Browse Source

Added ability to specify the model space axis of the wheel so that it is easier to place a wheel model in world space regardless of how the wheel was modelled and what is up

Jorrit Rouwe 4 years ago
parent
commit
25a6c9b0e3

+ 10 - 4
Jolt/Physics/Vehicle/VehicleConstraint.cpp

@@ -116,23 +116,29 @@ VehicleConstraint::~VehicleConstraint()
 		delete w;
 }
 
-Mat44 VehicleConstraint::GetWheelLocalTransform(uint inWheelIndex) const
+Mat44 VehicleConstraint::GetWheelLocalTransform(uint inWheelIndex, Vec3Arg inWheelRight, Vec3Arg inWheelUp) const
 {
 	JPH_ASSERT(inWheelIndex < mWheels.size());
 
 	const Wheel *wheel = mWheels[inWheelIndex];
 	const WheelSettings *settings = wheel->mSettings;
 
+	// Use the two vectors provided to calculate a matrix that takes us from wheel model space to X = right, Y = up, Z = forward (the space where we will rotate the wheel)
+	Mat44 wheel_to_rotational = Mat44(Vec4(inWheelRight, 0), Vec4(inWheelUp, 0), Vec4(inWheelUp.Cross(inWheelRight), 0), Vec4(0, 0, 0, 1)).Transposed();
+
+	// Calculate the matrix that takes us from the rotational space to vehicle local space
 	Vec3 local_forward = Quat::sRotation(mUp, wheel->mSteerAngle) * mForward;
 	Vec3 local_right = local_forward.Cross(mUp);
 	Vec3 local_wheel_pos = settings->mPosition + settings->mDirection * (wheel->mContactLength - settings->mRadius);
+	Mat44 rotational_to_local(Vec4(local_right, 0), Vec4(mUp, 0), Vec4(local_forward, 0), Vec4(local_wheel_pos, 1));
 
-	return Mat44(Vec4(mUp, 0), Vec4(local_right, 0), Vec4(local_forward, 0), Vec4(local_wheel_pos, 1)) * Mat44::sRotationY(-wheel->mAngle); // Flip wheel angle because positive is rolling forwards
+	// Calculate transform of rotated wheel
+	return rotational_to_local * Mat44::sRotationX(wheel->mAngle) * wheel_to_rotational;
 }
 
-Mat44 VehicleConstraint::GetWheelWorldTransform(uint inWheelIndex) const
+Mat44 VehicleConstraint::GetWheelWorldTransform(uint inWheelIndex, Vec3Arg inWheelRight, Vec3Arg inWheelUp) const
 {
-	return mBody->GetWorldTransform() * GetWheelLocalTransform(inWheelIndex);
+	return mBody->GetWorldTransform() * GetWheelLocalTransform(inWheelIndex, inWheelRight, inWheelUp);
 }
 
 void VehicleConstraint::OnStep(float inDeltaTime, PhysicsSystem &inPhysicsSystem)

+ 8 - 2
Jolt/Physics/Vehicle/VehicleConstraint.h

@@ -74,10 +74,16 @@ public:
 	Wheels &					GetWheels()									{ return mWheels; }
 
 	/// Get the transform of a wheel in local space to the vehicle body, returns a matrix that transforms a cylinder aligned with the Y axis in body space (not COM space)
-	Mat44						GetWheelLocalTransform(uint inWheelIndex) const;
+	/// @param inWheelIndex Index of the wheel to fetch
+	/// @param inWheelRight Unit vector that indicates right in model space of the wheel (so if you only have 1 wheel model, you probably want to specify the opposite direction for the left and right wheels)
+	/// @param inWheelUp Unit vector that indicates up in model space of the wheel
+	Mat44						GetWheelLocalTransform(uint inWheelIndex, Vec3Arg inWheelRight, Vec3Arg inWheelUp) const;
 
 	/// Get the transform of a wheel in world space, returns a matrix that transforms a cylinder aligned with the Y axis in world space
-	Mat44						GetWheelWorldTransform(uint inWheelIndex) const;
+	/// @param inWheelIndex Index of the wheel to fetch
+	/// @param inWheelRight Unit vector that indicates right in model space of the wheel (so if you only have 1 wheel model, you probably want to specify the opposite direction for the left and right wheels)
+	/// @param inWheelUp Unit vector that indicates up in model space of the wheel
+	Mat44						GetWheelWorldTransform(uint inWheelIndex, Vec3Arg inWheelRight, Vec3Arg inWheelUp) const;
 
 	// Generic interface of a constraint
 	virtual bool				IsActive() const override					{ return mIsActive && Constraint::IsActive(); }

+ 1 - 1
Samples/Tests/Vehicle/TankTest.cpp

@@ -278,7 +278,7 @@ void TankTest::PrePhysicsUpdate(const PreUpdateParams &inParams)
 	for (uint w = 0; w < mVehicleConstraint->GetWheels().size(); ++w)
 	{
 		const WheelSettings *settings = mVehicleConstraint->GetWheels()[w]->GetSettings();
-		Mat44 wheel_transform = mVehicleConstraint->GetWheelWorldTransform(w);
+		Mat44 wheel_transform = mVehicleConstraint->GetWheelWorldTransform(w, Vec3::sAxisY(), Vec3::sAxisX()); // The cylinder we draw is aligned with Y so we specify that as rotational axis
 		mDebugRenderer->DrawCylinder(wheel_transform, 0.5f * settings->mWidth, settings->mRadius, Color::sGreen);
 	}
 }

+ 1 - 1
Samples/Tests/Vehicle/VehicleConstraintTest.cpp

@@ -160,7 +160,7 @@ void VehicleConstraintTest::PrePhysicsUpdate(const PreUpdateParams &inParams)
 	for (uint w = 0; w < 4; ++w)
 	{
 		const WheelSettings *settings = mVehicleConstraint->GetWheels()[w]->GetSettings();
-		Mat44 wheel_transform = mVehicleConstraint->GetWheelWorldTransform(w);
+		Mat44 wheel_transform = mVehicleConstraint->GetWheelWorldTransform(w, Vec3::sAxisY(), Vec3::sAxisX()); // The cyclinder we draw is aligned with Y so we specify that as rotational axis
 		mDebugRenderer->DrawCylinder(wheel_transform, 0.5f * settings->mWidth, settings->mRadius, Color::sGreen);
 	}
 }