diff --git a/.github/workflows/FissionUnitTest.yml b/.github/workflows/FissionUnitTest.yml
index 1a0389244b..b3dc4e6be2 100644
--- a/.github/workflows/FissionUnitTest.yml
+++ b/.github/workflows/FissionUnitTest.yml
@@ -44,7 +44,7 @@ jobs:
with:
path: |
~/.cache/ms-playwright/
- key: ${{ runner.os }}-assets-playwright-${{ env.PLAYWRIGHT_VERSION }}
+ key: ${{ runner.os }}-assets-playwright-${{ env.PLAYWRIGHT_VERSION }}-v2
- name: Install Dependencies
run: |
diff --git a/.gitmodules b/.gitmodules
index 44da10b0bf..8f7b277463 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,6 @@
[submodule "mirabuf"]
path = mirabuf
url = https://github.com/HiceS/mirabuf.git
+[submodule "jolt"]
+ path = jolt
+ url = https://github.com/HunterBarclay/JoltPhysics.js.git
diff --git a/README.md b/README.md
index 3a6135d588..cd19a6d963 100644
--- a/README.md
+++ b/README.md
@@ -60,6 +60,10 @@ All code is under a configured formatting utility. See each component for more d
Mirabuf is a file format we use to store physical data from Fusion to load into the Synthesis simulator (Fission). This is a separate project that is a submodule of Synthesis. [See Mirabuf](https://github.com/HiceS/mirabuf/)
+### Jolt Physics
+
+Jolt is the core physics engine for our web biased simulator. [See JoltPhysics.js](https://github.com/HunterBarclay/JoltPhysics.js) for more information.
+
### Tutorials
Our source code for the tutorials featured on our [Tutorials Page](https://synthesis.autodesk.com/tutorials.html).
diff --git a/exporter/SynthesisFusionAddin/README.md b/exporter/SynthesisFusionAddin/README.md
index 4fc4933373..1e61d0735c 100644
--- a/exporter/SynthesisFusionAddin/README.md
+++ b/exporter/SynthesisFusionAddin/README.md
@@ -33,15 +33,14 @@ We use `VSCode` Primarily, download it to interact with our code or use your own
### How to Build + Run
-1. See root [`README`](/README.md) on how to run `init` script
-2. Open `Autodesk Fusion`
-3. Select `UTILITIES` from the top bar
-4. Click `ADD-INS` Button
-5. Click `Add-Ins` tab at the top of Scripts and Add-Ins dialog
-6. Press + Button under **My Add-Ins**
-7. Navigate to the containing folder for this Addin and click open at bottom - _clone-directory_/synthesis/exporters/SynthesisFusionAddin
-8. Synthesis should be an option - select it and click run at the bottom of the dialog
-9. There should now be a button that says Synthesis in your utilities menu
+1. Open `Autodesk Fusion`
+2. Select `UTILITIES` from the top bar
+3. Click `ADD-INS` Button
+4. Click `Add-Ins` tab at the top of Scripts and Add-Ins dialog
+5. Press + Button under **My Add-Ins**
+6. Navigate to the containing folder for this Addin and click open at bottom - _clone-directory_/synthesis/exporters/SynthesisFusionAddin
+7. Synthesis should be an option - select it and click run at the bottom of the dialog
+8. There should now be a button that says Synthesis in your utilities menu
- If there is no button there may be a problem - see below for [checking log file](#debug-non-start)
---
diff --git a/exporter/SynthesisFusionAddin/Synthesis.py b/exporter/SynthesisFusionAddin/Synthesis.py
index 180fae3b5f..ee630a12ca 100644
--- a/exporter/SynthesisFusionAddin/Synthesis.py
+++ b/exporter/SynthesisFusionAddin/Synthesis.py
@@ -6,7 +6,6 @@
# Required for absolute imports.
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "proto", "proto_out")))
from src.Dependencies import resolveDependencies
from src.Logging import logFailure, setupLogger
@@ -15,9 +14,17 @@
try:
# Attempt to import required pip dependencies to verify their installation.
- import google.protobuf
import requests
-except (ImportError, ModuleNotFoundError) as error:
+
+ from src.Proto import (
+ assembly_pb2,
+ joint_pb2,
+ material_pb2,
+ motor_pb2,
+ signal_pb2,
+ types_pb2,
+ )
+except (ImportError, ModuleNotFoundError, BaseException) as error: # BaseException required to catch proto.VersionError
logger.warn(f"Running resolve dependencies with error of:\n{error}")
result = resolveDependencies()
if result:
diff --git a/exporter/SynthesisFusionAddin/pyproject.toml b/exporter/SynthesisFusionAddin/pyproject.toml
index 01222be485..92f6c6ec1d 100644
--- a/exporter/SynthesisFusionAddin/pyproject.toml
+++ b/exporter/SynthesisFusionAddin/pyproject.toml
@@ -13,6 +13,7 @@ skip = [
".vscode/",
"/dist/",
"proto/proto_out",
+ "src/Proto",
]
[tool.black]
@@ -30,6 +31,7 @@ exclude = '''
| .vscode
| dist
| proto_out
+ | src/Proto
)/
)
'''
diff --git a/exporter/SynthesisFusionAddin/src/Dependencies.py b/exporter/SynthesisFusionAddin/src/Dependencies.py
index 29ed016199..284a8ad942 100644
--- a/exporter/SynthesisFusionAddin/src/Dependencies.py
+++ b/exporter/SynthesisFusionAddin/src/Dependencies.py
@@ -1,5 +1,4 @@
import importlib.machinery
-import importlib.util
import os
import subprocess
import sys
@@ -56,18 +55,6 @@ def executeCommand(*args: str) -> subprocess.CompletedProcess[str]:
raise error
-@logFailure
-def verifyCompiledProtoImports() -> bool:
- protoModules = ["assembly_pb2", "joint_pb2", "material_pb2", "types_pb2"]
- for module in protoModules:
- # Absolute imports must be set up by this point for importlib to be able to find each module.
- spec = importlib.util.find_spec(f"proto.proto_out.{module}")
- if spec is None:
- return False
-
- return True
-
-
def getInstalledPipPackages(pythonExecutablePath: str) -> dict[str, str]:
result: str = executeCommand(pythonExecutablePath, "-m", "pip", "freeze").stdout
# We don't need to check against packages with a specific hash as those are not required by Synthesis.
@@ -87,10 +74,6 @@ def packagesOutOfDate(installedPackages: dict[str, str]) -> bool:
def resolveDependencies() -> bool | None:
app = adsk.core.Application.get()
ui = app.userInterface
- if not verifyCompiledProtoImports():
- ui.messageBox("Missing required compiled protobuf files.")
- return False
-
if app.isOffLine:
# If we have gotten this far that means that an import error was thrown for possible missing
# dependencies... And we can't try to download them because we have no internet... ¯\_(ツ)_/¯
diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Components.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Components.py
index a0c026e60a..dd8726ad82 100644
--- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Components.py
+++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Components.py
@@ -2,7 +2,6 @@
import adsk.core
import adsk.fusion
-from proto.proto_out import assembly_pb2, joint_pb2, material_pb2, types_pb2
from src.Logging import logFailure
from src.Parser.ExporterOptions import ExporterOptions
from src.Parser.SynthesisParser import PhysicalProperties
@@ -12,6 +11,7 @@
guid_component,
guid_occurrence,
)
+from src.Proto import assembly_pb2, joint_pb2, material_pb2, types_pb2
from src.Types import ExportMode
# TODO: Impelement Material overrides
diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/JointHierarchy.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/JointHierarchy.py
index 34647c4160..3f5c628971 100644
--- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/JointHierarchy.py
+++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/JointHierarchy.py
@@ -4,12 +4,12 @@
import adsk.core
import adsk.fusion
-from proto.proto_out import joint_pb2, types_pb2
from src import gm
from src.Logging import getLogger, logFailure
from src.Parser.ExporterOptions import ExporterOptions
from src.Parser.SynthesisParser.PDMessage import PDMessage
from src.Parser.SynthesisParser.Utilities import guid_component, guid_occurrence
+from src.Proto import joint_pb2, types_pb2
logger = getLogger()
diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Joints.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Joints.py
index 80c1cd28d6..71c01326dd 100644
--- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Joints.py
+++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Joints.py
@@ -29,7 +29,6 @@
import adsk.core
import adsk.fusion
-from proto.proto_out import assembly_pb2, joint_pb2, signal_pb2, types_pb2
from src.Logging import getLogger
from src.Parser.ExporterOptions import ExporterOptions
from src.Parser.SynthesisParser.PDMessage import PDMessage
@@ -38,6 +37,7 @@
fill_info,
guid_occurrence,
)
+from src.Proto import assembly_pb2, joint_pb2, signal_pb2, types_pb2
from src.Types import Joint, JointParentType, SignalType, Wheel
logger = getLogger()
diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Materials.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Materials.py
index 964114ecc4..1ff5d3fe6c 100644
--- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Materials.py
+++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Materials.py
@@ -1,10 +1,10 @@
import adsk.core
-from proto.proto_out import material_pb2
from src.Logging import logFailure
from src.Parser.ExporterOptions import ExporterOptions
from src.Parser.SynthesisParser.PDMessage import PDMessage
from src.Parser.SynthesisParser.Utilities import construct_info, fill_info
+from src.Proto import material_pb2
OPACITY_RAMPING_CONSTANT = 14.0
diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py
index a2df3ef8cb..b085b48d32 100644
--- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py
+++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py
@@ -5,7 +5,6 @@
import adsk.fusion
from google.protobuf.json_format import MessageToJson
-from proto.proto_out import assembly_pb2, types_pb2
from src import gm
from src.APS.APS import getAuth, upload_mirabuf
from src.Logging import getLogger, logFailure, timed
@@ -18,6 +17,7 @@
PDMessage,
)
from src.Parser.SynthesisParser.Utilities import fill_info
+from src.Proto import assembly_pb2, types_pb2
from src.Types import ExportLocation, ExportMode
from src.UI.Camera import captureThumbnail, clearIconCache
diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PhysicalProperties.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PhysicalProperties.py
index ad26c7719e..53af57dfe5 100644
--- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PhysicalProperties.py
+++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PhysicalProperties.py
@@ -20,8 +20,8 @@
import adsk
-from proto.proto_out import types_pb2
from src.Logging import logFailure
+from src.Proto import types_pb2
@logFailure
diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/RigidGroup.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/RigidGroup.py
index d7e050a154..a5e389beda 100644
--- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/RigidGroup.py
+++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/RigidGroup.py
@@ -17,8 +17,8 @@
import adsk.core
import adsk.fusion
-from proto.proto_out import assembly_pb2
from src.Logging import logFailure
+from src.Proto import assembly_pb2
# Transition: AARD-1765
diff --git a/exporter/SynthesisFusionAddin/src/Proto/__init__.py b/exporter/SynthesisFusionAddin/src/Proto/__init__.py
new file mode 100644
index 0000000000..087dab646e
--- /dev/null
+++ b/exporter/SynthesisFusionAddin/src/Proto/__init__.py
@@ -0,0 +1,4 @@
+import os
+import sys
+
+sys.path.append(os.path.dirname(os.path.abspath(__file__)))
diff --git a/exporter/SynthesisFusionAddin/src/Proto/assembly_pb2.py b/exporter/SynthesisFusionAddin/src/Proto/assembly_pb2.py
new file mode 100644
index 0000000000..20803d3601
--- /dev/null
+++ b/exporter/SynthesisFusionAddin/src/Proto/assembly_pb2.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: assembly.proto
+# Protobuf Python Version: 5.27.1
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import descriptor_pool as _descriptor_pool
+from google.protobuf import runtime_version as _runtime_version
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf.internal import builder as _builder
+
+_runtime_version.ValidateProtobufRuntimeVersion(
+ _runtime_version.Domain.PUBLIC,
+ 5,
+ 27,
+ 1,
+ '',
+ 'assembly.proto'
+)
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+import joint_pb2 as joint__pb2
+import material_pb2 as material__pb2
+import signal_pb2 as signal__pb2
+import types_pb2 as types__pb2
+
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0e\x61ssembly.proto\x12\x07mirabuf\x1a\x0btypes.proto\x1a\x0bjoint.proto\x1a\x0ematerial.proto\x1a\x0csignal.proto\"\xc4\x02\n\x08\x41ssembly\x12\x1b\n\x04info\x18\x01 \x01(\x0b\x32\r.mirabuf.Info\x12#\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x15.mirabuf.AssemblyData\x12\x0f\n\x07\x64ynamic\x18\x03 \x01(\x08\x12\x32\n\rphysical_data\x18\x04 \x01(\x0b\x32\x1b.mirabuf.PhysicalProperties\x12\x31\n\x10\x64\x65sign_hierarchy\x18\x05 \x01(\x0b\x32\x17.mirabuf.GraphContainer\x12\x30\n\x0fjoint_hierarchy\x18\x06 \x01(\x0b\x32\x17.mirabuf.GraphContainer\x12%\n\ttransform\x18\x07 \x01(\x0b\x32\x12.mirabuf.Transform\x12%\n\tthumbnail\x18\x08 \x01(\x0b\x32\x12.mirabuf.Thumbnail\"\xae\x01\n\x0c\x41ssemblyData\x12\x1d\n\x05parts\x18\x01 \x01(\x0b\x32\x0e.mirabuf.Parts\x12%\n\x06joints\x18\x02 \x01(\x0b\x32\x15.mirabuf.joint.Joints\x12.\n\tmaterials\x18\x03 \x01(\x0b\x32\x1b.mirabuf.material.Materials\x12(\n\x07signals\x18\x04 \x01(\x0b\x32\x17.mirabuf.signal.Signals\"\xe2\x02\n\x05Parts\x12\x1b\n\x04info\x18\x01 \x01(\x0b\x32\r.mirabuf.Info\x12=\n\x10part_definitions\x18\x02 \x03(\x0b\x32#.mirabuf.Parts.PartDefinitionsEntry\x12\x39\n\x0epart_instances\x18\x03 \x03(\x0b\x32!.mirabuf.Parts.PartInstancesEntry\x12$\n\tuser_data\x18\x04 \x01(\x0b\x32\x11.mirabuf.UserData\x1aO\n\x14PartDefinitionsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.mirabuf.PartDefinition:\x02\x38\x01\x1aK\n\x12PartInstancesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x15.mirabuf.PartInstance:\x02\x38\x01\"\xef\x01\n\x0ePartDefinition\x12\x1b\n\x04info\x18\x01 \x01(\x0b\x32\r.mirabuf.Info\x12\x32\n\rphysical_data\x18\x02 \x01(\x0b\x32\x1b.mirabuf.PhysicalProperties\x12*\n\x0e\x62\x61se_transform\x18\x03 \x01(\x0b\x32\x12.mirabuf.Transform\x12\x1d\n\x06\x62odies\x18\x04 \x03(\x0b\x32\r.mirabuf.Body\x12\x0f\n\x07\x64ynamic\x18\x05 \x01(\x08\x12\x19\n\x11\x66riction_override\x18\x06 \x01(\x02\x12\x15\n\rmass_override\x18\x07 \x01(\x02\"\xf9\x01\n\x0cPartInstance\x12\x1b\n\x04info\x18\x01 \x01(\x0b\x32\r.mirabuf.Info\x12!\n\x19part_definition_reference\x18\x02 \x01(\t\x12%\n\ttransform\x18\x03 \x01(\x0b\x32\x12.mirabuf.Transform\x12,\n\x10global_transform\x18\x04 \x01(\x0b\x32\x12.mirabuf.Transform\x12\x0e\n\x06joints\x18\x05 \x03(\t\x12\x12\n\nappearance\x18\x06 \x01(\t\x12\x19\n\x11physical_material\x18\x07 \x01(\t\x12\x15\n\rskip_collider\x18\x08 \x01(\x08\"|\n\x04\x42ody\x12\x1b\n\x04info\x18\x01 \x01(\x0b\x32\r.mirabuf.Info\x12\x0c\n\x04part\x18\x02 \x01(\t\x12,\n\rtriangle_mesh\x18\x03 \x01(\x0b\x32\x15.mirabuf.TriangleMesh\x12\x1b\n\x13\x61ppearance_override\x18\x04 \x01(\t\"\xad\x01\n\x0cTriangleMesh\x12\x1b\n\x04info\x18\x01 \x01(\x0b\x32\r.mirabuf.Info\x12\x12\n\nhas_volume\x18\x02 \x01(\x08\x12\x1a\n\x12material_reference\x18\x03 \x01(\t\x12\x1d\n\x04mesh\x18\x04 \x01(\x0b\x32\r.mirabuf.MeshH\x00\x12$\n\x05\x62mesh\x18\x05 \x01(\x0b\x32\x13.mirabuf.BinaryMeshH\x00\x42\x0b\n\tmesh_type\"C\n\x04Mesh\x12\r\n\x05verts\x18\x01 \x03(\x02\x12\x0f\n\x07normals\x18\x02 \x03(\x02\x12\n\n\x02uv\x18\x03 \x03(\x02\x12\x0f\n\x07indices\x18\x04 \x03(\x05\"\x1a\n\nBinaryMesh\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\x42\x02H\x01\x62\x06proto3')
+
+_globals = globals()
+_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'assembly_pb2', _globals)
+if not _descriptor._USE_C_DESCRIPTORS:
+ _globals['DESCRIPTOR']._loaded_options = None
+ _globals['DESCRIPTOR']._serialized_options = b'H\001'
+ _globals['_PARTS_PARTDEFINITIONSENTRY']._loaded_options = None
+ _globals['_PARTS_PARTDEFINITIONSENTRY']._serialized_options = b'8\001'
+ _globals['_PARTS_PARTINSTANCESENTRY']._loaded_options = None
+ _globals['_PARTS_PARTINSTANCESENTRY']._serialized_options = b'8\001'
+ _globals['_ASSEMBLY']._serialized_start=84
+ _globals['_ASSEMBLY']._serialized_end=408
+ _globals['_ASSEMBLYDATA']._serialized_start=411
+ _globals['_ASSEMBLYDATA']._serialized_end=585
+ _globals['_PARTS']._serialized_start=588
+ _globals['_PARTS']._serialized_end=942
+ _globals['_PARTS_PARTDEFINITIONSENTRY']._serialized_start=786
+ _globals['_PARTS_PARTDEFINITIONSENTRY']._serialized_end=865
+ _globals['_PARTS_PARTINSTANCESENTRY']._serialized_start=867
+ _globals['_PARTS_PARTINSTANCESENTRY']._serialized_end=942
+ _globals['_PARTDEFINITION']._serialized_start=945
+ _globals['_PARTDEFINITION']._serialized_end=1184
+ _globals['_PARTINSTANCE']._serialized_start=1187
+ _globals['_PARTINSTANCE']._serialized_end=1436
+ _globals['_BODY']._serialized_start=1438
+ _globals['_BODY']._serialized_end=1562
+ _globals['_TRIANGLEMESH']._serialized_start=1565
+ _globals['_TRIANGLEMESH']._serialized_end=1738
+ _globals['_MESH']._serialized_start=1740
+ _globals['_MESH']._serialized_end=1807
+ _globals['_BINARYMESH']._serialized_start=1809
+ _globals['_BINARYMESH']._serialized_end=1835
+# @@protoc_insertion_point(module_scope)
diff --git a/exporter/SynthesisFusionAddin/src/Proto/joint_pb2.py b/exporter/SynthesisFusionAddin/src/Proto/joint_pb2.py
new file mode 100644
index 0000000000..6a14bfadaa
--- /dev/null
+++ b/exporter/SynthesisFusionAddin/src/Proto/joint_pb2.py
@@ -0,0 +1,76 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: joint.proto
+# Protobuf Python Version: 5.27.1
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import descriptor_pool as _descriptor_pool
+from google.protobuf import runtime_version as _runtime_version
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf.internal import builder as _builder
+
+_runtime_version.ValidateProtobufRuntimeVersion(
+ _runtime_version.Domain.PUBLIC,
+ 5,
+ 27,
+ 1,
+ '',
+ 'joint.proto'
+)
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+import motor_pb2 as motor__pb2
+import types_pb2 as types__pb2
+
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0bjoint.proto\x12\rmirabuf.joint\x1a\x0btypes.proto\x1a\x0bmotor.proto\"\x9d\x04\n\x06Joints\x12\x1b\n\x04info\x18\x01 \x01(\x0b\x32\r.mirabuf.Info\x12\x46\n\x11joint_definitions\x18\x02 \x03(\x0b\x32+.mirabuf.joint.Joints.JointDefinitionsEntry\x12\x42\n\x0fjoint_instances\x18\x03 \x03(\x0b\x32).mirabuf.joint.Joints.JointInstancesEntry\x12/\n\x0crigid_groups\x18\x04 \x03(\x0b\x32\x19.mirabuf.joint.RigidGroup\x12\x46\n\x11motor_definitions\x18\x05 \x03(\x0b\x32+.mirabuf.joint.Joints.MotorDefinitionsEntry\x1aM\n\x15JointDefinitionsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12#\n\x05value\x18\x02 \x01(\x0b\x32\x14.mirabuf.joint.Joint:\x02\x38\x01\x1aS\n\x13JointInstancesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12+\n\x05value\x18\x02 \x01(\x0b\x32\x1c.mirabuf.joint.JointInstance:\x02\x38\x01\x1aM\n\x15MotorDefinitionsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12#\n\x05value\x18\x02 \x01(\x0b\x32\x14.mirabuf.motor.Motor:\x02\x38\x01\"\x99\x02\n\rJointInstance\x12\x1b\n\x04info\x18\x01 \x01(\x0b\x32\r.mirabuf.Info\x12\x15\n\risEndEffector\x18\x02 \x01(\x08\x12\x13\n\x0bparent_part\x18\x03 \x01(\t\x12\x12\n\nchild_part\x18\x04 \x01(\t\x12\x17\n\x0fjoint_reference\x18\x05 \x01(\t\x12 \n\x06offset\x18\x06 \x01(\x0b\x32\x10.mirabuf.Vector3\x12&\n\x05parts\x18\x07 \x01(\x0b\x32\x17.mirabuf.GraphContainer\x12\x18\n\x10signal_reference\x18\x08 \x01(\t\x12.\n\x0bmotion_link\x18\t \x03(\x0b\x32\x19.mirabuf.joint.MotionLink\"E\n\nMotionLink\x12\x16\n\x0ejoint_instance\x18\x01 \x01(\t\x12\r\n\x05ratio\x18\x02 \x01(\x02\x12\x10\n\x08reversed\x18\x03 \x01(\x08\"\xfc\x02\n\x05Joint\x12\x1b\n\x04info\x18\x01 \x01(\x0b\x32\r.mirabuf.Info\x12 \n\x06origin\x18\x02 \x01(\x0b\x32\x10.mirabuf.Vector3\x12\x35\n\x11joint_motion_type\x18\x03 \x01(\x0e\x32\x1a.mirabuf.joint.JointMotion\x12\x17\n\x0f\x62reak_magnitude\x18\x04 \x01(\x02\x12\x34\n\nrotational\x18\x05 \x01(\x0b\x32\x1e.mirabuf.joint.RotationalJointH\x00\x12\x32\n\tprismatic\x18\x06 \x01(\x0b\x32\x1d.mirabuf.joint.PrismaticJointH\x00\x12,\n\x06\x63ustom\x18\x07 \x01(\x0b\x32\x1a.mirabuf.joint.CustomJointH\x00\x12$\n\tuser_data\x18\x08 \x01(\x0b\x32\x11.mirabuf.UserData\x12\x17\n\x0fmotor_reference\x18\t \x01(\tB\r\n\x0bJointMotion\"-\n\x08\x44ynamics\x12\x0f\n\x07\x64\x61mping\x18\x01 \x01(\x02\x12\x10\n\x08\x66riction\x18\x02 \x01(\x02\"H\n\x06Limits\x12\r\n\x05lower\x18\x01 \x01(\x02\x12\r\n\x05upper\x18\x02 \x01(\x02\x12\x10\n\x08velocity\x18\x03 \x01(\x02\x12\x0e\n\x06\x65\x66\x66ort\x18\x04 \x01(\x02\"Z\n\x06Safety\x12\x13\n\x0blower_limit\x18\x01 \x01(\x02\x12\x13\n\x0bupper_limit\x18\x02 \x01(\x02\x12\x12\n\nk_position\x18\x03 \x01(\x02\x12\x12\n\nk_velocity\x18\x04 \x01(\x02\"\xbb\x01\n\x03\x44OF\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x1e\n\x04\x61xis\x18\x02 \x01(\x0b\x32\x10.mirabuf.Vector3\x12%\n\x0epivotDirection\x18\x03 \x01(\x0e\x32\r.mirabuf.Axis\x12)\n\x08\x64ynamics\x18\x04 \x01(\x0b\x32\x17.mirabuf.joint.Dynamics\x12%\n\x06limits\x18\x05 \x01(\x0b\x32\x15.mirabuf.joint.Limits\x12\r\n\x05value\x18\x06 \x01(\x02\"/\n\x0b\x43ustomJoint\x12 \n\x04\x64ofs\x18\x01 \x03(\x0b\x32\x12.mirabuf.joint.DOF\"A\n\x0fRotationalJoint\x12.\n\x12rotational_freedom\x18\x01 \x01(\x0b\x32\x12.mirabuf.joint.DOF\"u\n\tBallJoint\x12\x1f\n\x03yaw\x18\x01 \x01(\x0b\x32\x12.mirabuf.joint.DOF\x12!\n\x05pitch\x18\x02 \x01(\x0b\x32\x12.mirabuf.joint.DOF\x12$\n\x08rotation\x18\x03 \x01(\x0b\x32\x12.mirabuf.joint.DOF\"?\n\x0ePrismaticJoint\x12-\n\x11prismatic_freedom\x18\x01 \x01(\x0b\x32\x12.mirabuf.joint.DOF\"/\n\nRigidGroup\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0boccurrences\x18\x02 \x03(\t*r\n\x0bJointMotion\x12\t\n\x05RIGID\x10\x00\x12\x0c\n\x08REVOLUTE\x10\x01\x12\n\n\x06SLIDER\x10\x02\x12\x0f\n\x0b\x43YLINDRICAL\x10\x03\x12\x0b\n\x07PINSLOT\x10\x04\x12\n\n\x06PLANAR\x10\x05\x12\x08\n\x04\x42\x41LL\x10\x06\x12\n\n\x06\x43USTOM\x10\x07\x62\x06proto3')
+
+_globals = globals()
+_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'joint_pb2', _globals)
+if not _descriptor._USE_C_DESCRIPTORS:
+ DESCRIPTOR._loaded_options = None
+ _globals['_JOINTS_JOINTDEFINITIONSENTRY']._loaded_options = None
+ _globals['_JOINTS_JOINTDEFINITIONSENTRY']._serialized_options = b'8\001'
+ _globals['_JOINTS_JOINTINSTANCESENTRY']._loaded_options = None
+ _globals['_JOINTS_JOINTINSTANCESENTRY']._serialized_options = b'8\001'
+ _globals['_JOINTS_MOTORDEFINITIONSENTRY']._loaded_options = None
+ _globals['_JOINTS_MOTORDEFINITIONSENTRY']._serialized_options = b'8\001'
+ _globals['_JOINTMOTION']._serialized_start=2090
+ _globals['_JOINTMOTION']._serialized_end=2204
+ _globals['_JOINTS']._serialized_start=57
+ _globals['_JOINTS']._serialized_end=598
+ _globals['_JOINTS_JOINTDEFINITIONSENTRY']._serialized_start=357
+ _globals['_JOINTS_JOINTDEFINITIONSENTRY']._serialized_end=434
+ _globals['_JOINTS_JOINTINSTANCESENTRY']._serialized_start=436
+ _globals['_JOINTS_JOINTINSTANCESENTRY']._serialized_end=519
+ _globals['_JOINTS_MOTORDEFINITIONSENTRY']._serialized_start=521
+ _globals['_JOINTS_MOTORDEFINITIONSENTRY']._serialized_end=598
+ _globals['_JOINTINSTANCE']._serialized_start=601
+ _globals['_JOINTINSTANCE']._serialized_end=882
+ _globals['_MOTIONLINK']._serialized_start=884
+ _globals['_MOTIONLINK']._serialized_end=953
+ _globals['_JOINT']._serialized_start=956
+ _globals['_JOINT']._serialized_end=1336
+ _globals['_DYNAMICS']._serialized_start=1338
+ _globals['_DYNAMICS']._serialized_end=1383
+ _globals['_LIMITS']._serialized_start=1385
+ _globals['_LIMITS']._serialized_end=1457
+ _globals['_SAFETY']._serialized_start=1459
+ _globals['_SAFETY']._serialized_end=1549
+ _globals['_DOF']._serialized_start=1552
+ _globals['_DOF']._serialized_end=1739
+ _globals['_CUSTOMJOINT']._serialized_start=1741
+ _globals['_CUSTOMJOINT']._serialized_end=1788
+ _globals['_ROTATIONALJOINT']._serialized_start=1790
+ _globals['_ROTATIONALJOINT']._serialized_end=1855
+ _globals['_BALLJOINT']._serialized_start=1857
+ _globals['_BALLJOINT']._serialized_end=1974
+ _globals['_PRISMATICJOINT']._serialized_start=1976
+ _globals['_PRISMATICJOINT']._serialized_end=2039
+ _globals['_RIGIDGROUP']._serialized_start=2041
+ _globals['_RIGIDGROUP']._serialized_end=2088
+# @@protoc_insertion_point(module_scope)
diff --git a/exporter/SynthesisFusionAddin/src/Proto/material_pb2.py b/exporter/SynthesisFusionAddin/src/Proto/material_pb2.py
new file mode 100644
index 0000000000..3c54e0c3dc
--- /dev/null
+++ b/exporter/SynthesisFusionAddin/src/Proto/material_pb2.py
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: material.proto
+# Protobuf Python Version: 5.27.1
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import descriptor_pool as _descriptor_pool
+from google.protobuf import runtime_version as _runtime_version
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf.internal import builder as _builder
+
+_runtime_version.ValidateProtobufRuntimeVersion(
+ _runtime_version.Domain.PUBLIC,
+ 5,
+ 27,
+ 1,
+ '',
+ 'material.proto'
+)
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+import types_pb2 as types__pb2
+
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0ematerial.proto\x12\x10mirabuf.material\x1a\x0btypes.proto\"\xea\x02\n\tMaterials\x12\x1b\n\x04info\x18\x01 \x01(\x0b\x32\r.mirabuf.Info\x12M\n\x11physicalMaterials\x18\x02 \x03(\x0b\x32\x32.mirabuf.material.Materials.PhysicalMaterialsEntry\x12\x41\n\x0b\x61ppearances\x18\x03 \x03(\x0b\x32,.mirabuf.material.Materials.AppearancesEntry\x1a\\\n\x16PhysicalMaterialsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x31\n\x05value\x18\x02 \x01(\x0b\x32\".mirabuf.material.PhysicalMaterial:\x02\x38\x01\x1aP\n\x10\x41ppearancesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12+\n\x05value\x18\x02 \x01(\x0b\x32\x1c.mirabuf.material.Appearance:\x02\x38\x01\"\x80\x01\n\nAppearance\x12\x1b\n\x04info\x18\x01 \x01(\x0b\x32\r.mirabuf.Info\x12\x1e\n\x06\x61lbedo\x18\x02 \x01(\x0b\x32\x0e.mirabuf.Color\x12\x11\n\troughness\x18\x03 \x01(\x01\x12\x10\n\x08metallic\x18\x04 \x01(\x01\x12\x10\n\x08specular\x18\x05 \x01(\x01\"\x82\x06\n\x10PhysicalMaterial\x12\x1b\n\x04info\x18\x01 \x01(\x0b\x32\r.mirabuf.Info\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12;\n\x07thermal\x18\x03 \x01(\x0b\x32*.mirabuf.material.PhysicalMaterial.Thermal\x12\x41\n\nmechanical\x18\x04 \x01(\x0b\x32-.mirabuf.material.PhysicalMaterial.Mechanical\x12=\n\x08strength\x18\x05 \x01(\x0b\x32+.mirabuf.material.PhysicalMaterial.Strength\x12\x18\n\x10\x64ynamic_friction\x18\x06 \x01(\x02\x12\x17\n\x0fstatic_friction\x18\x07 \x01(\x02\x12\x13\n\x0brestitution\x18\x08 \x01(\x02\x12\x12\n\ndeformable\x18\t \x01(\x08\x12@\n\x07matType\x18\n \x01(\x0e\x32/.mirabuf.material.PhysicalMaterial.MaterialType\x1a\x65\n\x07Thermal\x12\x1c\n\x14thermal_conductivity\x18\x01 \x01(\x02\x12\x15\n\rspecific_heat\x18\x02 \x01(\x02\x12%\n\x1dthermal_expansion_coefficient\x18\x03 \x01(\x02\x1aw\n\nMechanical\x12\x11\n\tyoung_mod\x18\x01 \x01(\x02\x12\x15\n\rpoisson_ratio\x18\x02 \x01(\x02\x12\x11\n\tshear_mod\x18\x03 \x01(\x02\x12\x0f\n\x07\x64\x65nsity\x18\x04 \x01(\x02\x12\x1b\n\x13\x64\x61mping_coefficient\x18\x05 \x01(\x02\x1aW\n\x08Strength\x12\x16\n\x0eyield_strength\x18\x01 \x01(\x02\x12\x18\n\x10tensile_strength\x18\x02 \x01(\x02\x12\x19\n\x11thermal_treatment\x18\x03 \x01(\x08\"&\n\x0cMaterialType\x12\t\n\x05METAL\x10\x00\x12\x0b\n\x07PLASTIC\x10\x01\x62\x06proto3')
+
+_globals = globals()
+_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'material_pb2', _globals)
+if not _descriptor._USE_C_DESCRIPTORS:
+ DESCRIPTOR._loaded_options = None
+ _globals['_MATERIALS_PHYSICALMATERIALSENTRY']._loaded_options = None
+ _globals['_MATERIALS_PHYSICALMATERIALSENTRY']._serialized_options = b'8\001'
+ _globals['_MATERIALS_APPEARANCESENTRY']._loaded_options = None
+ _globals['_MATERIALS_APPEARANCESENTRY']._serialized_options = b'8\001'
+ _globals['_MATERIALS']._serialized_start=50
+ _globals['_MATERIALS']._serialized_end=412
+ _globals['_MATERIALS_PHYSICALMATERIALSENTRY']._serialized_start=238
+ _globals['_MATERIALS_PHYSICALMATERIALSENTRY']._serialized_end=330
+ _globals['_MATERIALS_APPEARANCESENTRY']._serialized_start=332
+ _globals['_MATERIALS_APPEARANCESENTRY']._serialized_end=412
+ _globals['_APPEARANCE']._serialized_start=415
+ _globals['_APPEARANCE']._serialized_end=543
+ _globals['_PHYSICALMATERIAL']._serialized_start=546
+ _globals['_PHYSICALMATERIAL']._serialized_end=1316
+ _globals['_PHYSICALMATERIAL_THERMAL']._serialized_start=965
+ _globals['_PHYSICALMATERIAL_THERMAL']._serialized_end=1066
+ _globals['_PHYSICALMATERIAL_MECHANICAL']._serialized_start=1068
+ _globals['_PHYSICALMATERIAL_MECHANICAL']._serialized_end=1187
+ _globals['_PHYSICALMATERIAL_STRENGTH']._serialized_start=1189
+ _globals['_PHYSICALMATERIAL_STRENGTH']._serialized_end=1276
+ _globals['_PHYSICALMATERIAL_MATERIALTYPE']._serialized_start=1278
+ _globals['_PHYSICALMATERIAL_MATERIALTYPE']._serialized_end=1316
+# @@protoc_insertion_point(module_scope)
diff --git a/exporter/SynthesisFusionAddin/src/Proto/motor_pb2.py b/exporter/SynthesisFusionAddin/src/Proto/motor_pb2.py
new file mode 100644
index 0000000000..7371eb693f
--- /dev/null
+++ b/exporter/SynthesisFusionAddin/src/Proto/motor_pb2.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: motor.proto
+# Protobuf Python Version: 5.27.1
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import descriptor_pool as _descriptor_pool
+from google.protobuf import runtime_version as _runtime_version
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf.internal import builder as _builder
+
+_runtime_version.ValidateProtobufRuntimeVersion(
+ _runtime_version.Domain.PUBLIC,
+ 5,
+ 27,
+ 1,
+ '',
+ 'motor.proto'
+)
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+import types_pb2 as types__pb2
+
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0bmotor.proto\x12\rmirabuf.motor\x1a\x0btypes.proto\"\x98\x01\n\x05Motor\x12\x1b\n\x04info\x18\x01 \x01(\x0b\x32\r.mirabuf.Info\x12*\n\x08\x64\x63_motor\x18\x02 \x01(\x0b\x32\x16.mirabuf.motor.DCMotorH\x00\x12\x32\n\x0csimple_motor\x18\x03 \x01(\x0b\x32\x1a.mirabuf.motor.SimpleMotorH\x00\x42\x0c\n\nmotor_typeJ\x04\x08\x04\x10\x06\"S\n\x0bSimpleMotor\x12\x14\n\x0cstall_torque\x18\x01 \x01(\x02\x12\x14\n\x0cmax_velocity\x18\x02 \x01(\x02\x12\x18\n\x10\x62raking_constant\x18\x03 \x01(\x02\"\x9d\x03\n\x07\x44\x43Motor\x12\x15\n\rreference_url\x18\x02 \x01(\t\x12\x17\n\x0ftorque_constant\x18\x03 \x01(\x02\x12\x14\n\x0c\x65mf_constant\x18\x04 \x01(\x02\x12\x12\n\nresistance\x18\x05 \x01(\x02\x12\x1a\n\x12maximum_effeciency\x18\x06 \x01(\r\x12\x15\n\rmaximum_power\x18\x07 \x01(\r\x12-\n\nduty_cycle\x18\x08 \x01(\x0e\x32\x19.mirabuf.motor.DutyCycles\x12\x31\n\x08\x61\x64vanced\x18\x10 \x01(\x0b\x32\x1f.mirabuf.motor.DCMotor.Advanced\x1a\x96\x01\n\x08\x41\x64vanced\x12\x14\n\x0c\x66ree_current\x18\x01 \x01(\x02\x12\x12\n\nfree_speed\x18\x02 \x01(\r\x12\x15\n\rstall_current\x18\x03 \x01(\x02\x12\x14\n\x0cstall_torque\x18\x04 \x01(\x02\x12\x15\n\rinput_voltage\x18\x05 \x01(\r\x12\x1c\n\x14resistance_variation\x18\x07 \x01(\x02J\x04\x08\x01\x10\x02J\x04\x08\t\x10\x10*h\n\nDutyCycles\x12\x16\n\x12\x43ONTINUOUS_RUNNING\x10\x00\x12\x0e\n\nSHORT_TIME\x10\x01\x12\x19\n\x15INTERMITTENT_PERIODIC\x10\x02\x12\x17\n\x13\x43ONTINUOUS_PERIODIC\x10\x03\x62\x06proto3')
+
+_globals = globals()
+_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'motor_pb2', _globals)
+if not _descriptor._USE_C_DESCRIPTORS:
+ DESCRIPTOR._loaded_options = None
+ _globals['_DUTYCYCLES']._serialized_start=699
+ _globals['_DUTYCYCLES']._serialized_end=803
+ _globals['_MOTOR']._serialized_start=44
+ _globals['_MOTOR']._serialized_end=196
+ _globals['_SIMPLEMOTOR']._serialized_start=198
+ _globals['_SIMPLEMOTOR']._serialized_end=281
+ _globals['_DCMOTOR']._serialized_start=284
+ _globals['_DCMOTOR']._serialized_end=697
+ _globals['_DCMOTOR_ADVANCED']._serialized_start=535
+ _globals['_DCMOTOR_ADVANCED']._serialized_end=685
+# @@protoc_insertion_point(module_scope)
diff --git a/exporter/SynthesisFusionAddin/src/Proto/readme.md b/exporter/SynthesisFusionAddin/src/Proto/readme.md
new file mode 100644
index 0000000000..3f4ac2a4c6
--- /dev/null
+++ b/exporter/SynthesisFusionAddin/src/Proto/readme.md
@@ -0,0 +1 @@
+These files are autogenerated by protobuf. For more information visit [`/exporter/proto/`](../../proto/)
diff --git a/exporter/SynthesisFusionAddin/src/Proto/signal_pb2.py b/exporter/SynthesisFusionAddin/src/Proto/signal_pb2.py
new file mode 100644
index 0000000000..c981f82f04
--- /dev/null
+++ b/exporter/SynthesisFusionAddin/src/Proto/signal_pb2.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: signal.proto
+# Protobuf Python Version: 5.27.1
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import descriptor_pool as _descriptor_pool
+from google.protobuf import runtime_version as _runtime_version
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf.internal import builder as _builder
+
+_runtime_version.ValidateProtobufRuntimeVersion(
+ _runtime_version.Domain.PUBLIC,
+ 5,
+ 27,
+ 1,
+ '',
+ 'signal.proto'
+)
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+import types_pb2 as types__pb2
+
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0csignal.proto\x12\x0emirabuf.signal\x1a\x0btypes.proto\"\xac\x01\n\x07Signals\x12\x1b\n\x04info\x18\x01 \x01(\x0b\x32\r.mirabuf.Info\x12:\n\nsignal_map\x18\x02 \x03(\x0b\x32&.mirabuf.signal.Signals.SignalMapEntry\x1aH\n\x0eSignalMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12%\n\x05value\x18\x02 \x01(\x0b\x32\x16.mirabuf.signal.Signal:\x02\x38\x01\"\xa2\x01\n\x06Signal\x12\x1b\n\x04info\x18\x01 \x01(\x0b\x32\r.mirabuf.Info\x12\"\n\x02io\x18\x02 \x01(\x0e\x32\x16.mirabuf.signal.IOType\x12\x13\n\x0b\x63ustom_type\x18\x03 \x01(\t\x12\x11\n\tsignal_id\x18\x04 \x01(\r\x12/\n\x0b\x64\x65vice_type\x18\x05 \x01(\x0e\x32\x1a.mirabuf.signal.DeviceType*\x1f\n\x06IOType\x12\t\n\x05INPUT\x10\x00\x12\n\n\x06OUTPUT\x10\x01*O\n\nDeviceType\x12\x07\n\x03PWM\x10\x00\x12\x0b\n\x07\x44igital\x10\x01\x12\n\n\x06\x41nalog\x10\x02\x12\x07\n\x03I2C\x10\x03\x12\n\n\x06\x43\x41NBUS\x10\x04\x12\n\n\x06\x43USTOM\x10\x05\x62\x06proto3')
+
+_globals = globals()
+_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'signal_pb2', _globals)
+if not _descriptor._USE_C_DESCRIPTORS:
+ DESCRIPTOR._loaded_options = None
+ _globals['_SIGNALS_SIGNALMAPENTRY']._loaded_options = None
+ _globals['_SIGNALS_SIGNALMAPENTRY']._serialized_options = b'8\001'
+ _globals['_IOTYPE']._serialized_start=385
+ _globals['_IOTYPE']._serialized_end=416
+ _globals['_DEVICETYPE']._serialized_start=418
+ _globals['_DEVICETYPE']._serialized_end=497
+ _globals['_SIGNALS']._serialized_start=46
+ _globals['_SIGNALS']._serialized_end=218
+ _globals['_SIGNALS_SIGNALMAPENTRY']._serialized_start=146
+ _globals['_SIGNALS_SIGNALMAPENTRY']._serialized_end=218
+ _globals['_SIGNAL']._serialized_start=221
+ _globals['_SIGNAL']._serialized_end=383
+# @@protoc_insertion_point(module_scope)
diff --git a/exporter/SynthesisFusionAddin/src/Proto/types_pb2.py b/exporter/SynthesisFusionAddin/src/Proto/types_pb2.py
new file mode 100644
index 0000000000..658fabbb7d
--- /dev/null
+++ b/exporter/SynthesisFusionAddin/src/Proto/types_pb2.py
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: types.proto
+# Protobuf Python Version: 5.27.1
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import descriptor_pool as _descriptor_pool
+from google.protobuf import runtime_version as _runtime_version
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf.internal import builder as _builder
+
+_runtime_version.ValidateProtobufRuntimeVersion(
+ _runtime_version.Domain.PUBLIC,
+ 5,
+ 27,
+ 1,
+ '',
+ 'types.proto'
+)
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0btypes.proto\x12\x07mirabuf\"\\\n\x04Node\x12\r\n\x05value\x18\x01 \x01(\t\x12\x1f\n\x08\x63hildren\x18\x02 \x03(\x0b\x32\r.mirabuf.Node\x12$\n\tuser_data\x18\x03 \x01(\x0b\x32\x11.mirabuf.UserData\".\n\x0eGraphContainer\x12\x1c\n\x05nodes\x18\x01 \x03(\x0b\x32\r.mirabuf.Node\"b\n\x08UserData\x12)\n\x04\x64\x61ta\x18\x01 \x03(\x0b\x32\x1b.mirabuf.UserData.DataEntry\x1a+\n\tDataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"*\n\x07Vector3\x12\t\n\x01x\x18\x01 \x01(\x02\x12\t\n\x01y\x18\x02 \x01(\x02\x12\t\n\x01z\x18\x03 \x01(\x02\"p\n\x12PhysicalProperties\x12\x0f\n\x07\x64\x65nsity\x18\x01 \x01(\x01\x12\x0c\n\x04mass\x18\x02 \x01(\x01\x12\x0e\n\x06volume\x18\x03 \x01(\x01\x12\x0c\n\x04\x61rea\x18\x04 \x01(\x01\x12\x1d\n\x03\x63om\x18\x05 \x01(\x0b\x32\x10.mirabuf.Vector3\"#\n\tTransform\x12\x16\n\x0espatial_matrix\x18\x01 \x03(\x02\"3\n\x05\x43olor\x12\t\n\x01R\x18\x01 \x01(\x05\x12\t\n\x01G\x18\x02 \x01(\x05\x12\t\n\x01\x42\x18\x03 \x01(\x05\x12\t\n\x01\x41\x18\x04 \x01(\x05\"3\n\x04Info\x12\x0c\n\x04GUID\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0f\n\x07version\x18\x03 \x01(\r\"`\n\tThumbnail\x12\r\n\x05width\x18\x01 \x01(\x05\x12\x0e\n\x06height\x18\x02 \x01(\x05\x12\x11\n\textension\x18\x03 \x01(\t\x12\x13\n\x0btransparent\x18\x04 \x01(\x08\x12\x0c\n\x04\x64\x61ta\x18\x05 \x01(\x0c*\x1b\n\x04\x41xis\x12\x05\n\x01X\x10\x00\x12\x05\n\x01Y\x10\x01\x12\x05\n\x01Z\x10\x02\x62\x06proto3')
+
+_globals = globals()
+_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'types_pb2', _globals)
+if not _descriptor._USE_C_DESCRIPTORS:
+ DESCRIPTOR._loaded_options = None
+ _globals['_USERDATA_DATAENTRY']._loaded_options = None
+ _globals['_USERDATA_DATAENTRY']._serialized_options = b'8\001'
+ _globals['_AXIS']._serialized_start=665
+ _globals['_AXIS']._serialized_end=692
+ _globals['_NODE']._serialized_start=24
+ _globals['_NODE']._serialized_end=116
+ _globals['_GRAPHCONTAINER']._serialized_start=118
+ _globals['_GRAPHCONTAINER']._serialized_end=164
+ _globals['_USERDATA']._serialized_start=166
+ _globals['_USERDATA']._serialized_end=264
+ _globals['_USERDATA_DATAENTRY']._serialized_start=221
+ _globals['_USERDATA_DATAENTRY']._serialized_end=264
+ _globals['_VECTOR3']._serialized_start=266
+ _globals['_VECTOR3']._serialized_end=308
+ _globals['_PHYSICALPROPERTIES']._serialized_start=310
+ _globals['_PHYSICALPROPERTIES']._serialized_end=422
+ _globals['_TRANSFORM']._serialized_start=424
+ _globals['_TRANSFORM']._serialized_end=459
+ _globals['_COLOR']._serialized_start=461
+ _globals['_COLOR']._serialized_end=512
+ _globals['_INFO']._serialized_start=514
+ _globals['_INFO']._serialized_end=565
+ _globals['_THUMBNAIL']._serialized_start=567
+ _globals['_THUMBNAIL']._serialized_end=663
+# @@protoc_insertion_point(module_scope)
diff --git a/exporter/SynthesisFusionAddin/tools/verifyIsortFormatting.py b/exporter/SynthesisFusionAddin/tools/verifyIsortFormatting.py
index 0f9d899d5a..61772e05cb 100644
--- a/exporter/SynthesisFusionAddin/tools/verifyIsortFormatting.py
+++ b/exporter/SynthesisFusionAddin/tools/verifyIsortFormatting.py
@@ -18,9 +18,16 @@ def main() -> None:
exitCode = 0
for i, (oldFileState, newFileState) in enumerate(zip(oldFileStates, newFileStates)):
for j, (previousLine, newLine) in enumerate(zip(oldFileState, newFileState)):
- if previousLine != newLine:
- print(f"File {files[i]} is not formatted correctly!\nLine: {j + 1}")
- exitCode = 1
+ if previousLine == newLine:
+ continue
+
+ print(f"File {files[i]} is not formatted correctly!\nLine: {j + 1}")
+ oldFileStateRange = range(max(0, j - 10), min(len(oldFileState), j + 11))
+ print("\nOld file state:\n" + "\n".join(oldFileState[k].strip() for k in oldFileStateRange))
+ newFileStateRange = range(max(0, j - 10), min(len(newFileState), j + 11))
+ print("\nNew file state:\n" + "\n".join(newFileState[k].strip() for k in newFileStateRange))
+ exitCode = 1
+ break
if not exitCode:
print("All files are formatted correctly with isort!")
diff --git a/fission/index.html b/fission/index.html
index bf462bd999..5916fa6750 100644
--- a/fission/index.html
+++ b/fission/index.html
@@ -1,16 +1,22 @@
-
-
-
-
-
-
-
- Fission | Synthesis
-
-
-
-
-
+
+
+
+
+
+
+
+ Fission | Synthesis
+
+
+
+
+
diff --git a/fission/src/Synthesis.tsx b/fission/src/Synthesis.tsx
index e027a5e761..0e2fe2a29b 100644
--- a/fission/src/Synthesis.tsx
+++ b/fission/src/Synthesis.tsx
@@ -20,7 +20,6 @@ import UpdateAvailableModal from "@/modals/UpdateAvailableModal"
import ViewModal from "@/modals/ViewModal"
import ConnectToMultiplayerModal from "@/modals/aether/ConnectToMultiplayerModal"
import ServerHostingModal from "@/modals/aether/ServerHostingModal"
-import ChangeInputsModal from "@/ui/modals/configuring/inputs/ChangeInputsModal.tsx"
import ChooseMultiplayerModeModal from "@/modals/configuring/ChooseMultiplayerModeModal"
import ChooseSingleplayerModeModal from "@/modals/configuring/ChooseSingleplayerModeModal"
import ConfigMotorModal from "@/modals/configuring/ConfigMotorModal"
@@ -37,13 +36,9 @@ import ThemeEditorModal from "@/modals/configuring/theme-editor/ThemeEditorModal
import MatchModeModal from "@/modals/spawning/MatchModeModal"
import RobotSwitchPanel from "@/panels/RobotSwitchPanel"
import SpawnLocationsPanel from "@/panels/SpawnLocationPanel"
-import ConfigureGamepiecePickupPanel from "@/panels/configuring/ConfigureGamepiecePickupPanel"
-import ConfigureShotTrajectoryPanel from "@/panels/configuring/ConfigureShotTrajectoryPanel"
-import ScoringZonesPanel from "@/panels/configuring/scoring/ScoringZonesPanel"
import ScoreboardPanel from "@/panels/information/ScoreboardPanel"
import DriverStationPanel from "@/panels/simulation/DriverStationPanel"
import PokerPanel from "@/panels/PokerPanel.tsx"
-import ManageAssembliesModal from "@/modals/spawning/ManageAssembliesModal.tsx"
import World from "@/systems/World.ts"
import { AddRobotsModal, AddFieldsModal, SpawningModal } from "@/modals/spawning/SpawningModals.tsx"
import ImportLocalMirabufModal from "@/modals/mirabuf/ImportLocalMirabufModal.tsx"
@@ -51,14 +46,13 @@ import ImportMirabufPanel from "@/ui/panels/mirabuf/ImportMirabufPanel.tsx"
import Skybox from "./ui/components/Skybox.tsx"
import ChooseInputSchemePanel from "./ui/panels/configuring/ChooseInputSchemePanel.tsx"
import ProgressNotifications from "./ui/components/ProgressNotification.tsx"
-import ConfigureRobotModal from "./ui/modals/configuring/ConfigureRobotModal.tsx"
-import ResetAllInputsModal from "./ui/modals/configuring/inputs/ResetAllInputsModal.tsx"
-import ZoneConfigPanel from "./ui/panels/configuring/scoring/ZoneConfigPanel.tsx"
+import ConfigureRobotBrainPanel from "./ui/panels/configuring/ConfigureRobotBrainPanel.tsx"
import SceneOverlay from "./ui/components/SceneOverlay.tsx"
import WPILibWSWorker from "@/systems/simulation/wpilib_brain/WPILibWSWorker.ts?worker"
import WSViewPanel from "./ui/panels/WSViewPanel.tsx"
import Lazy from "./util/Lazy.ts"
+
import RCConfigPWMGroupModal from "@/modals/configuring/rio-config/RCConfigPWMGroupModal.tsx"
import RCConfigCANGroupModal from "@/modals/configuring/rio-config/RCConfigCANGroupModal.tsx"
import DebugPanel from "./ui/panels/DebugPanel.tsx"
@@ -66,6 +60,9 @@ import NewInputSchemeModal from "./ui/modals/configuring/theme-editor/NewInputSc
import AssignNewSchemeModal from "./ui/modals/configuring/theme-editor/AssignNewSchemeModal.tsx"
import AnalyticsConsent from "./ui/components/AnalyticsConsent.tsx"
import PreferencesSystem from "./systems/preferences/PreferencesSystem.ts"
+import ResetAllInputsModal from "./ui/modals/configuring/inputs/ResetAllInputsModal.tsx"
+import APSManagementModal from "./ui/modals/APSManagementModal.tsx"
+import ConfigurePanel from "./ui/panels/configuring/assembly-config/ConfigurePanel.tsx"
const worker = new Lazy(() => new WPILibWSWorker())
@@ -208,7 +205,6 @@ const initialModals = [
,
,
,
- ,
,
,
,
@@ -223,10 +219,9 @@ const initialModals = [
,
,
,
- ,
,
- ,
,
+ ,
]
const initialPanels: ReactElement[] = [
@@ -234,25 +229,18 @@ const initialPanels: ReactElement[] = [
,
,
,
- ,
- ,
+ ,
+ ,
- ,
- ,
- ,
- ,
,
,
,
+ ,
]
export default Synthesis
diff --git a/fission/src/index.css b/fission/src/index.css
index afa1fa6dc6..f3c04e2d14 100644
--- a/fission/src/index.css
+++ b/fission/src/index.css
@@ -2,6 +2,24 @@
@tailwind components;
@tailwind utilities;
+::-webkit-scrollbar {
+ width: 8px;
+ height: 8px;
+}
+
+::-webkit-scrollbar-track {
+ background: "transparent";
+}
+
+::-webkit-scrollbar-thumb {
+ background: #444444;
+ border-radius: 4px;
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: #555;
+}
+
:root {
/* font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; */
font-family: "Artifakt";
diff --git a/fission/src/mirabuf/MirabufInstance.ts b/fission/src/mirabuf/MirabufInstance.ts
index 174cbcbff3..700395611c 100644
--- a/fission/src/mirabuf/MirabufInstance.ts
+++ b/fission/src/mirabuf/MirabufInstance.ts
@@ -146,6 +146,7 @@ class MirabufInstance {
material = new THREE.MeshPhongMaterial({
color: hex,
shininess: 0.0,
+ shadowSide: THREE.DoubleSide,
opacity: opacity,
transparent: opacity < 1.0,
})
@@ -156,6 +157,7 @@ class MirabufInstance {
console.debug("Toon Material")
}
+ World.SceneRenderer.SetupMaterial(material!)
this._materials.set(appearanceId, material!)
}
)
diff --git a/fission/src/mirabuf/MirabufLoader.ts b/fission/src/mirabuf/MirabufLoader.ts
index 00c0068733..1355d9e38c 100644
--- a/fission/src/mirabuf/MirabufLoader.ts
+++ b/fission/src/mirabuf/MirabufLoader.ts
@@ -21,7 +21,7 @@ export interface MirabufRemoteInfo {
src: string
}
-type MiraCache = { [id: string]: MirabufCacheInfo }
+type MapCache = { [id: MirabufCacheID]: MirabufCacheInfo }
const robotsDirName = "Robots"
const fieldsDirName = "Fields"
@@ -29,6 +29,33 @@ const root = await navigator.storage.getDirectory()
const robotFolderHandle = await root.getDirectoryHandle(robotsDirName, { create: true })
const fieldFolderHandle = await root.getDirectoryHandle(fieldsDirName, { create: true })
+export const backUpRobots: Map = new Map()
+export const backUpFields: Map = new Map()
+
+const canOPFS = await (async () => {
+ try {
+ if (robotFolderHandle.name == robotsDirName) {
+ robotFolderHandle.entries
+ robotFolderHandle.keys
+
+ const fileHandle = await robotFolderHandle.getFileHandle("0", { create: true })
+ const writable = await fileHandle.createWritable()
+ await writable.close()
+ await fileHandle.getFile()
+
+ robotFolderHandle.removeEntry(fileHandle.name)
+
+ return true
+ } else {
+ console.log(`No access to OPFS`)
+ return false
+ }
+ } catch (e) {
+ console.log(`No access to OPFS`)
+ return false
+ }
+})()
+
export function UnzipMira(buff: Uint8Array): Uint8Array {
// Check if file is gzipped via magic gzip numbers 31 139
if (buff[0] == 31 && buff[1] == 139) {
@@ -42,11 +69,11 @@ class MirabufCachingService {
/**
* Get the map of mirabuf keys and paired MirabufCacheInfo from local storage
*
- * @param {MiraType} miraType Type of Mirabuf Assembly.
+ * @param {MiraType} miraType Type of Mirabuf Assembly
*
- * @returns {MiraCache} Map of cached keys and paired MirabufCacheInfo
+ * @returns {MapCache} Map of cached keys and paired MirabufCacheInfo
*/
- public static GetCacheMap(miraType: MiraType): MiraCache {
+ public static GetCacheMap(miraType: MiraType): MapCache {
if (
(window.localStorage.getItem(MIRABUF_LOCALSTORAGE_GENERATION_KEY) ?? "") == MIRABUF_LOCALSTORAGE_GENERATION
) {
@@ -159,18 +186,18 @@ class MirabufCachingService {
thumbnailStorageID?: string
): Promise {
try {
- const map: MiraCache = this.GetCacheMap(miraType)
+ const map: MapCache = this.GetCacheMap(miraType)
const id = map[key].id
const _name = map[key].name
const _thumbnailStorageID = map[key].thumbnailStorageID
- const hi: MirabufCacheInfo = {
+ const info: MirabufCacheInfo = {
id: id,
cacheKey: key,
miraType: miraType,
name: name ?? _name,
thumbnailStorageID: thumbnailStorageID ?? _thumbnailStorageID,
}
- map[key] = hi
+ map[key] = info
window.localStorage.setItem(miraType == MiraType.ROBOT ? robotsDirName : fieldsDirName, JSON.stringify(map))
return true
} catch (e) {
@@ -213,16 +240,21 @@ class MirabufCachingService {
*/
public static async Get(id: MirabufCacheID, miraType: MiraType): Promise {
try {
- const fileHandle = await (miraType == MiraType.ROBOT ? robotFolderHandle : fieldFolderHandle).getFileHandle(
- id,
- {
- create: false,
- }
- )
-
- // Get assembly from file
- if (fileHandle) {
- const buff = await fileHandle.getFile().then(x => x.arrayBuffer())
+ // Get buffer from hashMap. If not in hashMap, check OPFS. Otherwise, buff is undefined
+ const cache = miraType == MiraType.ROBOT ? backUpRobots : backUpFields
+ const buff =
+ cache.get(id) ??
+ (await (async () => {
+ const fileHandle = canOPFS
+ ? await (miraType == MiraType.ROBOT ? robotFolderHandle : fieldFolderHandle).getFileHandle(id, {
+ create: false,
+ })
+ : undefined
+ return fileHandle ? await fileHandle.getFile().then(x => x.arrayBuffer()) : undefined
+ })())
+
+ // If we have buffer, get assembly
+ if (buff) {
const assembly = this.AssemblyFromBuffer(buff)
World.AnalyticsSystem?.Event("Cache Get", {
key: id,
@@ -232,11 +264,10 @@ class MirabufCachingService {
})
return assembly
} else {
- console.error(`Failed to get file handle for ID: ${id}`)
- return undefined
+ console.error(`Failed to find arrayBuffer for id: ${id}`)
}
} catch (e) {
- console.error(`Failed to find file from OPFS\n${e}`)
+ console.error(`Failed to find file\n${e}`)
return undefined
}
}
@@ -261,8 +292,15 @@ class MirabufCachingService {
)
}
- const dir = miraType == MiraType.ROBOT ? robotFolderHandle : fieldFolderHandle
- await dir.removeEntry(id)
+ if (canOPFS) {
+ const dir = miraType == MiraType.ROBOT ? robotFolderHandle : fieldFolderHandle
+ await dir.removeEntry(id)
+ }
+
+ const backUpCache = miraType == MiraType.ROBOT ? backUpRobots : backUpFields
+ if (backUpCache) {
+ backUpCache.delete(id)
+ }
World.AnalyticsSystem?.Event("Cache Remove", {
key: key,
@@ -289,6 +327,9 @@ class MirabufCachingService {
window.localStorage.removeItem(robotsDirName)
window.localStorage.removeItem(fieldsDirName)
+
+ backUpRobots.clear()
+ backUpFields.clear()
}
// Optional name for when assembly is being decoded anyway like in CacheAndGetLocal()
@@ -298,7 +339,6 @@ class MirabufCachingService {
miraType?: MiraType,
name?: string
): Promise {
- // Store in OPFS
const backupID = Date.now().toString()
try {
if (!miraType) {
@@ -306,16 +346,8 @@ class MirabufCachingService {
miraType = this.AssemblyFromBuffer(miraBuff).dynamic ? MiraType.ROBOT : MiraType.FIELD
}
- const fileHandle = await (miraType == MiraType.ROBOT ? robotFolderHandle : fieldFolderHandle).getFileHandle(
- backupID,
- { create: true }
- )
- const writable = await fileHandle.createWritable()
- await writable.write(miraBuff)
- await writable.close()
-
// Local cache map
- const map: MiraCache = this.GetCacheMap(miraType)
+ const map: MapCache = this.GetCacheMap(miraType)
const info: MirabufCacheInfo = {
id: backupID,
cacheKey: key,
@@ -331,6 +363,22 @@ class MirabufCachingService {
type: miraType == MiraType.ROBOT ? "robot" : "field",
fileSize: miraBuff.byteLength,
})
+
+ // Store buffer
+ if (canOPFS) {
+ // Store in OPFS
+ const fileHandle = await (
+ miraType == MiraType.ROBOT ? robotFolderHandle : fieldFolderHandle
+ ).getFileHandle(backupID, { create: true })
+ const writable = await fileHandle.createWritable()
+ await writable.write(miraBuff)
+ await writable.close()
+ }
+
+ // Store in hash
+ const cache = miraType == MiraType.ROBOT ? backUpRobots : backUpFields
+ cache.set(backupID, miraBuff)
+
return info
} catch (e) {
console.error("Failed to cache mira " + e)
@@ -353,7 +401,7 @@ class MirabufCachingService {
export enum MiraType {
ROBOT = 1,
- FIELD = 2,
+ FIELD,
}
export default MirabufCachingService
diff --git a/fission/src/mirabuf/MirabufParser.ts b/fission/src/mirabuf/MirabufParser.ts
index dd7df1e7cf..7dab72156b 100644
--- a/fission/src/mirabuf/MirabufParser.ts
+++ b/fission/src/mirabuf/MirabufParser.ts
@@ -240,7 +240,6 @@ class MirabufParser {
console.log("Failed to get part definitions")
return
}
- console.log(partDefinitions)
}
private NewRigidNode(suffix?: string): RigidNode {
diff --git a/fission/src/systems/input/DefaultInputs.ts b/fission/src/systems/input/DefaultInputs.ts
index 2b9ac8d65a..e15fe82d44 100644
--- a/fission/src/systems/input/DefaultInputs.ts
+++ b/fission/src/systems/input/DefaultInputs.ts
@@ -91,8 +91,8 @@ class DefaultInputs {
shift: false,
meta: false,
}),
- new AxisInput("joint 5", "KeyN", "true", -1, false, false, -1, -1, EmptyModifierState, {
- ctrl: false,
+ new AxisInput("joint 5", "KeyN", "KeyN", -1, false, false, -1, -1, EmptyModifierState, {
+ ctrl: true,
alt: false,
shift: false,
meta: false,
diff --git a/fission/src/systems/input/InputSystem.ts b/fission/src/systems/input/InputSystem.ts
index 3a396f8968..d56aadd692 100644
--- a/fission/src/systems/input/InputSystem.ts
+++ b/fission/src/systems/input/InputSystem.ts
@@ -141,9 +141,6 @@ class InputSystem extends WorldSystem {
private static _gpIndex: number | null
public static gamepad: Gamepad | null
- // The scheme most recently selected in the controls modal
- public static selectedScheme: InputScheme | undefined
-
// Maps a brain index to a certain input scheme
public static brainIndexSchemeMap: Map = new Map()
diff --git a/fission/src/systems/preferences/PreferenceTypes.ts b/fission/src/systems/preferences/PreferenceTypes.ts
index 37b04a83ce..9331cc425e 100644
--- a/fission/src/systems/preferences/PreferenceTypes.ts
+++ b/fission/src/systems/preferences/PreferenceTypes.ts
@@ -43,10 +43,29 @@ export type EjectorPreferences = {
parentNode: string | undefined
}
+export type BehaviorType = "Elevator" | "Arm"
+
+export type SequentialBehaviorPreferences = {
+ jointIndex: number
+ parentJointIndex: number | undefined
+ type: BehaviorType
+ inverted: boolean
+}
+
+export function DefaultSequentialConfig(index: number, type: BehaviorType): SequentialBehaviorPreferences {
+ return {
+ jointIndex: index,
+ parentJointIndex: undefined,
+ type: type,
+ inverted: false,
+ }
+}
+
export type RobotPreferences = {
inputsSchemes: InputScheme[]
intake: IntakePreferences
ejector: EjectorPreferences
+ sequentialConfig?: SequentialBehaviorPreferences[]
}
export type Alliance = "red" | "blue"
diff --git a/fission/src/systems/scene/SceneRenderer.ts b/fission/src/systems/scene/SceneRenderer.ts
index 34e1f19e04..205aa4434d 100644
--- a/fission/src/systems/scene/SceneRenderer.ts
+++ b/fission/src/systems/scene/SceneRenderer.ts
@@ -13,8 +13,8 @@ import InputSystem from "../input/InputSystem"
import Jolt from "@barclah/jolt-physics"
import { PixelSpaceCoord, SceneOverlayEvent, SceneOverlayEventKey } from "@/ui/components/SceneOverlayEvents"
-import {} from "@/ui/components/SceneOverlayEvents"
import PreferencesSystem from "../preferences/PreferencesSystem"
+import { CSM } from "three/examples/jsm/csm/CSM.js"
const CLEAR_COLOR = 0x121212
const GROUND_COLOR = 0x4066c7
@@ -35,6 +35,8 @@ class SceneRenderer extends WorldSystem {
private _orbitControls: OrbitControls
private _transformControls: Map // maps all rendered transform controls to their size
+ private _light: THREE.DirectionalLight | CSM | undefined
+
public get sceneObjects() {
return this._sceneObjects
}
@@ -75,25 +77,10 @@ class SceneRenderer extends WorldSystem {
this._renderer.shadowMap.type = THREE.PCFSoftShadowMap
this._renderer.setSize(window.innerWidth, window.innerHeight)
- const directionalLight = new THREE.DirectionalLight(0xffffff, 3.0)
- directionalLight.position.set(-1.0, 3.0, 2.0)
- directionalLight.castShadow = true
- this._scene.add(directionalLight)
+ // Adding the lighting uisng quality preferences
+ this.ChangeLighting(PreferencesSystem.getGlobalPreference("QualitySettings"))
- const shadowMapSize = Math.min(4096, this._renderer.capabilities.maxTextureSize)
- const shadowCamSize = 15
- console.debug(`Shadow Map Size: ${shadowMapSize}`)
-
- directionalLight.shadow.camera.top = shadowCamSize
- directionalLight.shadow.camera.bottom = -shadowCamSize
- directionalLight.shadow.camera.left = -shadowCamSize
- directionalLight.shadow.camera.right = shadowCamSize
- directionalLight.shadow.mapSize = new THREE.Vector2(shadowMapSize, shadowMapSize)
- directionalLight.shadow.blurSamples = 16
- directionalLight.shadow.normalBias = 0.01
- directionalLight.shadow.bias = 0.0
-
- const ambientLight = new THREE.AmbientLight(0xffffff, 0.1)
+ const ambientLight = new THREE.AmbientLight(0xffffff, 0.3)
this._scene.add(ambientLight)
const ground = new THREE.Mesh(new THREE.BoxGeometry(10, 1, 10), this.CreateToonMaterial(GROUND_COLOR))
@@ -145,6 +132,11 @@ class SceneRenderer extends WorldSystem {
obj.Update()
})
+ this._mainCamera.updateMatrixWorld()
+
+ // updating the CSM light if it is enabled
+ if (this._light instanceof CSM) this._light.update()
+
this._skybox.position.copy(this._mainCamera.position)
const mainCameraFovRadians = (Math.PI * (this._mainCamera.fov * 0.5)) / 180
@@ -167,6 +159,75 @@ class SceneRenderer extends WorldSystem {
this.RemoveAllSceneObjects()
}
+ /**
+ * Changes the quality of lighting between cascading shadows and directional lights
+ *
+ * @param quality: string representing the quality of lighting - "Low", "Medium", "High"
+ */
+ public ChangeLighting(quality: string): void {
+ // removing the previous lighting method
+ if (this._light instanceof THREE.DirectionalLight) {
+ this._scene.remove(this._light)
+ } else if (this._light instanceof CSM) {
+ this._light.dispose()
+ this._light.remove()
+ }
+
+ // setting the shadow map size
+ const shadowMapSize = Math.min(4096, this._renderer.capabilities.maxTextureSize)
+
+ // setting the light to a basic directional light
+ if (quality === "Low" || quality === "Medium") {
+ const shadowCamSize = 15
+
+ this._light = new THREE.DirectionalLight(0xffffff, 5.0)
+ this._light.position.set(-1.0, 3.0, 2.0)
+ this._light.castShadow = true
+ this._light.shadow.camera.top = shadowCamSize
+ this._light.shadow.camera.bottom = -shadowCamSize
+ this._light.shadow.camera.left = -shadowCamSize
+ this._light.shadow.camera.right = shadowCamSize
+ this._light.shadow.mapSize = new THREE.Vector2(shadowMapSize, shadowMapSize)
+ this._light.shadow.blurSamples = 16
+ this._light.shadow.bias = 0.0
+ this._light.shadow.normalBias = 0.01
+ this._scene.add(this._light)
+ } else if (quality === "High") {
+ // setting light to cascading shadows
+ this._light = new CSM({
+ parent: this._scene,
+ camera: this._mainCamera,
+ cascades: 4,
+ lightDirection: new THREE.Vector3(1.0, -3.0, -2.0).normalize(),
+ lightIntensity: 5,
+ shadowMapSize: shadowMapSize,
+ mode: "custom",
+ maxFar: 30,
+ shadowBias: -0.00001,
+ customSplitsCallback: (cascades: number, near: number, far: number, breaks: number[]) => {
+ const blend = 0.7
+ for (let i = 1; i < cascades; i++) {
+ const uniformFactor = (near + ((far - near) * i) / cascades) / far
+ const logarithmicFactor = (near * (far / near) ** (i / cascades)) / far
+ const combinedFactor = uniformFactor * (1 - blend) + logarithmicFactor * blend
+
+ breaks.push(combinedFactor)
+ }
+
+ breaks.push(1)
+ },
+ })
+
+ // setting up the materials for all objects in the scene
+ this._light.fade = true
+ this._scene.children.forEach(child => {
+ if (child instanceof THREE.Mesh) {
+ if (this._light instanceof CSM) this._light.setupMaterial(child.material)
+ }
+ })
+ }
+ }
+
public RegisterSceneObject(obj: T): number {
const id = nextSceneObjectId++
obj.id = id
@@ -190,6 +251,7 @@ class SceneRenderer extends WorldSystem {
public CreateSphere(radius: number, material?: THREE.Material | undefined): THREE.Mesh {
const geo = new THREE.SphereGeometry(radius)
if (material) {
+ if (this._light instanceof CSM) this._light.setupMaterial(material)
return new THREE.Mesh(geo, material)
} else {
return new THREE.Mesh(geo, this.CreateToonMaterial())
@@ -213,10 +275,13 @@ class SceneRenderer extends WorldSystem {
}
const gradientMap = new THREE.DataTexture(colors, colors.length, 1, format)
gradientMap.needsUpdate = true
- return new THREE.MeshToonMaterial({
+ const material = new THREE.MeshToonMaterial({
color: color,
+ shadowSide: THREE.DoubleSide,
gradientMap: gradientMap,
})
+ if (this._light instanceof CSM) this._light.setupMaterial(material)
+ return material
}
/**
@@ -249,7 +314,7 @@ class SceneRenderer extends WorldSystem {
return [(window.innerWidth * (screenSpace.x + 1.0)) / 2.0, (window.innerHeight * (1.0 - screenSpace.y)) / 2.0]
}
- /**
+ /**
* Updates the skybox colors based on the current theme
* @param currentTheme: current theme from ThemeContext.useTheme()
@@ -359,6 +424,15 @@ class SceneRenderer extends WorldSystem {
public RemoveObject(obj: THREE.Object3D) {
this._scene.remove(obj)
}
+
+ /**
+ * Sets up the threejs material for cascading shadows if the CSM is enabled
+ *
+ * @param material
+ */
+ public SetupMaterial(material: THREE.Material) {
+ if (this._light instanceof CSM) this._light.setupMaterial(material)
+ }
}
export default SceneRenderer
diff --git a/fission/src/systems/simulation/Brain.ts b/fission/src/systems/simulation/Brain.ts
index a047d65671..d784195e8e 100644
--- a/fission/src/systems/simulation/Brain.ts
+++ b/fission/src/systems/simulation/Brain.ts
@@ -3,8 +3,8 @@ import Mechanism from "../physics/Mechanism"
abstract class Brain {
protected _mechanism: Mechanism
- constructor(mechansim: Mechanism) {
- this._mechanism = mechansim
+ constructor(mechanism: Mechanism) {
+ this._mechanism = mechanism
}
public abstract Update(deltaT: number): void
diff --git a/fission/src/systems/simulation/behavior/synthesis/ArcadeDriveBehavior.ts b/fission/src/systems/simulation/behavior/synthesis/ArcadeDriveBehavior.ts
index 6851ad4305..a76d2f98d3 100644
--- a/fission/src/systems/simulation/behavior/synthesis/ArcadeDriveBehavior.ts
+++ b/fission/src/systems/simulation/behavior/synthesis/ArcadeDriveBehavior.ts
@@ -11,6 +11,10 @@ class ArcadeDriveBehavior extends Behavior {
private _driveSpeed = 30
private _turnSpeed = 30
+ public get wheels(): WheelDriver[] {
+ return this.leftWheels.concat(this.rightWheels)
+ }
+
constructor(
leftWheels: WheelDriver[],
rightWheels: WheelDriver[],
diff --git a/fission/src/systems/simulation/behavior/synthesis/GenericArmBehavior.ts b/fission/src/systems/simulation/behavior/synthesis/GenericArmBehavior.ts
index a9d19c5c03..e177549d54 100644
--- a/fission/src/systems/simulation/behavior/synthesis/GenericArmBehavior.ts
+++ b/fission/src/systems/simulation/behavior/synthesis/GenericArmBehavior.ts
@@ -1,30 +1,31 @@
-import HingeDriver from "@/systems/simulation/driver/HingeDriver"
-import HingeStimulus from "@/systems/simulation/stimulus/HingeStimulus"
-import Behavior from "@/systems/simulation/behavior/Behavior"
-import InputSystem from "@/systems/input/InputSystem"
+import { SequentialBehaviorPreferences } from "@/systems/preferences/PreferenceTypes"
+import HingeDriver from "../../driver/HingeDriver"
+import HingeStimulus from "../../stimulus/HingeStimulus"
+import SequenceableBehavior from "./SequenceableBehavior"
-class GenericArmBehavior extends Behavior {
+class GenericArmBehavior extends SequenceableBehavior {
private _hingeDriver: HingeDriver
- private _inputName: string
- private _brainIndex: number
- private _rotationalSpeed = 6
+ public get hingeDriver(): HingeDriver {
+ return this._hingeDriver
+ }
- constructor(hingeDriver: HingeDriver, hingeStimulus: HingeStimulus, jointIndex: number, brainIndex: number) {
- super([hingeDriver], [hingeStimulus])
+ maxVelocity: number = 6
- this._hingeDriver = hingeDriver
- this._inputName = "joint " + jointIndex
- this._brainIndex = brainIndex
- }
+ constructor(
+ hingeDriver: HingeDriver,
+ hingeStimulus: HingeStimulus,
+ jointIndex: number,
+ brainIndex: number,
+ sequentialConfig: SequentialBehaviorPreferences | undefined
+ ) {
+ super(jointIndex, brainIndex, [hingeDriver], [hingeStimulus], sequentialConfig)
- // Sets the arms target rotational velocity
- rotateArm(rotationalVelocity: number) {
- this._hingeDriver.targetVelocity = rotationalVelocity
+ this._hingeDriver = hingeDriver
}
- public Update(_: number): void {
- this.rotateArm(InputSystem.getInput(this._inputName, this._brainIndex) * this._rotationalSpeed)
+ applyInput = (velocity: number) => {
+ this._hingeDriver.targetVelocity = velocity
}
}
diff --git a/fission/src/systems/simulation/behavior/synthesis/GenericElevatorBehavior.ts b/fission/src/systems/simulation/behavior/synthesis/GenericElevatorBehavior.ts
index fb8b237d16..ceb93f813f 100644
--- a/fission/src/systems/simulation/behavior/synthesis/GenericElevatorBehavior.ts
+++ b/fission/src/systems/simulation/behavior/synthesis/GenericElevatorBehavior.ts
@@ -1,30 +1,31 @@
-import SliderDriver from "@/systems/simulation/driver/SliderDriver"
-import SliderStimulus from "@/systems/simulation/stimulus/SliderStimulus"
-import Behavior from "@/systems/simulation/behavior/Behavior"
-import InputSystem from "@/systems/input/InputSystem"
+import { SequentialBehaviorPreferences } from "@/systems/preferences/PreferenceTypes"
+import SliderDriver from "../../driver/SliderDriver"
+import SliderStimulus from "../../stimulus/SliderStimulus"
+import SequenceableBehavior from "./SequenceableBehavior"
-class GenericElevatorBehavior extends Behavior {
+class GenericElevatorBehavior extends SequenceableBehavior {
private _sliderDriver: SliderDriver
- private _inputName: string
- private _brainIndex: number
- private _linearSpeed = 2.5
+ maxVelocity = 6
- constructor(sliderDriver: SliderDriver, sliderStimulus: SliderStimulus, jointIndex: number, brainIndex: number) {
- super([sliderDriver], [sliderStimulus])
-
- this._sliderDriver = sliderDriver
- this._inputName = "joint " + jointIndex
- this._brainIndex = brainIndex
+ public get sliderDriver(): SliderDriver {
+ return this._sliderDriver
}
- // Changes the elevators target position
- moveElevator(linearVelocity: number) {
- this._sliderDriver.targetVelocity = linearVelocity
+ constructor(
+ sliderDriver: SliderDriver,
+ sliderStimulus: SliderStimulus,
+ jointIndex: number,
+ brainIndex: number,
+ sequentialConfig: SequentialBehaviorPreferences | undefined
+ ) {
+ super(jointIndex, brainIndex, [sliderDriver], [sliderStimulus], sequentialConfig)
+
+ this._sliderDriver = sliderDriver
}
- public Update(_: number): void {
- this.moveElevator(InputSystem.getInput(this._inputName, this._brainIndex) * this._linearSpeed)
+ applyInput = (velocity: number) => {
+ this._sliderDriver.targetVelocity = velocity
}
}
diff --git a/fission/src/systems/simulation/behavior/synthesis/SequenceableBehavior.ts b/fission/src/systems/simulation/behavior/synthesis/SequenceableBehavior.ts
new file mode 100644
index 0000000000..034765097c
--- /dev/null
+++ b/fission/src/systems/simulation/behavior/synthesis/SequenceableBehavior.ts
@@ -0,0 +1,42 @@
+import { SequentialBehaviorPreferences } from "@/systems/preferences/PreferenceTypes"
+import Driver from "../../driver/Driver"
+import Stimulus from "../../stimulus/Stimulus"
+import Behavior from "../Behavior"
+import InputSystem from "@/systems/input/InputSystem"
+
+abstract class SequenceableBehavior extends Behavior {
+ private _jointIndex: number
+ private _brainIndex: number
+ private _sequentialConfig: SequentialBehaviorPreferences | undefined
+
+ abstract maxVelocity: number
+
+ public get jointIndex(): number {
+ return this._jointIndex
+ }
+
+ constructor(
+ jointIndex: number,
+ brainIndex: number,
+ drivers: Driver[],
+ stimuli: Stimulus[],
+ sequentialConfig: SequentialBehaviorPreferences | undefined
+ ) {
+ super(drivers, stimuli)
+
+ this._jointIndex = jointIndex
+ this._brainIndex = brainIndex
+ this._sequentialConfig = sequentialConfig
+ }
+
+ abstract applyInput: (velocity: number) => void
+
+ public Update(_: number): void {
+ const inputName = "joint " + (this._sequentialConfig?.parentJointIndex ?? this._jointIndex)
+ const inverted = this._sequentialConfig?.inverted ?? false
+
+ this.applyInput(InputSystem.getInput(inputName, this._brainIndex) * this.maxVelocity * (inverted ? -1 : 1))
+ }
+}
+
+export default SequenceableBehavior
diff --git a/fission/src/systems/simulation/driver/HingeDriver.ts b/fission/src/systems/simulation/driver/HingeDriver.ts
index 29ab7fc6af..1558f0f4c0 100644
--- a/fission/src/systems/simulation/driver/HingeDriver.ts
+++ b/fission/src/systems/simulation/driver/HingeDriver.ts
@@ -11,6 +11,10 @@ class HingeDriver extends Driver {
private _targetVelocity: number = 0.0
private _targetAngle: number
+ public get constraint(): Jolt.HingeConstraint {
+ return this._constraint
+ }
+
public get targetVelocity(): number {
return this._targetVelocity
}
diff --git a/fission/src/systems/simulation/driver/SliderDriver.ts b/fission/src/systems/simulation/driver/SliderDriver.ts
index dd442b38aa..9af74046e1 100644
--- a/fission/src/systems/simulation/driver/SliderDriver.ts
+++ b/fission/src/systems/simulation/driver/SliderDriver.ts
@@ -11,6 +11,10 @@ class SliderDriver extends Driver {
private _targetVelocity: number = 0.0
private _targetPosition: number = 0.0
+ public get constraint(): Jolt.SliderConstraint {
+ return this._constraint
+ }
+
public get targetVelocity(): number {
return this._targetVelocity
}
diff --git a/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts b/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts
index bdbd902102..03db0cdf2c 100644
--- a/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts
+++ b/fission/src/systems/simulation/synthesis_brain/SynthesisBrain.ts
@@ -15,6 +15,7 @@ import SliderDriver from "../driver/SliderDriver"
import SliderStimulus from "../stimulus/SliderStimulus"
import GenericElevatorBehavior from "../behavior/synthesis/GenericElevatorBehavior"
import PreferencesSystem from "@/systems/preferences/PreferencesSystem"
+import { DefaultSequentialConfig } from "@/systems/preferences/PreferenceTypes"
import InputSystem from "@/systems/input/InputSystem"
class SynthesisBrain extends Brain {
@@ -28,6 +29,17 @@ class SynthesisBrain extends Brain {
// Tracks how many joins have been made with unique controls
private _currentJointIndex = 1
+ public get assemblyName(): string {
+ return this._assemblyName
+ }
+
+ public get behaviors(): Behavior[] {
+ return this._behaviors
+ }
+
+ // Tracks the number of each specific mira file spawned
+ public static numberRobotsSpawned: { [key: string]: number } = {}
+
public get inputSchemeName(): string {
const scheme = InputSystem.brainIndexSchemeMap.get(this._brainIndex)
if (scheme == undefined) return "Not Configured"
@@ -132,8 +144,28 @@ class SynthesisBrain extends Brain {
) as HingeStimulus[]
for (let i = 0; i < hingeDrivers.length; i++) {
+ let sequentialConfig = PreferencesSystem.getRobotPreferences(this._assemblyName).sequentialConfig?.find(
+ sc => sc.jointIndex == this._currentJointIndex
+ )
+
+ if (sequentialConfig == undefined) {
+ sequentialConfig = DefaultSequentialConfig(this._currentJointIndex, "Arm")
+
+ if (PreferencesSystem.getRobotPreferences(this._assemblyName).sequentialConfig == undefined)
+ PreferencesSystem.getRobotPreferences(this._assemblyName).sequentialConfig = []
+
+ PreferencesSystem.getRobotPreferences(this._assemblyName).sequentialConfig?.push(sequentialConfig)
+ PreferencesSystem.savePreferences()
+ }
+
this._behaviors.push(
- new GenericArmBehavior(hingeDrivers[i], hingeStimuli[i], this._currentJointIndex, this._brainIndex)
+ new GenericArmBehavior(
+ hingeDrivers[i],
+ hingeStimuli[i],
+ this._currentJointIndex,
+ this._brainIndex,
+ sequentialConfig
+ )
)
this._currentJointIndex++
}
@@ -149,12 +181,27 @@ class SynthesisBrain extends Brain {
) as SliderStimulus[]
for (let i = 0; i < sliderDrivers.length; i++) {
+ let sequentialConfig = PreferencesSystem.getRobotPreferences(this._assemblyName).sequentialConfig?.find(
+ sc => sc.jointIndex == this._currentJointIndex
+ )
+
+ if (sequentialConfig == undefined) {
+ sequentialConfig = DefaultSequentialConfig(this._currentJointIndex, "Elevator")
+
+ if (PreferencesSystem.getRobotPreferences(this._assemblyName).sequentialConfig == undefined)
+ PreferencesSystem.getRobotPreferences(this._assemblyName).sequentialConfig = []
+
+ PreferencesSystem.getRobotPreferences(this._assemblyName).sequentialConfig?.push(sequentialConfig)
+ PreferencesSystem.savePreferences()
+ }
+
this._behaviors.push(
new GenericElevatorBehavior(
sliderDrivers[i],
sliderStimuli[i],
this._currentJointIndex,
- this._brainIndex
+ this._brainIndex,
+ sequentialConfig
)
)
this._currentJointIndex++
diff --git a/fission/src/ui/components/Checkbox.tsx b/fission/src/ui/components/Checkbox.tsx
index 451891073a..6ebdd578f8 100644
--- a/fission/src/ui/components/Checkbox.tsx
+++ b/fission/src/ui/components/Checkbox.tsx
@@ -8,16 +8,19 @@ type CheckboxProps = {
className?: string
defaultState: boolean
stateOverride?: boolean
+ hideLabel?: boolean
onClick?: (checked: boolean) => void
}
-const Checkbox: React.FC = ({ label, className, defaultState, stateOverride, onClick }) => {
+const Checkbox: React.FC = ({ label, className, defaultState, stateOverride, hideLabel, onClick }) => {
const [state] = useState(defaultState)
return (
-
+ {hideLabel ? null : (
+
+ )}
) => onClick && onClick(e.target.checked)}
slotProps={{
diff --git a/fission/src/ui/components/MainHUD.tsx b/fission/src/ui/components/MainHUD.tsx
index 91ace0dbeb..5c1e13a907 100644
--- a/fission/src/ui/components/MainHUD.tsx
+++ b/fission/src/ui/components/MainHUD.tsx
@@ -85,11 +85,6 @@ const MainHUD: React.FC = () => {
onClick={() => openPanel("import-mirabuf")}
/>
- openModal("manage-assemblies")}
- />
{
icon={SynthesisIcons.MagnifyingGlass}
onClick={() => openModal("view")}
/> */}
- openModal("change-inputs")}
- />
- openModal("import-local-mirabuf")}
- />
-
-
-
{
- openPanel("scoring-zones")
- }}
- />
openModal("config-robot")}
+ onClick={() => openPanel("configure")}
/>
{
value={`Hi, ${userInfo.givenName}`}
icon={}
larger={true}
- onClick={() => APS.logout()}
+ onClick={() => openModal("aps-management")}
/>
) : (
= ({ colorClass, size, value, pl
return (
-
+