Skip to content

Commit

Permalink
Refactor mesh importer to use osc's new UndoRedo abstraction etc. (#802)
Browse files Browse the repository at this point in the history
  • Loading branch information
adamkewley committed Nov 16, 2023
1 parent a888b1b commit 571a847
Show file tree
Hide file tree
Showing 11 changed files with 348 additions and 692 deletions.
850 changes: 193 additions & 657 deletions src/OpenSimCreator/UI/Tabs/MeshImporterTab.cpp

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions src/OpenSimCreator/Utils/OpenSimHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1657,3 +1657,24 @@ std::optional<osc::ComponentSpatialRepresentation> osc::TryGetSpatialRepresentat
}
return std::nullopt;
}

bool osc::IsValidOpenSimComponentNameCharacter(char c)
{
return
std::isalpha(static_cast<uint8_t>(c)) != 0 ||
('0' <= c && c <= '9') ||
(c == '-' || c == '_');
}

std::string osc::SanitizeToOpenSimComponentName(std::string_view sv)
{
std::string rv;
for (char c : sv)
{
if (IsValidOpenSimComponentNameCharacter(c))
{
rv += c;
}
}
return rv;
}
9 changes: 9 additions & 0 deletions src/OpenSimCreator/Utils/OpenSimHelpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <optional>
#include <span>
#include <string>
#include <string_view>
#include <stdexcept>
#include <type_traits>
#include <utility>
Expand Down Expand Up @@ -855,4 +856,12 @@ namespace osc
OpenSim::Component const&,
SimTK::State const&
);

// returns `true` if the given character is permitted to appear within the name
// of an `OpenSim::Component`
bool IsValidOpenSimComponentNameCharacter(char);

// returns a sanitized form of the given string that OpenSim would (probably) accept
// as a component name
std::string SanitizeToOpenSimComponentName(std::string_view);
}
1 change: 1 addition & 0 deletions src/oscar/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ add_library(oscar STATIC
Maths/BVHPrim.hpp
Maths/CollisionTests.hpp
Maths/Disc.hpp
Maths/EasingFunctions.hpp
Maths/Ellipsoid.hpp
Maths/EulerPerspectiveCamera.hpp
Maths/Line.hpp
Expand Down
7 changes: 7 additions & 0 deletions src/oscar/Maths/EasingFunctions.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

namespace osc
{
// returns easing function Y value for a given X in the range [0, 1.0f] (i.e. normalized)
float EaseOutElastic(float);
}
18 changes: 18 additions & 0 deletions src/oscar/Maths/MathHelpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,9 @@ namespace osc
// returns an AABB that tightly bounds the provided points
AABB AABBFromVerts(std::span<Vec3 const>);

// returns an AABB that tightly bounds the provided points (alias that matches BoundingSphereOf, etc.)
inline AABB BoundingAABBOf(std::span<Vec3 const> vs) { return AABBFromVerts(vs); }

// returns an AABB that tightly bounds the points indexed by the provided 32-bit indices
AABB AABBFromIndexedVerts(std::span<Vec3 const> verts, std::span<uint32_t const> indices);

Expand Down Expand Up @@ -489,4 +492,19 @@ namespace osc
//
// see: https://en.wikipedia.org/wiki/Euler_angles#Conventions_by_extrinsic_rotations
Vec3 ExtractExtrinsicEulerAnglesXYZ(Transform const&);

// returns the provided transform, but rotated such that the given axis, as expressed
// in the original transform, will instead point along the new direction
Transform PointAxisAlong(Transform const&, int axisIndex, Vec3 const& newDirection);

// returns the provided transform, but rotated such that the given axis, as expressed
// in the original transform, will instead point towards the given point
//
// alternate explanation: "performs the shortest (angular) rotation of the given
// transform such that the given axis points towards a point in the same space"
Transform PointAxisTowards(Transform const&, int axisIndex, Vec3 const& location);

// returns the provided transform, but intrinsically rotated along the given axis by
// the given number of radians
Transform RotateAlongAxis(Transform const&, int axisIndex, float angRadians);
}
39 changes: 39 additions & 0 deletions src/oscar/Maths/MathsImplementation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <oscar/Maths/BVH.hpp>
#include <oscar/Maths/CollisionTests.hpp>
#include <oscar/Maths/Disc.hpp>
#include <oscar/Maths/EasingFunctions.hpp>
#include <oscar/Maths/MathHelpers.hpp>
#include <oscar/Maths/Mat3.hpp>
#include <oscar/Maths/Mat4.hpp>
Expand Down Expand Up @@ -2308,6 +2309,34 @@ osc::Vec3 osc::ExtractExtrinsicEulerAnglesXYZ(Transform const& t)
return glm::eulerAngles(t.rotation);
}

