diff --git a/Content/models/vehicle_test.wiscene b/Content/models/vehicle_test.wiscene index fea9ccffef..52e6d04e44 100644 Binary files a/Content/models/vehicle_test.wiscene and b/Content/models/vehicle_test.wiscene differ diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 98fce7602e..201769328b 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -1513,6 +1513,8 @@ void EditorComponent::Update(float dt) { drive_orbit_horizontal -= XM_PI * dt; } + drive_cam_dist_next -= wi::input::GetPointer().z; + drive_cam_dist = lerp(drive_cam_dist, drive_cam_dist_next, dt * 2); drive_steering_smoothed = clamp(drive_steering_smoothed, -1.0f, 1.0f); @@ -2920,11 +2922,11 @@ void EditorComponent::PostUpdate() XMMATRIX W = XMMatrixIdentity(); if (rigidbody->vehicle.type == RigidBodyPhysicsComponent::Vehicle::Type::Car) { - W = XMMatrixTranslation(0, 0.5f, -6) * XMMatrixRotationX(XM_PI * 0.08f) * XMMatrixRotationY(drive_orbit_horizontal) * XMMatrixRotationQuaternion(Q) * XMMatrixTranslationFromVector(P); + W = XMMatrixTranslation(0, 0.5f, -drive_cam_dist) * XMMatrixRotationX(XM_PI * 0.08f) * XMMatrixRotationY(drive_orbit_horizontal) * XMMatrixRotationQuaternion(Q) * XMMatrixTranslationFromVector(P); } else if (rigidbody->vehicle.type == RigidBodyPhysicsComponent::Vehicle::Type::Motorcycle) { - W = XMMatrixTranslation(0, 1.5f, -7) * XMMatrixRotationX(XM_PI * 0.1f) * XMMatrixRotationY(drive_orbit_horizontal) * XMMatrixRotationQuaternion(Q) * XMMatrixTranslationFromVector(P); + W = XMMatrixTranslation(0, 1.5f, -drive_cam_dist) * XMMatrixRotationX(XM_PI * 0.1f) * XMMatrixRotationY(drive_orbit_horizontal) * XMMatrixRotationQuaternion(Q) * XMMatrixTranslationFromVector(P); } camera.TransformCamera(W); camera.UpdateCamera(); diff --git a/Editor/Editor.h b/Editor/Editor.h index df6a75dc93..d8fd3d861b 100644 --- a/Editor/Editor.h +++ b/Editor/Editor.h @@ -33,6 +33,8 @@ class EditorComponent : public wi::RenderPath2D XMFLOAT3 dummy_pos = XMFLOAT3(0, 0, 0); bool drive_mode = false; + float drive_cam_dist_next = 7; + float drive_cam_dist = drive_cam_dist_next; float drive_orbit_horizontal = 0; float drive_steering_smoothed = 0; diff --git a/Editor/RigidBodyWindow.cpp b/Editor/RigidBodyWindow.cpp index d685c244c8..9766c88d94 100644 --- a/Editor/RigidBodyWindow.cpp +++ b/Editor/RigidBodyWindow.cpp @@ -359,6 +359,18 @@ void RigidBodyWindow::Create(EditorComponent* _editor) AddWidget(&physicsDebugCheckBox); + vehicleLabel.Create("VehicleLabel"); + std::string tips; + tips += "Vehicle physics tips:\n"; + tips += "- The vehicle's base shape can be configured in the standard shape settings above\n"; + tips += "- A vehicle is always facing forward in +Z direction by default\n"; + tips += "- Check that mass is set higher than the default 1kg, somewhere around ~1000 kg\n"; + tips += "- Enable physics visualizer while editing vehicle parameters\n"; + tips += "- You can reset vehicles by Ctrl + left click on the physics toggle button\n"; + vehicleLabel.SetText(tips); + vehicleLabel.SetSize(XMFLOAT2(100, 240)); + AddWidget(&vehicleLabel); + vehicleCombo.Create("Vehicle physics: "); vehicleCombo.AddItem("None", (uint64_t)RigidBodyPhysicsComponent::Vehicle::Type::None); vehicleCombo.AddItem("Car", (uint64_t)RigidBodyPhysicsComponent::Vehicle::Type::Car); @@ -1050,6 +1062,7 @@ void RigidBodyWindow::ResizeLayout() add(vehicleCombo); if (vehicleCombo.GetSelected() > 0) { + vehicleLabel.SetVisible(true); vehicleCollisionCombo.SetVisible(true); wheelRadiusSlider.SetVisible(true); wheelWidthSlider.SetVisible(true); @@ -1073,6 +1086,8 @@ void RigidBodyWindow::ResizeLayout() rSuspensionFrequencySlider.SetVisible(true); rSuspensionDampingSlider.SetVisible(true); + add_fullwidth(vehicleLabel); + add_right(driveCheckbox); add(vehicleCollisionCombo); @@ -1142,6 +1157,7 @@ void RigidBodyWindow::ResizeLayout() } else { + vehicleLabel.SetVisible(false); vehicleCollisionCombo.SetVisible(false); wheelRadiusSlider.SetVisible(false); wheelWidthSlider.SetVisible(false); diff --git a/Editor/RigidBodyWindow.h b/Editor/RigidBodyWindow.h index eb0d6629e9..49f9a5abd1 100644 --- a/Editor/RigidBodyWindow.h +++ b/Editor/RigidBodyWindow.h @@ -32,6 +32,7 @@ class RigidBodyWindow : public wi::gui::Window wi::gui::Slider offsetZSlider; wi::gui::CheckBox physicsDebugCheckBox; + wi::gui::Label vehicleLabel; wi::gui::ComboBox vehicleCombo; wi::gui::ComboBox vehicleCollisionCombo; wi::gui::Slider wheelRadiusSlider; diff --git a/WickedEngine/wiPhysics_Jolt.cpp b/WickedEngine/wiPhysics_Jolt.cpp index 8626881bd8..ff41583fda 100644 --- a/WickedEngine/wiPhysics_Jolt.cpp +++ b/WickedEngine/wiPhysics_Jolt.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -289,11 +290,14 @@ namespace wi::physics BodyInterface& body_interface = jolt_physics_scene->physics_system.GetBodyInterface(); // locking version because destructor can be called from any thread body_interface.RemoveBody(bodyID); body_interface.DestroyBody(bodyID); + bodyID = {}; if (vehicle_constraint != nullptr) { jolt_physics_scene->physics_system.RemoveStepListener(vehicle_constraint); jolt_physics_scene->physics_system.RemoveConstraint(vehicle_constraint); + vehicle_constraint = nullptr; } + shape = nullptr; } ~RigidBody() @@ -472,13 +476,15 @@ namespace wi::physics static constexpr float sRearCamber = 0.0f; static constexpr float sRearToe = 0.0f; + const float wheel_offset_to_zero = 0.5f; // not sure why but without this, wheels are offset to -0.5 vertically + if (physicscomponent.IsCar()) { const float wheel_radius = physicscomponent.vehicle.wheel_radius; const float wheel_width = physicscomponent.vehicle.wheel_width; const float half_vehicle_length = physicscomponent.vehicle.chassis_half_length; const float half_vehicle_width = physicscomponent.vehicle.chassis_half_width; - const float half_vehicle_height = physicscomponent.vehicle.chassis_half_height; + const float half_vehicle_height = physicscomponent.vehicle.chassis_half_height + wheel_offset_to_zero; const float front_wheel_offset = physicscomponent.vehicle.front_wheel_offset; const float rear_wheel_offset = physicscomponent.vehicle.rear_wheel_offset; const bool four_wheel_drive = physicscomponent.vehicle.car.four_wheel_drive; @@ -664,7 +670,7 @@ namespace wi::physics const float front_suspension_max_length = physicscomponent.vehicle.front_suspension.max_length; const float front_suspension_freq = physicscomponent.vehicle.front_suspension.frequency; const float front_brake_torque = physicscomponent.vehicle.motorcycle.front_brake_torque; - const float half_vehicle_height = physicscomponent.vehicle.chassis_half_height; + const float half_vehicle_height = physicscomponent.vehicle.chassis_half_height + wheel_offset_to_zero; const float max_steering_angle = physicscomponent.vehicle.max_steering_angle; @@ -1532,6 +1538,12 @@ namespace wi::physics RigidBody& physicsobject = GetRigidBody(physicscomponent); physicsobject.shape = shape_result.Get(); + + if (physicscomponent.IsVehicle()) + { + // Vehicle center of mass will be offset to chassis height to improve handling: + physicsobject.shape = OffsetCenterOfMassShapeSettings(Vec3(0, physicscomponent.vehicle.chassis_half_height, 0), physicsobject.shape).Create().Get(); + } } bool IsEnabled() { return ENABLED; } @@ -2204,6 +2216,7 @@ namespace wi::physics static JoltDebugRenderer debug_renderer; BodyManager::DrawSettings settings; settings.mDrawCenterOfMassTransform = false; + settings.mDrawMassAndInertia = false; settings.mDrawShape = true; settings.mDrawSoftBodyVertices = true; settings.mDrawSoftBodyEdgeConstraints = true;