diff --git a/Content/models/constraint_test.wiscene b/Content/models/constraint_test.wiscene index 024f4f318..fc3dcccd6 100644 Binary files a/Content/models/constraint_test.wiscene and b/Content/models/constraint_test.wiscene differ diff --git a/Editor/ConstraintWindow.cpp b/Editor/ConstraintWindow.cpp index 7dedf8181..1882d05c6 100644 --- a/Editor/ConstraintWindow.cpp +++ b/Editor/ConstraintWindow.cpp @@ -85,6 +85,7 @@ void ConstraintWindow::Create(EditorComponent* _editor) typeComboBox.AddItem("Cone", (uint64_t)PhysicsConstraintComponent::Type::Cone); typeComboBox.AddItem("Six DOF", (uint64_t)PhysicsConstraintComponent::Type::SixDOF); typeComboBox.AddItem("Swing Twist", (uint64_t)PhysicsConstraintComponent::Type::SwingTwist); + typeComboBox.AddItem("Slider", (uint64_t)PhysicsConstraintComponent::Type::Slider); typeComboBox.OnSelect([&](wi::gui::EventArgs args) { wi::scene::Scene& scene = editor->GetCurrentScene(); for (auto& x : editor->translator.selected) @@ -158,6 +159,9 @@ void ConstraintWindow::Create(EditorComponent* _editor) case PhysicsConstraintComponent::Type::SwingTwist: physicscomponent->swing_twist.min_twist_angle = wi::math::DegreesToRadians(args.fValue); break; + case PhysicsConstraintComponent::Type::Slider: + physicscomponent->slider_constraint.min_limit = args.fValue; + break; default: break; } @@ -186,6 +190,9 @@ void ConstraintWindow::Create(EditorComponent* _editor) case PhysicsConstraintComponent::Type::SwingTwist: physicscomponent->swing_twist.max_twist_angle = wi::math::DegreesToRadians(args.fValue); break; + case PhysicsConstraintComponent::Type::Slider: + physicscomponent->slider_constraint.max_limit = args.fValue; + break; default: break; } @@ -560,6 +567,14 @@ void ConstraintWindow::SetEntity(Entity entity) minSlider.SetValue(physicsComponent->distance_constraint.min_distance); maxSlider.SetValue(physicsComponent->distance_constraint.max_distance); break; + case PhysicsConstraintComponent::Type::Slider: + minSlider.SetText("Min limit: "); + maxSlider.SetText("Max limit: "); + minSlider.SetRange(-10, 0); + maxSlider.SetRange(0, 10); + minSlider.SetValue(physicsComponent->slider_constraint.min_limit); + maxSlider.SetValue(physicsComponent->slider_constraint.max_limit); + break; case PhysicsConstraintComponent::Type::Hinge: minSlider.SetText("Min angle: "); maxSlider.SetText("Max angle: "); @@ -684,6 +699,7 @@ void ConstraintWindow::ResizeLayout() switch (physicsComponent->type) { case PhysicsConstraintComponent::Type::Distance: + case PhysicsConstraintComponent::Type::Slider: case PhysicsConstraintComponent::Type::Hinge: minSlider.SetVisible(true); maxSlider.SetVisible(true); diff --git a/WickedEngine/wiPhysics_Jolt.cpp b/WickedEngine/wiPhysics_Jolt.cpp index f8cdbc22c..1be526673 100644 --- a/WickedEngine/wiPhysics_Jolt.cpp +++ b/WickedEngine/wiPhysics_Jolt.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -1072,6 +1073,15 @@ namespace wi::physics settings.mTwistMaxAngle = physicscomponent.swing_twist.max_twist_angle; physicsobject.constraint = settings.Create(*body1, *body2); } + else if (physicscomponent.type == PhysicsConstraintComponent::Type::Slider) + { + SliderConstraintSettings settings; + settings.mSpace = EConstraintSpace::WorldSpace; + settings.mPoint1 = settings.mPoint2 = cast(transform.GetPosition()); + settings.mSliderAxis1 = settings.mSliderAxis2 = cast(transform.GetRight()).Normalized(); + settings.mNormalAxis1 = settings.mNormalAxis2 = cast(transform.GetUp()).Normalized(); + physicsobject.constraint = settings.Create(*body1, *body2); + } else { wilog("Constraint creation failed: constraint type is not valid!"); @@ -2053,6 +2063,11 @@ namespace wi::physics ptr->SetTwistMinAngle(physicscomponent.swing_twist.min_twist_angle); ptr->SetTwistMaxAngle(physicscomponent.swing_twist.max_twist_angle); } + else if (physicscomponent.type == PhysicsConstraintComponent::Type::Slider) + { + SliderConstraint* ptr = ((SliderConstraint*)constraint.constraint.GetPtr()); + ptr->SetLimits(physicscomponent.slider_constraint.min_limit, physicscomponent.slider_constraint.max_limit); + } } }); diff --git a/WickedEngine/wiScene.h b/WickedEngine/wiScene.h index f78d4fcec..371b77007 100644 --- a/WickedEngine/wiScene.h +++ b/WickedEngine/wiScene.h @@ -63,7 +63,7 @@ namespace wi::scene wi::ecs::ComponentManager& voxel_grids = componentLibrary.Register("wi::scene::Scene::voxel_grids"); wi::ecs::ComponentManager& metadatas = componentLibrary.Register("wi::scene::Scene::metadatas"); wi::ecs::ComponentManager& characters = componentLibrary.Register("wi::scene::Scene::characters"); - wi::ecs::ComponentManager& constraints = componentLibrary.Register("wi::scene::Scene::constraints", 3); // version = 3 + wi::ecs::ComponentManager& constraints = componentLibrary.Register("wi::scene::Scene::constraints", 4); // version = 4 // Non-serialized attributes: float dt = 0; diff --git a/WickedEngine/wiScene_Components.h b/WickedEngine/wiScene_Components.h index b8ea77094..b8f2e7cb4 100644 --- a/WickedEngine/wiScene_Components.h +++ b/WickedEngine/wiScene_Components.h @@ -536,15 +536,23 @@ namespace wi::scene }; uint32_t _flags = EMPTY; + // Note: the constraint axes are taken from the TransformComponent on the constraint's entity + // RIGHT axis means X axis in the default orientation + // UP axis means Y axis in the default orientation + // + // The constraints are created in world space from the current TransformComponent orientation + // To issue recreation of the constraint, reset the physicsobject pointer of this structure + // To only refresh cosntraint settings without recreating the constraint, use SetRefreshParametersNeeded(true) enum class Type { Fixed, // fixed in place completely Point, // fixed to a point but can rotate around it Distance, // point constraint within specified distance Hinge, // rotation around a point on the UP axis of the contraint transform - Cone, // constrain to a cone shape specified by the cone angle + Cone, // constrain to a cone shape specified by the cone angle (cone axis: UP) SixDOF, // manual specification of axes movement and rotation limits - SwingTwist, // cone + rotational limits + SwingTwist, // cone (UP axis) + rotational limits + Slider, // constrain on the RIGHT axis between limits } type = Type::Fixed; wi::ecs::Entity bodyA = wi::ecs::INVALID_ENTITY; @@ -561,12 +569,12 @@ namespace wi::scene float min_angle = -XM_PI; // radians float max_angle = XM_PI; // radians float target_angular_velocity = 0; // motor - } hinge_constraint; // note: hinge axis is UP, normal axis is RIGHT directions of the TransformComponent on this entity + } hinge_constraint; struct ConeConstraintSettings { float half_cone_angle = 0; // radians - } cone_constraint; // note: cone axis is RIGHT of the TransformComponent on this entity + } cone_constraint; struct SixDOFConstraintSettings { @@ -598,6 +606,12 @@ namespace wi::scene float max_twist_angle = 0; // radians [-PI, PI] } swing_twist; + struct SliderConstraintSettings + { + float min_limit = -FLT_MAX; + float max_limit = FLT_MAX; + } slider_constraint; + // Non-serialized attributes: std::shared_ptr physicsobject = nullptr; // You can set to null to recreate the physics object the next time phsyics system will be running. diff --git a/WickedEngine/wiScene_Serializers.cpp b/WickedEngine/wiScene_Serializers.cpp index c69c1c1e3..03505cd31 100644 --- a/WickedEngine/wiScene_Serializers.cpp +++ b/WickedEngine/wiScene_Serializers.cpp @@ -940,6 +940,11 @@ namespace wi::scene { archive >> hinge_constraint.target_angular_velocity; } + if (seri.GetVersion() >= 4) + { + archive >> slider_constraint.min_limit; + archive >> slider_constraint.max_limit; + } } else { @@ -970,6 +975,11 @@ namespace wi::scene { archive << hinge_constraint.target_angular_velocity; } + if (seri.GetVersion() >= 4) + { + archive << slider_constraint.min_limit; + archive << slider_constraint.max_limit; + } } } void SoftBodyPhysicsComponent::Serialize(wi::Archive& archive, EntitySerializer& seri) diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index edf8af635..b56a6e10f 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 735; + const int revision = 736; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);