osc::Transform osc::PointAxisAlong(Transform const& t, int axisIndex, Vec3 const& newDirection)
{
Vec3 beforeDir{};
beforeDir[axisIndex] = 1.0f;
beforeDir = t.rotation * beforeDir;

Quat const rotBeforeToAfter = osc::Rotation(beforeDir, newDirection);
Quat const newRotation = osc::Normalize(rotBeforeToAfter * t.rotation);

return t.withRotation(newRotation);
}

osc::Transform osc::PointAxisTowards(Transform const& t, int axisIndex, Vec3 const& location)
{
return PointAxisAlong(t, axisIndex, osc::Normalize(location - t.position));
}

osc::Transform osc::RotateAlongAxis(Transform const& t, int axisIndex, float angRadians)
{
Vec3 ax{};
ax[axisIndex] = 1.0f;
ax = t.rotation * ax;

Quat const q = osc::AngleAxis(angRadians, ax);

return t.withRotation(osc::Normalize(q * t.rotation));
}

bool osc::IsPointInRect(Rect const& r, Vec2 const& p)
{
Vec2 relPos = p - r.p1;
Expand Down Expand Up @@ -2501,3 +2530,13 @@ std::optional<osc::RayCollision> osc::GetRayCollisionTriangle(Line const& l, Tri

return osc::RayCollision{.distance = t, .position = l.origin + t*l.direction};
}

float osc::EaseOutElastic(float x)
{
// adopted from: https://easings.net/#easeOutElastic

constexpr float c4 = 2.0f*std::numbers::pi_v<float> / 3.0f;
float const normalized = osc::Clamp(x, 0.0f, 1.0f);

return std::pow(2.0f, -5.0f*normalized) * std::sin((normalized*10.0f - 0.75f) * c4) + 1.0f;
}
75 changes: 40 additions & 35 deletions src/oscar/UI/Panels/UndoRedoPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,52 +24,57 @@ class osc::UndoRedoPanel::Impl final : public osc::StandardPanel {
private:
void implDrawContent() final
{
if (ImGui::Button("undo"))
{
m_Storage->undo();
}
UndoRedoPanel::DrawContent(*m_Storage);
}

ImGui::SameLine();
std::shared_ptr<osc::UndoRedo> m_Storage;
};

if (ImGui::Button("redo"))
{
m_Storage->redo();
}

int imguiID = 0;
// public API (PIMPL)

// draw undo entries oldest (highest index) to newest (lowest index)
for (ptrdiff_t i = m_Storage->getNumUndoEntriesi()-1; 0 <= i && i < m_Storage->getNumUndoEntriesi(); --i)
{
ImGui::PushID(imguiID++);
if (ImGui::Selectable(m_Storage->getUndoEntry(i).getMessage().c_str()))
{
m_Storage->undoTo(i);
}
ImGui::PopID();
}
void osc::UndoRedoPanel::DrawContent(UndoRedo& storage)
{
if (ImGui::Button("undo"))
{
storage.undo();
}

ImGui::PushID(imguiID++);
ImGui::Text(" %s", m_Storage->getHead().getMessage().c_str());
ImGui::PopID();
ImGui::SameLine();

// draw redo entries oldest (lowest index) to newest (highest index)
for (ptrdiff_t i = 0; i < m_Storage->getNumRedoEntriesi(); ++i)
if (ImGui::Button("redo"))
{
storage.redo();
}

int imguiID = 0;

// draw undo entries oldest (highest index) to newest (lowest index)
for (ptrdiff_t i = storage.getNumUndoEntriesi()-1; 0 <= i && i < storage.getNumUndoEntriesi(); --i)
{
ImGui::PushID(imguiID++);
if (ImGui::Selectable(storage.getUndoEntry(i).getMessage().c_str()))
{
ImGui::PushID(imguiID++);
if (ImGui::Selectable(m_Storage->getRedoEntry(i).getMessage().c_str()))
{
m_Storage->redoTo(i);
}
ImGui::PopID();
storage.undoTo(i);
}
ImGui::PopID();
}

std::shared_ptr<osc::UndoRedo> m_Storage;
};

ImGui::PushID(imguiID++);
ImGui::Text(" %s", storage.getHead().getMessage().c_str());
ImGui::PopID();

// public API (PIMPL)
// draw redo entries oldest (lowest index) to newest (highest index)
for (ptrdiff_t i = 0; i < storage.getNumRedoEntriesi(); ++i)
{
ImGui::PushID(imguiID++);
if (ImGui::Selectable(storage.getRedoEntry(i).getMessage().c_str()))
{
storage.redoTo(i);
}
ImGui::PopID();
}
}

