sixdof constraint

This commit is contained in:
Turánszki János
2025-04-06 12:45:41 +02:00
parent 27c770b9cc
commit 8bff4ee849
9 changed files with 552 additions and 18 deletions
Binary file not shown.
+398 -5
View File
@@ -50,6 +50,7 @@ void ConstraintWindow::Create(EditorComponent* _editor)
typeComboBox.AddItem("Distance", (uint64_t)PhysicsConstraintComponent::Type::Distance);
typeComboBox.AddItem("Hinge", (uint64_t)PhysicsConstraintComponent::Type::Hinge);
typeComboBox.AddItem("Cone", (uint64_t)PhysicsConstraintComponent::Type::Cone);
typeComboBox.AddItem("Six DOF", (uint64_t)PhysicsConstraintComponent::Type::SixDOF);
typeComboBox.OnSelect([&](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
@@ -123,7 +124,7 @@ void ConstraintWindow::Create(EditorComponent* _editor)
default:
break;
}
physicscomponent->physicsobject = nullptr;
physicscomponent->SetRefreshParametersNeeded(true);
}
}
});
@@ -148,13 +149,295 @@ void ConstraintWindow::Create(EditorComponent* _editor)
default:
break;
}
physicscomponent->physicsobject = nullptr;
physicscomponent->SetRefreshParametersNeeded(true);
}
}
});
AddWidget(&maxSlider);
fixedXButton.Create("Fix X");
fixedXButton.OnClick([=](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
PhysicsConstraintComponent* physicscomponent = scene.constraints.GetComponent(x.entity);
if (physicscomponent != nullptr)
{
physicscomponent->six_dof.SetFixedX();
physicscomponent->SetRefreshParametersNeeded(true);
}
}
SetEntity(entity);
});
AddWidget(&fixedXButton);
fixedYButton.Create("Fix Y");
fixedYButton.OnClick([=](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
PhysicsConstraintComponent* physicscomponent = scene.constraints.GetComponent(x.entity);
if (physicscomponent != nullptr)
{
physicscomponent->six_dof.SetFixedY();
physicscomponent->SetRefreshParametersNeeded(true);
}
}
SetEntity(entity);
});
AddWidget(&fixedYButton);
fixedZButton.Create("Fix Z");
fixedZButton.OnClick([=](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
PhysicsConstraintComponent* physicscomponent = scene.constraints.GetComponent(x.entity);
if (physicscomponent != nullptr)
{
physicscomponent->six_dof.SetFixedZ();
physicscomponent->SetRefreshParametersNeeded(true);
}
}
SetEntity(entity);
});
AddWidget(&fixedZButton);
fixedXRotationButton.Create("Fix Rot X");
fixedXRotationButton.OnClick([=](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
PhysicsConstraintComponent* physicscomponent = scene.constraints.GetComponent(x.entity);
if (physicscomponent != nullptr)
{
physicscomponent->six_dof.SetFixedRotationX();
physicscomponent->SetRefreshParametersNeeded(true);
}
}
SetEntity(entity);
});
AddWidget(&fixedXRotationButton);
fixedYRotationButton.Create("Fix Rot Y");
fixedYRotationButton.OnClick([=](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
PhysicsConstraintComponent* physicscomponent = scene.constraints.GetComponent(x.entity);
if (physicscomponent != nullptr)
{
physicscomponent->six_dof.SetFixedRotationY();
physicscomponent->SetRefreshParametersNeeded(true);
}
}
SetEntity(entity);
});
AddWidget(&fixedYRotationButton);
fixedZRotationButton.Create("Fix Rot Z");
fixedZRotationButton.OnClick([=](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
PhysicsConstraintComponent* physicscomponent = scene.constraints.GetComponent(x.entity);
if (physicscomponent != nullptr)
{
physicscomponent->six_dof.SetFixedRotationZ();
physicscomponent->SetRefreshParametersNeeded(true);
}
}
SetEntity(entity);
});
AddWidget(&fixedZRotationButton);
minTranslationXSlider.Create(-10, 0, 1, 100000, "Min Translation X: ");
minTranslationXSlider.OnSlide([&](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
PhysicsConstraintComponent* physicscomponent = scene.constraints.GetComponent(x.entity);
if (physicscomponent != nullptr)
{
physicscomponent->six_dof.minTranslationAxes.x = args.fValue;
physicscomponent->SetRefreshParametersNeeded(true);
}
}
});
AddWidget(&minTranslationXSlider);
minTranslationYSlider.Create(-10, 0, 1, 100000, "Min Translation Y: ");
minTranslationYSlider.OnSlide([&](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
PhysicsConstraintComponent* physicscomponent = scene.constraints.GetComponent(x.entity);
if (physicscomponent != nullptr)
{
physicscomponent->six_dof.minTranslationAxes.y = args.fValue;
physicscomponent->SetRefreshParametersNeeded(true);
}
}
});
AddWidget(&minTranslationYSlider);
minTranslationZSlider.Create(-10, 0, 1, 100000, "Min Translation Z: ");
minTranslationZSlider.OnSlide([&](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
PhysicsConstraintComponent* physicscomponent = scene.constraints.GetComponent(x.entity);
if (physicscomponent != nullptr)
{
physicscomponent->six_dof.minTranslationAxes.z = args.fValue;
physicscomponent->SetRefreshParametersNeeded(true);
}
}
});
AddWidget(&minTranslationZSlider);
maxTranslationXSlider.Create(0, 10, 1, 100000, "Max Translation X: ");
maxTranslationXSlider.OnSlide([&](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
PhysicsConstraintComponent* physicscomponent = scene.constraints.GetComponent(x.entity);
if (physicscomponent != nullptr)
{
physicscomponent->six_dof.maxTranslationAxes.x = args.fValue;
physicscomponent->SetRefreshParametersNeeded(true);
}
}
});
AddWidget(&maxTranslationXSlider);
maxTranslationYSlider.Create(0, 10, 1, 100000, "Max Translation Y: ");
maxTranslationYSlider.OnSlide([&](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
PhysicsConstraintComponent* physicscomponent = scene.constraints.GetComponent(x.entity);
if (physicscomponent != nullptr)
{
physicscomponent->six_dof.maxTranslationAxes.y = args.fValue;
physicscomponent->SetRefreshParametersNeeded(true);
}
}
});
AddWidget(&maxTranslationYSlider);
maxTranslationZSlider.Create(0, 10, 1, 100000, "Max Translation Z: ");
maxTranslationZSlider.OnSlide([&](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
PhysicsConstraintComponent* physicscomponent = scene.constraints.GetComponent(x.entity);
if (physicscomponent != nullptr)
{
physicscomponent->six_dof.maxTranslationAxes.z = args.fValue;
physicscomponent->SetRefreshParametersNeeded(true);
}
}
});
AddWidget(&maxTranslationZSlider);
minRotationXSlider.Create(-180, 0, 1, 100000, "Min Rotation X: ");
minRotationXSlider.OnSlide([&](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
PhysicsConstraintComponent* physicscomponent = scene.constraints.GetComponent(x.entity);
if (physicscomponent != nullptr)
{
physicscomponent->six_dof.minRotationAxes.x = wi::math::DegreesToRadians(args.fValue);
physicscomponent->SetRefreshParametersNeeded(true);
}
}
});
AddWidget(&minRotationXSlider);
minRotationYSlider.Create(-180, 0, 1, 100000, "Min Rotation Y: ");
minRotationYSlider.OnSlide([&](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
PhysicsConstraintComponent* physicscomponent = scene.constraints.GetComponent(x.entity);
if (physicscomponent != nullptr)
{
physicscomponent->six_dof.minRotationAxes.y = wi::math::DegreesToRadians(args.fValue);
physicscomponent->SetRefreshParametersNeeded(true);
}
}
});
AddWidget(&minRotationYSlider);
minRotationZSlider.Create(-180, 0, 1, 100000, "Min Rotation Z: ");
minRotationZSlider.OnSlide([&](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
PhysicsConstraintComponent* physicscomponent = scene.constraints.GetComponent(x.entity);
if (physicscomponent != nullptr)
{
physicscomponent->six_dof.minRotationAxes.z = wi::math::DegreesToRadians(args.fValue);
physicscomponent->SetRefreshParametersNeeded(true);
}
}
});
AddWidget(&minRotationZSlider);
maxRotationXSlider.Create(0, 180, 1, 100000, "Max Rotation X: ");
maxRotationXSlider.OnSlide([&](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
PhysicsConstraintComponent* physicscomponent = scene.constraints.GetComponent(x.entity);
if (physicscomponent != nullptr)
{
physicscomponent->six_dof.maxRotationAxes.x = wi::math::DegreesToRadians(args.fValue);
physicscomponent->SetRefreshParametersNeeded(true);
}
}
});
AddWidget(&maxRotationXSlider);
maxRotationYSlider.Create(0, 180, 1, 100000, "Max Rotation Y: ");
maxRotationYSlider.OnSlide([&](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
PhysicsConstraintComponent* physicscomponent = scene.constraints.GetComponent(x.entity);
if (physicscomponent != nullptr)
{
physicscomponent->six_dof.maxRotationAxes.y = wi::math::DegreesToRadians(args.fValue);
physicscomponent->SetRefreshParametersNeeded(true);
}
}
});
AddWidget(&maxRotationYSlider);
maxRotationZSlider.Create(0, 180, 1, 100000, "Max Rotation Z: ");
maxRotationZSlider.OnSlide([&](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
PhysicsConstraintComponent* physicscomponent = scene.constraints.GetComponent(x.entity);
if (physicscomponent != nullptr)
{
physicscomponent->six_dof.maxRotationAxes.z = wi::math::DegreesToRadians(args.fValue);
physicscomponent->SetRefreshParametersNeeded(true);
}
}
});
AddWidget(&maxRotationZSlider);
SetMinimized(true);
SetVisible(false);
@@ -169,8 +452,6 @@ void ConstraintWindow::SetEntity(Entity entity)
if (physicsComponent != nullptr)
{
if (this->entity == entity)
return;
this->entity = entity;
typeComboBox.SetSelectedByUserdataWithoutCallback((uint64_t)physicsComponent->type);
@@ -218,6 +499,19 @@ void ConstraintWindow::SetEntity(Entity entity)
}
bodyAComboBox.SetSelectedByUserdataWithoutCallback(physicsComponent->bodyA);
bodyBComboBox.SetSelectedByUserdataWithoutCallback(physicsComponent->bodyB);
minTranslationXSlider.SetValue(physicsComponent->six_dof.minTranslationAxes.x);
minTranslationYSlider.SetValue(physicsComponent->six_dof.minTranslationAxes.y);
minTranslationZSlider.SetValue(physicsComponent->six_dof.minTranslationAxes.z);
maxTranslationXSlider.SetValue(physicsComponent->six_dof.maxTranslationAxes.x);
maxTranslationYSlider.SetValue(physicsComponent->six_dof.maxTranslationAxes.y);
maxTranslationZSlider.SetValue(physicsComponent->six_dof.maxTranslationAxes.z);
minRotationXSlider.SetValue(wi::math::RadiansToDegrees(physicsComponent->six_dof.minRotationAxes.x));
minRotationYSlider.SetValue(wi::math::RadiansToDegrees(physicsComponent->six_dof.minRotationAxes.y));
minRotationZSlider.SetValue(wi::math::RadiansToDegrees(physicsComponent->six_dof.minRotationAxes.z));
maxRotationXSlider.SetValue(wi::math::RadiansToDegrees(physicsComponent->six_dof.maxRotationAxes.x));
maxRotationYSlider.SetValue(wi::math::RadiansToDegrees(physicsComponent->six_dof.maxRotationAxes.y));
maxRotationZSlider.SetValue(wi::math::RadiansToDegrees(physicsComponent->six_dof.maxRotationAxes.z));
}
else
{
@@ -236,7 +530,7 @@ void ConstraintWindow::ResizeLayout()
float jump = 20;
const float margin_left = 145;
const float margin_right = 40;
float margin_right = 40;
auto add = [&](wi::gui::Widget& widget) {
if (!widget.IsVisible())
@@ -281,14 +575,113 @@ void ConstraintWindow::ResizeLayout()
case PhysicsConstraintComponent::Type::Hinge:
minSlider.SetVisible(true);
maxSlider.SetVisible(true);
fixedXButton.SetVisible(false);
fixedYButton.SetVisible(false);
fixedZButton.SetVisible(false);
fixedXRotationButton.SetVisible(false);
fixedYRotationButton.SetVisible(false);
fixedZRotationButton.SetVisible(false);
minTranslationXSlider.SetVisible(false);
minTranslationYSlider.SetVisible(false);
minTranslationZSlider.SetVisible(false);
maxTranslationXSlider.SetVisible(false);
maxTranslationYSlider.SetVisible(false);
maxTranslationZSlider.SetVisible(false);
minRotationXSlider.SetVisible(false);
minRotationYSlider.SetVisible(false);
minRotationZSlider.SetVisible(false);
maxRotationXSlider.SetVisible(false);
maxRotationYSlider.SetVisible(false);
maxRotationZSlider.SetVisible(false);
break;
case PhysicsConstraintComponent::Type::Cone:
minSlider.SetVisible(true);
maxSlider.SetVisible(false);
fixedXButton.SetVisible(false);
fixedYButton.SetVisible(false);
fixedZButton.SetVisible(false);
fixedXRotationButton.SetVisible(false);
fixedYRotationButton.SetVisible(false);
fixedZRotationButton.SetVisible(false);
minTranslationXSlider.SetVisible(false);
minTranslationYSlider.SetVisible(false);
minTranslationZSlider.SetVisible(false);
maxTranslationXSlider.SetVisible(false);
maxTranslationYSlider.SetVisible(false);
maxTranslationZSlider.SetVisible(false);
minRotationXSlider.SetVisible(false);
minRotationYSlider.SetVisible(false);
minRotationZSlider.SetVisible(false);
maxRotationXSlider.SetVisible(false);
maxRotationYSlider.SetVisible(false);
maxRotationZSlider.SetVisible(false);
break;
case PhysicsConstraintComponent::Type::SixDOF:
minSlider.SetVisible(false);
maxSlider.SetVisible(false);
fixedXButton.SetVisible(true);
fixedYButton.SetVisible(true);
fixedZButton.SetVisible(true);
fixedXRotationButton.SetVisible(true);
fixedYRotationButton.SetVisible(true);
fixedZRotationButton.SetVisible(true);
minTranslationXSlider.SetVisible(true);
minTranslationYSlider.SetVisible(true);
minTranslationZSlider.SetVisible(true);
maxTranslationXSlider.SetVisible(true);
maxTranslationYSlider.SetVisible(true);
maxTranslationZSlider.SetVisible(true);
minRotationXSlider.SetVisible(true);
minRotationYSlider.SetVisible(true);
minRotationZSlider.SetVisible(true);
maxRotationXSlider.SetVisible(true);
maxRotationYSlider.SetVisible(true);
maxRotationZSlider.SetVisible(true);
add_fullwidth(fixedXButton);
add_fullwidth(fixedYButton);
add_fullwidth(fixedZButton);
add_fullwidth(fixedXRotationButton);
add_fullwidth(fixedYRotationButton);
add_fullwidth(fixedZRotationButton);
margin_right = 80;
add(minTranslationXSlider);
add(minTranslationYSlider);
add(minTranslationZSlider);
add(maxTranslationXSlider);
add(maxTranslationYSlider);
add(maxTranslationZSlider);
add(minRotationXSlider);
add(minRotationYSlider);
add(minRotationZSlider);
add(maxRotationXSlider);
add(maxRotationYSlider);
add(maxRotationZSlider);
break;
default:
minSlider.SetVisible(false);
maxSlider.SetVisible(false);
fixedXButton.SetVisible(false);
fixedYButton.SetVisible(false);
fixedZButton.SetVisible(false);
fixedXRotationButton.SetVisible(false);
fixedYRotationButton.SetVisible(false);
fixedZRotationButton.SetVisible(false);
minTranslationXSlider.SetVisible(false);
minTranslationYSlider.SetVisible(false);
minTranslationZSlider.SetVisible(false);
maxTranslationXSlider.SetVisible(false);
maxTranslationYSlider.SetVisible(false);
maxTranslationZSlider.SetVisible(false);
minRotationXSlider.SetVisible(false);
minRotationYSlider.SetVisible(false);
minRotationZSlider.SetVisible(false);
maxRotationXSlider.SetVisible(false);
maxRotationYSlider.SetVisible(false);
maxRotationZSlider.SetVisible(false);
break;
}
+19
View File
@@ -18,6 +18,25 @@ public:
wi::gui::Slider minSlider;
wi::gui::Slider maxSlider;
wi::gui::Button fixedXButton;
wi::gui::Button fixedYButton;
wi::gui::Button fixedZButton;
wi::gui::Button fixedXRotationButton;
wi::gui::Button fixedYRotationButton;
wi::gui::Button fixedZRotationButton;
wi::gui::Slider minTranslationXSlider;
wi::gui::Slider minTranslationYSlider;
wi::gui::Slider minTranslationZSlider;
wi::gui::Slider maxTranslationXSlider;
wi::gui::Slider maxTranslationYSlider;
wi::gui::Slider maxTranslationZSlider;
wi::gui::Slider minRotationXSlider;
wi::gui::Slider minRotationYSlider;
wi::gui::Slider minRotationZSlider;
wi::gui::Slider maxRotationXSlider;
wi::gui::Slider maxRotationYSlider;
wi::gui::Slider maxRotationZSlider;
void ResizeLayout() override;
};
+1
View File
@@ -4,6 +4,7 @@
// This is a helper include file pasted into all engine headers, try to keep it minimal!
// Do not include engine features in this file!
#include <cfloat>
#include <cstdint>
#include <type_traits>
+27 -4
View File
@@ -1480,9 +1480,20 @@ namespace wi::gui
}
void TextInputField::SetValue(float newValue)
{
std::stringstream ss("");
ss << newValue;
font.SetText(ss.str());
if (newValue == FLT_MAX)
{
font.SetText(L"FLT_MAX");
}
else if (newValue == -FLT_MAX)
{
font.SetText(L"-FLT_MAX");
}
else
{
std::stringstream ss("");
ss << newValue;
font.SetText(ss.str());
}
}
const std::string TextInputField::GetValue()
{
@@ -1901,7 +1912,7 @@ namespace wi::gui
valueInputField.Create(name + "_endInputField");
valueInputField.SetLocalizationEnabled(LocalizationEnabled::None);
valueInputField.SetShadowRadius(0);
valueInputField.SetTooltip("Enter number to modify value even outside slider limits. Enter \"reset\" to reset slider to initial state.");
valueInputField.SetTooltip("Enter number to modify value even outside slider limits. Other inputs:\n - reset : reset slider to initial state.\n - FLT_MAX : float max value\n - -FLT_MAX : negative float max value.");
valueInputField.SetValue(end);
valueInputField.OnInputAccepted([this, start, end, defaultValue](EventArgs args) {
if (args.sValue.compare("reset") == 0)
@@ -1912,6 +1923,18 @@ namespace wi::gui
args.fValue = this->value;
args.iValue = (int)this->value;
}
else if (args.sValue.compare("FLT_MAX") == 0)
{
this->value = FLT_MAX;
args.fValue = this->value;
args.iValue = (int)this->value;
}
else if (args.sValue.compare("-FLT_MAX") == 0)
{
this->value = -FLT_MAX;
args.fValue = this->value;
args.iValue = (int)this->value;
}
else
{
this->value = args.fValue;
+56
View File
@@ -38,6 +38,7 @@
#include <Jolt/Physics/Constraints/SwingTwistConstraint.h>
#include <Jolt/Physics/Constraints/HingeConstraint.h>
#include <Jolt/Physics/Constraints/ConeConstraint.h>
#include <Jolt/Physics/Constraints/SixDOFConstraint.h>
#include <Jolt/Physics/Ragdoll/Ragdoll.h>
#include <Jolt/Skeleton/Skeleton.h>
#include <Jolt/Physics/Vehicle/VehicleConstraint.h>
@@ -1034,6 +1035,27 @@ namespace wi::physics
settings.mHalfConeAngle = physicscomponent.cone_constraint.half_cone_angle;
physicsobject.constraint = settings.Create(*body1, *body2);
}
else if (physicscomponent.type == PhysicsConstraintComponent::Type::SixDOF)
{
SixDOFConstraintSettings settings;
settings.mSpace = EConstraintSpace::WorldSpace;
settings.mPosition1 = settings.mPosition2 = cast(transform.GetPosition());
settings.mAxisX1 = settings.mAxisX2 = cast(transform.GetRight()).Normalized();
settings.mAxisY1 = settings.mAxisY2 = cast(transform.GetUp()).Normalized();
settings.mLimitMin[SixDOFConstraintSettings::EAxis::TranslationX] = physicscomponent.six_dof.minTranslationAxes.x;
settings.mLimitMin[SixDOFConstraintSettings::EAxis::TranslationY] = physicscomponent.six_dof.minTranslationAxes.y;
settings.mLimitMin[SixDOFConstraintSettings::EAxis::TranslationZ] = physicscomponent.six_dof.minTranslationAxes.z;
settings.mLimitMax[SixDOFConstraintSettings::EAxis::TranslationX] = physicscomponent.six_dof.maxTranslationAxes.x;
settings.mLimitMax[SixDOFConstraintSettings::EAxis::TranslationY] = physicscomponent.six_dof.maxTranslationAxes.y;
settings.mLimitMax[SixDOFConstraintSettings::EAxis::TranslationZ] = physicscomponent.six_dof.maxTranslationAxes.z;
settings.mLimitMin[SixDOFConstraintSettings::EAxis::RotationX] = physicscomponent.six_dof.minRotationAxes.x;
settings.mLimitMin[SixDOFConstraintSettings::EAxis::RotationY] = physicscomponent.six_dof.minRotationAxes.y;
settings.mLimitMin[SixDOFConstraintSettings::EAxis::RotationZ] = physicscomponent.six_dof.minRotationAxes.z;
settings.mLimitMax[SixDOFConstraintSettings::EAxis::RotationX] = physicscomponent.six_dof.maxRotationAxes.x;
settings.mLimitMax[SixDOFConstraintSettings::EAxis::RotationY] = physicscomponent.six_dof.maxRotationAxes.y;
settings.mLimitMax[SixDOFConstraintSettings::EAxis::RotationZ] = physicscomponent.six_dof.maxRotationAxes.z;
physicsobject.constraint = settings.Create(*body1, *body2);
}
else
{
wilog("Constraint creation failed: constraint type is not valid!");
@@ -1047,6 +1069,7 @@ namespace wi::physics
}
physics_scene.physics_system.AddConstraint(physicsobject.constraint);
physicscomponent.SetRefreshParametersNeeded(false);
}
struct Ragdoll
@@ -1934,6 +1957,39 @@ namespace wi::physics
return;
AddConstraint(scene, entity, physicscomponent, *transform);
}
if (physicscomponent.physicsobject != nullptr && physicscomponent.IsRefreshParametersNeeded())
{
physicscomponent.SetRefreshParametersNeeded(false);
Constraint& constraint = GetConstraint(physicscomponent);
if (physicscomponent.type == PhysicsConstraintComponent::Type::Fixed)
{
}
else if (physicscomponent.type == PhysicsConstraintComponent::Type::Point)
{
}
else if (physicscomponent.type == PhysicsConstraintComponent::Type::Distance)
{
DistanceConstraint* ptr = ((DistanceConstraint*)constraint.constraint.GetPtr());
ptr->SetDistance(physicscomponent.distance_constraint.min_distance, physicscomponent.distance_constraint.max_distance);
}
else if (physicscomponent.type == PhysicsConstraintComponent::Type::Hinge)
{
HingeConstraint* ptr = ((HingeConstraint*)constraint.constraint.GetPtr());
ptr->SetLimits(physicscomponent.hinge_constraint.min_angle, physicscomponent.hinge_constraint.max_angle);
}
else if (physicscomponent.type == PhysicsConstraintComponent::Type::Cone)
{
ConeConstraint* ptr = ((ConeConstraint*)constraint.constraint.GetPtr());
ptr->SetHalfConeAngle(physicscomponent.cone_constraint.half_cone_angle);
}
else if (physicscomponent.type == PhysicsConstraintComponent::Type::SixDOF)
{
SixDOFConstraint* ptr = ((SixDOFConstraint*)constraint.constraint.GetPtr());
ptr->SetTranslationLimits(cast(physicscomponent.six_dof.minTranslationAxes), cast(physicscomponent.six_dof.maxTranslationAxes));
ptr->SetRotationLimits(cast(physicscomponent.six_dof.minRotationAxes), cast(physicscomponent.six_dof.maxRotationAxes));
}
}
});
wi::jobsystem::Wait(ctx); // wait for all creations
+1 -1
View File
@@ -63,7 +63,7 @@ namespace wi::scene
wi::ecs::ComponentManager<wi::VoxelGrid>& voxel_grids = componentLibrary.Register<wi::VoxelGrid>("wi::scene::Scene::voxel_grids");
wi::ecs::ComponentManager<MetadataComponent>& metadatas = componentLibrary.Register<MetadataComponent>("wi::scene::Scene::metadatas");
wi::ecs::ComponentManager<CharacterComponent>& characters = componentLibrary.Register<CharacterComponent>("wi::scene::Scene::characters");
wi::ecs::ComponentManager<PhysicsConstraintComponent>& constraints = componentLibrary.Register<PhysicsConstraintComponent>("wi::scene::Scene::constraints");
wi::ecs::ComponentManager<PhysicsConstraintComponent>& constraints = componentLibrary.Register<PhysicsConstraintComponent>("wi::scene::Scene::constraints", 1); // version = 1
// Non-serialized attributes:
float dt = 0;
+36 -8
View File
@@ -531,16 +531,18 @@ namespace wi::scene
enum FLAGS
{
EMPTY = 0,
REFRESH_PARAMETERS_REQUEST = 1 << 0,
};
uint32_t _flags = EMPTY;
enum class Type
{
Fixed,
Point,
Distance,
Hinge,
Cone,
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
SixDOF, // manual specification of axes movement and rotation limits
} type = Type::Fixed;
wi::ecs::Entity bodyA = wi::ecs::INVALID_ENTITY;
@@ -554,18 +556,44 @@ namespace wi::scene
struct HingeConstraintSettings
{
float min_angle = -XM_PI;
float max_angle = XM_PI;
float min_angle = -XM_PI; // radians
float max_angle = XM_PI; // radians
} hinge_constraint; // note: hinge axis is UP, normal axis is RIGHT directions of the TransformComponent on this entity
struct ConeConstraintSettings
{
float half_cone_angle = 0;
float half_cone_angle = 0; // radians
} cone_constraint; // note: cone axis is RIGHT of the TransformComponent on this entity
struct SixDOFConstraintSettings
{
XMFLOAT3 minTranslationAxes = XMFLOAT3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
XMFLOAT3 maxTranslationAxes = XMFLOAT3(FLT_MAX, FLT_MAX, FLT_MAX);
XMFLOAT3 minRotationAxes = XMFLOAT3(-XM_PI, -XM_PI, -XM_PI);
XMFLOAT3 maxRotationAxes = XMFLOAT3(XM_PI, XM_PI, XM_PI);
void SetFixedX() { minTranslationAxes.x = FLT_MAX; maxTranslationAxes.x = -FLT_MAX; }
void SetFreeX() { minTranslationAxes.x = -FLT_MAX; maxTranslationAxes.x = FLT_MAX; }
void SetFixedY() { minTranslationAxes.y = FLT_MAX; maxTranslationAxes.y = -FLT_MAX; }
void SetFreeY() { minTranslationAxes.y = -FLT_MAX; maxTranslationAxes.y = FLT_MAX; }
void SetFixedZ() { minTranslationAxes.z = FLT_MAX; maxTranslationAxes.z = -FLT_MAX; }
void SetFreeZ() { minTranslationAxes.z = -FLT_MAX; maxTranslationAxes.z = FLT_MAX; }
void SetFixedRotationX() { minRotationAxes.x = XM_PI; maxRotationAxes.x = -XM_PI; }
void SetFreeRotationX() { minRotationAxes.x = -XM_PI; maxRotationAxes.x = XM_PI; }
void SetFixedRotationY() { minRotationAxes.y = XM_PI; maxRotationAxes.y = -XM_PI; }
void SetFreeRotationY() { minRotationAxes.y = -XM_PI; maxRotationAxes.y = XM_PI; }
void SetFixedRotationZ() { minRotationAxes.z = XM_PI; maxRotationAxes.z = -XM_PI; }
void SetFreeRotationZ() { minRotationAxes.z = -XM_PI; maxRotationAxes.z = XM_PI; }
} six_dof;
// Non-serialized attributes:
std::shared_ptr<void> physicsobject = nullptr; // You can set to null to recreate the physics object the next time phsyics system will be running.
// Request refreshing of constraint settings without recreating the constraint
constexpr void SetRefreshParametersNeeded(bool value = true) { if (value) { _flags |= REFRESH_PARAMETERS_REQUEST; } else { _flags &= ~REFRESH_PARAMETERS_REQUEST; } }
constexpr bool IsRefreshParametersNeeded() const { return _flags & REFRESH_PARAMETERS_REQUEST; }
void Serialize(wi::Archive& archive, wi::ecs::EntitySerializer& seri);
};
+14
View File
@@ -922,6 +922,13 @@ namespace wi::scene
archive >> hinge_constraint.min_angle;
archive >> hinge_constraint.max_angle;
archive >> cone_constraint.half_cone_angle;
if (seri.GetVersion() >= 1)
{
archive >> six_dof.minTranslationAxes;
archive >> six_dof.maxTranslationAxes;
archive >> six_dof.minRotationAxes;
archive >> six_dof.maxRotationAxes;
}
}
else
{
@@ -934,6 +941,13 @@ namespace wi::scene
archive << hinge_constraint.min_angle;
archive << hinge_constraint.max_angle;
archive << cone_constraint.half_cone_angle;
if (seri.GetVersion() >= 1)
{
archive << six_dof.minTranslationAxes;
archive << six_dof.maxTranslationAxes;
archive << six_dof.minRotationAxes;
archive << six_dof.maxRotationAxes;
}
}
}
void SoftBodyPhysicsComponent::Serialize(wi::Archive& archive, EntitySerializer& seri)