mechanicsdsl-unity 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mechanicsdsl_unity-0.1.0/.github/workflows/publish-pypi.yml +85 -0
- mechanicsdsl_unity-0.1.0/.gitignore +47 -0
- mechanicsdsl_unity-0.1.0/CHANGELOG.md +20 -0
- mechanicsdsl_unity-0.1.0/CITATION.cff +30 -0
- mechanicsdsl_unity-0.1.0/CONTRIBUTING.md +47 -0
- mechanicsdsl_unity-0.1.0/Editor/DoublePendulumComponentEditor.cs +57 -0
- mechanicsdsl_unity-0.1.0/Editor/PendulumComponentEditor.cs +121 -0
- mechanicsdsl_unity-0.1.0/Editor/com.mechanicsdsl.unity.editor.asmdef +18 -0
- mechanicsdsl_unity-0.1.0/LICENSE +21 -0
- mechanicsdsl_unity-0.1.0/PKG-INFO +158 -0
- mechanicsdsl_unity-0.1.0/README.md +133 -0
- mechanicsdsl_unity-0.1.0/Runtime/Components/CoupledPendulumsComponent.cs +138 -0
- mechanicsdsl_unity-0.1.0/Runtime/Components/DoublePendulumComponent.cs +139 -0
- mechanicsdsl_unity-0.1.0/Runtime/Components/PendulumComponent.cs +250 -0
- mechanicsdsl_unity-0.1.0/Runtime/Utilites/ConservationMonitor.cs +105 -0
- mechanicsdsl_unity-0.1.0/Runtime/Utilites/MechanicsDSLMath.cs +69 -0
- mechanicsdsl_unity-0.1.0/Runtime/Utilites/PhaseSpaceTrail.cs +110 -0
- mechanicsdsl_unity-0.1.0/Runtime/com.mechanicsdsl.unity.runtime.asmdef +14 -0
- mechanicsdsl_unity-0.1.0/Samples~/DoublePendulum/README.md +38 -0
- mechanicsdsl_unity-0.1.0/Samples~/SimplePendulum/README.md +44 -0
- mechanicsdsl_unity-0.1.0/Tests/Runtime/MechanicsDSL.Tests.Runtime.asmdef +19 -0
- mechanicsdsl_unity-0.1.0/Tests/Runtime/TestDoublePendulumEOM.cs +71 -0
- mechanicsdsl_unity-0.1.0/Tests/Runtime/TestPendulumEOM.cs +87 -0
- mechanicsdsl_unity-0.1.0/docs/adding_systems.md +83 -0
- mechanicsdsl_unity-0.1.0/docs/components_reference.md +71 -0
- mechanicsdsl_unity-0.1.0/docs/getting_started.md +68 -0
- mechanicsdsl_unity-0.1.0/package.json +38 -0
- mechanicsdsl_unity-0.1.0/pyproject.toml +47 -0
- mechanicsdsl_unity-0.1.0/src/mechanicsdsl_unity/__init__.py +19 -0
- mechanicsdsl_unity-0.1.0/src/mechanicsdsl_unity/_components.py +89 -0
- mechanicsdsl_unity-0.1.0/src/mechanicsdsl_unity/_version.py +1 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*.*.*'
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
test_pypi:
|
|
10
|
+
description: 'Publish to PyPI'
|
|
11
|
+
type: boolean
|
|
12
|
+
default: false
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
build:
|
|
16
|
+
name: Build distribution
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- name: Checkout
|
|
21
|
+
uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Set up Python
|
|
24
|
+
uses: actions/setup-python@v5
|
|
25
|
+
with:
|
|
26
|
+
python-version: '3.11'
|
|
27
|
+
|
|
28
|
+
- name: Install build tools
|
|
29
|
+
run: pip install hatch build twine
|
|
30
|
+
|
|
31
|
+
- name: Build package
|
|
32
|
+
run: python -m build
|
|
33
|
+
|
|
34
|
+
- name: Check distribution
|
|
35
|
+
run: twine check dist/*
|
|
36
|
+
|
|
37
|
+
- name: Upload distribution artifacts
|
|
38
|
+
uses: actions/upload-artifact@v4
|
|
39
|
+
with:
|
|
40
|
+
name: dist
|
|
41
|
+
path: dist/
|
|
42
|
+
|
|
43
|
+
publish-pypi:
|
|
44
|
+
name: Publish to PyPI
|
|
45
|
+
needs: build
|
|
46
|
+
runs-on: ubuntu-latest
|
|
47
|
+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && !inputs.test_pypi
|
|
48
|
+
environment:
|
|
49
|
+
name: pypi
|
|
50
|
+
url: https://pypi.org/p/${{ github.event.repository.name }}
|
|
51
|
+
permissions:
|
|
52
|
+
id-token: write # Required for trusted publishing
|
|
53
|
+
|
|
54
|
+
steps:
|
|
55
|
+
- name: Download artifacts
|
|
56
|
+
uses: actions/download-artifact@v4
|
|
57
|
+
with:
|
|
58
|
+
name: dist
|
|
59
|
+
path: dist/
|
|
60
|
+
|
|
61
|
+
- name: Publish to PyPI
|
|
62
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
63
|
+
|
|
64
|
+
publish-testpypi:
|
|
65
|
+
name: Publish to TestPyPI
|
|
66
|
+
needs: build
|
|
67
|
+
runs-on: ubuntu-latest
|
|
68
|
+
if: inputs.test_pypi
|
|
69
|
+
environment:
|
|
70
|
+
name: testpypi
|
|
71
|
+
url: https://test.pypi.org/p/${{ github.event.repository.name }}
|
|
72
|
+
permissions:
|
|
73
|
+
id-token: write
|
|
74
|
+
|
|
75
|
+
steps:
|
|
76
|
+
- name: Download artifacts
|
|
77
|
+
uses: actions/download-artifact@v4
|
|
78
|
+
with:
|
|
79
|
+
name: dist
|
|
80
|
+
path: dist/
|
|
81
|
+
|
|
82
|
+
- name: Publish to TestPyPI
|
|
83
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
84
|
+
with:
|
|
85
|
+
repository-url: https://test.pypi.org/legacy/
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Unity
|
|
2
|
+
[Ll]ibrary/
|
|
3
|
+
[Tt]emp/
|
|
4
|
+
[Oo]bj/
|
|
5
|
+
[Bb]uild/
|
|
6
|
+
[Bb]uilds/
|
|
7
|
+
[Ll]ogs/
|
|
8
|
+
[Mm]emoryCaptures/
|
|
9
|
+
[Uu]serSettings/
|
|
10
|
+
*.pidb.meta
|
|
11
|
+
*.pdb.meta
|
|
12
|
+
*.mdb.meta
|
|
13
|
+
sysinfo.txt
|
|
14
|
+
*.apk
|
|
15
|
+
*.aab
|
|
16
|
+
*.unitypackage
|
|
17
|
+
*.app
|
|
18
|
+
crashlytics-build.properties
|
|
19
|
+
.DS_Store
|
|
20
|
+
*.swp
|
|
21
|
+
*.swo
|
|
22
|
+
|
|
23
|
+
# Unreal Engine
|
|
24
|
+
Binaries/
|
|
25
|
+
DerivedDataCache/
|
|
26
|
+
Intermediate/
|
|
27
|
+
Saved/
|
|
28
|
+
.vs/
|
|
29
|
+
*.VC.db
|
|
30
|
+
*.opensdf
|
|
31
|
+
*.opendb
|
|
32
|
+
*.sdf
|
|
33
|
+
*.sln
|
|
34
|
+
*.suo
|
|
35
|
+
*.xcworkspace
|
|
36
|
+
*.xcodeproj
|
|
37
|
+
*.pdb
|
|
38
|
+
|
|
39
|
+
# Generated code (tracked separately)
|
|
40
|
+
Generated/
|
|
41
|
+
|
|
42
|
+
# Python (for code generation tooling)
|
|
43
|
+
__pycache__/
|
|
44
|
+
*.py[cod]
|
|
45
|
+
.venv/
|
|
46
|
+
venv/
|
|
47
|
+
.env
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to mechanicsdsl-unity are documented here.
|
|
4
|
+
Format follows [Keep a Changelog](https://keepachangelog.com).
|
|
5
|
+
|
|
6
|
+
## [Unreleased]
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
- `PendulumComponent` — simple pendulum MonoBehaviour with RK4, Noether monitor, Gizmos
|
|
10
|
+
- `DoublePendulumComponent` — double pendulum MonoBehaviour with chaos detection
|
|
11
|
+
- `MechanicsDSLMath` — shared utilities: generic RK4, symplectic Euler, angle wrapping
|
|
12
|
+
- `ConservationMonitor` — on-screen HUD for Noether conservation law monitoring
|
|
13
|
+
- `PendulumComponentEditor` — custom Inspector with live state readout and reset button
|
|
14
|
+
- UPM `package.json` manifest with sample declarations
|
|
15
|
+
- Runtime tests: `TestPendulumEOM`
|
|
16
|
+
- Sample documentation: SimplePendulum, DoublePendulum
|
|
17
|
+
|
|
18
|
+
## [0.1.0] — 2026-03-13
|
|
19
|
+
|
|
20
|
+
- Initial repository scaffold
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use this software in your project, please cite:"
|
|
3
|
+
type: software
|
|
4
|
+
title: "MechanicsDSL Unity"
|
|
5
|
+
abstract: >
|
|
6
|
+
Unity and Unreal Engine plugin packages for MechanicsDSL.
|
|
7
|
+
Provides physically accurate simulation components compiled from
|
|
8
|
+
DSL notation, targeting game development, digital twins,
|
|
9
|
+
interactive science exhibits, and educational physics visualisations.
|
|
10
|
+
authors:
|
|
11
|
+
- family-names: Parsons
|
|
12
|
+
given-names: Noah
|
|
13
|
+
orcid: "https://orcid.org/0009-0000-7224-6040"
|
|
14
|
+
affiliation: "American Forge Institute & Eastern Wyoming College"
|
|
15
|
+
repository-code: "https://github.com/MechanicsDSL/mechanicsdsl-unity"
|
|
16
|
+
license: MIT
|
|
17
|
+
date-released: "2026-03-13"
|
|
18
|
+
keywords:
|
|
19
|
+
- Unity
|
|
20
|
+
- Unreal Engine
|
|
21
|
+
- physics simulation
|
|
22
|
+
- Lagrangian mechanics
|
|
23
|
+
- game engine
|
|
24
|
+
references:
|
|
25
|
+
- type: software
|
|
26
|
+
title: "MechanicsDSL"
|
|
27
|
+
doi: "10.5281/zenodo.17771040"
|
|
28
|
+
authors:
|
|
29
|
+
- family-names: Parsons
|
|
30
|
+
given-names: Noah
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Contributing to mechanicsdsl-unity
|
|
2
|
+
|
|
3
|
+
## Contribution Types
|
|
4
|
+
|
|
5
|
+
### New Physics Components
|
|
6
|
+
|
|
7
|
+
Generate a new component from DSL notation:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
mechanicsdsl generate my_system.msl --target unity --out Runtime/Components/
|
|
11
|
+
mechanicsdsl generate my_system.msl --target unity_editor --out Editor/
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Include:
|
|
15
|
+
- The originating `.msl` specification as a header comment
|
|
16
|
+
- An `AddComponentMenu` attribute for discoverability
|
|
17
|
+
- A custom Inspector Editor script with live state readout
|
|
18
|
+
- Runtime tests in `Tests/Runtime/`
|
|
19
|
+
- Entry in `CHANGELOG.md`
|
|
20
|
+
|
|
21
|
+
### Sample Scenes
|
|
22
|
+
|
|
23
|
+
Well-documented sample scenes demonstrating MechanicsDSL components are especially valuable for new users. Add samples to `Samples~/YourSampleName/` and declare them in `package.json`.
|
|
24
|
+
|
|
25
|
+
### Bug Reports
|
|
26
|
+
|
|
27
|
+
Include:
|
|
28
|
+
- Unity version
|
|
29
|
+
- How to reproduce (minimal scene setup)
|
|
30
|
+
- Expected vs actual behaviour
|
|
31
|
+
- Whether the issue is in the EOM, integrator, or Unity integration layer
|
|
32
|
+
|
|
33
|
+
## Testing
|
|
34
|
+
|
|
35
|
+
Run tests via **Window → General → Test Runner → PlayMode → Run All**.
|
|
36
|
+
|
|
37
|
+
All physics components must have:
|
|
38
|
+
- Energy conservation test (5+ seconds simulation)
|
|
39
|
+
- Reset/initial-conditions test
|
|
40
|
+
- Equilibrium stability test
|
|
41
|
+
|
|
42
|
+
## Code Style
|
|
43
|
+
|
|
44
|
+
- Use `[AddComponentMenu("MechanicsDSL/...")]` for all MonoBehaviours
|
|
45
|
+
- All MechanicsDSL-generated code must be clearly labelled with the originating DSL spec
|
|
46
|
+
- Inspector properties should have `[Tooltip]` attributes
|
|
47
|
+
- Use `[Range]` attributes for physical parameters to prevent unphysical values
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#if UNITY_EDITOR
|
|
2
|
+
using UnityEditor;
|
|
3
|
+
using UnityEngine;
|
|
4
|
+
using MechanicsDSL.Classical;
|
|
5
|
+
|
|
6
|
+
namespace MechanicsDSL.Classical.Editor
|
|
7
|
+
{
|
|
8
|
+
[CustomEditor(typeof(DoublePendulumComponent))]
|
|
9
|
+
public class DoublePendulumComponentEditor : UnityEditor.Editor
|
|
10
|
+
{
|
|
11
|
+
private bool _showState = true;
|
|
12
|
+
|
|
13
|
+
public override void OnInspectorGUI()
|
|
14
|
+
{
|
|
15
|
+
var comp = (DoublePendulumComponent)target;
|
|
16
|
+
serializedObject.Update();
|
|
17
|
+
|
|
18
|
+
EditorGUILayout.Space(4);
|
|
19
|
+
EditorGUILayout.LabelField("MechanicsDSL — Double Pendulum", EditorStyles.boldLabel);
|
|
20
|
+
EditorGUILayout.LabelField("L = ½ml²(2θ̇₁²+θ̇₂²+2θ̇₁θ̇₂cos Δθ)+mgl(2cosθ₁+cosθ₂)", EditorStyles.miniLabel);
|
|
21
|
+
EditorGUILayout.Space(6);
|
|
22
|
+
|
|
23
|
+
DrawPropertiesExcluding(serializedObject, "m_script");
|
|
24
|
+
|
|
25
|
+
if (Application.isPlaying)
|
|
26
|
+
{
|
|
27
|
+
EditorGUILayout.Space(8);
|
|
28
|
+
_showState = EditorGUILayout.Foldout(_showState, "Live State", true, EditorStyles.foldoutHeader);
|
|
29
|
+
if (_showState)
|
|
30
|
+
{
|
|
31
|
+
EditorGUI.indentLevel++;
|
|
32
|
+
EditorGUILayout.LabelField("θ₁ (rad)", $"{comp.Theta1:F6}");
|
|
33
|
+
EditorGUILayout.LabelField("θ₂ (rad)", $"{comp.Theta2:F6}");
|
|
34
|
+
EditorGUILayout.LabelField("ω₁ (rad/s)", $"{comp.Omega1:F6}");
|
|
35
|
+
EditorGUILayout.LabelField("ω₂ (rad/s)", $"{comp.Omega2:F6}");
|
|
36
|
+
EditorGUILayout.LabelField("t (s)", $"{comp.SimTime:F3}");
|
|
37
|
+
EditorGUILayout.LabelField("Energy (J)", $"{comp.Energy:F8}");
|
|
38
|
+
|
|
39
|
+
Color prev = GUI.color;
|
|
40
|
+
GUI.color = comp.EnergyDrift > comp.driftTolerance
|
|
41
|
+
? new Color(1f,0.4f,0.4f) : new Color(0.4f,1f,0.6f);
|
|
42
|
+
EditorGUILayout.LabelField("|ΔE/E₀|",
|
|
43
|
+
comp.EnergyDrift < 1e-10f ? "< 1e-10 ✓" : $"{comp.EnergyDrift:E3}");
|
|
44
|
+
GUI.color = prev;
|
|
45
|
+
|
|
46
|
+
EditorGUI.indentLevel--;
|
|
47
|
+
EditorGUILayout.Space(4);
|
|
48
|
+
if (GUILayout.Button("Reset")) comp.Reset();
|
|
49
|
+
}
|
|
50
|
+
Repaint();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
serializedObject.ApplyModifiedProperties();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
#endif
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#if UNITY_EDITOR
|
|
2
|
+
using UnityEditor;
|
|
3
|
+
using UnityEngine;
|
|
4
|
+
|
|
5
|
+
namespace MechanicsDSL.Classical.Editor
|
|
6
|
+
{
|
|
7
|
+
/// <summary>
|
|
8
|
+
/// Custom Inspector for PendulumComponent.
|
|
9
|
+
/// Adds a live state readout, reset button, and energy drift gauge
|
|
10
|
+
/// directly in the Inspector during Play Mode.
|
|
11
|
+
/// </summary>
|
|
12
|
+
[CustomEditor(typeof(PendulumComponent))]
|
|
13
|
+
public class PendulumComponentEditor : UnityEditor.Editor
|
|
14
|
+
{
|
|
15
|
+
private bool _showState = true;
|
|
16
|
+
private bool _showPhysics = true;
|
|
17
|
+
private bool _showEvents = false;
|
|
18
|
+
|
|
19
|
+
public override void OnInspectorGUI()
|
|
20
|
+
{
|
|
21
|
+
var comp = (PendulumComponent)target;
|
|
22
|
+
serializedObject.Update();
|
|
23
|
+
|
|
24
|
+
// ------------------------------------------------------------------
|
|
25
|
+
// Header
|
|
26
|
+
// ------------------------------------------------------------------
|
|
27
|
+
EditorGUILayout.Space(4);
|
|
28
|
+
EditorGUILayout.LabelField("MechanicsDSL — Simple Pendulum",
|
|
29
|
+
EditorStyles.boldLabel);
|
|
30
|
+
EditorGUILayout.LabelField(
|
|
31
|
+
"Lagrangian: L = ½ml²ω² − mgl(1−cosθ)",
|
|
32
|
+
EditorStyles.miniLabel);
|
|
33
|
+
EditorGUILayout.Space(6);
|
|
34
|
+
|
|
35
|
+
// ------------------------------------------------------------------
|
|
36
|
+
// Physical parameters
|
|
37
|
+
// ------------------------------------------------------------------
|
|
38
|
+
_showPhysics = EditorGUILayout.Foldout(_showPhysics,
|
|
39
|
+
"Physical Parameters", true, EditorStyles.foldoutHeader);
|
|
40
|
+
if (_showPhysics)
|
|
41
|
+
{
|
|
42
|
+
EditorGUI.indentLevel++;
|
|
43
|
+
EditorGUILayout.PropertyField(serializedObject.FindProperty("mass"));
|
|
44
|
+
EditorGUILayout.PropertyField(serializedObject.FindProperty("length"));
|
|
45
|
+
EditorGUILayout.PropertyField(serializedObject.FindProperty("gravity"));
|
|
46
|
+
EditorGUILayout.Space(4);
|
|
47
|
+
EditorGUILayout.PropertyField(serializedObject.FindProperty("theta0"));
|
|
48
|
+
EditorGUILayout.PropertyField(serializedObject.FindProperty("omega0"));
|
|
49
|
+
EditorGUI.indentLevel--;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
EditorGUILayout.Space(4);
|
|
53
|
+
EditorGUILayout.PropertyField(serializedObject.FindProperty("dt"));
|
|
54
|
+
EditorGUILayout.PropertyField(serializedObject.FindProperty("driftTolerance"));
|
|
55
|
+
EditorGUILayout.PropertyField(serializedObject.FindProperty("bobTransform"));
|
|
56
|
+
EditorGUILayout.PropertyField(serializedObject.FindProperty("drawGizmos"));
|
|
57
|
+
|
|
58
|
+
// ------------------------------------------------------------------
|
|
59
|
+
// Live state readout (Play Mode only)
|
|
60
|
+
// ------------------------------------------------------------------
|
|
61
|
+
if (Application.isPlaying)
|
|
62
|
+
{
|
|
63
|
+
EditorGUILayout.Space(8);
|
|
64
|
+
_showState = EditorGUILayout.Foldout(_showState,
|
|
65
|
+
"Live State", true, EditorStyles.foldoutHeader);
|
|
66
|
+
|
|
67
|
+
if (_showState)
|
|
68
|
+
{
|
|
69
|
+
EditorGUI.indentLevel++;
|
|
70
|
+
|
|
71
|
+
EditorGUILayout.LabelField("θ (rad)",
|
|
72
|
+
$"{comp.Theta:F6}");
|
|
73
|
+
EditorGUILayout.LabelField("ω (rad/s)",
|
|
74
|
+
$"{comp.Omega:F6}");
|
|
75
|
+
EditorGUILayout.LabelField("t (s)",
|
|
76
|
+
$"{comp.SimTime:F3}");
|
|
77
|
+
EditorGUILayout.LabelField("Energy (J)",
|
|
78
|
+
$"{comp.Energy:F8}");
|
|
79
|
+
|
|
80
|
+
// Energy drift gauge
|
|
81
|
+
float drift = comp.EnergyDrift;
|
|
82
|
+
Color prevColor = GUI.color;
|
|
83
|
+
GUI.color = drift > comp.driftTolerance
|
|
84
|
+
? new Color(1f, 0.4f, 0.4f)
|
|
85
|
+
: new Color(0.4f, 1f, 0.6f);
|
|
86
|
+
EditorGUILayout.LabelField("|ΔE/E₀|",
|
|
87
|
+
drift < 1e-10f ? "< 1e-10 ✓" : $"{drift:E3}");
|
|
88
|
+
GUI.color = prevColor;
|
|
89
|
+
|
|
90
|
+
EditorGUI.indentLevel--;
|
|
91
|
+
|
|
92
|
+
EditorGUILayout.Space(4);
|
|
93
|
+
if (GUILayout.Button("Reset to Initial Conditions"))
|
|
94
|
+
comp.ResetToInitialConditions();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Repaint every frame during play to keep live readout updated
|
|
98
|
+
Repaint();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// ------------------------------------------------------------------
|
|
102
|
+
// Events (collapsed by default — keep Inspector clean)
|
|
103
|
+
// ------------------------------------------------------------------
|
|
104
|
+
EditorGUILayout.Space(4);
|
|
105
|
+
_showEvents = EditorGUILayout.Foldout(_showEvents,
|
|
106
|
+
"Events", true, EditorStyles.foldoutHeader);
|
|
107
|
+
if (_showEvents)
|
|
108
|
+
{
|
|
109
|
+
EditorGUI.indentLevel++;
|
|
110
|
+
EditorGUILayout.PropertyField(
|
|
111
|
+
serializedObject.FindProperty("OnStateUpdate"));
|
|
112
|
+
EditorGUILayout.PropertyField(
|
|
113
|
+
serializedObject.FindProperty("OnEnergyDrift"));
|
|
114
|
+
EditorGUI.indentLevel--;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
serializedObject.ApplyModifiedProperties();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
#endif
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "com.mechanicsdsl.unity.editor",
|
|
3
|
+
"rootNamespace": "MechanicsDSL.Classical.Editor",
|
|
4
|
+
"references": [
|
|
5
|
+
"com.mechanicsdsl.unity.runtime"
|
|
6
|
+
],
|
|
7
|
+
"includePlatforms": [
|
|
8
|
+
"Editor"
|
|
9
|
+
],
|
|
10
|
+
"excludePlatforms": [],
|
|
11
|
+
"allowUnsafeCode": false,
|
|
12
|
+
"overrideReferences": false,
|
|
13
|
+
"precompiledReferences": [],
|
|
14
|
+
"autoReferenced": true,
|
|
15
|
+
"defineConstraints": [],
|
|
16
|
+
"versionDefines": [],
|
|
17
|
+
"noEngineReferences": false
|
|
18
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MechanicsDSL
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mechanicsdsl-unity
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Unity and Unreal Engine plugin packages for MechanicsDSL — physically accurate simulation components compiled from DSL notation
|
|
5
|
+
Project-URL: Homepage, https://github.com/MechanicsDSL/mechanicsdsl-unity
|
|
6
|
+
Project-URL: Repository, https://github.com/MechanicsDSL/mechanicsdsl-unity
|
|
7
|
+
Project-URL: DOI, https://doi.org/10.5281/zenodo.17771040
|
|
8
|
+
Author-email: Noah Parsons <nomapa223@gmail.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: Lagrangian mechanics,MechanicsDSL,digital-twin,game-engine,physics simulation,unity,unreal-engine
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Topic :: Games/Entertainment
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Requires-Dist: mechanicsdsl-core
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
23
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
<p align="center">
|
|
27
|
+
<img src="https://raw.githubusercontent.com/MechanicsDSL/mechanicsdsl/main/docs/images/logo.png" alt="MechanicsDSL Logo" width="360">
|
|
28
|
+
</p>
|
|
29
|
+
|
|
30
|
+
<h1 align="center">mechanicsdsl-unity</h1>
|
|
31
|
+
|
|
32
|
+
<p align="center">
|
|
33
|
+
<em>Physically accurate simulation components for Unity and Unreal Engine, compiled from DSL notation.</em>
|
|
34
|
+
</p>
|
|
35
|
+
|
|
36
|
+
<p align="center">
|
|
37
|
+
<img src="https://img.shields.io/badge/status-active-green" alt="Active">
|
|
38
|
+
<img src="https://img.shields.io/badge/Unity-2021.3%2B-black" alt="Unity">
|
|
39
|
+
<img src="https://img.shields.io/badge/components-3-blue" alt="3 Components">
|
|
40
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="MIT License"></a>
|
|
41
|
+
<a href="https://github.com/MechanicsDSL/mechanicsdsl"><img src="https://img.shields.io/badge/core-mechanicsdsl-blue" alt="Core Package"></a>
|
|
42
|
+
</p>
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Overview
|
|
47
|
+
|
|
48
|
+
`mechanicsdsl-unity` provides Unity MonoBehaviour components generated from MechanicsDSL DSL specifications. All components bypass PhysX with Lagrangian equations of motion, include Noether-based energy monitoring, and expose parameters in the Unity Inspector for real-time tuning.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Components
|
|
53
|
+
|
|
54
|
+
### Classical Mechanics
|
|
55
|
+
|
|
56
|
+
| Component | System | Conserved | Gizmos |
|
|
57
|
+
|-----------|--------|-----------|--------|
|
|
58
|
+
| `PendulumComponent` | Simple pendulum | Energy (Noether) | Pivot, rod, bob |
|
|
59
|
+
| `DoublePendulumComponent` | Double pendulum (chaotic) | Energy (Noether) | Full double pendulum |
|
|
60
|
+
| `CoupledPendulumsComponent` | Coupled pendulums | Energy (Noether) | Both pendulums + spring |
|
|
61
|
+
|
|
62
|
+
### Utilities
|
|
63
|
+
|
|
64
|
+
| Component | Description |
|
|
65
|
+
|-----------|-------------|
|
|
66
|
+
| `ConservationMonitor` | On-screen HUD for energy drift across any MechanicsDSL component |
|
|
67
|
+
| `PhaseSpaceTrail` | Renders θ vs ω phase portrait as a LineRenderer trail |
|
|
68
|
+
| `MechanicsDSLMath` | Generic RK4, symplectic Euler, angle wrap, bob position helpers |
|
|
69
|
+
|
|
70
|
+
### Editor
|
|
71
|
+
|
|
72
|
+
| Script | Description |
|
|
73
|
+
|--------|-------------|
|
|
74
|
+
| `PendulumComponentEditor` | Live state readout (θ, ω, t, E, \|ΔE/E₀\|) + Reset button |
|
|
75
|
+
| `DoublePendulumComponentEditor` | Dual-angle live readout + Reset button |
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Repository Structure
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
mechanicsdsl-unity/
|
|
83
|
+
├── Runtime/
|
|
84
|
+
│ ├── Components/
|
|
85
|
+
│ │ ├── PendulumComponent.cs
|
|
86
|
+
│ │ ├── DoublePendulumComponent.cs
|
|
87
|
+
│ │ └── CoupledPendulumsComponent.cs
|
|
88
|
+
│ ├── Utilities/
|
|
89
|
+
│ │ ├── ConservationMonitor.cs
|
|
90
|
+
│ │ ├── PhaseSpaceTrail.cs
|
|
91
|
+
│ │ └── MechanicsDSLMath.cs
|
|
92
|
+
│ └── com.mechanicsdsl.unity.runtime.asmdef
|
|
93
|
+
├── Editor/
|
|
94
|
+
│ ├── PendulumComponentEditor.cs
|
|
95
|
+
│ ├── DoublePendulumComponentEditor.cs
|
|
96
|
+
│ └── com.mechanicsdsl.unity.editor.asmdef
|
|
97
|
+
├── Tests/Runtime/
|
|
98
|
+
│ ├── TestPendulumEOM.cs
|
|
99
|
+
│ ├── TestDoublePendulumEOM.cs
|
|
100
|
+
│ └── MechanicsDSL.Tests.Runtime.asmdef
|
|
101
|
+
├── Samples~/
|
|
102
|
+
│ ├── SimplePendulum/README.md
|
|
103
|
+
│ └── DoublePendulum/README.md
|
|
104
|
+
├── docs/
|
|
105
|
+
│ ├── getting_started.md
|
|
106
|
+
│ ├── components_reference.md
|
|
107
|
+
│ └── adding_systems.md
|
|
108
|
+
└── package.json (UPM manifest)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Installation
|
|
114
|
+
|
|
115
|
+
**Via UPM (Unity Package Manager):**
|
|
116
|
+
|
|
117
|
+
1. Open **Window → Package Manager**
|
|
118
|
+
2. Click **+** → **Add package from git URL**
|
|
119
|
+
3. Enter: `https://github.com/MechanicsDSL/mechanicsdsl-unity.git`
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Quick Start
|
|
124
|
+
|
|
125
|
+
1. Add **MechanicsDSL → Classical → Pendulum** to any GameObject
|
|
126
|
+
2. Create a Sphere child and drag to **Bob Transform**
|
|
127
|
+
3. Press Play — the sphere is driven by MechanicsDSL-generated Lagrangian equations
|
|
128
|
+
|
|
129
|
+
The Inspector shows live θ, ω, E, and |ΔE/E₀| during Play Mode. Click **Reset** to return to initial conditions without stopping.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Running Tests
|
|
134
|
+
|
|
135
|
+
**Window → General → Test Runner → PlayMode → Run All**
|
|
136
|
+
|
|
137
|
+
Tests cover energy conservation (5–10 s), reset/initial conditions, equilibrium stability, and bob Transform updates.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Generating New Components
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
pip install mechanicsdsl-core
|
|
145
|
+
mechanicsdsl generate my_system.msl --target unity --out Assets/Physics/
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
See [docs/adding_systems.md](docs/adding_systems.md) for the full workflow.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Contributing
|
|
153
|
+
|
|
154
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
155
|
+
|
|
156
|
+
## License
|
|
157
|
+
|
|
158
|
+
MIT License — see [LICENSE](LICENSE).
|