osc::UndoRedoPanel::UndoRedoPanel(std::string_view panelName_, std::shared_ptr<osc::UndoRedo> storage_) :
m_Impl{std::make_unique<Impl>(panelName_, std::move(storage_))}
Expand Down
2 changes: 2 additions & 0 deletions src/oscar/UI/Panels/UndoRedoPanel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ namespace osc
// a user-visible panel that lists undo/redo history
class UndoRedoPanel final : public Panel {
public:
static void DrawContent(UndoRedo&);

UndoRedoPanel(std::string_view panelName, std::shared_ptr<UndoRedo>);
UndoRedoPanel(UndoRedoPanel const&) = delete;
UndoRedoPanel(UndoRedoPanel&&) noexcept;
Expand Down
5 changes: 5 additions & 0 deletions src/oscar/Utils/UndoRedo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ osc::UndoRedoEntry const& osc::UndoRedo::getHead() const
return m_Head;
}

osc::UID osc::UndoRedo::getHeadID() const
{
return m_Head.getID();
}

size_t osc::UndoRedo::getNumUndoEntries() const
{
return m_Undo.size();
Expand Down
13 changes: 13 additions & 0 deletions src/oscar/Utils/UndoRedo.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <oscar/Utils/CStringView.hpp>
#include <oscar/Utils/UID.hpp>

#include <chrono>
#include <cstddef>
Expand Down Expand Up @@ -28,6 +29,11 @@ namespace osc
public:
virtual ~UndoRedoEntryMetadata() noexcept;

UID getID() const
{
return m_ID;
}

std::chrono::system_clock::time_point getTime() const
{
return m_Time;
Expand All @@ -38,6 +44,7 @@ namespace osc
return m_Message;
}
private:
UID m_ID;
std::chrono::system_clock::time_point m_Time;
std::string m_Message;
};
Expand Down Expand Up @@ -74,6 +81,11 @@ namespace osc
}

public:
UID getID() const
{
return m_Data->getID();
}

std::chrono::system_clock::time_point getTime() const
{
return m_Data->getTime();
Expand Down Expand Up @@ -122,6 +134,7 @@ namespace osc

void commitScratch(std::string_view commitMsg);
UndoRedoEntry const& getHead() const;
UID getHeadID() const;

size_t getNumUndoEntries() const;
ptrdiff_t getNumUndoEntriesi() const;
Expand Down

0 comments on commit 571a847

Please sign in to comment.