sixdof constraint
This commit is contained in:
Binary file not shown.
+398
-5
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user