2
0
Эх сурвалжийг харах

Merge branch 'main' into incisor/GeomNodes

incisor 2 жил өмнө
parent
commit
d02cb5ec21
61 өөрчлөгдсөн 8017 нэмэгдсэн , 0 устгасан
  1. 142 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/OneMeterBoxdae.dae
  2. 216 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/base_platform.dae
  3. 21 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/base_platform_aluminumAnodizedGrey.material
  4. 21 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/base_platform_aluminumAnodizedRed.material
  5. 20 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/base_platform_blackPaint.material
  6. 21 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/base_platform_chrome.material
  7. 20 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/base_platform_rubberBlack.material
  8. 216 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/digit_left.dae
  9. 216 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/digit_right.dae
  10. 216 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/fifth_axis.dae
  11. 216 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/fifth_extending_arm.dae
  12. 216 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/first_arm.dae
  13. 216 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/forth_axis.dae
  14. 44 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/frist_axis.dae
  15. 216 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/hand_left.dae
  16. 216 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/hand_right.dae
  17. 18 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/joint.dae
  18. 21 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/orangePaint.material
  19. 21 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/silverPolished.material
  20. 216 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/sixth_axis.dae
  21. 216 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/third_axis.dae
  22. 67 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/wrist.dae
  23. 2868 0
      Gems/O3DE/UrdfExporter/Assets/Prefabs/robotic_arm.prefab
  24. 18 0
      Gems/O3DE/UrdfExporter/CMakeLists.txt
  25. 100 0
      Gems/O3DE/UrdfExporter/Code/CMakeLists.txt
  26. 31 0
      Gems/O3DE/UrdfExporter/Code/Include/UrdfExporter/UrdfExporterBus.h
  27. 4 0
      Gems/O3DE/UrdfExporter/Code/Platform/Linux/PAL_linux.cmake
  28. 3 0
      Gems/O3DE/UrdfExporter/Code/Platform/Linux/urdfexporter_editor_api_files.cmake
  29. 8 0
      Gems/O3DE/UrdfExporter/Code/Platform/Linux/urdfexporter_editor_private_files.cmake
  30. 8 0
      Gems/O3DE/UrdfExporter/Code/Platform/Linux/urdfexporter_editor_shared_files.cmake
  31. 4 0
      Gems/O3DE/UrdfExporter/Code/Platform/Mac/PAL_mac.cmake
  32. 3 0
      Gems/O3DE/UrdfExporter/Code/Platform/Mac/urdfexporter_editor_api_files.cmake
  33. 8 0
      Gems/O3DE/UrdfExporter/Code/Platform/Mac/urdfexporter_editor_private_files.cmake
  34. 8 0
      Gems/O3DE/UrdfExporter/Code/Platform/Mac/urdfexporter_editor_shared_files.cmake
  35. 4 0
      Gems/O3DE/UrdfExporter/Code/Platform/Windows/PAL_windows.cmake
  36. 3 0
      Gems/O3DE/UrdfExporter/Code/Platform/Windows/urdfexporter_editor_api_files.cmake
  37. 8 0
      Gems/O3DE/UrdfExporter/Code/Platform/Windows/urdfexporter_editor_private_files.cmake
  38. 8 0
      Gems/O3DE/UrdfExporter/Code/Platform/Windows/urdfexporter_editor_shared_files.cmake
  39. 5 0
      Gems/O3DE/UrdfExporter/Code/Source/Tools/UrdfExporter.qrc
  40. 50 0
      Gems/O3DE/UrdfExporter/Code/Source/Tools/UrdfExporterEditorModule.cpp
  41. 59 0
      Gems/O3DE/UrdfExporter/Code/Source/Tools/UrdfExporterEditorSystemComponent.cpp
  42. 31 0
      Gems/O3DE/UrdfExporter/Code/Source/Tools/UrdfExporterEditorSystemComponent.h
  43. 1 0
      Gems/O3DE/UrdfExporter/Code/Source/Tools/toolbar_icon.svg
  44. 27 0
      Gems/O3DE/UrdfExporter/Code/Source/UrdfExporterModuleInterface.h
  45. 4 0
      Gems/O3DE/UrdfExporter/Code/Tests/Tools/UrdfExporterEditorTest.cpp
  46. 5 0
      Gems/O3DE/UrdfExporter/Code/urdfexporter_editor_api_files.cmake
  47. 7 0
      Gems/O3DE/UrdfExporter/Code/urdfexporter_editor_private_files.cmake
  48. 4 0
      Gems/O3DE/UrdfExporter/Code/urdfexporter_editor_shared_files.cmake
  49. 4 0
      Gems/O3DE/UrdfExporter/Code/urdfexporter_editor_tests_files.cmake
  50. 9 0
      Gems/O3DE/UrdfExporter/Editor/Scripts/__init__.py
  51. 22 0
      Gems/O3DE/UrdfExporter/Editor/Scripts/bootstrap.py
  52. 28 0
      Gems/O3DE/UrdfExporter/Editor/Scripts/constants.py
  53. 230 0
      Gems/O3DE/UrdfExporter/Editor/Scripts/editor_tools.py
  54. 726 0
      Gems/O3DE/UrdfExporter/Editor/Scripts/export.py
  55. 225 0
      Gems/O3DE/UrdfExporter/Editor/Scripts/urdfexporter_dialog.py
  56. 367 0
      Gems/O3DE/UrdfExporter/Editor/Scripts/utilities.py
  57. 244 0
      Gems/O3DE/UrdfExporter/README.md
  58. 18 0
      Gems/O3DE/UrdfExporter/Registry/assetprocessor_settings.setreg
  59. 40 0
      Gems/O3DE/UrdfExporter/Registry/sceneassetimporter.setreg
  60. 30 0
      Gems/O3DE/UrdfExporter/gem.json
  61. 3 0
      Gems/O3DE/UrdfExporter/preview.png

+ 142 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/OneMeterBoxdae.dae

@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="utf-8"?>
+<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <asset>
+    <contributor>
+      <author>Blender User</author>
+      <authoring_tool>Blender 3.4.1 commit date:2022-12-19, commit time:17:00, hash:55485cb379f7</authoring_tool>
+    </contributor>
+    <created>2023-01-25T13:51:35</created>
+    <modified>2023-01-25T13:51:35</modified>
+    <unit name="meter" meter="1"/>
+    <up_axis>Z_UP</up_axis>
+  </asset>
+  <library_cameras>
+    <camera id="Camera-camera" name="Camera">
+      <optics>
+        <technique_common>
+          <perspective>
+            <xfov sid="xfov">39.59775</xfov>
+            <aspect_ratio>1.777778</aspect_ratio>
+            <znear sid="znear">0.1</znear>
+            <zfar sid="zfar">100</zfar>
+          </perspective>
+        </technique_common>
+      </optics>
+      <extra>
+        <technique profile="blender">
+          <shiftx sid="shiftx" type="float">0</shiftx>
+          <shifty sid="shifty" type="float">0</shifty>
+          <dof_distance sid="dof_distance" type="float">10</dof_distance>
+        </technique>
+      </extra>
+    </camera>
+  </library_cameras>
+  <library_lights>
+    <light id="Light-light" name="Light">
+      <technique_common>
+        <point>
+          <color sid="color">1000 1000 1000</color>
+          <constant_attenuation>1</constant_attenuation>
+          <linear_attenuation>0</linear_attenuation>
+          <quadratic_attenuation>0.00111109</quadratic_attenuation>
+        </point>
+      </technique_common>
+      <extra>
+        <technique profile="blender">
+          <type sid="type" type="int">0</type>
+          <flag sid="flag" type="int">0</flag>
+          <mode sid="mode" type="int">1</mode>
+          <gamma sid="blender_gamma" type="float">1</gamma>
+          <red sid="red" type="float">1</red>
+          <green sid="green" type="float">1</green>
+          <blue sid="blue" type="float">1</blue>
+          <shadow_r sid="blender_shadow_r" type="float">0</shadow_r>
+          <shadow_g sid="blender_shadow_g" type="float">0</shadow_g>
+          <shadow_b sid="blender_shadow_b" type="float">0</shadow_b>
+          <energy sid="blender_energy" type="float">1000</energy>
+          <dist sid="blender_dist" type="float">29.99998</dist>
+          <spotsize sid="spotsize" type="float">75</spotsize>
+          <spotblend sid="spotblend" type="float">0.15</spotblend>
+          <att1 sid="att1" type="float">0</att1>
+          <att2 sid="att2" type="float">1</att2>
+          <falloff_type sid="falloff_type" type="int">2</falloff_type>
+          <clipsta sid="clipsta" type="float">0.04999995</clipsta>
+          <clipend sid="clipend" type="float">30.002</clipend>
+          <bias sid="bias" type="float">1</bias>
+          <soft sid="soft" type="float">3</soft>
+          <bufsize sid="bufsize" type="int">2880</bufsize>
+          <samp sid="samp" type="int">3</samp>
+          <buffers sid="buffers" type="int">1</buffers>
+          <area_shape sid="area_shape" type="int">1</area_shape>
+          <area_size sid="area_size" type="float">0.1</area_size>
+          <area_sizey sid="area_sizey" type="float">0.1</area_sizey>
+          <area_sizez sid="area_sizez" type="float">1</area_sizez>
+        </technique>
+      </extra>
+    </light>
+  </library_lights>
+  <library_images/>
+  <library_geometries>
+    <geometry id="Cube_001-mesh" name="Cube.001">
+      <mesh>
+        <source id="Cube_001-mesh-positions">
+          <float_array id="Cube_001-mesh-positions-array" count="24">-0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 0.5 -0.5 -0.5 0.5 0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 0.5 0.5 -0.5 0.5 0.5 0.5</float_array>
+          <technique_common>
+            <accessor source="#Cube_001-mesh-positions-array" count="8" stride="3">
+              <param name="X" type="float"/>
+              <param name="Y" type="float"/>
+              <param name="Z" type="float"/>
+            </accessor>
+          </technique_common>
+        </source>
+        <source id="Cube_001-mesh-normals">
+          <float_array id="Cube_001-mesh-normals-array" count="18">-1 0 0 0 1 0 1 0 0 0 -1 0 0 0 -1 0 0 1</float_array>
+          <technique_common>
+            <accessor source="#Cube_001-mesh-normals-array" count="6" stride="3">
+              <param name="X" type="float"/>
+              <param name="Y" type="float"/>
+              <param name="Z" type="float"/>
+            </accessor>
+          </technique_common>
+        </source>
+        <source id="Cube_001-mesh-map-0">
+          <float_array id="Cube_001-mesh-map-0-array" count="72">0.625 0 0.375 0.25 0.375 0 0.625 0.25 0.375 0.5 0.375 0.25 0.625 0.5 0.375 0.75 0.375 0.5 0.625 0.75 0.375 1 0.375 0.75 0.375 0.5 0.125 0.75 0.125 0.5 0.875 0.5 0.625 0.75 0.625 0.5 0.625 0 0.625 0.25 0.375 0.25 0.625 0.25 0.625 0.5 0.375 0.5 0.625 0.5 0.625 0.75 0.375 0.75 0.625 0.75 0.625 1 0.375 1 0.375 0.5 0.375 0.75 0.125 0.75 0.875 0.5 0.875 0.75 0.625 0.75</float_array>
+          <technique_common>
+            <accessor source="#Cube_001-mesh-map-0-array" count="36" stride="2">
+              <param name="S" type="float"/>
+              <param name="T" type="float"/>
+            </accessor>
+          </technique_common>
+        </source>
+        <vertices id="Cube_001-mesh-vertices">
+          <input semantic="POSITION" source="#Cube_001-mesh-positions"/>
+        </vertices>
+        <triangles count="12">
+          <input semantic="VERTEX" source="#Cube_001-mesh-vertices" offset="0"/>
+          <input semantic="NORMAL" source="#Cube_001-mesh-normals" offset="1"/>
+          <input semantic="TEXCOORD" source="#Cube_001-mesh-map-0" offset="2" set="0"/>
+          <p>1 0 0 2 0 1 0 0 2 3 1 3 6 1 4 2 1 5 7 2 6 4 2 7 6 2 8 5 3 9 0 3 10 4 3 11 6 4 12 0 4 13 2 4 14 3 5 15 5 5 16 7 5 17 1 0 18 3 0 19 2 0 20 3 1 21 7 1 22 6 1 23 7 2 24 5 2 25 4 2 26 5 3 27 1 3 28 0 3 29 6 4 30 4 4 31 0 4 32 3 5 33 1 5 34 5 5 35</p>
+        </triangles>
+      </mesh>
+    </geometry>
+  </library_geometries>
+  <library_visual_scenes>
+    <visual_scene id="Scene" name="Scene">
+      <node id="Cube" name="Cube" type="NODE">
+        <matrix sid="transform">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>
+        <instance_geometry url="#Cube_001-mesh" name="Cube"/>
+      </node>
+      <node id="Camera" name="Camera" type="NODE">
+        <matrix sid="transform">0.6859207 -0.3240135 0.6515582 7.358891 0.7276763 0.3054208 -0.6141704 -6.925791 0 0.8953956 0.4452714 4.958309 0 0 0 1</matrix>
+        <instance_camera url="#Camera-camera"/>
+      </node>
+      <node id="Light" name="Light" type="NODE">
+        <matrix sid="transform">-0.2908646 -0.7711008 0.5663932 4.076245 0.9551712 -0.1998834 0.2183912 1.005454 -0.05518906 0.6045247 0.7946723 5.903862 0 0 0 1</matrix>
+        <instance_light url="#Light-light"/>
+      </node>
+    </visual_scene>
+  </library_visual_scenes>
+  <scene>
+    <instance_visual_scene url="#Scene"/>
+  </scene>
+</COLLADA>

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 216 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/base_platform.dae


+ 21 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/base_platform_aluminumAnodizedGrey.material

@@ -0,0 +1,21 @@
+{
+    "materialType": "@gemroot:Atom_Feature_Common@/Assets/Materials/Types/StandardPBR.materialtype",
+    "materialTypeVersion": 5,
+    "propertyValues": {
+        "baseColor.color": [
+            0.014812000095844269,
+            0.014812000095844269,
+            0.014812000095844269,
+            1.0
+        ],
+        "emissive.color": [
+            0.0,
+            0.0,
+            0.0,
+            1.0
+        ],
+        "metallic.factor": 0.3799999952316284,
+        "opacity.factor": 1.0,
+        "roughness.factor": 0.47999998927116394
+    }
+}

+ 21 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/base_platform_aluminumAnodizedRed.material

@@ -0,0 +1,21 @@
+{
+    "materialType": "@gemroot:Atom_Feature_Common@/Assets/Materials/Types/StandardPBR.materialtype",
+    "materialTypeVersion": 5,
+    "propertyValues": {
+        "baseColor.color": [
+            0.29366108775138855,
+            0.0030833000782877207,
+            0.003333200002089143,
+            1.0
+        ],
+        "emissive.color": [
+            0.0,
+            0.0,
+            0.0,
+            1.0
+        ],
+        "metallic.factor": 0.6899999976158142,
+        "opacity.factor": 1.0,
+        "roughness.factor": 0.4300000071525574
+    }
+}

+ 20 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/base_platform_blackPaint.material

@@ -0,0 +1,20 @@
+{
+    "materialType": "@gemroot:Atom_Feature_Common@/Assets/Materials/Types/StandardPBR.materialtype",
+    "materialTypeVersion": 5,
+    "propertyValues": {
+        "baseColor.color": [
+            0.0,
+            0.0,
+            0.0,
+            1.0
+        ],
+        "emissive.color": [
+            0.0,
+            0.0,
+            0.0,
+            1.0
+        ],
+        "opacity.factor": 1.0,
+        "roughness.factor": 0.5799999833106995
+    }
+}

+ 21 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/base_platform_chrome.material

@@ -0,0 +1,21 @@
+{
+    "materialType": "@gemroot:Atom_Feature_Common@/Assets/Materials/Types/StandardPBR.materialtype",
+    "materialTypeVersion": 5,
+    "propertyValues": {
+        "baseColor.color": [
+            0.8000000715255737,
+            0.7671090960502625,
+            0.6732295751571655,
+            1.0
+        ],
+        "emissive.color": [
+            0.0,
+            0.0,
+            0.0,
+            1.0
+        ],
+        "metallic.factor": 1.0,
+        "opacity.factor": 1.0,
+        "roughness.factor": 0.09000000357627869
+    }
+}

+ 20 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/base_platform_rubberBlack.material

@@ -0,0 +1,20 @@
+{
+    "materialType": "@gemroot:Atom_Feature_Common@/Assets/Materials/Types/StandardPBR.materialtype",
+    "materialTypeVersion": 5,
+    "propertyValues": {
+        "baseColor.color": [
+            0.0,
+            0.0,
+            0.0,
+            1.0
+        ],
+        "emissive.color": [
+            0.0,
+            0.0,
+            0.0,
+            1.0
+        ],
+        "opacity.factor": 1.0,
+        "roughness.factor": 0.6299999952316284
+    }
+}

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 216 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/digit_left.dae


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 216 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/digit_right.dae


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 216 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/fifth_axis.dae


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 216 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/fifth_extending_arm.dae


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 216 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/first_arm.dae


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 216 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/forth_axis.dae


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 44 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/frist_axis.dae


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 216 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/hand_left.dae


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 216 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/hand_right.dae


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 18 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/joint.dae


+ 21 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/orangePaint.material

@@ -0,0 +1,21 @@
+{
+    "materialType": "@gemroot:Atom_Feature_Common@/Assets/Materials/Types/StandardPBR.materialtype",
+    "materialTypeVersion": 5,
+    "propertyValues": {
+        "baseColor.color": [
+            0.8000000715255737,
+            0.15432380139827728,
+            0.0,
+            1.0
+        ],
+        "emissive.color": [
+            0.0,
+            0.0,
+            0.0,
+            1.0
+        ],
+        "metallic.factor": 0.4099999964237213,
+        "opacity.factor": 1.0,
+        "roughness.factor": 0.18000000715255737
+    }
+}

+ 21 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/silverPolished.material

@@ -0,0 +1,21 @@
+{
+    "materialType": "@gemroot:Atom_Feature_Common@/Assets/Materials/Types/StandardPBR.materialtype",
+    "materialTypeVersion": 5,
+    "propertyValues": {
+        "baseColor.color": [
+            0.800000011920929,
+            0.800000011920929,
+            0.800000011920929,
+            1.0
+        ],
+        "emissive.color": [
+            0.0,
+            0.0,
+            0.0,
+            1.0
+        ],
+        "metallic.factor": 0.9399999976158142,
+        "opacity.factor": 1.0,
+        "roughness.factor": 0.27000001072883606
+    }
+}

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 216 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/sixth_axis.dae


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 216 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/third_axis.dae


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 67 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/meshs/wrist.dae


+ 2868 - 0
Gems/O3DE/UrdfExporter/Assets/Prefabs/robotic_arm.prefab

@@ -0,0 +1,2868 @@
+{
+    "ContainerEntity": {
+        "Id": "ContainerEntity",
+        "Name": "robotic_arm",
+        "Components": {
+            "Component_[13915794073979606344]": {
+                "$type": "EditorPendingCompositionComponent",
+                "Id": 13915794073979606344
+            },
+            "Component_[14398174832539203105]": {
+                "$type": "EditorOnlyEntityComponent",
+                "Id": 14398174832539203105
+            },
+            "Component_[15412796712917498207]": {
+                "$type": "EditorDisabledCompositionComponent",
+                "Id": 15412796712917498207
+            },
+            "Component_[15817457762908803035]": {
+                "$type": "EditorVisibilityComponent",
+                "Id": 15817457762908803035
+            },
+            "Component_[1583404562177537559]": {
+                "$type": "EditorLockComponent",
+                "Id": 1583404562177537559
+            },
+            "Component_[2032338609420553970]": {
+                "$type": "EditorEntityIconComponent",
+                "Id": 2032338609420553970
+            },
+            "Component_[8150508617137793007]": {
+                "$type": "EditorInspectorComponent",
+                "Id": 8150508617137793007
+            },
+            "Component_[8174985473737589490]": {
+                "$type": "EditorEntitySortComponent",
+                "Id": 8174985473737589490,
+                "Child Entity Order": [
+                    "Entity_[642193963399]"
+                ]
+            },
+            "Component_[8635446010738764751]": {
+                "$type": "EditorPrefabComponent",
+                "Id": 8635446010738764751
+            },
+            "Component_[9411348064598532889]": {
+                "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                "Id": 9411348064598532889,
+                "Parent Entity": ""
+            }
+        }
+    },
+    "Entities": {
+        "Entity_[551999650183]": {
+            "Id": "Entity_[551999650183]",
+            "Name": "hand_right_joint",
+            "Components": {
+                "Component_[1023211850860498786]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 1023211850860498786
+                },
+                "Component_[11402704802795454573]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 11402704802795454573
+                },
+                "Component_[13434751477247218404]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 13434751477247218404
+                },
+                "Component_[14974996773523387120]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 14974996773523387120
+                },
+                "Component_[17722717871746365623]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 17722717871746365623
+                },
+                "Component_[17800997910811694260]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 17800997910811694260
+                },
+                "Component_[4009006179163806296]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 4009006179163806296,
+                    "Child Entity Order": [
+                        "Entity_[590654355847]"
+                    ]
+                },
+                "Component_[5760728684619500317]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 5760728684619500317,
+                    "Parent Entity": "Entity_[659373832583]",
+                    "Transform Data": {
+                        "Translate": [
+                            0.0,
+                            0.37036895751953125,
+                            -0.08016681671142578
+                        ]
+                    }
+                },
+                "Component_[6973109471285341605]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 6973109471285341605
+                }
+            }
+        },
+        "Entity_[556294617479]": {
+            "Id": "Entity_[556294617479]",
+            "Name": "hand_left",
+            "Components": {
+                "Component_[1023211850860498786]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 1023211850860498786
+                },
+                "Component_[11402704802795454573]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 11402704802795454573
+                },
+                "Component_[13434751477247218404]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 13434751477247218404
+                },
+                "Component_[14974996773523387120]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 14974996773523387120
+                },
+                "Component_[17722717871746365623]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 17722717871746365623
+                },
+                "Component_[17800997910811694260]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 17800997910811694260
+                },
+                "Component_[3226453374962359334]": {
+                    "$type": "EditorRigidBodyComponent",
+                    "Id": 3226453374962359334,
+                    "Configuration": {
+                        "entityId": "",
+                        "Gravity Enabled": false,
+                        "Compute Mass": false,
+                        "Centre of mass offset": [
+                            0.0,
+                            0.0,
+                            -0.20000000298023224
+                        ],
+                        "Inertia tensor": [
+                            0.00937499850988388,
+                            0.0,
+                            0.0,
+                            0.0,
+                            0.0208333320915699,
+                            0.0,
+                            0.0,
+                            0.0,
+                            0.015208332799375057
+                        ]
+                    }
+                },
+                "Component_[4009006179163806296]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 4009006179163806296,
+                    "Child Entity Order": [
+                        "Entity_[560589584775]"
+                    ]
+                },
+                "Component_[4664594385639213386]": {
+                    "$type": "EditorHingeJointComponent",
+                    "Id": 4664594385639213386,
+                    "Configuration": {
+                        "Local Rotation": [
+                            90.0,
+                            0.0,
+                            0.0
+                        ],
+                        "Parent Entity": "Entity_[620719126919]",
+                        "Child Entity": "Entity_[556294617479]"
+                    },
+                    "Angular Limit": {
+                        "Positive Limit": 145.0,
+                        "Negative Limit": 0.0
+                    }
+                },
+                "Component_[5426849745670871106]": {
+                    "$type": "EditorColliderComponent",
+                    "Id": 5426849745670871106,
+                    "ColliderConfiguration": {
+                        "Position": [
+                            0.0,
+                            0.0,
+                            -0.20000000298023224
+                        ],
+                        "MaterialSlots": {
+                            "Slots": [
+                                {
+                                    "Name": "Entire object"
+                                }
+                            ]
+                        }
+                    },
+                    "ShapeConfiguration": {
+                        "ShapeType": 1,
+                        "Box": {
+                            "Configuration": [
+                                0.4000000059604645,
+                                0.15000000596046448,
+                                0.30000001192092896
+                            ]
+                        }
+                    }
+                },
+                "Component_[5760728684619500317]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 5760728684619500317,
+                    "Parent Entity": "Entity_[620719126919]"
+                },
+                "Component_[6973109471285341605]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 6973109471285341605
+                },
+                "Component_[8729971515401851948]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 8729971515401851948,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{D8FEB0D7-E145-52AE-8274-14CF5E5C48A5}",
+                                    "subId": 276794797
+                                },
+                                "assetHint": "prefabs/meshs/hand_left.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[919529981696949154]": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 919529981696949154,
+                    "Controller": {
+                        "Configuration": {
+                            "materials": [
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 411659043
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{2457475C-263F-5FA0-A412-C01BC49E33A9}"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
+        "Entity_[560589584775]": {
+            "Id": "Entity_[560589584775]",
+            "Name": "digit_left_joint",
+            "Components": {
+                "Component_[11489146677624140676]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 11489146677624140676
+                },
+                "Component_[13017153777003290516]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 13017153777003290516
+                },
+                "Component_[16310323416065759014]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 16310323416065759014
+                },
+                "Component_[26743869235772550]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 26743869235772550
+                },
+                "Component_[2773421673211466633]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 2773421673211466633
+                },
+                "Component_[6525273861851362886]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 6525273861851362886,
+                    "Child Entity Order": [
+                        "Entity_[582064421255]"
+                    ]
+                },
+                "Component_[6799352960972820203]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 6799352960972820203
+                },
+                "Component_[7504792106159211932]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 7504792106159211932
+                },
+                "Component_[9659707703958871644]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 9659707703958871644,
+                    "Parent Entity": "Entity_[556294617479]",
+                    "Transform Data": {
+                        "Translate": [
+                            0.0,
+                            0.0,
+                            -0.3661990165710449
+                        ]
+                    }
+                }
+            }
+        },
+        "Entity_[564884552071]": {
+            "Id": "Entity_[564884552071]",
+            "Name": "digit_right",
+            "Components": {
+                "Component_[10398716782691769261]": {
+                    "$type": "EditorRigidBodyComponent",
+                    "Id": 10398716782691769261,
+                    "Configuration": {
+                        "entityId": "",
+                        "Gravity Enabled": false,
+                        "Compute Mass": false,
+                        "Centre of mass offset": [
+                            0.0,
+                            0.0,
+                            -0.20000000298023224
+                        ],
+                        "Inertia tensor": [
+                            0.00937499850988388,
+                            0.0,
+                            0.0,
+                            0.0,
+                            0.0208333320915699,
+                            0.0,
+                            0.0,
+                            0.0,
+                            0.015208332799375057
+                        ]
+                    }
+                },
+                "Component_[11489146677624140676]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 11489146677624140676
+                },
+                "Component_[11715287625053615148]": {
+                    "$type": "EditorColliderComponent",
+                    "Id": 11715287625053615148,
+                    "ColliderConfiguration": {
+                        "Position": [
+                            0.0,
+                            0.0,
+                            -0.20000000298023224
+                        ],
+                        "MaterialSlots": {
+                            "Slots": [
+                                {
+                                    "Name": "Entire object"
+                                }
+                            ]
+                        }
+                    },
+                    "ShapeConfiguration": {
+                        "ShapeType": 1,
+                        "Box": {
+                            "Configuration": [
+                                0.4000000059604645,
+                                0.15000000596046448,
+                                0.30000001192092896
+                            ]
+                        }
+                    }
+                },
+                "Component_[12351144674120142159]": {
+                    "$type": "EditorHingeJointComponent",
+                    "Id": 12351144674120142159,
+                    "Configuration": {
+                        "Local Rotation": [
+                            90.0,
+                            0.0,
+                            0.0
+                        ],
+                        "Parent Entity": "Entity_[594949323143]",
+                        "Child Entity": "Entity_[564884552071]"
+                    },
+                    "Angular Limit": {
+                        "Positive Limit": 145.0,
+                        "Negative Limit": 0.0
+                    }
+                },
+                "Component_[13017153777003290516]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 13017153777003290516
+                },
+                "Component_[16310323416065759014]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 16310323416065759014
+                },
+                "Component_[26743869235772550]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 26743869235772550
+                },
+                "Component_[2773421673211466633]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 2773421673211466633
+                },
+                "Component_[3348449984293259184]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 3348449984293259184,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{390AD287-F00B-5D2F-86EB-BD0D29B40639}",
+                                    "subId": 281665538
+                                },
+                                "assetHint": "prefabs/meshs/digit_right.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[6525273861851362886]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 6525273861851362886
+                },
+                "Component_[6799352960972820203]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 6799352960972820203
+                },
+                "Component_[7504792106159211932]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 7504792106159211932
+                },
+                "Component_[7896427902011259342]": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 7896427902011259342,
+                    "Controller": {
+                        "Configuration": {
+                            "materials": [
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 411659043
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{2457475C-263F-5FA0-A412-C01BC49E33A9}"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                },
+                "Component_[9659707703958871644]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 9659707703958871644,
+                    "Parent Entity": "Entity_[594949323143]"
+                }
+            }
+        },
+        "Entity_[569179519367]": {
+            "Id": "Entity_[569179519367]",
+            "Name": "fifth_axis",
+            "Components": {
+                "Component_[14277172426395713142]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 14277172426395713142,
+                    "Child Entity Order": [
+                        "Entity_[573474486663]"
+                    ]
+                },
+                "Component_[15808101983194378273]": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 15808101983194378273,
+                    "Controller": {
+                        "Configuration": {
+                            "materials": [
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 1378043131
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{9C7FB3EE-8707-51CD-BF13-D2B5AFB7F1B1}"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                },
+                "Component_[15838160574819741113]": {
+                    "$type": "EditorHingeJointComponent",
+                    "Id": 15838160574819741113,
+                    "Configuration": {
+                        "Local Position": [
+                            0.0,
+                            -0.008406500332057476,
+                            0.011848700232803822
+                        ],
+                        "Local Rotation": [
+                            0.0,
+                            0.0,
+                            90.0
+                        ],
+                        "Parent Entity": "Entity_[637898996103]",
+                        "Child Entity": "Entity_[569179519367]"
+                    },
+                    "Angular Limit": {
+                        "Positive Limit": 180.0,
+                        "Negative Limit": -180.0
+                    }
+                },
+                "Component_[17589935685956967256]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 17589935685956967256
+                },
+                "Component_[3227744676858555161]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 3227744676858555161
+                },
+                "Component_[3362822306899345061]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 3362822306899345061
+                },
+                "Component_[4388658803999797632]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 4388658803999797632
+                },
+                "Component_[477954718324805862]": {
+                    "$type": "EditorColliderComponent",
+                    "Id": 477954718324805862,
+                    "ColliderConfiguration": {
+                        "Position": [
+                            0.0,
+                            -1.5,
+                            0.0
+                        ],
+                        "Rotation": [
+                            0.7071068286895752,
+                            0.0,
+                            0.0,
+                            0.7071067094802856
+                        ],
+                        "MaterialSlots": {
+                            "Slots": [
+                                {
+                                    "Name": "Entire object"
+                                }
+                            ]
+                        }
+                    },
+                    "ShapeConfiguration": {
+                        "ShapeType": 3,
+                        "Cylinder": {
+                            "Configuration": {
+                                "CookedData": "TlhTAUNWWE0NAAAAAAAAAElDRQFDTEhMCQAAACAAAAAwAAAAEgAAAGAAAABgg2y+AAAAwAnvwz3zBDW+AAAAwOwENT7zBDW+AACAv/YENT5gg2y+AACAvx3vwz0X78O9AAAAwFmDbD4X78O9AACAv2ODbD71BDU+AACAv+wENb71BDU+AAAAwPYENb4a78M9AAAAwGODbL4a78M9AACAv1mDbL4tvTuyAACAvwIAgD4tvTuyAAAAwPr/fz4U78M9AAAAwFqDbD4U78M9AACAv2SDbD7yBDU+AACAv/cENT7yBDU+AAAAwO0ENT5eg2w+AAAAwAzvwz0AAIA+AAAAwAAAoLMAAIA+AACAvwAAoDNeg2w+AACAvyDvwz1gg2w+AAAAwBrvw71gg2w+AACAvwbvw70AAIC+AAAAwEvvzrNeg2y+AAAAwCHvw73xBDW+AAAAwPgENb4R78O9AAAAwGSDbL7jzQwzAAAAwAIAgL7jzQwzAACAv/r/f74R78O9AACAv1qDbL7xBDW+AACAv+4ENb5eg2y+AACAvw3vw70AAIC+AACAv2ohYjMAAAAAAACAvwAAAAAAAADAAAAQAi7bVL9VyLGz3jkOP8YUe74QAAQH3jkOv/0IBbQu21Q/yhR7vhQABAbeOQ4//QgFNC/bVL+yFHu+GAAEBbzFR7747By0vxR7P80Ue74cAAQIs8VHPvfsHLS/FHs/zBR7viAABBneOQ4//QgFtC/bVD/LFHu+JAAEGL8Uez84t/myxsVHPsMUe74oAAQWL9tUP1TIsbPdOQ4/xRR7viwABBcy21Q/T8ixM9k5Dr+2FHu+MAAEAL8Uez8mt/kyuMVHvrwUe740AAQAs8VHvvfsHDS/FHu/rRR7vjgABAq8xUc++OwcNL8Ue7+vFHu+PAAEBNs5Dr/+CAU0MNtUv7IUe75AAAQNLttUv1XIsTPeOQ6/tRR7vkQABA6/FHu/Hrf5srLFRz7BFHu+SAAEEQAAAAAAAIA/AAAAAAAAgD9MABAAvhR7vzm3+TLHxUe+uxR7vlwABBAUERAPDAsEAQAWFxgZGggHAAECAwQFAgEGBwgJCgUECwoLDA0ODQwPEBESExATDg8UBwYVFBUSERsaGRwbCQgaHRwZGB0YFx4fFgADHwMCBQoNDhMSFQYJGxwdHh8eFxYACgAHAAgABgAFAAQAAgABAA8AEQAOAA0ACwAMAAMACQECARABDwIEAhADCQMMAxAEEAQFBQYFEAYQBggHCgcQBwgIEAkQCQoKEAsMCw0LEAwQDRANDg4RDhAPEQ8QEBEAAQ8AAQIBAhABDxAAAgQCBBADCRAAAwkAAwwDDBAEBRAABAUABQYFBhAGCBAABggABwgABwoHChAHCBAACQoJChAADxEADhEADQ4ACw0ACwwLDBALDRANDhAOEBEPEBEAAAAAAACAvgAAAMACAIC+AACAPgAAgL8CAIA+Fe9DPtoU5j7Miz2wHH4IL8yLPbBe9r47lSAOsRx+CC+VIA6x2hTmPkQaJbEAAMC/GkdOMAAAgL+8FHs+7wQ1PgAAAD/vBDU+",
+                                "Type": 1
+                            },
+                            "Radius": 0.25
+                        }
+                    }
+                },
+                "Component_[5174473392366422306]": {
+                    "$type": "EditorRigidBodyComponent",
+                    "Id": 5174473392366422306,
+                    "Configuration": {
+                        "entityId": "",
+                        "Gravity Enabled": false,
+                        "Compute Mass": false,
+                        "Centre of mass offset": [
+                            -2.4025590406040465e-9,
+                            -1.5000001192092896,
+                            7.504340482356042e-10
+                        ],
+                        "Inertia tensor": [
+                            0.09856128692626953,
+                            0.0,
+                            0.0,
+                            0.0,
+                            0.03045707754790783,
+                            0.0,
+                            0.0,
+                            0.0,
+                            0.09856128692626953
+                        ]
+                    }
+                },
+                "Component_[5659743372837115840]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 5659743372837115840
+                },
+                "Component_[5673825379655474680]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 5673825379655474680
+                },
+                "Component_[7461337861335650908]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 7461337861335650908,
+                    "Parent Entity": "Entity_[637898996103]"
+                },
+                "Component_[9225660274345766291]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 9225660274345766291,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{C30A2FCA-5A92-5937-9299-3BB257685FA0}",
+                                    "subId": 281016945
+                                },
+                                "assetHint": "prefabs/meshs/fifth_axis.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[9516352464075544482]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 9516352464075544482
+                }
+            }
+        },
+        "Entity_[573474486663]": {
+            "Id": "Entity_[573474486663]",
+            "Name": "sixth_axis_joint",
+            "Components": {
+                "Component_[10397611513359004520]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 10397611513359004520
+                },
+                "Component_[14440286784524790779]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 14440286784524790779
+                },
+                "Component_[15067324202740711833]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 15067324202740711833
+                },
+                "Component_[16760336204622161715]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 16760336204622161715
+                },
+                "Component_[3018525883815806949]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 3018525883815806949,
+                    "Child Entity Order": [
+                        "Entity_[577769453959]"
+                    ]
+                },
+                "Component_[3431421845831260811]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 3431421845831260811
+                },
+                "Component_[4035568261117473061]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 4035568261117473061
+                },
+                "Component_[5722039166658365910]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 5722039166658365910
+                },
+                "Component_[950069446479337813]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 950069446479337813,
+                    "Parent Entity": "Entity_[569179519367]",
+                    "Transform Data": {
+                        "Translate": [
+                            0.0,
+                            -2.3707895278930664,
+                            0.0015940666198730469
+                        ]
+                    }
+                }
+            }
+        },
+        "Entity_[577769453959]": {
+            "Id": "Entity_[577769453959]",
+            "Name": "sixth_axis",
+            "Components": {
+                "Component_[10397611513359004520]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 10397611513359004520
+                },
+                "Component_[14260174658811594950]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 14260174658811594950,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{69955B52-0C47-5CF2-9209-D2242DF9A00C}",
+                                    "subId": 269063108
+                                },
+                                "assetHint": "prefabs/meshs/sixth_axis.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[14440286784524790779]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 14440286784524790779
+                },
+                "Component_[15067324202740711833]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 15067324202740711833
+                },
+                "Component_[15661212638881475054]": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 15661212638881475054,
+                    "Controller": {
+                        "Configuration": {
+                            "materials": [
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 2547188506
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{2457475C-263F-5FA0-A412-C01BC49E33A9}"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                },
+                "Component_[16760336204622161715]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 16760336204622161715
+                },
+                "Component_[3018525883815806949]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 3018525883815806949,
+                    "Child Entity Order": [
+                        "Entity_[655078865287]"
+                    ]
+                },
+                "Component_[3431421845831260811]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 3431421845831260811
+                },
+                "Component_[3817623659562904314]": {
+                    "$type": "EditorColliderComponent",
+                    "Id": 3817623659562904314,
+                    "ColliderConfiguration": {
+                        "Position": [
+                            0.0,
+                            0.0,
+                            -0.30000001192092896
+                        ],
+                        "MaterialSlots": {
+                            "Slots": [
+                                {
+                                    "Name": "Entire object"
+                                }
+                            ]
+                        }
+                    },
+                    "ShapeConfiguration": {
+                        "ShapeType": 3,
+                        "Cylinder": {
+                            "Configuration": {
+                                "CookedData": "TlhTAUNWWE0NAAAAAAAAAElDRQFDTEhMCQAAACAAAAAwAAAAEgAAAGAAAADnNb29Q78cPZqZGb7D0JC9wtCQPZqZGb7D0JC9wtCQPWdm5r7nNb29Q78cPWdm5r7D0JA9w9CQPWdm5r5Dvxw95zW9PWdm5r5Dvxw95zW9PZqZGb7D0JA9w9CQPZqZGb7nNb09QL8cvWdm5r7NzMw9AAAAAGdm5r7NzMw9AAAAAJqZGb7nNb09QL8cvZqZGb7E0JA9wdCQvZqZGb7E0JA9wdCQvWdm5r5Bvxy95zW9vZqZGb5Bvxy95zW9vWdm5r5rSWEyzczMvWdm5r5rSWEyzczMvZqZGb7lNb09Rb8cPZqZGb7lNb09Rb8cPWdm5r5Ivxw95TW9vWdm5r5Ivxw95TW9vZqZGb7NzMy98jAWsmdm5r7NzMy98jAWspqZGb7lNb29R78cvWdm5r7lNb29R78cvZqZGb7yMJaxzczMPWdm5r7yMJaxzczMPZqZGb5Hvxy95TW9PZqZGb5Hvxy95TW9PWdm5r7C0JC9w9CQvZqZGb7C0JC9w9CQvWdm5r4AAAAAAAAAAAAAgD+amRk+AAAQAi/bVL/cOQ4/AAAAAGbdyL0QAAQM2zkOPy/bVD8AAAAAZd3IvRQABA6+FHs/scVHvgAAAABl3ci9GAAEADHbVD/aOQ6/AAAAAGTdyL0cAAQAq8VHvr8Ue78AAAAAZd3IvSAABAW9FHs/xcVHPgAAAABk3ci9JAAEFjPbVD/ZOQ4/AAAAAGfdyL0oAAQY3TkOPy/bVL8AAAAAZd3IvSwABAHHxUc+vhR7vwAAAABm3ci9MAAEGr8Ue7+rxUc+AAAAAGXdyL00AAQJvRR7v8XFR74AAAAAZd3IvTgABAmuxUc+vxR7PwAAAABl3ci9PAAEDsXFR76/FHs/AAAAAGbdyL1AAAQQ3DkOvzDbVD8AAAAAZt3IvUQABBQAAAAAAAAAAAAAgL9kZua+SAAQANs5Dr8v21S/AAAAAGXdyL1YAAQEMNtUv9w5Dr8AAAAAZd3IvVwABAQcAQAXGR4OERUMCwoSBwYbAAECAwQFBgcICQoLCAsMDQ4PEBESCgkTEhMEBxQNDBUUFREQFhcAAxYYGRcaGwYFHBsaHRwdAgEfGBYDAh0aBQQTCQgNFBAPHw8OHh8eGRgADgABAAoACwARABAABQAJAAgABAADAAYABwACAAwADQEOAQ8BCgIPAgwCBwMPAwYDBAQIBA8FEAUPBQkGDwYHBw8IDwgJCQ8KCwoPCw8LEQwNDA8NDw0ODg8PEQ8QEBEAAQoAAQ4BDg8BCg8CBw8CDA8AAgwAAgcDBA8DBg8AAwYAAwQABAgECA8ABRAFDxAFCQ8ABQkABgcGBw8ICQ8ACAkKCw8ACgsLDxEACxEMDQ8ADA0ADQ4NDg8AEBEPEBEAAAAAzczMvc3MzL1nZua+zczMPc3MzD2amRm+LnoWPGWccDrZ/Iqq9Iapqtn8iqplnHA6JbFHLPSGqaolsUcsRbk7OMINpa+DjY0wmpmZvgAAgL9k3cg9wdCQPcHQkD2UmRk+",
+                                "Type": 1
+                            },
+                            "Height": 0.30000001192092896,
+                            "Radius": 0.10000000149011612
+                        }
+                    }
+                },
+                "Component_[4035568261117473061]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 4035568261117473061
+                },
+                "Component_[5722039166658365910]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 5722039166658365910
+                },
+                "Component_[893141901747506007]": {
+                    "$type": "EditorHingeJointComponent",
+                    "Id": 893141901747506007,
+                    "Configuration": {
+                        "Local Rotation": [
+                            90.0,
+                            0.0,
+                            0.0
+                        ],
+                        "Parent Entity": "Entity_[573474486663]",
+                        "Child Entity": "Entity_[577769453959]"
+                    },
+                    "Angular Limit": {
+                        "Positive Limit": 125.0,
+                        "Negative Limit": -125.0
+                    }
+                },
+                "Component_[950069446479337813]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 950069446479337813,
+                    "Parent Entity": "Entity_[573474486663]"
+                },
+                "Component_[9928456096052031657]": {
+                    "$type": "EditorRigidBodyComponent",
+                    "Id": 9928456096052031657,
+                    "Configuration": {
+                        "entityId": "",
+                        "Gravity Enabled": false,
+                        "Compute Mass": false,
+                        "Centre of mass offset": [
+                            -3.0023100672238456e-10,
+                            1.0299320285511726e-9,
+                            -0.30000001192092896
+                        ],
+                        "Inertia tensor": [
+                            0.00993657112121582,
+                            0.0,
+                            0.0,
+                            0.0,
+                            0.00993657112121582,
+                            0.0,
+                            0.0,
+                            0.0,
+                            0.004873132798820734
+                        ]
+                    }
+                }
+            }
+        },
+        "Entity_[582064421255]": {
+            "Id": "Entity_[582064421255]",
+            "Name": "digit_left",
+            "Components": {
+                "Component_[10398716782691769261]": {
+                    "$type": "EditorRigidBodyComponent",
+                    "Id": 10398716782691769261,
+                    "Configuration": {
+                        "entityId": "",
+                        "Gravity Enabled": false,
+                        "Compute Mass": false,
+                        "Centre of mass offset": [
+                            0.0,
+                            0.0,
+                            -0.20000000298023224
+                        ],
+                        "Inertia tensor": [
+                            0.00937499850988388,
+                            0.0,
+                            0.0,
+                            0.0,
+                            0.0208333320915699,
+                            0.0,
+                            0.0,
+                            0.0,
+                            0.015208332799375057
+                        ]
+                    }
+                },
+                "Component_[11489146677624140676]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 11489146677624140676
+                },
+                "Component_[11715287625053615148]": {
+                    "$type": "EditorColliderComponent",
+                    "Id": 11715287625053615148,
+                    "ColliderConfiguration": {
+                        "Position": [
+                            0.0,
+                            0.0,
+                            -0.20000000298023224
+                        ],
+                        "MaterialSlots": {
+                            "Slots": [
+                                {
+                                    "Name": "Entire object"
+                                }
+                            ]
+                        }
+                    },
+                    "ShapeConfiguration": {
+                        "ShapeType": 1,
+                        "Box": {
+                            "Configuration": [
+                                0.4000000059604645,
+                                0.15000000596046448,
+                                0.30000001192092896
+                            ]
+                        }
+                    }
+                },
+                "Component_[12351144674120142159]": {
+                    "$type": "EditorHingeJointComponent",
+                    "Id": 12351144674120142159,
+                    "Configuration": {
+                        "Local Rotation": [
+                            90.0,
+                            0.0,
+                            0.0
+                        ],
+                        "Parent Entity": "Entity_[560589584775]",
+                        "Child Entity": "Entity_[582064421255]"
+                    },
+                    "Angular Limit": {
+                        "Positive Limit": 145.0,
+                        "Negative Limit": 0.0
+                    }
+                },
+                "Component_[13017153777003290516]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 13017153777003290516
+                },
+                "Component_[16310323416065759014]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 16310323416065759014
+                },
+                "Component_[26743869235772550]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 26743869235772550
+                },
+                "Component_[2773421673211466633]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 2773421673211466633
+                },
+                "Component_[3348449984293259184]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 3348449984293259184,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{8950B84F-E919-5338-A3BF-AA2DB6092262}",
+                                    "subId": 278230190
+                                },
+                                "assetHint": "prefabs/meshs/digit_left.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[6525273861851362886]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 6525273861851362886
+                },
+                "Component_[6799352960972820203]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 6799352960972820203
+                },
+                "Component_[7504792106159211932]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 7504792106159211932
+                },
+                "Component_[7896427902011259342]": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 7896427902011259342,
+                    "Controller": {
+                        "Configuration": {
+                            "materials": [
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 411659043
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{2457475C-263F-5FA0-A412-C01BC49E33A9}"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                },
+                "Component_[9659707703958871644]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 9659707703958871644,
+                    "Parent Entity": "Entity_[560589584775]"
+                }
+            }
+        },
+        "Entity_[586359388551]": {
+            "Id": "Entity_[586359388551]",
+            "Name": "fifth_extending_arm",
+            "Components": {
+                "Component_[1079010805368390686]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 1079010805368390686
+                },
+                "Component_[12628290419265707113]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 12628290419265707113
+                },
+                "Component_[1270571256934344216]": {
+                    "$type": "EditorRigidBodyComponent",
+                    "Id": 1270571256934344216,
+                    "Configuration": {
+                        "entityId": "",
+                        "Gravity Enabled": false,
+                        "Compute Mass": false,
+                        "Centre of mass offset": [
+                            1.6711979577976876e-9,
+                            -2.0,
+                            -2.796618318867683e-11
+                        ],
+                        "Inertia tensor": [
+                            0.09856176376342773,
+                            0.0,
+                            0.0,
+                            0.0,
+                            0.030457070097327232,
+                            0.0,
+                            0.0,
+                            0.0,
+                            0.09856176376342773
+                        ]
+                    }
+                },
+                "Component_[13645284086660062469]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 13645284086660062469,
+                    "Child Entity Order": [
+                        "Entity_[637898996103]"
+                    ]
+                },
+                "Component_[13778971132196727319]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 13778971132196727319
+                },
+                "Component_[14722653508342047742]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 14722653508342047742
+                },
+                "Component_[16342570532678235738]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 16342570532678235738
+                },
+                "Component_[16793091695150659389]": {
+                    "$type": "EditorHingeJointComponent",
+                    "Id": 16793091695150659389,
+                    "Configuration": {
+                        "Local Position": [
+                            0.0,
+                            -0.008406500332057476,
+                            0.011848700232803822
+                        ],
+                        "Local Rotation": [
+                            0.0,
+                            0.0,
+                            90.0
+                        ],
+                        "Parent Entity": "Entity_[633604028807]",
+                        "Child Entity": "Entity_[586359388551]"
+                    },
+                    "Angular Limit": {
+                        "Positive Limit": 180.0,
+                        "Negative Limit": -180.0
+                    }
+                },
+                "Component_[17449503550395123070]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 17449503550395123070
+                },
+                "Component_[3367979723151905861]": {
+                    "$type": "EditorColliderComponent",
+                    "Id": 3367979723151905861,
+                    "ColliderConfiguration": {
+                        "Position": [
+                            0.0,
+                            -2.0,
+                            0.0
+                        ],
+                        "Rotation": [
+                            0.7071067690849304,
+                            0.0,
+                            0.0,
+                            0.7071067094802856
+                        ],
+                        "MaterialSlots": {
+                            "Slots": [
+                                {
+                                    "Name": "Entire object"
+                                }
+                            ]
+                        }
+                    },
+                    "ShapeConfiguration": {
+                        "ShapeType": 3,
+                        "Cylinder": {
+                            "Configuration": {
+                                "CookedData": "TlhTAUNWWE0NAAAAAAAAAElDRQFDTEhMCQAAACAAAAAwAAAAEgAAAGAAAADxBDW+AADAv/AENb7xBDW+AAAgwPQENb5cg2y+AAAgwBvvw71cg2y+AADAvxPvw70Q78O9AAAgwGCDbL4Q78O9AADAv1yDbL4Y78M9AAAgwF6DbL4Y78M9AADAv1qDbL7zBDU+AADAv+4ENb7zBDU+AAAgwPIENb4T78M9AAAgwFyDbD7xBDU+AAAgwO8ENT7xBDU+AADAv/MENT4T78M9AADAv2CDbD5eg2y+AAAgwA3vwz3yBDW+AAAgwO8ENT7yBDW+AADAv/MENT5eg2y+AADAvxXvwz0W78O9AAAgwFqDbD4W78O9AADAv16DbD5cg2w+AAAgwBDvwz3+/38+AAAgwAAAALP+/38+AADAvwAAADNcg2w+AADAvxjvwz3+/3++AADAv6aFCDL+/3++AAAgwJbeXbMtvTuyAADAvwAAgD4tvTuyAAAgwPz/fz7izQwzAADAv/z/f77izQwzAAAgwAAAgL5eg2w+AADAvwrvw71eg2w+AAAgwBLvw70AAAAAAACAPwAAAAAAAMA/AAAQATDbVL/cOQ4z3DkOv7kUe74QAAQL2zkOvzLbVDMy21S/txR7vhQABArdOQ4/L9tUMy/bVL+2FHu+GAAEEN45Dj8u21SzLttUP8IUe74cAAQAMNtUv9s5DrPbOQ4/wBR7viAABAjbOQ6/MNtUszDbVD/CFHu+JAAEBr4Uez/HxUeyx8VHPr4Ue74oAAQCMNtUP9s5DrPbOQ4/vxR7viwABAC/FHu/tMVHsrTFRz6+FHu+MAAEFr4Ue7/HxUcyx8VHvrwUe740AAQUxsVHvr0Ue7O9FHs/xBR7vjgABAa0xUc+vxR7s78Uez/EFHu+PAAEBLTFR76/FHszvxR7v7QUe75AAAQKx8VHPr4UezO+FHu/tRR7vkQABBIy21Q/2TkOM9k5Dr+4FHu+SAAEDr4Uez+5xUcyucVHvroUe75MAAQOAAAAAAAAgL8AAAAAAAAgwFAAEAAcBQADGBEQExoNDBcWHggHAAECAwQBAAUGBwgJCgsMDQ4PEBESExAPFBUWFxQXDAsYGQ4RGAMCGRoTEhsaGwoNHB0EBRwHBh0fCQgeHx4WFR8VFAsKGxIPDhkCAQQdBgkADQACAAEACgAJAAUABgALAAwABAAIAAcAEAAPAAMADgECAREBCgIRAg0DDgMPAxEEEQQIBAwFEQUGBQkGCwYRBxEHEAcICBEJCgkRChELEQsMDBENDg0RDhEPEQ8QEBEAAQIBAhEBChEAAQoCDREAAg0DDhEAAw4AAw8DDxEEDBEECBEABAgABAwFCREFBhEABQYABQkGCxEABgsHCBEHEBEABxAABwgACQoJChEACwwLDBEADQ4NDhEADxAPEBEAAAAA/v9/vgAAIMAAAIC+/v9/PgAAwL8AAIA+Eu9DPgTDSD+ayy8wjokCLprLLzBZ9r47L46VsI6JAi4vjpWwBMNIPw6w5TAAAADAQP71rQAAgL+6FHs+7wQ1PgAAAD/vBDU+",
+                                "Type": 1
+                            },
+                            "Radius": 0.25
+                        }
+                    }
+                },
+                "Component_[446243873701512482]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 446243873701512482,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{097291FB-6DEF-526C-A740-62351E6D9281}",
+                                    "subId": 270700844
+                                },
+                                "assetHint": "prefabs/meshs/fifth_extending_arm.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[7325421905903791889]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 7325421905903791889,
+                    "Parent Entity": "Entity_[633604028807]"
+                },
+                "Component_[8234750748415261518]": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 8234750748415261518,
+                    "Controller": {
+                        "Configuration": {
+                            "materials": [
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 3307370396
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{2457475C-263F-5FA0-A412-C01BC49E33A9}"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                },
+                "Component_[8284900474443359654]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 8284900474443359654
+                }
+            }
+        },
+        "Entity_[590654355847]": {
+            "Id": "Entity_[590654355847]",
+            "Name": "hand_right",
+            "Components": {
+                "Component_[1023211850860498786]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 1023211850860498786
+                },
+                "Component_[11402704802795454573]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 11402704802795454573
+                },
+                "Component_[13434751477247218404]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 13434751477247218404
+                },
+                "Component_[14974996773523387120]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 14974996773523387120
+                },
+                "Component_[17722717871746365623]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 17722717871746365623
+                },
+                "Component_[17800997910811694260]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 17800997910811694260
+                },
+                "Component_[3226453374962359334]": {
+                    "$type": "EditorRigidBodyComponent",
+                    "Id": 3226453374962359334,
+                    "Configuration": {
+                        "entityId": "",
+                        "Gravity Enabled": false,
+                        "Compute Mass": false,
+                        "Centre of mass offset": [
+                            0.0,
+                            0.0,
+                            -0.20000000298023224
+                        ],
+                        "Inertia tensor": [
+                            0.00937499850988388,
+                            0.0,
+                            0.0,
+                            0.0,
+                            0.0208333320915699,
+                            0.0,
+                            0.0,
+                            0.0,
+                            0.015208332799375057
+                        ]
+                    }
+                },
+                "Component_[4009006179163806296]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 4009006179163806296,
+                    "Child Entity Order": [
+                        "Entity_[594949323143]"
+                    ]
+                },
+                "Component_[4664594385639213386]": {
+                    "$type": "EditorHingeJointComponent",
+                    "Id": 4664594385639213386,
+                    "Configuration": {
+                        "Local Rotation": [
+                            90.0,
+                            0.0,
+                            0.0
+                        ],
+                        "Parent Entity": "Entity_[551999650183]",
+                        "Child Entity": "Entity_[590654355847]"
+                    },
+                    "Angular Limit": {
+                        "Positive Limit": 145.0,
+                        "Negative Limit": 0.0
+                    }
+                },
+                "Component_[5426849745670871106]": {
+                    "$type": "EditorColliderComponent",
+                    "Id": 5426849745670871106,
+                    "ColliderConfiguration": {
+                        "Position": [
+                            0.0,
+                            0.0,
+                            -0.20000000298023224
+                        ],
+                        "MaterialSlots": {
+                            "Slots": [
+                                {
+                                    "Name": "Entire object"
+                                }
+                            ]
+                        }
+                    },
+                    "ShapeConfiguration": {
+                        "ShapeType": 1,
+                        "Box": {
+                            "Configuration": [
+                                0.4000000059604645,
+                                0.15000000596046448,
+                                0.30000001192092896
+                            ]
+                        }
+                    }
+                },
+                "Component_[5760728684619500317]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 5760728684619500317,
+                    "Parent Entity": "Entity_[551999650183]"
+                },
+                "Component_[6973109471285341605]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 6973109471285341605
+                },
+                "Component_[8729971515401851948]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 8729971515401851948,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{9FAF59B0-AB58-52C4-88F4-EEE893525CDD}",
+                                    "subId": 269114177
+                                },
+                                "assetHint": "prefabs/meshs/hand_right.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[919529981696949154]": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 919529981696949154,
+                    "Controller": {
+                        "Configuration": {
+                            "materials": [
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 411659043
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{2457475C-263F-5FA0-A412-C01BC49E33A9}"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
+        "Entity_[594949323143]": {
+            "Id": "Entity_[594949323143]",
+            "Name": "digit_right_joint",
+            "Components": {
+                "Component_[11489146677624140676]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 11489146677624140676
+                },
+                "Component_[13017153777003290516]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 13017153777003290516
+                },
+                "Component_[16310323416065759014]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 16310323416065759014
+                },
+                "Component_[26743869235772550]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 26743869235772550
+                },
+                "Component_[2773421673211466633]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 2773421673211466633
+                },
+                "Component_[6525273861851362886]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 6525273861851362886,
+                    "Child Entity Order": [
+                        "Entity_[564884552071]"
+                    ]
+                },
+                "Component_[6799352960972820203]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 6799352960972820203
+                },
+                "Component_[7504792106159211932]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 7504792106159211932
+                },
+                "Component_[9659707703958871644]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 9659707703958871644,
+                    "Parent Entity": "Entity_[590654355847]",
+                    "Transform Data": {
+                        "Translate": [
+                            0.0,
+                            0.0,
+                            -0.3661990165710449
+                        ]
+                    }
+                }
+            }
+        },
+        "Entity_[599244290439]": {
+            "Id": "Entity_[599244290439]",
+            "Name": "first_arm",
+            "Components": {
+                "Component_[11688363628545883540]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 11688363628545883540
+                },
+                "Component_[14085578646230429495]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 14085578646230429495,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{FE365C1E-EFFB-501A-B159-7FAE0508883A}",
+                                    "subId": 280368896
+                                },
+                                "assetHint": "prefabs/meshs/first_arm.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[15854793457548110068]": {
+                    "$type": "EditorHingeJointComponent",
+                    "Id": 15854793457548110068,
+                    "Configuration": {
+                        "Local Position": [
+                            0.0,
+                            -0.008406500332057476,
+                            0.0
+                        ],
+                        "Local Rotation": [
+                            90.0,
+                            0.0,
+                            0.0
+                        ],
+                        "Parent Entity": "Entity_[650783897991]",
+                        "Child Entity": "Entity_[599244290439]"
+                    }
+                },
+                "Component_[16896367397395997714]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 16896367397395997714
+                },
+                "Component_[17054476835086239712]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 17054476835086239712
+                },
+                "Component_[191426375985139181]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 191426375985139181
+                },
+                "Component_[2897015329131593759]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 2897015329131593759
+                },
+                "Component_[3704167068356982662]": {
+                    "$type": "EditorRigidBodyComponent",
+                    "Id": 3704167068356982662,
+                    "Configuration": {
+                        "entityId": "",
+                        "Gravity Enabled": false,
+                        "Compute Mass": false,
+                        "Mass": 29.999998092651367,
+                        "Centre of mass offset": [
+                            0.0,
+                            0.0,
+                            1.0
+                        ],
+                        "Inertia tensor": [
+                            3.124998092651367,
+                            0.0,
+                            0.0,
+                            0.0,
+                            3.124998092651367,
+                            0.0,
+                            0.0,
+                            0.0,
+                            5.0
+                        ]
+                    }
+                },
+                "Component_[5455744605101540502]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 5455744605101540502
+                },
+                "Component_[648599470501636010]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 648599470501636010,
+                    "Parent Entity": "Entity_[650783897991]",
+                    "Transform Data": {
+                        "Translate": [
+                            0.021306633949279785,
+                            0.06691408157348633,
+                            0.0
+                        ]
+                    }
+                },
+                "Component_[658439284799658219]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 658439284799658219,
+                    "Child Entity Order": [
+                        "Entity_[603539257735]"
+                    ]
+                },
+                "Component_[9085452150473622490]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 9085452150473622490
+                },
+                "Component_[9331303603723857046]": {
+                    "$type": "EditorColliderComponent",
+                    "Id": 9331303603723857046,
+                    "ColliderConfiguration": {
+                        "Position": [
+                            0.0,
+                            0.0,
+                            1.0
+                        ],
+                        "MaterialSlots": {
+                            "Slots": [
+                                {
+                                    "Name": "Entire object"
+                                }
+                            ]
+                        }
+                    },
+                    "ShapeConfiguration": {
+                        "ShapeType": 1,
+                        "Box": {
+                            "Configuration": [
+                                1.0,
+                                1.0,
+                                0.5
+                            ]
+                        }
+                    }
+                },
+                "Component_[9965638143047159397]": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 9965638143047159397,
+                    "Controller": {
+                        "Configuration": {
+                            "materials": [
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 411659043
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{2457475C-263F-5FA0-A412-C01BC49E33A9}"
+                                            }
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 1378043131
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{9C7FB3EE-8707-51CD-BF13-D2B5AFB7F1B1}"
+                                            },
+                                            "assetHint": "prefabs/meshs/orangepaint.azmaterial"
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 2547188506
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{7360179C-A9A1-55DB-B902-39D7C8568A39}"
+                                            },
+                                            "assetHint": "prefabs/meshs/base_platform_aluminumanodizedgrey.azmaterial"
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
+        "Entity_[603539257735]": {
+            "Id": "Entity_[603539257735]",
+            "Name": "third_axis_joint",
+            "Components": {
+                "Component_[11093958753318678011]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 11093958753318678011
+                },
+                "Component_[14808974483350575994]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 14808974483350575994
+                },
+                "Component_[15323971543880478407]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 15323971543880478407
+                },
+                "Component_[17198570525150895419]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 17198570525150895419,
+                    "Child Entity Order": [
+                        "Entity_[607834225031]"
+                    ]
+                },
+                "Component_[4906559468672324960]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 4906559468672324960
+                },
+                "Component_[5689857475509006536]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 5689857475509006536
+                },
+                "Component_[6021292966780672075]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 6021292966780672075
+                },
+                "Component_[7240051742807364100]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 7240051742807364100
+                },
+                "Component_[9004005532762795313]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 9004005532762795313,
+                    "Parent Entity": "Entity_[599244290439]",
+                    "Transform Data": {
+                        "Translate": [
+                            -0.021306633949279785,
+                            -0.0007126927375793457,
+                            1.818979263305664
+                        ]
+                    }
+                }
+            }
+        },
+        "Entity_[607834225031]": {
+            "Id": "Entity_[607834225031]",
+            "Name": "third_axis",
+            "Components": {
+                "Component_[11093958753318678011]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 11093958753318678011
+                },
+                "Component_[11650144723200730858]": {
+                    "$type": "EditorColliderComponent",
+                    "Id": 11650144723200730858,
+                    "ColliderConfiguration": {
+                        "Position": [
+                            0.0,
+                            0.0,
+                            1.4097604751586914
+                        ],
+                        "MaterialSlots": {
+                            "Slots": [
+                                {
+                                    "Name": "Entire object"
+                                }
+                            ]
+                        }
+                    },
+                    "ShapeConfiguration": {
+                        "ShapeType": 1
+                    }
+                },
+                "Component_[14463590363816931121]": {
+                    "$type": "EditorHingeJointComponent",
+                    "Id": 14463590363816931121,
+                    "Configuration": {
+                        "Local Position": [
+                            0.0,
+                            -0.008406500332057476,
+                            0.0
+                        ],
+                        "Local Rotation": [
+                            90.0,
+                            0.0,
+                            0.0
+                        ],
+                        "Parent Entity": "Entity_[603539257735]",
+                        "Child Entity": "Entity_[607834225031]"
+                    }
+                },
+                "Component_[14808974483350575994]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 14808974483350575994
+                },
+                "Component_[15323971543880478407]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 15323971543880478407
+                },
+                "Component_[17198570525150895419]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 17198570525150895419,
+                    "Child Entity Order": [
+                        "Entity_[616424159623]"
+                    ]
+                },
+                "Component_[2160875982352191545]": {
+                    "$type": "EditorRigidBodyComponent",
+                    "Id": 2160875982352191545,
+                    "Configuration": {
+                        "entityId": "",
+                        "Gravity Enabled": false,
+                        "Compute Mass": false,
+                        "Mass": 10.0,
+                        "Centre of mass offset": [
+                            0.0,
+                            0.0,
+                            1.4097604751586914
+                        ],
+                        "Inertia tensor": [
+                            1.6666661500930786,
+                            0.0,
+                            0.0,
+                            0.0,
+                            1.6666661500930786,
+                            0.0,
+                            0.0,
+                            0.0,
+                            1.6666667461395264
+                        ]
+                    }
+                },
+                "Component_[3281216797322440297]": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 3281216797322440297,
+                    "Controller": {
+                        "Configuration": {
+                            "materials": [
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 411659043
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{2457475C-263F-5FA0-A412-C01BC49E33A9}"
+                                            },
+                                            "assetHint": "prefabs/meshs/silverpolished.azmaterial"
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 1378043131
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{9C7FB3EE-8707-51CD-BF13-D2B5AFB7F1B1}"
+                                            },
+                                            "assetHint": "prefabs/meshs/orangepaint.azmaterial"
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 2209014885
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{03D6F6C9-FAAB-5C7B-BBE4-1E47E3285A23}"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                },
+                "Component_[4895043180552911490]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 4895043180552911490,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{BFEC53BF-E87E-515C-B9A2-C596B485BCFF}",
+                                    "subId": 279795722
+                                },
+                                "assetHint": "prefabs/meshs/third_axis.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[4906559468672324960]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 4906559468672324960
+                },
+                "Component_[5689857475509006536]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 5689857475509006536
+                },
+                "Component_[6021292966780672075]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 6021292966780672075
+                },
+                "Component_[7240051742807364100]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 7240051742807364100
+                },
+                "Component_[9004005532762795313]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 9004005532762795313,
+                    "Parent Entity": "Entity_[603539257735]"
+                }
+            }
+        },
+        "Entity_[612129192327]": {
+            "Id": "Entity_[612129192327]",
+            "Name": "frist_axis_joint",
+            "Components": {
+                "Component_[11006892309164011783]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 11006892309164011783
+                },
+                "Component_[11722477296039848815]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 11722477296039848815,
+                    "Parent Entity": "Entity_[625014094215]",
+                    "Transform Data": {
+                        "Translate": [
+                            0.0,
+                            -0.920893669128418,
+                            3.262155532836914
+                        ]
+                    }
+                },
+                "Component_[11894522099192018465]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 11894522099192018465
+                },
+                "Component_[15755572643227284312]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 15755572643227284312
+                },
+                "Component_[17819075278864683550]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 17819075278864683550
+                },
+                "Component_[1878811958358686826]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 1878811958358686826
+                },
+                "Component_[5793539545445890761]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 5793539545445890761
+                },
+                "Component_[5883085161775640887]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 5883085161775640887,
+                    "Child Entity Order": [
+                        "Entity_[646488930695]"
+                    ]
+                },
+                "Component_[7054666824936675605]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 7054666824936675605
+                }
+            }
+        },
+        "Entity_[616424159623]": {
+            "Id": "Entity_[616424159623]",
+            "Name": "forth_axis_joint",
+            "Components": {
+                "Component_[10773912635496830]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 10773912635496830,
+                    "Parent Entity": "Entity_[607834225031]",
+                    "Transform Data": {
+                        "Translate": [
+                            0.0,
+                            0.0014330744743347168,
+                            2.243685245513916
+                        ]
+                    }
+                },
+                "Component_[14007597470960889220]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 14007597470960889220
+                },
+                "Component_[15316890410414480879]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 15316890410414480879
+                },
+                "Component_[16077202998146352339]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 16077202998146352339
+                },
+                "Component_[16179233008928231683]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 16179233008928231683
+                },
+                "Component_[16639253208265711288]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 16639253208265711288
+                },
+                "Component_[17528994699206186764]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 17528994699206186764
+                },
+                "Component_[2106708107092873363]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 2106708107092873363,
+                    "Child Entity Order": [
+                        "Entity_[629309061511]"
+                    ]
+                },
+                "Component_[7870021159364900255]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 7870021159364900255
+                }
+            }
+        },
+        "Entity_[620719126919]": {
+            "Id": "Entity_[620719126919]",
+            "Name": "hand_left_joint",
+            "Components": {
+                "Component_[1023211850860498786]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 1023211850860498786
+                },
+                "Component_[11402704802795454573]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 11402704802795454573
+                },
+                "Component_[13434751477247218404]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 13434751477247218404
+                },
+                "Component_[14974996773523387120]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 14974996773523387120
+                },
+                "Component_[17722717871746365623]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 17722717871746365623
+                },
+                "Component_[17800997910811694260]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 17800997910811694260
+                },
+                "Component_[4009006179163806296]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 4009006179163806296,
+                    "Child Entity Order": [
+                        "Entity_[556294617479]"
+                    ]
+                },
+                "Component_[5760728684619500317]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 5760728684619500317,
+                    "Parent Entity": "Entity_[659373832583]",
+                    "Transform Data": {
+                        "Translate": [
+                            0.0,
+                            -0.38101911544799805,
+                            -0.08016681671142578
+                        ]
+                    }
+                },
+                "Component_[6973109471285341605]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 6973109471285341605
+                }
+            }
+        },
+        "Entity_[625014094215]": {
+            "Id": "Entity_[625014094215]",
+            "Name": "base_platform",
+            "Components": {
+                "Component_[10774893747950814963]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 10774893747950814963
+                },
+                "Component_[11165507655775266478]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 11165507655775266478,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{92B6714D-18DC-5DFE-AC38-F888DBD4A8E0}",
+                                    "subId": 280589107
+                                },
+                                "assetHint": "prefabs/meshs/base_platform.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[14411595268855871897]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 14411595268855871897
+                },
+                "Component_[15280064131785704070]": {
+                    "$type": "EditorColliderComponent",
+                    "Id": 15280064131785704070,
+                    "ColliderConfiguration": {
+                        "Position": [
+                            0.0,
+                            -0.2263193130493164,
+                            1.1058895587921143
+                        ],
+                        "MaterialSlots": {
+                            "Slots": [
+                                {
+                                    "Name": "Entire object"
+                                }
+                            ]
+                        }
+                    },
+                    "ShapeConfiguration": {
+                        "ShapeType": 1,
+                        "Box": {
+                            "Configuration": [
+                                3.0,
+                                5.0,
+                                2.0
+                            ]
+                        }
+                    }
+                },
+                "Component_[157001582553735443]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 157001582553735443
+                },
+                "Component_[15864730727137905877]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 15864730727137905877
+                },
+                "Component_[16436485561176337020]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 16436485561176337020
+                },
+                "Component_[17003030262771706166]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 17003030262771706166
+                },
+                "Component_[17683127599792061953]": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 17683127599792061953,
+                    "Controller": {
+                        "Configuration": {
+                            "materials": [
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 411659043
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{2457475C-263F-5FA0-A412-C01BC49E33A9}"
+                                            }
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 832243232
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{B48DDB9C-028E-529E-93F0-3F0AFA46ADB1}"
+                                            },
+                                            "assetHint": "prefabs/meshs/base_platform_rubberblack.azmaterial"
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 1378043131
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{9C7FB3EE-8707-51CD-BF13-D2B5AFB7F1B1}"
+                                            },
+                                            "assetHint": "prefabs/meshs/orangepaint.azmaterial"
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 1493308189
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{7360179C-A9A1-55DB-B902-39D7C8568A39}"
+                                            },
+                                            "assetHint": "prefabs/meshs/base_platform_aluminumanodizedgrey.azmaterial"
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 1864407945
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{559DB617-354A-5BD0-8A7F-B682B9872A2D}"
+                                            },
+                                            "assetHint": "prefabs/meshs/base_platform_aluminumanodizedred.azmaterial"
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 2209014885
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{03D6F6C9-FAAB-5C7B-BBE4-1E47E3285A23}"
+                                            },
+                                            "assetHint": "prefabs/meshs/base_platform_blackpaint.azmaterial"
+                                        }
+                                    }
+                                },
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 3307370396
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{0DD69615-1218-5EF5-BD57-CBE7A367CEE5}"
+                                            },
+                                            "assetHint": "prefabs/meshs/base_platform_chrome.azmaterial"
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                },
+                "Component_[6031885685395762765]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 6031885685395762765,
+                    "Parent Entity": "Entity_[642193963399]"
+                },
+                "Component_[6822255122850844601]": {
+                    "$type": "EditorRigidBodyComponent",
+                    "Id": 6822255122850844601,
+                    "Configuration": {
+                        "entityId": "",
+                        "Gravity Enabled": false,
+                        "Compute Mass": false,
+                        "Mass": 29.999998092651367,
+                        "Centre of mass offset": [
+                            0.0,
+                            -0.2263193279504776,
+                            1.1058895587921143
+                        ],
+                        "Inertia tensor": [
+                            72.5,
+                            0.0,
+                            0.0,
+                            0.0,
+                            32.49999237060547,
+                            0.0,
+                            0.0,
+                            0.0,
+                            84.99999237060547
+                        ]
+                    }
+                },
+                "Component_[7059620530827282481]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 7059620530827282481
+                },
+                "Component_[7351049240010246650]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 7351049240010246650,
+                    "Child Entity Order": [
+                        "Entity_[612129192327]"
+                    ]
+                }
+            }
+        },
+        "Entity_[629309061511]": {
+            "Id": "Entity_[629309061511]",
+            "Name": "forth_axis",
+            "Components": {
+                "Component_[10306453298195351199]": {
+                    "$type": "EditorHingeJointComponent",
+                    "Id": 10306453298195351199,
+                    "Configuration": {
+                        "Local Position": [
+                            0.0,
+                            -0.008406500332057476,
+                            0.011848747730255127
+                        ],
+                        "Local Rotation": [
+                            90.0,
+                            0.0,
+                            0.0
+                        ],
+                        "Parent Entity": "Entity_[616424159623]",
+                        "Child Entity": "Entity_[629309061511]"
+                    }
+                },
+                "Component_[10773912635496830]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 10773912635496830,
+                    "Parent Entity": "Entity_[616424159623]"
+                },
+                "Component_[14007597470960889220]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 14007597470960889220
+                },
+                "Component_[15316890410414480879]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 15316890410414480879
+                },
+                "Component_[1552848634559408262]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 1552848634559408262,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{14A03C43-2EBE-5501-B879-551391819D88}",
+                                    "subId": 273988650
+                                },
+                                "assetHint": "prefabs/meshs/forth_axis.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[16077202998146352339]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 16077202998146352339
+                },
+                "Component_[16179233008928231683]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 16179233008928231683
+                },
+                "Component_[16639253208265711288]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 16639253208265711288
+                },
+                "Component_[17528994699206186764]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 17528994699206186764
+                },
+                "Component_[2106708107092873363]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 2106708107092873363,
+                    "Child Entity Order": [
+                        "Entity_[633604028807]"
+                    ]
+                },
+                "Component_[3099892878400243384]": {
+                    "$type": "EditorColliderComponent",
+                    "Id": 3099892878400243384,
+                    "ColliderConfiguration": {
+                        "Position": [
+                            0.0,
+                            0.0,
+                            0.10330910235643387
+                        ],
+                        "Rotation": [
+                            0.7071067690849304,
+                            0.0,
+                            0.0,
+                            0.7071067094802856
+                        ],
+                        "MaterialSlots": {
+                            "Slots": [
+                                {
+                                    "Name": "Entire object"
+                                }
+                            ]
+                        }
+                    },
+                    "ShapeConfiguration": {
+                        "ShapeType": 3,
+                        "Cylinder": {
+                            "Configuration": {
+                                "CookedData": "TlhTAUNWWE0NAAAAAAAAAElDRQFDTEhMCQAAACAAAAAwAAAAEgAAAGAAAADmNb0+ZGYmP37VS73MzMw+ZGYmP76T0z3MzMw+ZGYmv7ST0z3mNb0+ZGYmv5bVS73D0JA+ZGYmv6bXN77D0JA+ZGYmP6LXN77jNb2+ZGYmv7LVS73jNb2+ZGYmP5rVS73B0JC+ZGYmP6bXN77B0JC+ZGYmv6rXN77MzMy+ZGYmv7CT0z3MzMy+ZGYmP7mT0z0/vxy+ZGYmv/dQiL4/vxy+ZGYmP/VQiL5qSWEzZGYmP93nl75qSWEzZGYmv9/nl75Hvxw+ZGYmP/RQiL5Hvxw+ZGYmv/ZQiL7kNb2+ZGYmv45Egz7D0JC+ZGYmv661xT7D0JC+ZGYmP7C1xT7kNb2+ZGYmP5FEgz5Fvxy+ZGYmP9Ea8j5Fvxy+ZGYmv9Aa8j7xMJayZGYmv93YAD/xMJayZGYmP97YAD9Bvxw+ZGYmP9Ma8j7D0JA+ZGYmP7G1xT7jNb0+ZGYmP5JEgz5Bvxw+ZGYmv9Ea8j7D0JA+ZGYmv6+1xT7jNb0+ZGYmv49Egz4AAAAAAACAPwAAAABiZia/AAAQAr8Uez+7FkAytcVHvrKLvr4QAAQLMNtUP2EbJDPaOQ6/dHqrvhQABBMx21S/YBskM9k5Dr90equ+GAAEHr0Ue79c4Swy1MVHvq+Lvr4cAAQB1zkOv1G8IzMz21S/hOKcviAABBrGxUe+qCNBM70Ue7+l/JS+JAAEGNw5Dj9OvCMzMNtUv4XinL4oAAQT1MVHPqgjQTO9FHu/pfyUviwABBgz21S/J8/astc5Dj9VQOa+MAAEAL4Ue7/AgWayxcVHPhkv0740AAQD2DkOv1K8I7M021Q/RNj0vjgABBDlxUe+qCPBsr0Uez8ivvy+PAAEEdU5Dj9RvCOzM9tUP0LY9L5AAAQI1sVHPqkjQbO+FHs/I778vkQABAy+FHs/1xZAstPFRz4aL9O+SAAEBjTbVD9bGySz1TkOP1RA5r5MAAQGAAAAAAAAgL8AAAAAYmYmv1AAEAAWGRobHAEABRAODQgHCxUUAAECAwADBAUGBwgJBgoLBwwJCA0MDQ4PEAUEERARDw4SExQVEhULChYUExcWFxgZHR4bGh0aGRgfAgEcHxwbHh8eHRgXExIKBgkMDxEEAwIADAAOAA0AEAAPAAEAAgAHAAgABgAFAAMABAAKAAkACwEPAREBAgIRAgcDBAMFAxEEEQQKBREFBgYIBhEHEQcICBEJEQkLCQoKEQsRCwwMEQwODRENEA0ODhEPEQ8QEBEAAQIAAQ8BDxEBAhECBxEAAgcDBBEAAwQAAwUDBREEChEABAoFBhEABQYABggGCBEABwgHCBEJChEJCxEACQsACQoACwwLDBEMDhEADA4ADQ4ADRAADxANDhENEBEPEBEAAAAAzMzMvmRmJr/g55e+zMzMPmRmJj/e2AA/VwQjPx5t+D3+20YvsrrDMP7bRi9lNGc9I1OSsbK6wzAjU5Kx64HqPZpaJLI9DMkvuJPTPQAAgL9j3cg+wdCQPmJmJj/B0JA+",
+                                "Type": 1
+                            },
+                            "Height": 1.2999999523162842,
+                            "Radius": 0.4000000059604645
+                        }
+                    }
+                },
+                "Component_[4126852497596858021]": {
+                    "$type": "EditorRigidBodyComponent",
+                    "Id": 4126852497596858021,
+                    "Configuration": {
+                        "entityId": "",
+                        "Gravity Enabled": false,
+                        "Compute Mass": false,
+                        "Mass": 29.999998092651367,
+                        "Centre of mass offset": [
+                            -9.56665680007518e-9,
+                            3.657038005755453e-10,
+                            0.10330908745527267
+                        ],
+                        "Inertia tensor": [
+                            5.39454984664917,
+                            0.0,
+                            0.0,
+                            0.0,
+                            2.3391029834747314,
+                            0.0,
+                            0.0,
+                            0.0,
+                            5.394549369812012
+                        ]
+                    }
+                },
+                "Component_[5847995519799250221]": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 5847995519799250221,
+                    "Controller": {
+                        "Configuration": {
+                            "materials": [
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 411659043
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{2457475C-263F-5FA0-A412-C01BC49E33A9}"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                },
+                "Component_[7870021159364900255]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 7870021159364900255
+                }
+            }
+        },
+        "Entity_[633604028807]": {
+            "Id": "Entity_[633604028807]",
+            "Name": "fifth_extending_arm_joint",
+            "Components": {
+                "Component_[1079010805368390686]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 1079010805368390686
+                },
+                "Component_[12628290419265707113]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 12628290419265707113
+                },
+                "Component_[13645284086660062469]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 13645284086660062469,
+                    "Child Entity Order": [
+                        "Entity_[586359388551]"
+                    ]
+                },
+                "Component_[13778971132196727319]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 13778971132196727319
+                },
+                "Component_[14722653508342047742]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 14722653508342047742
+                },
+                "Component_[16342570532678235738]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 16342570532678235738
+                },
+                "Component_[17449503550395123070]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 17449503550395123070
+                },
+                "Component_[7325421905903791889]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 7325421905903791889,
+                    "Parent Entity": "Entity_[629309061511]",
+                    "Transform Data": {
+                        "Translate": [
+                            0.0,
+                            0.6918350458145142,
+                            0.13075590133666992
+                        ]
+                    }
+                },
+                "Component_[8284900474443359654]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 8284900474443359654
+                }
+            }
+        },
+        "Entity_[637898996103]": {
+            "Id": "Entity_[637898996103]",
+            "Name": "fifth_axis_joint",
+            "Components": {
+                "Component_[14277172426395713142]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 14277172426395713142,
+                    "Child Entity Order": [
+                        "Entity_[569179519367]"
+                    ]
+                },
+                "Component_[17589935685956967256]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 17589935685956967256
+                },
+                "Component_[3227744676858555161]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 3227744676858555161
+                },
+                "Component_[3362822306899345061]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 3362822306899345061
+                },
+                "Component_[4388658803999797632]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 4388658803999797632
+                },
+                "Component_[5659743372837115840]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 5659743372837115840
+                },
+                "Component_[5673825379655474680]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 5673825379655474680
+                },
+                "Component_[7461337861335650908]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 7461337861335650908,
+                    "Parent Entity": "Entity_[586359388551]",
+                    "Transform Data": {
+                        "Translate": [
+                            0.0,
+                            -1.8350001573562622,
+                            0.0
+                        ]
+                    }
+                },
+                "Component_[9516352464075544482]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 9516352464075544482
+                }
+            }
+        },
+        "Entity_[642193963399]": {
+            "Id": "Entity_[642193963399]",
+            "Name": "base_link",
+            "Components": {
+                "Component_[10775252123323175837]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 10775252123323175837
+                },
+                "Component_[12093182339601003220]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 12093182339601003220
+                },
+                "Component_[14666724924299945317]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 14666724924299945317
+                },
+                "Component_[15144454330645338069]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 15144454330645338069
+                },
+                "Component_[5089661084456918277]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 5089661084456918277,
+                    "Child Entity Order": [
+                        "Entity_[625014094215]"
+                    ]
+                },
+                "Component_[5240596019728018055]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 5240596019728018055,
+                    "ComponentOrderEntryArray": [
+                        {
+                            "ComponentId": 761996142889444302
+                        }
+                    ]
+                },
+                "Component_[761996142889444302]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 761996142889444302,
+                    "Parent Entity": "ContainerEntity"
+                },
+                "Component_[9760916191029451609]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 9760916191029451609
+                },
+                "Component_[9803769645201849340]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 9803769645201849340
+                }
+            }
+        },
+        "Entity_[646488930695]": {
+            "Id": "Entity_[646488930695]",
+            "Name": "frist_axis",
+            "Components": {
+                "Component_[11006892309164011783]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 11006892309164011783
+                },
+                "Component_[11722477296039848815]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 11722477296039848815,
+                    "Parent Entity": "Entity_[612129192327]"
+                },
+                "Component_[11894522099192018465]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 11894522099192018465
+                },
+                "Component_[15755572643227284312]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 15755572643227284312
+                },
+                "Component_[17731679325118981462]": {
+                    "$type": "EditorRigidBodyComponent",
+                    "Id": 17731679325118981462,
+                    "Configuration": {
+                        "entityId": "",
+                        "Gravity Enabled": false,
+                        "Compute Mass": false,
+                        "Mass": 20.0,
+                        "Centre of mass offset": [
+                            1.3929978059934456e-8,
+                            4.440697587426712e-9,
+                            0.09999998658895493
+                        ],
+                        "Inertia tensor": [
+                            3.5354714393615723,
+                            0.0,
+                            0.0,
+                            0.0,
+                            3.5354714393615723,
+                            0.0,
+                            0.0,
+                            0.0,
+                            6.237610340118408
+                        ]
+                    }
+                },
+                "Component_[17819075278864683550]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 17819075278864683550
+                },
+                "Component_[1878811958358686826]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 1878811958358686826
+                },
+                "Component_[2859476963594147091]": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 2859476963594147091,
+                    "Controller": {
+                        "Configuration": {
+                            "materials": [
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 411659043
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{2457475C-263F-5FA0-A412-C01BC49E33A9}"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                },
+                "Component_[4515199893762968493]": {
+                    "$type": "EditorHingeJointComponent",
+                    "Id": 4515199893762968493,
+                    "Configuration": {
+                        "Local Position": [
+                            0.0,
+                            -0.008406500332057476,
+                            0.0
+                        ],
+                        "Local Rotation": [
+                            90.0,
+                            0.0,
+                            90.0
+                        ],
+                        "Parent Entity": "Entity_[612129192327]",
+                        "Child Entity": "Entity_[646488930695]"
+                    }
+                },
+                "Component_[5793539545445890761]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 5793539545445890761
+                },
+                "Component_[5883085161775640887]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 5883085161775640887,
+                    "Child Entity Order": [
+                        "Entity_[650783897991]"
+                    ]
+                },
+                "Component_[6110211952808469616]": {
+                    "$type": "EditorColliderComponent",
+                    "Id": 6110211952808469616,
+                    "ColliderConfiguration": {
+                        "Position": [
+                            0.0,
+                            0.0,
+                            0.10000000149011612
+                        ],
+                        "MaterialSlots": {
+                            "Slots": [
+                                {
+                                    "Name": "Entire object"
+                                }
+                            ]
+                        }
+                    },
+                    "ShapeConfiguration": {
+                        "ShapeType": 3,
+                        "Cylinder": {
+                            "Configuration": {
+                                "CookedData": "TlhTAUNWWE0NAAAAAAAAAElDRQFDTEhMCQAAACAAAAAwAAAAEgAAAGAAAADlNT0/Rb+cPjMzsz7D0BA/w9AQPzMzsz5Dv5w+5zU9PzMzsz7yMBazzcxMPzMzsz5Hv5y+5TU9PzMzsz7D0BC/wtAQPzMzsz7nNT2/Q7+cPjMzsz7NzEy/8jCWszMzsz7lNT2/R7+cvjMzsz7C0BC/w9AQvzMzsz5Bv5y+5zU9vzMzsz5rSeEzzcxMvzMzsz5Iv5w+5TU9vzMzsz7E0BA/wdAQvzMzsz7nNT0/QL+cvjMzsz7NzEw/AAAAADMzsz7nNT2/Q7+cPpqZGb7NzEy/8jCWs5qZGb7D0BC/wtAQP5qZGb5Dv5w+5zU9P5qZGb7yMBazzcxMP5qZGb7D0BA/w9AQP5qZGb5Bv5y+5zU9v5qZGb5rSeEzzcxMv5qZGb7C0BC/w9AQv5qZGb5Iv5w+5TU9v5qZGb7E0BA/wdAQv5qZGb7nNT0/QL+cvpqZGb7NzEw/AAAAAJqZGb7lNT2/R7+cvpqZGb5Hv5y+5TU9P5qZGb7lNT0/Rb+cPpqZGb4AAAAAAAAAAAAAgD8xM7O+AAAQEMAUe7+txUc+AAAAAGbdSL8QAAQPLttUv9w5Dj8AAAAAZN1IvxQABA2uxUc+vxR7PwAAAABl3Ui/GAAECts5Dj8w21Q/AAAAAGbdSL8cAAQJrcVHvsAUe78AAAAAZt1IvyAABALbOQ6/MNtUvwAAAABm3Ui/JAAEAd05Dj8v21S/AAAAAGXdSL8oAAQFx8VHPr4Ue78AAAAAZt1IvywABAO/FHs/s8VHvgAAAABl3Ui/MAAEBjLbVD/aOQ6/AAAAAGbdSL80AAQFL9tUv9w5Dr8AAAAAZN1IvzgABAG+FHu/xsVHvgAAAABm3Ui/PAAEANw5Dr8v21Q/AAAAAGTdSL9AAAQMxMVHvr4Uez8AAAAAZt1Iv0QABAsy21Q/2DkOPwAAAABl3Ui/SAAECL4Uez/GxUc+AAAAAGXdSL9MAAQHAAAAAAAAAAAAAIC/mpkZvlAAEAAAAQIDBAUGBwgJCgsMDQ4PEBEHBhAGBRITFAMCEwIBFRYXCwoWCgkYGRoNDBkMCxcbHA8OGw4NGh0YCQgdCAcRHhIFBB4EAxQfFQEAHwAPHB8cGxoZFxYYHREQEh4UExUADwAEAAMADgANAAIAAQAMAAsABgAFAAgABwAKAAkAEAERAQwBAgINAhEDEQMOAwQEDwQRBREFCAUGBgsGEQcRBwoHCAgRCREJEAkKChELEQsMDBENEQ0ODhEPEQ8QEBEADxAABA8AAwQAAw4ADQ4AAg0AAQIAAQwACwwABgsABQYABQgABwgABwoACQoACRABAhEBDBECDREDBBEDDhEEDxEFBhEFCBEGCxEHCBEHChEJChEJEBELDBENDhEPEBEAAAAAzcxMv83MTL+amRm+zcxMP83MTD8zM7M+oct6PyteOz6OF72wVI+7sI4XvbArXjs+qirvr1SPu7CqKu+vuW+cPrFQbzLKlJgxy8zMPQAAgL/8/38+OXNFP1PNEz5TzRM+",
+                                "Type": 1
+                            },
+                            "Height": 0.5,
+                            "Radius": 0.800000011920929
+                        }
+                    }
+                },
+                "Component_[7054666824936675605]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 7054666824936675605
+                },
+                "Component_[8533584325989905880]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 8533584325989905880,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{F4F7B51F-6F35-5F16-BEFE-05B09F940765}",
+                                    "subId": 280610847
+                                },
+                                "assetHint": "prefabs/meshs/frist_axis.azmodel"
+                            }
+                        }
+                    }
+                }
+            }
+        },
+        "Entity_[650783897991]": {
+            "Id": "Entity_[650783897991]",
+            "Name": "first_arm_joint",
+            "Components": {
+                "Component_[11688363628545883540]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 11688363628545883540
+                },
+                "Component_[16896367397395997714]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 16896367397395997714
+                },
+                "Component_[17054476835086239712]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 17054476835086239712
+                },
+                "Component_[191426375985139181]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 191426375985139181
+                },
+                "Component_[2897015329131593759]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 2897015329131593759
+                },
+                "Component_[5455744605101540502]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 5455744605101540502
+                },
+                "Component_[648599470501636010]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 648599470501636010,
+                    "Parent Entity": "Entity_[646488930695]",
+                    "Transform Data": {
+                        "Translate": [
+                            0.0,
+                            0.002004384994506836,
+                            0.2507777214050293
+                        ]
+                    }
+                },
+                "Component_[658439284799658219]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 658439284799658219,
+                    "Child Entity Order": [
+                        "Entity_[599244290439]"
+                    ]
+                },
+                "Component_[9085452150473622490]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 9085452150473622490
+                }
+            }
+        },
+        "Entity_[655078865287]": {
+            "Id": "Entity_[655078865287]",
+            "Name": "wrist_joint",
+            "Components": {
+                "Component_[11484317717399371634]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 11484317717399371634
+                },
+                "Component_[11656094359109409585]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 11656094359109409585
+                },
+                "Component_[16234581348303117126]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 16234581348303117126,
+                    "Child Entity Order": [
+                        "Entity_[659373832583]"
+                    ]
+                },
+                "Component_[17584654619532131115]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 17584654619532131115
+                },
+                "Component_[18321866157180876197]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 18321866157180876197,
+                    "Parent Entity": "Entity_[577769453959]",
+                    "Transform Data": {
+                        "Translate": [
+                            0.0,
+                            -0.010531425476074219,
+                            -0.49530744552612305
+                        ]
+                    }
+                },
+                "Component_[2712425658040964588]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 2712425658040964588
+                },
+                "Component_[5480456398266916568]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 5480456398266916568
+                },
+                "Component_[7475490295669280553]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 7475490295669280553
+                },
+                "Component_[9657416080375605349]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 9657416080375605349
+                }
+            }
+        },
+        "Entity_[659373832583]": {
+            "Id": "Entity_[659373832583]",
+            "Name": "wrist",
+            "Components": {
+                "Component_[11484317717399371634]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 11484317717399371634
+                },
+                "Component_[11656094359109409585]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 11656094359109409585
+                },
+                "Component_[16234581348303117126]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 16234581348303117126,
+                    "Child Entity Order": [
+                        "Entity_[551999650183]",
+                        "Entity_[620719126919]"
+                    ]
+                },
+                "Component_[16403049392549641226]": {
+                    "$type": "EditorColliderComponent",
+                    "Id": 16403049392549641226,
+                    "ColliderConfiguration": {
+                        "MaterialSlots": {
+                            "Slots": [
+                                {
+                                    "Name": "Entire object"
+                                }
+                            ]
+                        }
+                    },
+                    "ShapeConfiguration": {
+                        "ShapeType": 1,
+                        "Box": {
+                            "Configuration": [
+                                0.5,
+                                0.5,
+                                0.25
+                            ]
+                        }
+                    }
+                },
+                "Component_[17154721294562464004]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 17154721294562464004,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{ACBDAA7D-3CE9-5CE8-87B1-15BA64F7162F}",
+                                    "subId": 278580330
+                                },
+                                "assetHint": "prefabs/meshs/wrist.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[17584654619532131115]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 17584654619532131115
+                },
+                "Component_[18321866157180876197]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 18321866157180876197,
+                    "Parent Entity": "Entity_[655078865287]"
+                },
+                "Component_[2684773951877420099]": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 2684773951877420099,
+                    "Controller": {
+                        "Configuration": {
+                            "materials": [
+                                {
+                                    "Key": {
+                                        "materialSlotStableId": 411659043
+                                    },
+                                    "Value": {
+                                        "MaterialAsset": {
+                                            "assetId": {
+                                                "guid": "{2457475C-263F-5FA0-A412-C01BC49E33A9}"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                },
+                "Component_[2712425658040964588]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 2712425658040964588
+                },
+                "Component_[347832631299823125]": {
+                    "$type": "EditorHingeJointComponent",
+                    "Id": 347832631299823125,
+                    "Configuration": {
+                        "Local Rotation": [
+                            90.0,
+                            0.0,
+                            90.0
+                        ],
+                        "Parent Entity": "Entity_[655078865287]",
+                        "Child Entity": "Entity_[659373832583]"
+                    },
+                    "Angular Limit": {
+                        "Positive Limit": 180.0,
+                        "Negative Limit": -180.0
+                    }
+                },
+                "Component_[5480456398266916568]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 5480456398266916568
+                },
+                "Component_[7475490295669280553]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 7475490295669280553
+                },
+                "Component_[7753569138971729063]": {
+                    "$type": "EditorRigidBodyComponent",
+                    "Id": 7753569138971729063,
+                    "Configuration": {
+                        "entityId": "",
+                        "Gravity Enabled": false,
+                        "Compute Mass": false,
+                        "Inertia tensor": [
+                            0.0260416679084301,
+                            0.0,
+                            0.0,
+                            0.0,
+                            0.0260416679084301,
+                            0.0,
+                            0.0,
+                            0.0,
+                            0.0416666679084301
+                        ]
+                    }
+                },
+                "Component_[9657416080375605349]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 9657416080375605349
+                }
+            }
+        }
+    }
+}

+ 18 - 0
Gems/O3DE/UrdfExporter/CMakeLists.txt

@@ -0,0 +1,18 @@
+
+# Query the gem name from the gem.json file if possible
+# otherwise fallback to using UrdfExporter
+o3de_find_ancestor_gem_root(gem_path gem_name "${CMAKE_CURRENT_SOURCE_DIR}")
+if (NOT gem_name)
+    set(gem_name "UrdfExporter")
+endif()
+
+# Fallback to using the current source CMakeLists.txt directory as the gem root path
+if (NOT gem_path)
+    set(gem_path ${CMAKE_CURRENT_SOURCE_DIR})
+endif()
+
+set(gem_json ${gem_path}/gem.json)
+
+o3de_restricted_path(${gem_json} o3de_gem_restricted_path)
+
+add_subdirectory(Code)

+ 100 - 0
Gems/O3DE/UrdfExporter/Code/CMakeLists.txt

@@ -0,0 +1,100 @@
+
+# Currently we are in the Code folder: ${CMAKE_CURRENT_LIST_DIR}
+# Get the platform specific folder ${pal_dir} for the current folder: ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}
+# Note: o3de_pal_dir will take care of the details for us, as this may be a restricted platform
+#       in which case it will see if that platform is present here or in the restricted folder.
+#       i.e. It could here in our gem : Gems/UrdfExporter/Code/Platform/<platorm_name>  or
+#            <restricted_folder>/<platform_name>/Gems/UrdfExporter/Code
+o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} "${gem_restricted_path}" "${gem_path}" "${gem_parent_relative_path}")
+
+# Now that we have the platform abstraction layer (PAL) folder for this folder, thats where we will find the
+# traits for this platform. Traits for a platform are defines for things like whether or not something in this gem
+# is supported by this platform.
+include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
+
+# Check to see if building the Gem Modules are supported for the current platform
+if(NOT PAL_TRAIT_URDFEXPORTER_SUPPORTED)
+    return()
+endif()
+
+# If we are on a host platform, we want to add the host tools targets like the ${gem_name}.Editor target which
+# will also depend on ${gem_name}.Editor.API target
+if(PAL_TRAIT_BUILD_HOST_TOOLS)
+     # The ${gem_name}.Editor.API target can be used by other gems that want to interact with the ${gem_name}.Editor module
+    ly_add_target(
+        NAME ${gem_name}.Editor.API INTERFACE
+        NAMESPACE Gem
+        FILES_CMAKE
+            urdfexporter_editor_api_files.cmake
+            ${pal_dir}/urdfexporter_editor_api_files.cmake
+        INCLUDE_DIRECTORIES
+            INTERFACE
+                Include
+        BUILD_DEPENDENCIES
+            INTERFACE
+                AZ::AzToolsFramework
+    )
+
+    # The ${gem_name}.Editor.Private.Object target is an internal target
+    # which is only to be used by this gems CMakeLists.txt and any subdirectories
+    # Other gems should not use this target
+    ly_add_target(
+        NAME ${gem_name}.Editor.Private.Object STATIC
+        NAMESPACE Gem
+        AUTORCC
+        FILES_CMAKE
+            urdfexporter_editor_private_files.cmake
+        TARGET_PROPERTIES
+            O3DE_PRIVATE_TARGET TRUE
+        INCLUDE_DIRECTORIES
+            PRIVATE
+                Include
+                Source
+        BUILD_DEPENDENCIES
+            PUBLIC
+                AZ::AzToolsFramework
+    )
+
+    ly_add_target(
+        NAME ${gem_name}.Editor GEM_MODULE
+        NAMESPACE Gem
+        AUTOMOC
+        FILES_CMAKE
+            urdfexporter_editor_shared_files.cmake
+        INCLUDE_DIRECTORIES
+            PRIVATE
+                Source
+            PUBLIC
+                Include
+        BUILD_DEPENDENCIES
+            PUBLIC
+                Gem::${gem_name}.Editor.API
+            PRIVATE
+                Gem::${gem_name}.Editor.Private.Object
+        RUNTIME_DEPENDENCIES
+            Gem::QtForPython.Editor
+    )
+
+    # By default, we will specify that the above target ${gem_name} would be used by
+    # Tool and Builder type targets when this gem is enabled.  If you don't want it
+    # active in Tools or Builders by default, delete one of both of the following lines:
+    ly_create_alias(NAME ${gem_name}.Tools    NAMESPACE Gem TARGETS Gem::${gem_name}.Editor)
+    ly_create_alias(NAME ${gem_name}.Builders NAMESPACE Gem TARGETS Gem::${gem_name}.Editor)
+
+    # For the Tools and Builders variants of ${gem_name} Gem, an alias to the ${gem_name}.Editor API target will be made
+    ly_create_alias(NAME ${gem_name}.Tools.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
+    ly_create_alias(NAME ${gem_name}.Builders.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
+
+endif()
+
+################################################################################
+# Tests
+################################################################################
+# See if globally, tests are supported
+if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
+    # We globally support tests, see if we support tests on this platform for ${gem_name}.Editor.Tests
+
+    # If we are a host platform we want to add tools test like editor tests here
+    if(PAL_TRAIT_BUILD_HOST_TOOLS)
+    endif()
+endif()

+ 31 - 0
Gems/O3DE/UrdfExporter/Code/Include/UrdfExporter/UrdfExporterBus.h

@@ -0,0 +1,31 @@
+
+#pragma once
+
+#include <AzCore/EBus/EBus.h>
+#include <AzCore/Interface/Interface.h>
+
+namespace UrdfExporter
+{
+    class UrdfExporterRequests
+    {
+    public:
+        AZ_RTTI(UrdfExporterRequests, "{6268B4A9-6A4E-49AE-9AA7-69DF622CE4E9}");
+        virtual ~UrdfExporterRequests() = default;
+        // Put your public methods here
+    };
+    
+    class UrdfExporterBusTraits
+        : public AZ::EBusTraits
+    {
+    public:
+        //////////////////////////////////////////////////////////////////////////
+        // EBusTraits overrides
+        static constexpr AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
+        static constexpr AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
+        //////////////////////////////////////////////////////////////////////////
+    };
+
+    using UrdfExporterRequestBus = AZ::EBus<UrdfExporterRequests, UrdfExporterBusTraits>;
+    using UrdfExporterInterface = AZ::Interface<UrdfExporterRequests>;
+
+} // namespace UrdfExporter

+ 4 - 0
Gems/O3DE/UrdfExporter/Code/Platform/Linux/PAL_linux.cmake

@@ -0,0 +1,4 @@
+
+set(PAL_TRAIT_URDFEXPORTER_SUPPORTED TRUE)
+set(PAL_TRAIT_URDFEXPORTER_TEST_SUPPORTED FALSE)
+set(PAL_TRAIT_URDFEXPORTER_EDITOR_TEST_SUPPORTED FALSE)

+ 3 - 0
Gems/O3DE/UrdfExporter/Code/Platform/Linux/urdfexporter_editor_api_files.cmake

@@ -0,0 +1,3 @@
+
+set(FILES
+)

+ 8 - 0
Gems/O3DE/UrdfExporter/Code/Platform/Linux/urdfexporter_editor_private_files.cmake

@@ -0,0 +1,8 @@
+
+# Platform specific files for Linux
+# i.e. ../Source/Linux/UrdfExporterLinux.cpp
+#      ../Source/Linux/UrdfExporterLinux.h
+#      ../Include/Linux/UrdfExporterLinux.h
+
+set(FILES
+)

+ 8 - 0
Gems/O3DE/UrdfExporter/Code/Platform/Linux/urdfexporter_editor_shared_files.cmake

@@ -0,0 +1,8 @@
+
+# Platform specific files for Linux
+# i.e. ../Source/Linux/UrdfExporterLinux.cpp
+#      ../Source/Linux/UrdfExporterLinux.h
+#      ../Include/Linux/UrdfExporterLinux.h
+
+set(FILES
+)

+ 4 - 0
Gems/O3DE/UrdfExporter/Code/Platform/Mac/PAL_mac.cmake

@@ -0,0 +1,4 @@
+
+set(PAL_TRAIT_URDFEXPORTER_SUPPORTED TRUE)
+set(PAL_TRAIT_URDFEXPORTER_TEST_SUPPORTED FALSE)
+set(PAL_TRAIT_URDFEXPORTER_EDITOR_TEST_SUPPORTED FALSE)

+ 3 - 0
Gems/O3DE/UrdfExporter/Code/Platform/Mac/urdfexporter_editor_api_files.cmake

@@ -0,0 +1,3 @@
+
+set(FILES
+)

+ 8 - 0
Gems/O3DE/UrdfExporter/Code/Platform/Mac/urdfexporter_editor_private_files.cmake

@@ -0,0 +1,8 @@
+
+# Platform specific files for Mac
+# i.e. ../Source/Mac/UrdfExporterMac.cpp
+#      ../Source/Mac/UrdfExporterMac.h
+#      ../Include/Mac/UrdfExporterMac.h
+
+set(FILES
+)

+ 8 - 0
Gems/O3DE/UrdfExporter/Code/Platform/Mac/urdfexporter_editor_shared_files.cmake

@@ -0,0 +1,8 @@
+
+# Platform specific files for Mac
+# i.e. ../Source/Mac/UrdfExporterMac.cpp
+#      ../Source/Mac/UrdfExporterMac.h
+#      ../Include/Mac/UrdfExporterMac.h
+
+set(FILES
+)

+ 4 - 0
Gems/O3DE/UrdfExporter/Code/Platform/Windows/PAL_windows.cmake

@@ -0,0 +1,4 @@
+
+set(PAL_TRAIT_URDFEXPORTER_SUPPORTED TRUE)
+set(PAL_TRAIT_URDFEXPORTER_TEST_SUPPORTED FALSE)
+set(PAL_TRAIT_URDFEXPORTER_EDITOR_TEST_SUPPORTED FALSE)

+ 3 - 0
Gems/O3DE/UrdfExporter/Code/Platform/Windows/urdfexporter_editor_api_files.cmake

@@ -0,0 +1,3 @@
+
+set(FILES
+)

+ 8 - 0
Gems/O3DE/UrdfExporter/Code/Platform/Windows/urdfexporter_editor_private_files.cmake

@@ -0,0 +1,8 @@
+
+# Platform specific files for Windows
+# i.e. ../Source/Windows/UrdfExporterWindows.cpp
+#      ../Source/Windows/UrdfExporterWindows.h
+#      ../Include/Windows/UrdfExporterWindows.h
+
+set(FILES
+)

+ 8 - 0
Gems/O3DE/UrdfExporter/Code/Platform/Windows/urdfexporter_editor_shared_files.cmake

@@ -0,0 +1,8 @@
+
+# Platform specific files for Windows
+# i.e. ../Source/Windows/UrdfExporterWindows.cpp
+#      ../Source/Windows/UrdfExporterWindows.h
+#      ../Include/Windows/UrdfExporterWindows.h
+
+set(FILES
+)

+ 5 - 0
Gems/O3DE/UrdfExporter/Code/Source/Tools/UrdfExporter.qrc

@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+    <qresource prefix="/UrdfExporter">
+        <file alias="toolbar_icon.svg">toolbar_icon.svg</file>
+    </qresource>
+</RCC>

+ 50 - 0
Gems/O3DE/UrdfExporter/Code/Source/Tools/UrdfExporterEditorModule.cpp

@@ -0,0 +1,50 @@
+
+#include <UrdfExporterModuleInterface.h>
+#include "UrdfExporterEditorSystemComponent.h"
+#include <AzToolsFramework/API/PythonLoader.h>
+
+#include <QtGlobal>
+
+void InitUrdfExporterResources()
+{
+    // We must register our Qt resources (.qrc file) since this is being loaded from a separate module (gem)
+    Q_INIT_RESOURCE(UrdfExporter);
+}
+
+namespace UrdfExporter
+{
+    class UrdfExporterEditorModule
+        : public UrdfExporterModuleInterface
+        , public AzToolsFramework::EmbeddedPython::PythonLoader
+    {
+    public:
+        AZ_RTTI(UrdfExporterEditorModule, "{0C23F845-1369-42FC-95EE-5079CFC1E133}", UrdfExporterModuleInterface);
+        AZ_CLASS_ALLOCATOR(UrdfExporterEditorModule, AZ::SystemAllocator, 0);
+
+        UrdfExporterEditorModule()
+        {
+            InitUrdfExporterResources();
+
+            // Push results of [MyComponent]::CreateDescriptor() into m_descriptors here.
+            // Add ALL components descriptors associated with this gem to m_descriptors.
+            // This will associate the AzTypeInfo information for the components with the the SerializeContext, BehaviorContext and EditContext.
+            // This happens through the [MyComponent]::Reflect() function.
+            m_descriptors.insert(m_descriptors.end(), {
+                UrdfExporterEditorSystemComponent::CreateDescriptor(),
+            });
+        }
+
+        /**
+         * Add required SystemComponents to the SystemEntity.
+         * Non-SystemComponents should not be added here
+         */
+        AZ::ComponentTypeList GetRequiredSystemComponents() const override
+        {
+            return AZ::ComponentTypeList {
+                azrtti_typeid<UrdfExporterEditorSystemComponent>(),
+            };
+        }
+    };
+}// namespace UrdfExporter
+
+AZ_DECLARE_MODULE_CLASS(Gem_UrdfExporter, UrdfExporter::UrdfExporterEditorModule)

+ 59 - 0
Gems/O3DE/UrdfExporter/Code/Source/Tools/UrdfExporterEditorSystemComponent.cpp

@@ -0,0 +1,59 @@
+
+#include <AzCore/Serialization/SerializeContext.h>
+#include "UrdfExporterEditorSystemComponent.h"
+
+namespace UrdfExporter
+{
+    void UrdfExporterEditorSystemComponent::Reflect(AZ::ReflectContext* context)
+    {
+        if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
+        {
+            serializeContext->Class<UrdfExporterEditorSystemComponent, AZ::Component>();
+        }
+    }
+
+    UrdfExporterEditorSystemComponent::UrdfExporterEditorSystemComponent()
+    {
+        if (UrdfExporterInterface::Get() == nullptr)
+        {
+            UrdfExporterInterface::Register(this);
+        }
+    }
+
+    UrdfExporterEditorSystemComponent::~UrdfExporterEditorSystemComponent()
+    {
+        if (UrdfExporterInterface::Get() == this)
+        {
+            UrdfExporterInterface::Unregister(this);
+        }
+    }
+
+    void UrdfExporterEditorSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
+    {
+        provided.push_back(AZ_CRC_CE("UrdfExporterEditorService"));
+    }
+
+    void UrdfExporterEditorSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
+    {
+        incompatible.push_back(AZ_CRC_CE("UrdfExporterEditorService"));
+    }
+
+    void UrdfExporterEditorSystemComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required)
+    {
+    }
+
+    void UrdfExporterEditorSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
+    {
+    }
+
+    void UrdfExporterEditorSystemComponent::Activate()
+    {
+        UrdfExporterRequestBus::Handler::BusConnect();
+    }
+
+    void UrdfExporterEditorSystemComponent::Deactivate()
+    {
+        UrdfExporterRequestBus::Handler::BusDisconnect();
+    }
+
+} // namespace UrdfExporter

+ 31 - 0
Gems/O3DE/UrdfExporter/Code/Source/Tools/UrdfExporterEditorSystemComponent.h

@@ -0,0 +1,31 @@
+
+#pragma once
+#include <AzCore/Component/Component.h>
+#include <UrdfExporter/UrdfExporterBus.h>
+
+
+namespace UrdfExporter
+{
+    /// System component for UrdfExporter editor
+    class UrdfExporterEditorSystemComponent
+        : public UrdfExporterRequestBus::Handler
+        , public AZ::Component
+    {
+    public:
+        AZ_COMPONENT(UrdfExporterEditorSystemComponent, "{7F4B1D9D-2346-4836-A197-837860FCC9D0}");
+        static void Reflect(AZ::ReflectContext* context);
+
+        UrdfExporterEditorSystemComponent();
+        ~UrdfExporterEditorSystemComponent();
+
+    private:
+        static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
+        static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
+        static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
+        static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
+
+        // AZ::Component
+        void Activate();
+        void Deactivate();
+    };
+} // namespace UrdfExporter

+ 1 - 0
Gems/O3DE/UrdfExporter/Code/Source/Tools/toolbar_icon.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#FFFFFF"><g><rect fill="none" height="24" width="24"/><path d="M19,3H5C3.89,3,3,3.9,3,5v14c0,1.1,0.89,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.11,3,19,3z M19,19H5V7h14V19z M13.5,13 c0,0.83-0.67,1.5-1.5,1.5s-1.5-0.67-1.5-1.5c0-0.83,0.67-1.5,1.5-1.5S13.5,12.17,13.5,13z M12,9c-2.73,0-5.06,1.66-6,4 c0.94,2.34,3.27,4,6,4s5.06-1.66,6-4C17.06,10.66,14.73,9,12,9z M12,15.5c-1.38,0-2.5-1.12-2.5-2.5c0-1.38,1.12-2.5,2.5-2.5 c1.38,0,2.5,1.12,2.5,2.5C14.5,14.38,13.38,15.5,12,15.5z"/></g></svg>

+ 27 - 0
Gems/O3DE/UrdfExporter/Code/Source/UrdfExporterModuleInterface.h

@@ -0,0 +1,27 @@
+
+#include <AzCore/Memory/SystemAllocator.h>
+#include <AzCore/Module/Module.h>
+
+namespace UrdfExporter
+{
+    class UrdfExporterModuleInterface
+        : public AZ::Module
+    {
+    public:
+        AZ_RTTI(UrdfExporterModuleInterface, "{7E550FCD-AB54-4BB0-9B8F-77E1FF07D387}", AZ::Module);
+        AZ_CLASS_ALLOCATOR(UrdfExporterModuleInterface, AZ::SystemAllocator, 0);
+
+        UrdfExporterModuleInterface()
+        {
+        }
+
+        /**
+         * Add required SystemComponents to the SystemEntity.
+         */
+        AZ::ComponentTypeList GetRequiredSystemComponents() const override
+        {
+            return AZ::ComponentTypeList{
+            };
+        }
+    };
+}// namespace UrdfExporter

+ 4 - 0
Gems/O3DE/UrdfExporter/Code/Tests/Tools/UrdfExporterEditorTest.cpp

@@ -0,0 +1,4 @@
+
+#include <AzTest/AzTest.h>
+
+AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV);

+ 5 - 0
Gems/O3DE/UrdfExporter/Code/urdfexporter_editor_api_files.cmake

@@ -0,0 +1,5 @@
+
+
+set(FILES
+    Include/UrdfExporter/UrdfExporterBus.h
+)

+ 7 - 0
Gems/O3DE/UrdfExporter/Code/urdfexporter_editor_private_files.cmake

@@ -0,0 +1,7 @@
+
+set(FILES
+    Source/UrdfExporterModuleInterface.h
+    Source/Tools/UrdfExporterEditorSystemComponent.cpp
+    Source/Tools/UrdfExporterEditorSystemComponent.h
+    Source/Tools/UrdfExporter.qrc
+)

+ 4 - 0
Gems/O3DE/UrdfExporter/Code/urdfexporter_editor_shared_files.cmake

@@ -0,0 +1,4 @@
+
+set(FILES
+    Source/Tools/UrdfExporterEditorModule.cpp
+)

+ 4 - 0
Gems/O3DE/UrdfExporter/Code/urdfexporter_editor_tests_files.cmake

@@ -0,0 +1,4 @@
+
+set(FILES
+    Tests/Tools/UrdfExporterEditorTest.cpp
+)

+ 9 - 0
Gems/O3DE/UrdfExporter/Editor/Scripts/__init__.py

@@ -0,0 +1,9 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+# -------------------------------------------------------------------------
+
+__ALL__ = ['bootstrap','urdfexporter_dialog']

+ 22 - 0
Gems/O3DE/UrdfExporter/Editor/Scripts/bootstrap.py

@@ -0,0 +1,22 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+# -------------------------------------------------------------------------
+"""UrdfExporter\\editor\\scripts\\bootstrap.py
+Generated from O3DE PythonToolGem Template"""
+
+import az_qt_helpers
+import azlmbr.editor as editor
+from urdfexporter_dialog import UrdfExporterDialog
+
+if __name__ == "__main__":
+    print("UrdfExporter.boostrap, Generated from O3DE PythonToolGem Template")
+
+    # Register our custom widget as a dockable tool with the Editor under an Examples sub-menu
+    options = editor.ViewPaneOptions()
+    options.showOnToolsToolbar = True
+    options.toolbarIcon = ":/UrdfExporter/toolbar_icon.svg"
+    az_qt_helpers.register_view_pane('UrdfExporter', UrdfExporterDialog, category="Examples", options=options)

+ 28 - 0
Gems/O3DE/UrdfExporter/Editor/Scripts/constants.py

@@ -0,0 +1,28 @@
+# coding:utf-8
+#!/usr/bin/python
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+# -------------------------------------------------------------------------
+from pathlib import Path
+# -------------------------------------------------------------------------
+
+USER_HOME = Path.home()
+WIKI_URL = 'README.md'
+PLUGIN_VERSION = '1.0'
+
+ROBOT_BASE_LINK_NODE = 'base_link'
+URDF_DESCRIPTION_SUB_FOLDER_LIST = ['urdf', 'meshes', 'launch', 'rviz', 'images', 'worlds']
+URDF_COLLISION_SHAPE_LIST = ['sphere', 'box', 'capsule', 'cylinder'] 
+URDF_RVIS_DEFUALT = 'rviz/urdf.rviz'
+# capsule is not supported in URDF but is in PhysX
+URDF_COLLISION_SHAPE_PATH = {0: {'shape': 'sphere', 'radius': 'Shape Configuration|Sphere|Radius'},
+                            1: {'shape': 'box', 'size': 'Shape Configuration|Box|Dimensions'},
+                            2: {'shape': 'capsule', 'radius': 'Shape Configuration|Capsule|Radius', 'length': 'Shape Configuration|Capsule|Height'},
+                            3: {'shape': 'cylinder', 'radius': 'Shape Configuration|Cylinder|Radius', 'length': 'Shape Configuration|Cylinder|Height'}
+                            }
+

+ 230 - 0
Gems/O3DE/UrdfExporter/Editor/Scripts/editor_tools.py

@@ -0,0 +1,230 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+
+-------------------------------------------------------------------------
+DEPRECATION NOTICE: Editor Entity & Editor Component utils are to be considered deprecated
+and will be replaced with the EditorPythonBindings libraries once they've relocated from
+AutomatedTesting into their own gem (o3de/sig-testing#67
+"""
+# -------------------------------------------------------------------------
+
+
+import azlmbr
+import azlmbr.bus as bus
+import azlmbr.entity as entity
+import azlmbr.legacy.general as general
+import azlmbr.editor as editor
+import azlmbr.math as math
+import azlmbr.asset as asset
+import azlmbr.paths as projectPath
+
+
+def get_property_list(component_id: object) -> str:
+    """
+    This function will get the component property list, this is used to print a list for development
+
+    :param component_id: This is the Entity Component Object ID
+    :returns value: value of property list for component
+    """
+    # Print the property list of a component
+    property_list = editor.EditorComponentAPIBus(bus.Broadcast, 'BuildComponentPropertyList', component_id)
+    
+    return property_list
+
+def has_component(entity_id: object, type_id: object) -> bool:
+    """
+    This function will check to see if entity has a component from a component type id
+    
+    :param entity_id: This is the Entity Object ID
+    :param type_id: This is component type id
+    :return: true if the entity has component(s)
+    """
+    component_bool = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', entity_id, type_id)
+    
+    return component_bool
+
+def add_component(entity_id: object, component_name: str):
+    """
+    This function will add a component.
+
+    :param entity_id:  The entity ID
+    :param component_name: The component name
+    """
+    type_id = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', [component_name], 0)
+    component_type_id = type_id[0]
+    editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', entity_id, [component_type_id])
+
+def get_property(component_id: object, property_path: str) -> str:
+    """
+    This function will get the component property value
+
+    :param component_id : This is the Entity Component Object ID
+    :param property_path: This is the Component Property Path you wish to get a value.
+    :return: value of property
+    """
+    # you can now get or set one of those properties by their strings, such as:
+    object_property = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentProperty', component_id, property_path)
+    
+    if(object_property.IsSuccess()):
+        value = object_property.GetValue()
+        
+        return value
+    else:
+        return None
+
+def set_property(component_id: object, property_path: str, value: any):
+    """
+    This function will set the component property
+
+    :param component_id : This is the Entity Component Object ID
+    :param property_path: This is the Component Property Path you wish to set a value.
+    :return: value of property
+    """
+    # you can now get or set one of those properties by their strings, such as:
+    property_set = editor.EditorComponentAPIBus(bus.Broadcast, 'SetComponentProperty', component_id, property_path, value)
+    assert property_set.IsSuccess(), f"Failure: Unable to set the property {property_path} on {component_id} to {value}"
+
+def get_entity_name(entity_id: object) -> str:
+    """
+    This function will get a name from and entity id.
+
+    :param entity_id : The entity component object id
+    :return: The name of entity
+    """
+    name = editor.EditorEntityInfoRequestBus(bus.Event, 'GetName', entity_id)
+    
+    return name
+
+def create_object_from_id(id_int: int) -> object:
+    """
+    This function will create an object from an id number
+
+    :param id_int : The id number to create the object with
+    :return: The created object
+    """
+    object_id = entity.EntityId(id_int)
+    
+    return object_id
+
+def get_parent(child_id: object) -> tuple[object, str]:
+    """
+    This function will return the parent's entity id and name from the given ID of the child
+
+    :param child_id : The child entity id to query for the parent
+    :return: tuple of the id and name of the parent
+    """
+    parent_id = editor.EditorEntityInfoRequestBus(bus.Event, 'GetParent', child_id)
+    parent_name = get_entity_name(parent_id)
+
+    return parent_id, parent_name
+
+def search_for_entity(entity_name: str) -> object:
+    """
+    This function will search for an entity
+
+    :param entity_name : Name string: search_filter.names = ['TestEntity']
+    :return: The resulting entity result
+    """
+    search_filter = azlmbr.entity.SearchFilter()
+    search_filter.names = [entity_name]
+    entity_object_id = azlmbr.entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
+    
+    return entity_object_id
+
+def convert_entity_object_to_id(entity_object_id: object) -> int:
+    """
+    This function will create an object to an id int
+
+    :param entity_object_id : <EntityComponentIdPair via PythonProxyObject at 2428988078368>
+    :return: The id integer
+    """
+    entity_id = entity_object_id[0]
+    
+    return entity_id
+
+def find_component_by_type_id(entity_id: int, component_name: str) -> any:
+    """
+    This function will find a component by type_id
+
+    :param entity_id: The entity id
+    :param component_name: The component name
+    :return: The resulting component
+    """
+    GAME = azlmbr.entity.EntityType().Game
+    type_ids = editor.EditorComponentAPIBus(bus.Broadcast, "FindComponentTypeIdsByEntityType", component_name, GAME)
+    component_type_id = type_ids[0]
+    component_outcome = editor.EditorComponentAPIBus(bus.Broadcast, "GetComponentOfType", entity_id, component_type_id)
+    component_object_value = component_outcome.GetValue()
+    
+    return component_object_value
+
+def get_value_from_property_path(component_object_id: object, property_path: str) -> int:
+    """
+    This function will get a component value from a property path
+
+    :param component_object_id : The component to look up
+    :param property_path: The property path to query
+    :return: The resulting value
+    """
+    entity_outcome = editor.EditorComponentAPIBus(bus.Broadcast, "GetComponentProperty", component_object_id, property_path)
+    entity_id = entity_outcome.GetValue()
+    
+    return entity_id
+
+def get_transforms_from_id(entity_id: object) -> tuple[object, object, object]:
+    """
+    This function will get a transforms from and entity id.
+
+    :param entity_id : The entity id to get the transforms for
+    :return: Translation Vector 3 (x,y,z), Entity Rotation Vector 3 (x,y,x), Entity Uniform Scale Vector 3 (x,y,x)
+    """
+    local_translation = azlmbr.components.TransformBus(azlmbr.bus.Event, 'GetLocalTranslation', entity_id)
+    local_rotation = azlmbr.components.TransformBus(azlmbr.bus.Event, 'GetLocalRotation', entity_id)
+    local_uniform_scale = azlmbr.components.TransformBus(azlmbr.bus.Event, 'GetLocalUniformScale', entity_id) # Maybe root we can get GetWorldUniformScale
+
+    return local_translation, local_rotation, local_uniform_scale
+
+def get_urdf_component_type_id(entity_id: object) -> tuple[object, object]:
+    """
+    This function will find a component types on a giving entity.
+    Then build a list of a component type name and type id and return these two list.
+
+    :param entity_id : The entity id
+    :return: tuple of the [List of Components Name(s) Type String, List of component ID(s) on an Entity]
+    """
+    components_on_entity = []
+    components_on_entity_id = []
+    # Component_type_to_urdf_element_type
+    component_types_to_urdf_types = {
+        "Mesh":"mesh",
+        "Material":"material",
+        "PhysX Collider":"collision",
+        "PhysX Rigid Body":"rigid_body",
+        "PhysX Ball Joint":"continuous",
+        "PhysX Hinge Joint":"revolute",
+        "PhysX Fixed Joint":"fixed",
+        "PhysX Prismatic Joint":"prismatic"
+    }
+    # Get Component Types Dict Keys
+    component_types = list(component_types_to_urdf_types.keys())
+    # Find Component Type IDs By Entity Type
+    component_type_ids = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', component_types, 0)
+    if not component_type_ids == None:
+        count = 0
+        for type_id in component_type_ids:
+            # If entity has component
+            if editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', entity_id, type_id):
+                # Look the type in this count
+                component_type = component_types[count]
+                # Get the urdf_type string name
+                urdf_type = component_types_to_urdf_types[component_type]
+                # Lets add this to the lists
+                if urdf_type:
+                    components_on_entity.append(urdf_type)
+                    components_on_entity_id.append(type_id)
+            count += 1
+
+    return components_on_entity, components_on_entity_id

+ 726 - 0
Gems/O3DE/UrdfExporter/Editor/Scripts/export.py

@@ -0,0 +1,726 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+# -------------------------------------------------------------------------
+import azlmbr
+import azlmbr.bus as bus
+import azlmbr.entity as entity
+import azlmbr.legacy.general as general
+import azlmbr.editor as editor
+import azlmbr.render as render
+import azlmbr.math as math
+import azlmbr.asset as asset
+import azlmbr.paths as projectPath
+
+import xml.etree.cElementTree as xml_et
+from pathlib import Path
+import utilities as py_utilities
+import editor_tools as editor_tools
+import constants as const
+import os
+import subprocess
+import logging
+
+
+logger = logging.getLogger(__name__)
+_PROCESS_OUTPUT_ENCODING = 'utf-8'
+
+def search_tree(root: object, xml_obj: object, urdf_mesh_path: Path, robot_name: str):
+    """
+    This function will search the tree from the root base_link Entity ID found by search
+
+    :param root: Entity Object ID
+    :param xml_obj: XML Object
+    :param urdf_mesh_path: The Path to URDF Meshes Folder
+    :param robot_name: Robot Description Name
+    """
+    # base_link Name_link_obj
+    name = editor_tools.get_entity_name(root)
+    
+    # Check if this node name is base_link
+    if name == "base_link":
+        add_elements(root, xml_obj, urdf_mesh_path, robot_name)
+    
+    # Go down the tree chain
+    model_tree = editor.EditorEntityInfoRequestBus(bus.Event, 'GetChildren', root)
+    
+    # Loop the tree and find the childern
+    for child_id in model_tree:
+        add_elements(child_id, xml_obj, urdf_mesh_path, robot_name)
+        
+        # Get the child ID if this entity has one
+        entity_child_id = editor.EditorEntityInfoRequestBus(bus.Event, "GetChildren", child_id)
+        
+        # Get the name of the entity   
+        name = editor_tools.get_entity_name(root)
+        
+        # Search through children of children.
+        for sub_child_id in entity_child_id:
+            name = editor_tools.get_entity_name(root)
+            add_elements(sub_child_id, xml_obj, urdf_mesh_path, robot_name)
+            # Search tree for subchildern
+            search_tree(sub_child_id, xml_obj, urdf_mesh_path, robot_name)
+
+def add_elements(entity_id: object, xml_obj: object, urdf_mesh_path: Path, robot_name: str):
+    """
+    This function will add the XML elements from the search loop
+
+    :param entity_id: Entity Object ID
+    :param xml_obj: XML Object
+    :param urdf_mesh_path: The Path to URDF Meshes Folder
+    :param robot_name: Robot Description Name
+    """
+    joint_type = ""
+    lead_name = ""
+    lead_entity_object_id = None
+    neg_limit_value = 0
+    pos_limit_value = 0
+    joint_origin_xyz = 0
+    joint_origin_rpy = 0
+    
+    # search through childern of root, find the entity names and ids
+    child_name = editor_tools.get_entity_name(entity_id)
+    
+    # XML- this is the XML SubElement Object
+    xml_child_obj = xml_et.SubElement(xml_obj, "link", name=child_name)
+    
+    # We need to add this for the root base link
+    if child_name == "base_link":
+        # This function will return Origin Rotation and Transform
+        local_translation, local_rotation, local_uniform_scale  = editor_tools.get_transforms_from_id(entity_id)
+        xml_et.SubElement(xml_child_obj, "origin", rpy=f"{float(local_rotation.x)} {float(local_rotation.y)} {float(local_rotation.z)}",
+                            xyz=f"{float(local_translation.x)} {float(local_translation.y)} {float(local_translation.z)}")
+    
+    # This function will return the component type names and their ids that a detected
+    component_type_name, component_type_id = editor_tools.get_urdf_component_type_id(entity_id)
+    
+    # If not empty
+    if len(component_type_name) > 0:
+        joint_origin_xyz, joint_origin_rpy, lead_entity_object_id, joint_type, axis, pos_limit_value, neg_limit_value = look_up_component_type(component_type_name, entity_id, 
+                                                                        component_type_id, urdf_mesh_path, xml_child_obj, robot_name)
+    else:
+        print("No components")
+        if not child_name == "base_link":
+            # This function will return Origin Rotation and Transform
+            local_translation, local_rotation, local_uniform_scale  = editor_tools.get_transforms_from_id(entity_id)
+            xml_et.SubElement(xml_child_obj, "origin", rpy=f"{float(local_rotation.x)} {float(local_rotation.y)} {float(local_rotation.z)}",
+                                xyz=f"{float(local_translation.x)} {float(local_translation.y)} {float(local_translation.z)}")
+            # For Gazebo
+            # Create XML for Inertial
+            inertial = xml_et.SubElement(xml_child_obj, "inertial")
+            xml_et.SubElement(inertial, "mass", value="0.1")
+            xml_et.SubElement(inertial, "inertia", ixx="0.0", ixy="0.0",ixz="0.0", iyy="0.0", iyz="0.0", izz="0.0")
+           
+    # Get the parent ID of this entity ID
+    parent_id, parent_name = editor_tools.get_parent(entity_id)
+    
+    # Get the lead enitity name
+    if lead_entity_object_id is None:
+        lead_name = editor_tools.get_entity_name(lead_entity_object_id)
+    else:
+        lead_name = parent_name
+    
+    # write joint xml child
+    if not child_name == "base_link": # Untill figure out
+        if joint_type == "":
+            local_translation, local_rotation, local_uniform_scale  = editor_tools.get_transforms_from_id(entity_id)
+            joint_link_obj = xml_et.SubElement(xml_obj, "joint", name=f"{child_name}_to_{parent_name}", type="fixed")
+            xml_et.SubElement(joint_link_obj, "origin", xyz=f"{float(local_translation.x)} {float(local_translation.y)} {float(local_translation.z)}", rpy="0 0 0")
+            xml_et.SubElement(joint_link_obj, "parent", link=f"{parent_name}")
+            xml_et.SubElement(joint_link_obj, "child", link=f"{child_name}")
+            xml_et.SubElement(joint_link_obj, "axis", xyz="0.0 0.0 1.0") # Defaults for now WIP
+        else:
+            try:
+                axis = py_utilities.euler_yzx_to_axis_angle(joint_origin_rpy.x, joint_origin_rpy.y, joint_origin_rpy.z)
+            except AttributeError:
+                axis = py_utilities.euler_yzx_to_axis_angle(0,0,0)
+
+            joint_link_obj = xml_et.SubElement(xml_obj, "joint", name=f"{child_name}_to_{lead_name}", type=f"{joint_type}")
+            try:
+                xml_et.SubElement(joint_link_obj, "origin", xyz=f"{float(joint_origin_xyz.x)} {float(joint_origin_xyz.y)} {float(joint_origin_xyz.z)}", rpy="0 0 0")
+            except AttributeError:
+                xml_et.SubElement(joint_link_obj, "origin", xyz="0 0 0", rpy="0 0 0")
+
+            xml_et.SubElement(joint_link_obj, "parent", link=f"{lead_name}")
+            xml_et.SubElement(joint_link_obj, "child", link=f"{child_name}")
+            
+            # This will be default for now untill we can get an XYZ Euler Rotation conversion to a Axis Rotation Angle
+            xml_et.SubElement(joint_link_obj, "axis", xyz=f"{float(axis[0])} {float(axis[1])} {float(axis[2])}")
+            
+            # Chech for joint types
+            if joint_type == "revolute":
+                xml_et.SubElement(joint_link_obj, "dynamics", damping="2.0", friction="1.0") # Defaults for now WIP
+                xml_et.SubElement(joint_link_obj, "limit", effort="1000.0", lower=f"{neg_limit_value}", upper=f"{pos_limit_value}", velocity="1.0")
+            if joint_type == "continuous":
+                xml_et.SubElement(joint_link_obj, "dynamics", damping="2.0", friction="1.0") # Defaults for now WIP
+                xml_et.SubElement(joint_link_obj, "limit", effort="1000.0", lower=f"{neg_limit_value}", upper=f"{pos_limit_value}", velocity="1.0")
+
+def look_up_component_type(component_type_name: str, root: object, component_type_id: object,
+                           urdf_mesh_path: Path, xml_obj: object,
+                           robot_name: str) -> tuple [object, object, str, str, object]:
+    """
+    This function will look at the component type name and if found run the components function to look up
+    property paths of the component and build the xml element with properties. 
+
+    :param component_type_name (String): This is a string describing the component type
+    :param root (Object): Entity Object ID
+    :param component_type_id: Component Type on Entity Object ID
+    :param xml_obj): XML Child Object
+
+    :return: origin_xyz: The joint is Local Position Origin,
+                origin_rpy: The joint is Local Rotation Origin,
+                lead_entity_value: The Lead Entity, most cases the Parent,
+                joint_type: Type of joint name,
+                axis: This is the axis of rotation for revolute joints,
+                        the axis of translation for prismatic joints,
+                        surface normal for planar joints. Fixed and floating
+                        joints do not use the axis field. 
+    """
+    joint_type = ""
+    origin_xyz = ""
+    origin_rpy = ""
+    lead_entity_object_id = None
+    axis = ""
+    pos_limit_value = ""
+    neg_limit_value = ""
+
+    if 'mesh' in component_type_name:
+        index = component_type_name.index('mesh')
+        if 'material' in component_type_name:
+            mat_index = component_type_name.index('mesh')
+            component_is_mesh(root, component_type_id[index], component_type_id[mat_index], urdf_mesh_path, xml_obj, robot_name)
+        else:
+            # Add material if its not added already.
+            editor_tools.add_component(root, 'Material')
+            mat_index = component_type_name.index('mesh')
+            component_is_mesh(root, component_type_id[index], component_type_id[mat_index], urdf_mesh_path, xml_obj, robot_name)
+            
+    # Check to see if there is a PhysX Collider
+    if 'collision' in component_type_name:
+        index = component_type_name.index('collision')
+        component_is_collision(root, component_type_id[index], xml_obj)
+    
+    # Check to see if there is a PhysX Collider, this is for Inertia
+    if 'rigid_body' in component_type_name:
+        index = component_type_name.index('rigid_body')
+        component_is_rigid_body(root, component_type_id[index], xml_obj)
+    
+    # Check to see if there is a PhysX Joints
+    if 'continuous' in component_type_name:
+        index = component_type_name.index('continuous')
+        origin_xyz, origin_rpy, lead_entity_object_id, axis, pos_limit_value, neg_limit_value = get_joint_details(root, component_type_id[index], 'continuous')
+        joint_type = 'continuous'
+    if 'revolute' in component_type_name:
+        index = component_type_name.index('revolute')
+        origin_xyz, origin_rpy, lead_entity_object_id, axis, pos_limit_value, neg_limit_value = get_joint_details(root, component_type_id[index], 'revolute')
+        joint_type = 'revolute'
+    if 'fixed' in component_type_name:
+        index = component_type_name.index('fixed')
+        origin_xyz, origin_rpy, lead_entity_object_id, axis, pos_limit_value, neg_limit_value = get_joint_details(root, component_type_id[index], 'fixed')
+        joint_type = 'fixed'
+    if 'prismatic' in component_type_name:
+        index = component_type_name.index('prismatic')
+        origin_xyz, origin_rpy, lead_entity_object_id, axis, pos_limit_value, neg_limit_value = get_joint_details(root, component_type_id[index], 'prismatic')
+        joint_type = 'prismatic'
+    return origin_xyz, origin_rpy, lead_entity_object_id, joint_type, axis, pos_limit_value, neg_limit_value
+
+def component_is_mesh(child_id: object, component_type_id: object,
+                      material_type_id: object, urdf_mesh_path: Path,
+                      xml_obj: Path, robot_name: str):
+    """
+    This function will look at your entity child_id and the attached component id, find the property path
+    and get the file path value and add this value to the package xml link, copy the mesh files to the package
+
+    :param child_id: Entity Object ID of Child of Parent Entity
+    :param component_type_id: Mesh Component on Entity Object ID
+    :param material_type_id: Mesh Material Component on Entity Object ID
+    :param xml_obj: XML Child Object
+    """
+    mesh_file_path = ""
+    # returns a list of mesh component IDs for a component type
+    mesh_multiple_component_outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentsOfType', child_id, component_type_id)
+    
+    # Check if this is a success
+    if (mesh_multiple_component_outcome.IsSuccess()):
+        first_mesh_component_id = mesh_multiple_component_outcome.GetValue()[0]
+    else:
+        first_mesh_component_id = None
+
+    if not first_mesh_component_id is None:
+        # Property path for Controller|Configuration|Mesh Asset
+        value_outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentProperty', first_mesh_component_id,
+                                                        'Controller|Configuration|Mesh Asset')
+        if not material_type_id == 'None':
+            # returns a list of material component IDs for a component type
+            material_multiple_component_outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentsOfType', child_id, material_type_id)
+        
+        # Get the Value from the valueOutcome
+        value = value_outcome.GetValue()
+        
+        # Get the asset path from the value
+        asset_path = asset.AssetCatalogRequestBus(bus.Broadcast, 'GetAssetPathById', value)
+        
+        # Lets replace the .azmodel with the .dae
+        file_path = asset_path.replace(".azmodel", ".dae")
+        
+        # LINUX ONLY Lets replace the lower case assets with Assets .azmodel with the .dae
+        if "assets" in file_path:
+            mesh_file_path = file_path.replace("assets", "Assets")
+        if "prefabs" in file_path:
+            mesh_file_path = file_path.replace("prefabs", "Prefabs")
+        
+        # Copy mesh to urdf mesh directory
+        source = Path(projectPath.projectroot, mesh_file_path)
+        
+        # Get the file name
+        file_name = Path(mesh_file_path).name
+        destination = Path(urdf_mesh_path, file_name)
+        
+        # This function will copy the files from o3de to the used selected path destination
+        py_utilities.copy_files_assets(source, destination)
+
+        # Create XML URDF Mesh Path, We man need to have a full path for use back into o3de and gazebo
+        portable = False
+        if portable:
+            to_directory_path = f'package://{robot_name}/{const.URDF_DESCRIPTION_SUB_FOLDER_LIST[1]}/{file_name}'
+        else:
+            full_path = str(Path(urdf_mesh_path, file_name))
+            to_directory_path = f'file://{full_path}'
+        
+        # This function will return Origin Rotation and Transform
+        local_translation, local_rotation, local_uniform_scale  = editor_tools.get_transforms_from_id(child_id)
+        
+        # Create XML for Visual and Geometry
+        visual = xml_et.SubElement(xml_obj, "visual")
+        geometry = xml_et.SubElement(visual, "geometry")
+        
+        # Create XML for Material if we find material component
+        if not material_type_id == 'None':
+            xml_et.SubElement(visual, "material", name="white")
+        
+        # Create XML for Mesh and Origin
+        xml_et.SubElement(geometry, "mesh", filename=to_directory_path,
+                            scale=f"{float(local_uniform_scale)} {float(local_uniform_scale)} {float(local_uniform_scale)}")
+        xml_et.SubElement(visual, "origin", rpy=f"{float(local_rotation.x)} {float(local_rotation.y)} {float(local_rotation.z)}",
+                            xyz=f"{float(local_translation.x)} {float(local_translation.y)} {float(local_translation.z)}")
+
+def get_joint_details(entity_id: object, component_type_id: object, joint_type: str) -> tuple[list[float,float,float],
+                        list[float,float,float], object, list[float,float,float], float, float]:
+    """
+    This function will look at your entity_id and the PhysX Ball Joint component id, find the
+    property paths of the component and build the xml element with properties.
+
+    :param entity_id: Entity Object ID of Child of Parent Entity
+    :param component_type_id: Mesh Component on Entity Object ID
+    :param xml_obj: XML Child Object
+    :param joint_type: What type of joint it is
+
+    :return:
+        local_position_value: The joint is Local Position Origin,
+        local_rotation_value: The joint is Local Rotation Origin,
+        lead_entity_value: The Lead Entity, most cases the Parent,
+        axis: This is the axis of rotation for revolute joints,
+                        the axis of translation for prismatic joints,
+                        surface normal for planar joints. Fixed and floating
+                        joints do not use the axis field.
+    """
+    # returns a list of joints, we will call inertial component IDs for a component type
+    joint_multiple_component_outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentsOfType', entity_id, component_type_id)
+    
+    # If we find the Joint Component
+    if (joint_multiple_component_outcome.IsSuccess()):
+        pos_limit_value = 0.0
+        neg_limit_value = 0.0
+        axis = 0.0
+        local_position_value = 0.0
+        local_rotation_value = 0.0
+        lead_object_id = ''
+
+        first_joint_component_id = joint_multiple_component_outcome.GetValue()[0]
+        
+        # Print the property list - This is for working dev of pluing to print out component get_property
+        editor_tools.get_property_list(first_joint_component_id)
+        
+        # origin
+        local_position_value = editor_tools.get_property(first_joint_component_id, 'Standard Joint Parameters|Local Position')
+        local_rotation_value = editor_tools.get_property(first_joint_component_id, 'Standard Joint Parameters|Local Rotation')
+        
+        # get the Lead Entity
+        lead_value = editor_tools.get_property(first_joint_component_id, 'Standard Joint Parameters|Lead Entity')
+        if not lead_value is None:
+            lead_object_id = editor_tools.get_value_from_property_path(first_joint_component_id, 'Standard Joint Parameters|Lead Entity')
+        else:
+            lead_object_id = None
+        
+        # Joint Specific
+        if joint_type == "revolute":
+            pos_limit_value = editor_tools.get_property(first_joint_component_id, 'Angular Limit|Positive angular limit')
+            neg_limit_value = editor_tools.get_property(first_joint_component_id, 'Angular Limit|Negative angular limit')
+        if joint_type == "continuous":
+            pos_limit_value = editor_tools.get_property(first_joint_component_id, 'Swing Limit|Y axis angular limit')
+            neg_limit_value = editor_tools.get_property(first_joint_component_id, 'Swing Limit|Z axis angular limit')
+
+        return local_position_value, local_rotation_value, lead_object_id, axis, pos_limit_value, neg_limit_value
+
+def component_is_rigid_body(entity_id: object, component_type_id: object, xml_obj: object):
+    """
+    This function will look at your entity_id and the PhysX Rigid Body component id, find the
+    property paths of the component and build the xml element with properties.
+
+    :param entity_id: Entity Object ID of Child of Parent Entity
+    :param component_type_id: Mesh Component on Entity Object ID
+    :param xml_obj: XML Child Object
+    """
+    # returns a list of rigid_body, we will call inertial component IDs for a component type
+    inertial_multiple_component_outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentsOfType', entity_id, component_type_id)
+    
+    # If we find the component
+    if (inertial_multiple_component_outcome.IsSuccess()):
+        first_inertial_component_id = inertial_multiple_component_outcome.GetValue()[0]
+        
+        # Print the property list
+        editor_tools.get_property_list(first_inertial_component_id)
+        
+        # Get the Mass property
+        mass_value = editor_tools.get_property(first_inertial_component_id, 'Configuration|Mass')
+        
+        # Get the Inertia property
+        inertia_linear_value = editor_tools.get_property(first_inertial_component_id, 'Configuration|Initial linear velocity')
+        inertia_angular_value = editor_tools.get_property(first_inertial_component_id, 'Configuration|Initial angular velocity')
+        
+        # Create XML for Inertial
+        inertial = xml_et.SubElement(xml_obj, "inertial")
+        
+        # Create XML for Mass and Inertia
+        try:
+            xml_et.SubElement(inertial, "mass", value=f"{float(mass_value)}")
+        except TypeError:
+            xml_et.SubElement(inertial, "mass", value="1.0")
+
+        try:
+            xml_et.SubElement(inertial, "inertia", ixx=f"{float(inertia_linear_value.x)}", ixy=f"{float(inertia_linear_value.y)}",
+                            ixz=f"{float(inertia_linear_value.z)}", iyy=f"{float(inertia_angular_value.x)}",
+                            iyz=f"{float(inertia_angular_value.y)}", izz=f"{float(inertia_angular_value.z)}")
+        except AttributeError:
+            xml_et.SubElement(inertial, "inertia", ixx="0.0", ixy="0.0",ixz="0.0", iyy="0.0", iyz="0.0", izz="0.0")
+
+def component_is_collision(entity_id: object, component_type_id: object, xml_obj: object):
+    """
+    This function will look at your entity_id and the PhysX Collider component id, find the
+    property paths of the component and build the xml element with properties./
+
+    Note: 
+    /// Used to identify shape configuration type from base class.
+    enum class ShapeType : AZ::u8
+    {
+        Sphere,
+        Box,
+        Capsule,
+        Cylinder,
+        ConvexHull, ///< Not Supported in physx
+        TriangleMesh, ///< Not Supported in physx
+        Native, ///< Native shape configuration if user wishes to bypass generic shape configurations.
+        PhysicsAsset, ///< Shapes configured in the asset.
+        CookedMesh, ///< Stores a blob of mesh data cooked for the specific engine.
+        Heightfield ///< Interacts with the physics system heightfield
+    };
+    Sphere is 0, Box is 1, Capsule is 2, Cylinder is 3, PhysicAsset is None
+
+    URDF_COLLISION_SHAPE_LIST = ['sphere', 'box', 'capsule', 'cylinder']
+    /// capsule is not supported in URDF but is in PhysX
+
+    :param entity_id: Entity Object ID of Child of Parent Entity
+    :param component_type_id: Mesh Component on Entity Object ID
+    :param material_type_id: Mesh Material Component on Entity Object ID
+    :param xml_child_obj: XML Child Object
+    :param robot_name: Robot Description Name
+    """
+    # returns a list of collision component IDs for a component type
+    collision_multiple_component_outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentsOfType', entity_id, component_type_id)
+    
+    if (collision_multiple_component_outcome.IsSuccess()):
+        first_collision_component_id = collision_multiple_component_outcome.GetValue()[0]
+        
+        # Print the property list
+        editor_tools.get_property_list(first_collision_component_id)
+        
+        # Get Shape Configuration|Shape LIST OF VALUE CODE: Sphere is 0, Box is 1, Capsule is 2, Cylinder is 3, PhysicAsset is None
+        shape_value = editor_tools.get_property(first_collision_component_id, 'Shape Configuration|Shape')
+        
+        # Check to see if we see a shape, if None its a Physic Mesh
+        if shape_value is None: 
+            print('---------> This is a PhysX Mesh, this is currently not supported. Work in progress.')
+            physx_mesh_property_path = 'Shape Configuration|Asset|PhysX Mesh'
+        elif shape_value == '':
+            print('Key Error, something is wrong, no Key found for shape.')
+        elif shape_value in range(4):
+            shape_name = const.URDF_COLLISION_SHAPE_PATH[shape_value]['shape']
+            
+            # Create XML for Collision and Geometry
+            collision = xml_et.SubElement(xml_obj, "collision")
+            
+            # Get Shape Origin and Radius from Property Path
+            offset_origin = editor_tools.get_property(first_collision_component_id, 'Collider Configuration|Offset')
+            rotation_origin = editor_tools.get_property(first_collision_component_id, 'Collider Configuration|Rotation')
+            xml_et.SubElement(collision, "origin", rpy=f"{float(rotation_origin.x)} {float(rotation_origin.y)} {float(rotation_origin.z)}",
+                                xyz=f"{float(offset_origin.x)} {float(offset_origin.y)} {float(offset_origin.z)}")
+            geometry = xml_et.SubElement(collision, "geometry")
+            if shape_name == 'sphere':
+                shape_radius_path = const.URDF_COLLISION_SHAPE_PATH[shape_value]['radius']
+                
+                # Get Shape Radius from Property Path
+                shape_radius = editor_tools.get_property(first_collision_component_id, shape_radius_path)
+                
+                # Create XML for Collision Shape and Size
+                xml_et.SubElement(geometry, shape_name, radius=f"{float(shape_radius)}")
+            elif shape_name == 'box':
+                shape_size_path = const.URDF_COLLISION_SHAPE_PATH[shape_value]['size']
+                
+                # Get Shape Size from Property Path
+                shape_size = editor_tools.get_property(first_collision_component_id, shape_size_path)
+                xml_et.SubElement(geometry, shape_name, size=f"{float(shape_size.x)} {float(shape_size.y)} {float(shape_size.z)}")
+            elif shape_name == 'cylinder':
+                shape_radius_path = const.URDF_COLLISION_SHAPE_PATH[shape_value]['radius']
+                shape_length_path = const.URDF_COLLISION_SHAPE_PATH[shape_value]['length']
+                
+                # Get Shape Radius and Length from Property Paths
+                shape_radius = editor_tools.get_property(first_collision_component_id, shape_radius_path)
+                shape_length = editor_tools.get_property(first_collision_component_id, shape_length_path)
+                xml_et.SubElement(geometry, shape_name, radius=f"{float(shape_radius)}", length=f"{float(shape_length)}")
+
+def search_for_base_link(robot_name: str, ros2_path: Path, ros2_ws_src_path: Path) -> tuple[bool, str, str]:
+    """
+    This function will search for base_link entity in the current scene.
+
+    :param robot_name: Robot Description Name
+    :param ros2_path: Path to main Ros root folder
+    :param ros2_ws_src_path: Path to Users Ros Workspace
+        
+    :return: tuple of the [Found 1 base_link True or False,
+            Message to QT UI if the search found a base_link, Launch Command for rvis subproccess]
+    """
+    search_filter = entity.SearchFilter()
+    search_filter.names = [const.ROBOT_BASE_LINK_NODE] # List of names (matches if any match); can contain wildcards in the name
+    search_filter.names_case_sensitive = True # Determines if the name matching should be case-sensitive
+    search_filter.components_match_all = False # Determines if the filter should match all component type IDs
+    search_filter.names_are_root_based = False # Determines if the names are relative to the root or should be searched in children too
+
+    # The SearchBus interface
+    bus_type = bus.Broadcast
+
+    # Iterates through all entities in the current level, and returns a list of the ones that match the conditions
+    entity_id_list = entity.SearchBus(bus_type, 'SearchEntities', search_filter)
+
+    if len(entity_id_list) > 1: # make sure there is just 1 base_link in the scene
+        message = "Only 1 URDF base_link at a time."
+        return False, message
+    elif len(entity_id_list) < 1:
+        message = "No base_link at a time."
+        return False, message
+    else:
+        message = "base_link found!"
+
+        # Start XML root and name robot from arg.
+        if not robot_name is None:
+            root_xml = xml_et.Element("robot", name=robot_name)
+        else:
+            root_xml = xml_et.Element("robot", name="Test_Robot")
+        
+        # Add a defualt material White
+        defualt_material = xml_et.SubElement(root_xml, "material", name="white")
+        xml_et.SubElement(defualt_material, "color", rgba="1 1 1 1")
+        
+        # Create the URDF description folder
+        robot_description_folder_path = Path(ros2_ws_src_path, robot_name)
+        py_utilities.create_urdf_description_folder(robot_description_folder_path)
+        
+        # This is the new URDF directory
+        urdf_directory_path = Path(robot_description_folder_path, const.URDF_DESCRIPTION_SUB_FOLDER_LIST[0])
+        
+        # This is the new MESH directory
+        urdf_mesh_path = Path(robot_description_folder_path, const.URDF_DESCRIPTION_SUB_FOLDER_LIST[1])
+        
+        # This is the new LAUNCH directory path
+        urdf_launch_path = Path(robot_description_folder_path, const.URDF_DESCRIPTION_SUB_FOLDER_LIST[2])
+        
+        # This is the new rviz directory path
+        urdf_rviz_path = Path(robot_description_folder_path, const.URDF_DESCRIPTION_SUB_FOLDER_LIST[3])
+
+        # This is the new gazebo world directory path
+        gazebo_world_path = Path(robot_description_folder_path, const.URDF_DESCRIPTION_SUB_FOLDER_LIST[5])
+        
+        # Create a Package XML
+        py_utilities.create_package_file(robot_name, robot_description_folder_path)
+        
+        # Create the display.launch xml file
+        py_utilities.create_launch_file(robot_name, urdf_launch_path)
+        
+        # Create the CMake List
+        py_utilities.create_cmake_file(robot_name, robot_description_folder_path)
+        
+        # Create the rviz file
+        py_utilities.create_rviz_file(robot_name, urdf_rviz_path)
+
+        # Create the gazebo world file
+        py_utilities.create_empty_world_file(gazebo_world_path)
+
+        # Create the gazebo launch_file
+        py_utilities.create_gazebo_launch_file(robot_name, urdf_launch_path)
+        
+        # START SEARCH TREE ------------------
+        root = entity_id_list[0]
+        search_tree(root, root_xml, urdf_mesh_path, robot_name)
+
+        # Add Gazebo Tags
+        gazebo_obj = xml_et.SubElement(root_xml, 'gazebo')
+        xml_et.SubElement(gazebo_obj, "plugin", name="gazebo_ros_control", filename="libgazebo_ros_control.so")
+        xml_et.SubElement(gazebo_obj, 'robotNamespace').text = '/'
+        
+        # Export the URDF XML in the robot description folder
+        py_utilities.save_urdf_xml(robot_name, 'urdf', root_xml, urdf_directory_path)
+        
+        # Send CLI Commands
+        ros_source = str(Path(ros2_path, 'setup.bash'))
+        ws_source = str(Path(ros2_ws_src_path, 'install', 'setup.bash'))
+        
+        # Send Build Command
+        send_ros_build_commands(ros_source, ros2_ws_src_path, ws_source)
+
+        # Send Gazebo SDF Convert Commands (Gazebo must be installed)
+        send_gazebo_sdf_build_commands(urdf_directory_path, robot_name)
+        
+        # Build Launch Command for rvis, this will be used as a subprocess command if user click Open in RVIS button on gui
+        rviz_launch_message = f'source {ros_source}; cd {ros2_ws_src_path}; source {ws_source}; ros2 launch {robot_name} display.launch.py'
+
+        # Build Launch Command for gazebo, this will be used as a subprocess command if user click Open in GAZEBO button on gui
+        gazebo_launch_message = f'source {ros_source}; cd {ros2_ws_src_path}; source {ws_source}; ros2 launch {robot_name} gazebo.launch.py'
+        
+    return True, message, rviz_launch_message, gazebo_launch_message
+
+def send_ros_build_commands(ros_source: Path, ros2_ws_src_path: Path, ws_source: Path):
+    """
+    This function will send ros commands to build the urdf package 
+
+    :param ros_source: Path to main Ros root folder
+    :param ros2_ws_src_path: Path to Users Ros Workspace
+    :param ws_source: Path to main Ros root folder
+    """
+    # Linux Bash Commands
+    linux_terminal = 'gnome-terminal -e '
+    bash = ' "bash -c '
+    bash_end = ' "'
+    
+    # Build Command
+    build_cmd_list = f'source {ros_source}; cd {ros2_ws_src_path}; colcon build --merge-install; source {ws_source}'
+    
+    # Build Subprocess
+    build = subprocess.Popen(f"{linux_terminal}{bash}'{build_cmd_list}'{bash_end}", stdout=subprocess.PIPE, shell=True)
+    output = build.communicate()[0]
+    print(f'Build: {output}')
+
+def send_gazebo_sdf_build_commands(urdf_directory_path: Path, robot_name: str):
+    """
+    This function will send ros commands to build the urdf package 
+
+    :param ros_source: Path to main Ros root folder
+    :param ros2_ws_src_path: Path to Users Ros Workspace
+    :param ws_source: Path to main Ros root folder
+    """
+    # Linux Bash Commands
+    linux_terminal = 'gnome-terminal -e '
+    bash = ' "bash -c '
+    bash_end = ' "'
+    
+    # Build URDF and SDF Paths
+    urdf = Path(urdf_directory_path, f"{robot_name}.urdf")
+    sdf = Path(urdf_directory_path, f"{robot_name}.sdf")
+    
+    # Build Command  gz sdf -p /my_urdf.urdf > /my_sdf.sdf
+    build_cmd_list = f"gz sdf -p {urdf} > {sdf}"
+    
+    # Build Subprocess
+    build = subprocess.Popen(f"{linux_terminal}{bash}'{build_cmd_list}'{bash_end}", stdout=subprocess.PIPE, shell=True)
+    output = build.communicate()[0]
+    print(f'SDF Build: {output}')
+
+def launch_gazebo(message: str):
+    """
+    This function will launch the ROS2 Gazebo application with robot launch description
+
+    :param message: Launch Command for gazebo subprocess.
+    """
+    # we are going to pass the system environ
+    gazebo_env = os.environ.copy()
+    
+    # prunes non-string key:value envars
+    gazebo_env = {key: value for key, value in gazebo_env.items() if py_utilities.check_is_ascii(key) and py_utilities.check_is_ascii(value)}
+    
+    # will prune QT_ envars, to be used with QT bases apps like Maya or Wing
+    gazebo_env = {key: value for key, value in gazebo_env.items() if not key.startswith("QT_")}
+    
+    # if o3de env passes PYTHONHOME it will cause systemic boot failure for maya
+    gazebo_env = {key: value for key, value in gazebo_env.items() if not 'PYTHONHOM' in key}
+    
+    # Linux Bash Command Vars
+    linux_terminal = 'gnome-terminal -e '
+    bash = ' "bash -c '
+    bash_end = ' "'
+    
+    # Build env var
+    env: dict = gazebo_env
+    
+    # Build final command
+    command = f"{linux_terminal}{bash}'{message}'{bash_end}"
+    
+    # Send command to subprocess
+    gazebo = subprocess.Popen(args = command,
+                                env = env,
+                                shell=True,
+                                stdout = subprocess.PIPE,
+                                stderr = subprocess.PIPE,
+                                close_fds=True)
+    output = gazebo.communicate()[0]
+    print(f'gazebo: {output}')
+
+def launch_rviz(message: str):
+    """
+    This function will launch the ROS2 rVIS application with robot launch description
+
+    :param message: Launch Command for rvis subprocess.
+    """
+    # we are going to pass the system environ
+    rviz_env = os.environ.copy()
+    
+    # prunes non-string key:value envars
+    rviz_env = {key: value for key, value in rviz_env.items() if py_utilities.check_is_ascii(key) and py_utilities.check_is_ascii(value)}
+    
+    # will prune QT_ envars, to be used with QT bases apps like Maya or Wing
+    rviz_env = {key: value for key, value in rviz_env.items() if not key.startswith("QT_")}
+    
+    # if o3de env passes PYTHONHOME it will cause systemic boot failure for maya
+    rviz_env = {key: value for key, value in rviz_env.items() if not 'PYTHONHOM' in key}
+    
+    # Linux Bash Command Vars
+    linux_terminal = 'gnome-terminal -e '
+    bash = ' "bash -c '
+    bash_end = ' "'
+    
+    # Build env var
+    env: dict = rviz_env
+    
+    # Build final command
+    command = f"{linux_terminal}{bash}'{message}'{bash_end}"
+    
+    # Send command to subprocess
+    rvis = subprocess.Popen(args = command,
+                                env = env,
+                                shell=True,
+                                stdout = subprocess.PIPE,
+                                stderr = subprocess.PIPE,
+                                close_fds=True)
+    output = rvis.communicate()[0]
+    print(f'rvis: {output}')
+

+ 225 - 0
Gems/O3DE/UrdfExporter/Editor/Scripts/urdfexporter_dialog.py

@@ -0,0 +1,225 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+# -------------------------------------------------------------------------
+"""urdf_exporter_gem\\editor\\scripts\\urdf_exporter_gem_dialog.py
+Generated from O3DE PythonToolGem Template"""
+
+from PySide2.QtCore import Qt
+from PySide2.QtCore import QProcess
+from PySide2.QtWidgets import QCheckBox, QComboBox, QDialog, QFormLayout, QGridLayout, QGroupBox, QLabel,  QPushButton, QVBoxLayout, QWidget, QLineEdit, QFileDialog
+from functools import partial
+import export as URDF
+from pathlib import Path
+import re
+
+
+class UrdfExporterDialog(QDialog):
+    def __init__(self, parent=None):
+        """ 
+        This is the start of the QT O3DE URDF tool window panel.
+        """
+        # Window Functions
+        super(UrdfExporterDialog, self).__init__(parent)
+        
+        self.ros2_path = '/opt/ros/humble/'
+        self.ros2_ws_src_path = '~/ros2_ws/src/'
+        self.ros2_ws_path = '~/ros2_ws/'
+        self.title_label_info = ''
+        self.rvis_command = ''
+        self.gazebo_command = ''
+        self.main_text_window()
+        self.main_layout = QVBoxLayout()
+        self.main_layout.setAlignment(Qt.AlignCenter)
+        self.main_layout.addWidget(self.form_group_box)
+        self.setLayout(self.main_layout)
+
+        self.form_group_box = QGroupBox()
+        self.main_layout = QFormLayout(self)
+        self.main_layout.setAlignment(Qt.AlignCenter)
+
+    def start_export_button(self):
+        """
+        This function will grab all the form information and send to export.
+        """
+        # User entered robot name
+        robot_name = self.name_input.text()
+        # Send infomration to export, recieve message on status
+        robot_found, message, rviz_launch_message, gazebo_launch_message = URDF.search_for_base_link(robot_name, self.ros2_path, self.ros2_ws_src_path)
+        # Status from export scene search
+        if not robot_found:
+            self.rvis_button.setDisabled(True)
+            self.gazebo_button.setDisabled(True)
+            self.title_label_info.setText(message)
+        else:
+            self.rvis_button.setDisabled(False)
+            self.gazebo_button.setDisabled(False)
+            self.title_label_info.setText(rviz_launch_message)
+            self.rvis_command = rviz_launch_message
+            self.gazebo_command = gazebo_launch_message
+
+    def select_folder(self, ui_type: str):
+        """
+        This function will ask user to select folder paths and store thus path var
+        
+        :param ui_type: Type of folder selected by UI
+        """
+        file_dialog = QFileDialog()
+        if ui_type is 'ros2':
+            ros2_path = file_dialog.getExistingDirectory(self, 'Select ROS2 Directory')
+            self.title_label_info.setText(ros2_path)
+            self.ros2_path_line.setText(ros2_path)
+            # Create Path from string
+            self.ros2_path = Path(ros2_path)
+        else:
+            ros2_ws_src_path = file_dialog.getExistingDirectory(self, 'Select ROS2 WS SRC Directory')
+            self.title_label_info.setText(ros2_ws_src_path)
+            self.ros2_ws_path_line.setText(ros2_ws_src_path)
+            # Create Path from string
+            self.ros2_ws_src_path = Path(ros2_ws_src_path)
+            self.ros2_ws_path = Path(self.ros2_ws_src_path).parents[0]
+            print(self.ros2_ws_path)
+            # Check to see if this is a valid Directoy
+            if self.ros2_ws_path.is_dir():
+                # If Valid Directory enable save button
+                self.save_button.setDisabled(False)
+
+    def check_string(self):
+        """
+        This function will check to see if the robots name string is lower case and valid.
+        """   
+        update_text = re.sub(r'[A-Z]+', '', self.name_input.text())
+        self.name_input.setText(update_text)
+
+    def update_info_text(self, message: str):
+        """
+        This function will update info text from other scripts
+
+        :param message: Message for title label text
+        """
+        self.title_label_info.setText(message)
+
+    def start_rvis_process(self):
+        """
+        This function will start the rVis launch application subprocess
+        """
+        URDF.launch_rviz(self.rvis_command)
+
+    def start_gazebo_process(self):
+        """
+        This function will start the Gazebo launch application subprocess
+        """
+        URDF.launch_gazebo(self.gazebo_command)
+
+    def main_text_window(self):
+        """
+        This is the main game text output window and main user text edit input
+        """
+        self.form_group_box = QGroupBox()
+        self.main_layout = QFormLayout()
+        self.main_layout.setAlignment(Qt.AlignCenter)
+        self.main_layout.update()
+
+        # Title
+        self.title_lable = QLabel("Export your selected Visual Robot to URDF XML")
+        self.title_lable.setStyleSheet('text-align: center; font: 10pt')
+        self.title_lable.setFixedWidth(300)
+        self.main_layout.addRow(self.title_lable)
+
+        self.title_lable_base_link = QLabel("The root entity must be named base_link.")
+        self.title_lable_base_link.setStyleSheet('text-align: center; font: 10pt; color: rgb(255, 208, 0)')
+        self.title_lable_base_link.setFixedWidth(300)
+        self.main_layout.addRow(self.title_lable_base_link)
+
+        self.title_lable_note = QLabel("all names including mesh names need to be lower case.")
+        self.title_lable_note.setStyleSheet('text-align: center; font: 10pt; color: rgb(255, 208, 0)')
+        self.title_lable_note.setFixedWidth(300)
+        self.main_layout.addRow(self.title_lable_note)
+        
+        # Select ROS2 Path
+        self.ros2_path_lable = QLabel("ROS2 Location")
+        self.ros2_path_lable.setFixedWidth(300)
+        self.main_layout.addRow(self.ros2_path_lable)
+
+        self.ros2_path_line = QLineEdit(self)
+        self.ros2_path_line.setPlaceholderText("/opt/ros/humble/")
+        self.ros2_path_line.setClearButtonEnabled(True)
+        self.ros2_path_line.setFixedWidth(260)
+
+        self.ros2_path_button = QPushButton("SET")
+        self.ros2_path_button.setFixedWidth(40)
+        self.ros2_path_button.setDisabled(False)
+        self.ros2_path_button.clicked.connect(lambda:self.select_folder('ros2'))
+        self.main_layout.addRow(self.ros2_path_line, self.ros2_path_button)
+
+        # Select ROS2 WorkSpace Path
+        self.ros2_ws_path_lable = QLabel("ROS2 Workpsace Source Location")
+        self.ros2_ws_path_lable.setFixedWidth(300)
+        self.main_layout.addRow(self.ros2_ws_path_lable)
+
+        self.ros2_ws_path_line = QLineEdit(self)
+        self.ros2_ws_path_line.setPlaceholderText("/ros2_ws/src/")
+        self.ros2_ws_path_line.setClearButtonEnabled(True)
+        self.ros2_ws_path_line.setFixedWidth(260)
+
+        self.ros2_ws_path_button = QPushButton("SET")
+        self.ros2_ws_path_button.setFixedWidth(40)
+        self.ros2_ws_path_button.setDisabled(False)
+        self.ros2_ws_path_button.clicked.connect(lambda:self.select_folder('ros2_ws'))
+        self.main_layout.addRow(self.ros2_ws_path_line, self.ros2_ws_path_button)
+        
+        # Enter Robot Description Name
+        self.robot_name_lable = QLabel("Enter your Robot Name")
+        self.robot_name_lable.setFixedWidth(300)
+        self.main_layout.addRow(self.robot_name_lable)
+
+        self.name_input = QLineEdit(self)
+        self.name_input.setPlaceholderText("my_robot")
+        self.name_input.setClearButtonEnabled(True)
+        self.name_input.setFixedWidth(300)
+        self.name_input.textChanged.connect(lambda:self.check_string())
+        self.main_layout.addRow(self.name_input)
+
+        # Export the Robot Description Package Files and Build
+        self.save_button = QPushButton("EXPORT ROBOT PACKAGE")
+        self.save_button.setFixedWidth(300)
+        self.save_button.setDisabled(True)
+        self.save_button.clicked.connect(self.start_export_button)
+        self.main_layout.addRow(self.save_button)
+
+        # Launch rIVZ
+        self.rvis_button = QPushButton("LAUNCH RVIZ")
+        self.rvis_button.setFixedWidth(300)
+        self.rvis_button.setDisabled(True)
+        self.rvis_button.clicked.connect(self.start_rvis_process)
+        self.main_layout.addRow(self.rvis_button)
+
+        # Launch Gazebo
+        self.gazebo_button = QPushButton("LAUNCH GAZEBO")
+        self.gazebo_button.setFixedWidth(300)
+        self.gazebo_button.setDisabled(True)
+        self.gazebo_button.clicked.connect(self.start_gazebo_process)
+        self.main_layout.addRow(self.gazebo_button)
+
+        self.title_label_info = QLabel("INFO:")
+        self.title_label_info.setStyleSheet('text-align: center; background-color: rgb(10, 10, 10); color: rgb(170, 170, 170); padding: 6px; font: 10pt')
+        self.title_label_info.setFixedWidth(300)
+        self.main_layout.addRow(self.title_label_info)
+
+        spacer = QLabel("")
+        spacer.setStyleSheet('min-width: 5em')
+        self.main_layout.addRow(spacer)
+        self.form_group_box.setLayout(self.main_layout)
+        self.form_group_box.setAlignment(Qt.AlignCenter)
+
+
+if __name__ == "__main__":
+    # Create a new instance of the tool if launched from the Python Scripts window,
+    # which allows for quick iteration without having to close/re-launch the Editor
+    test_dialog = UrdfExporterDialog()
+    test_dialog.setWindowTitle("O3DE URDF EXPORTER")
+    test_dialog.show()
+    test_dialog.resize(300, 200)

+ 367 - 0
Gems/O3DE/UrdfExporter/Editor/Scripts/utilities.py

@@ -0,0 +1,367 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+# -------------------------------------------------------------------------
+from pathlib import Path
+import shutil
+import xml.etree.cElementTree as xml_et
+import constants as const
+import math
+import numpy as np
+
+
+def euler_yzx_to_axis_angle(roll: float, pitch: float, yaw: float) -> list[float,float,float]:
+    """
+    This function will convert a xyz Euler to an xyz Axis.
+    
+    :param roll: The roll or x
+    :param pitch: The pitch or z
+    :param yaw: The yaw or y:
+    :return: normalized float3 axis xyz
+    """
+    # Convert the Euler angles to a 3x3 rotation matrix
+    yawMatrix = np.matrix([
+    [math.cos(yaw), -math.sin(yaw), 0],
+    [math.sin(yaw), math.cos(yaw), 0],
+    [0, 0, 1]
+    ])
+
+    pitchMatrix = np.matrix([
+    [math.cos(pitch), 0, math.sin(pitch)],
+    [0, 1, 0],
+    [-math.sin(pitch), 0, math.cos(pitch)]
+    ])
+
+    rollMatrix = np.matrix([
+    [1, 0, 0],
+    [0, math.cos(roll), -math.sin(roll)],
+    [0, math.sin(roll), math.cos(roll)]
+    ])
+
+    # Multiply the three matrices to obtian the total rotation matrix
+    R = yawMatrix * pitchMatrix * rollMatrix
+    # Extract the rotation axis and angle from rotation matrix
+    theta = math.acos(((R[0, 0] + R[1, 1] + R[2, 2]) - 1) / 2)
+    try:
+        multi = 1 / (2 * math.sin(theta))
+    except ZeroDivisionError:
+        multi = 0.0
+
+    # Multiply Value
+    rx = multi * (R[2, 1] - R[1, 2]) * theta
+    ry = multi * (R[0, 2] - R[2, 0]) * theta
+    rz = multi * (R[1, 0] - R[0, 1]) * theta
+    # This is our raw axis
+    raw_value = [rx, rz, ry] #swap the z and y
+    # Normalized Value
+    if not raw_value == [0,0,0]:
+        normalized = [(float(i)-min(raw_value))/(max(raw_value)-min(raw_value)) for i in raw_value]
+    else:
+        normalized = [0.0,0.0,1.0]
+    # Return the normalized rotation axis
+    return normalized
+
+def create_directory_folder(directory: Path):
+    """
+    This function will create a directory
+    
+    :param directory : Directory Path
+    """
+    Path(directory).mkdir(parents=True, exist_ok=True)
+
+def copy_files_assets(source: Path, destination: Path):
+    """
+    This function will copy a source file to destination
+    
+    :param source: Source Directory Path to copy from
+    :param destination: Destination Directory Path to copy to
+    """
+    try:
+        shutil.copy(source, destination)
+    except (FileNotFoundError, IsADirectoryError) as error:
+        print(f'Copy Files Assets Error: {error}')
+
+def check_is_ascii(string: str) -> bool:
+    """
+    This function will check and validate an string for proper ascii
+
+    :param string: ASCII String to validate
+    :return bool:
+    """
+    try:
+        string.isascii()
+    except UnicodeEncodeError:
+        return False
+    else:
+        return True
+
+def create_package_file(robot_name: str, package_path: Path):
+    """
+    Creates a ros robot urdf description xml package file
+    
+    :param robot_name: Name of the robots package
+    :param package_path: This is the path to the Robot Description
+    """
+    root_xml = xml_et.Element('package', format='3')
+    xml_et.SubElement(root_xml, 'name').text = robot_name
+    xml_et.SubElement(root_xml, 'version').text ='1.0.0'
+    xml_et.SubElement(root_xml, 'description').text = 'URDF from O3DE'
+    xml_et.SubElement(root_xml,'author', email='[email protected]').text = 'Your Name'
+    xml_et.SubElement(root_xml,'maintainer', email='[email protected]').text = 'Starr Shaw'
+    xml_et.SubElement(root_xml,'license').text = 'MIT'
+    xml_et.SubElement(root_xml,'url').text = 'https://www.o3de.org/'
+    xml_et.SubElement(root_xml,'buildtool_depend').text = 'ament_cmake'
+    xml_et.SubElement(root_xml,'exec_depend').text = 'joint_state_publisher'
+    xml_et.SubElement(root_xml,'exec_depend').text = 'joint_state_publisher_gui'
+    xml_et.SubElement(root_xml,'exec_depend').text = 'robot_state_publisher'
+    xml_et.SubElement(root_xml,'exec_depend').text = 'rviz2'
+    xml_et.SubElement(root_xml,'exec_depend').text = 'xacro'
+    xml_et.SubElement(root_xml,'test_depend').text = 'ament_lint_auto'
+    export = xml_et.SubElement(root_xml, 'export')
+    xml_et.SubElement(export,'build_type').text = 'ament_cmake'
+    
+    # Export the XML
+    save_urdf_xml('package', 'xml', root_xml, package_path)
+
+def create_cmake_file(robot_name: str, package_directory_path: Path):
+    """
+    Create a Cmake file for the Robot Description
+    
+    :param robot_name: Name of the robots package
+    :param package_directory_path: This is the path to the Robot Description
+    """
+    text = [ 'cmake_minimum_required(VERSION 3.5)',
+            f'project({robot_name})', '',
+            'find_package(ament_cmake REQUIRED)', '',
+            'install(',
+            '   DIRECTORY images launch meshes rviz urdf',
+            '   DESTINATION share/${PROJECT_NAME}',
+            ')', '',
+            'if(BUILD_TESTING)',
+            '   find_package(ament_lint_auto REQUIRED)',
+            '   ament_lint_auto_find_test_dependencies()',
+            'endif()', '',
+            'ament_package()'
+            ]
+    # Save File
+    file_path = Path(package_directory_path, 'CMakeLists.txt')
+    with open (file_path, 'w') as f:
+        for item in text:
+            f.write(item + '\n')
+
+def create_launch_file(robot_name: str, urdf_launch_path: Path):
+    """
+    Create a ros launch file for the Robot Description
+
+    :param robot_name: Name of the robots package
+    :param urdf_launch_path: This is the path to the Robot Description Launch Folder
+    """
+    text = [
+            'from ament_index_python.packages import get_package_share_path',
+            '',
+            'from launch import LaunchDescription',
+            'from launch.actions import DeclareLaunchArgument',
+            'from launch.conditions import IfCondition, UnlessCondition',
+            'from launch.substitutions import Command, LaunchConfiguration',
+            '',
+            'from launch_ros.actions import Node',
+            'from launch_ros.parameter_descriptions import ParameterValue',
+            '',
+            'from pathlib import Path',
+            '',
+            'def generate_launch_description():',
+            f'\tpackage_path = get_package_share_path("{robot_name}")',
+            f'\tdefault_model_path = Path(package_path, "urdf/{robot_name}.urdf")',
+            f'\tdefault_rviz_config_path = Path(package_path, "{const.URDF_RVIS_DEFUALT}")',
+            '',
+            '\tgui_arg = DeclareLaunchArgument(name="gui", default_value="true", choices=["true", "false"], description="Flag to enable joint_state_publisher_gui")',
+            '\tmodel_arg = DeclareLaunchArgument(name="model", default_value=str(default_model_path), description="Absolute path to robot urdf file")',
+            '\trviz_arg = DeclareLaunchArgument(name="rvizconfig", default_value=str(default_rviz_config_path), description="Absolute path to rviz config file")',
+            '',
+            '\trobot_description = ParameterValue(Command(["xacro ", LaunchConfiguration("model")]), value_type=str)',
+            '',
+            '\trobot_state_publisher_node = Node(package="robot_state_publisher", executable="robot_state_publisher", parameters=[{"robot_description": robot_description}])',
+            '',
+            '\tjoint_state_publisher_node = Node(package="joint_state_publisher", executable="joint_state_publisher", condition=UnlessCondition(LaunchConfiguration("gui")))',
+            '',
+            '\tjoint_state_publisher_gui_node = Node(package="joint_state_publisher_gui", executable="joint_state_publisher_gui", condition=IfCondition(LaunchConfiguration("gui")))',
+            '',
+            '\trviz_node = Node(package="rviz2", executable="rviz2", name="rviz2", output="screen", arguments=["-d", LaunchConfiguration("rvizconfig")])',
+            '',
+            '\treturn LaunchDescription([gui_arg, model_arg, rviz_arg, joint_state_publisher_node, joint_state_publisher_gui_node, robot_state_publisher_node, rviz_node])'
+    ]
+    # Save File
+    file_path = Path(urdf_launch_path, 'display.launch.py')
+    with open (file_path, 'w') as f:
+        for item in text:
+            f.write(item + '\n')
+
+def create_gazebo_launch_file(robot_name: str, urdf_launch_path: Path):
+    """
+    Create a ros Gazebo launch file for the Robot Description
+
+    :param robot_name: Name of the robots package
+    :param urdf_launch_path: This is the path to the Robot Description Launch Folder
+    """
+    slash = '\\\"'
+    xml_replace = f"\'\"\', \'{slash}\'"
+    text = [
+            'from ament_index_python.packages import get_package_share_directory',
+            'from launch import LaunchDescription',
+            'from launch.actions import ExecuteProcess',
+            'from launch.substitutions import LaunchConfiguration',
+            'from pathlib import Path',
+            '',
+            'def generate_launch_description():',
+            '\tuse_sim_time = LaunchConfiguration("use_sim_time", default="true")',
+            f'\trobot_name = "{robot_name}"',
+            '\tworld_file_name = "empty.world"',
+            '',
+            '\tworld = str(Path(get_package_share_directory(',
+            '\t\trobot_name), "worlds", world_file_name))',
+            '',
+            '\tsdf = str(Path(get_package_share_directory(',
+            f'\t\trobot_name), "urdf", "{robot_name}.sdf"))',
+            '',
+            '\txml = open(sdf, "r").read()',
+            '',
+            f"\txml = xml.replace({xml_replace})",
+            '',
+            "\tswpan_args = '{name: \"' + robot_name + '\", xml: \"' + xml + '\" }' ",
+            '',
+            '\treturn LaunchDescription([',
+            '\t\tExecuteProcess(',
+            '\t\t\tcmd=["gazebo", "--verbose", world,',
+            '\t\t\t\t"-s", "libgazebo_ros_factory.so"],',
+            '\t\t\toutput="screen"),',
+            '',
+            '\t\tExecuteProcess(',
+            '\t\t\tcmd=["ros2", "param", "set", "/gazebo",',
+            '\t\t\t\t"use_sim_time", use_sim_time],',
+            '\t\t\toutput="screen"),',
+            '',
+            '\t\tExecuteProcess(',
+            '\t\t\tcmd=["ros2", "service", "call", "/spawn_entity" ,',
+            '\t\t\t\t"gazebo_msgs/SpawnEntity", swpan_args],',
+            '\t\t\toutput="screen"),',
+            '\t])'
+    ]
+    # Save File
+    file_path = Path(urdf_launch_path, 'gazebo.launch.py')
+    with open (file_path, 'w') as f:
+        for item in text:
+            f.write(item + '\n')
+
+def create_rviz_file(robot_name: str, urdf_rviz_path: Path):
+    """
+    Create a rviz file
+
+    :param robot_name: Name of the robots package (Not used currently, but this might change)
+    :param urdf_rviz_path (Path): This is the path to the Robot Description RVIZ Folder
+    """
+    text = [ 'Panels:',
+            '  - Class: rviz_common/Displays',
+            '    Name: Displays',
+            '  - Class: rviz_common/Views',
+            '    Name: Views',
+            'Visualization Manager:',
+            '  Class: ""',
+            '  Displays:',
+            '    - Class: rviz_default_plugins/Grid',
+            '      Name: Grid',
+            '      Value: true',
+            '    - Alpha: 0.8',
+            '      Class: rviz_default_plugins/RobotModel',
+            '      Description Source: Topic',
+            '      Description Topic:',
+            '        Value: /robot_description',
+            '      Enabled: true',
+            '      Name: RobotModel',
+            '      Value: true',
+            '    - Class: rviz_default_plugins/TF',
+            '      Name: TF',
+            '      Value: true',
+            '  Global Options:',
+            '    Fixed Frame: base_link',
+            '    Frame Rate: 30',
+            '  Name: root',
+            '  Tools:',
+            '    - Class: rviz_default_plugins/MoveCamera',
+            '  Value: true',
+            '  Views:',
+            '    Current:',
+            '      Class: rviz_default_plugins/Orbit',
+            '      Distance: 1.7',
+            '      Name: Current View',
+            '      Pitch: 0.33',
+            '      Value: Orbit (rviz)',
+            '      Yaw: 5.5',
+            'Window Geometry:',
+            '  Height: 800',
+            '  Width: 1200'
+            ]
+    # Save File
+    file_path = Path(urdf_rviz_path, 'urdf.rviz')
+    with open (file_path, 'w', encoding = 'utf-8') as file_rvis:
+        for item in text:
+            file_rvis.write(item + '\n')      
+        file_rvis.close()
+
+def create_empty_world_file(gazebo_world_path: Path):
+    """
+    Create a Gazebo World File
+
+    :param gazebo_world_path(Path): This is the path to the Gazebo World Folder
+    """
+    text = [
+            '<sdf version="1.7">',
+            '  <world name="default">',
+            '    <include>',
+            '      <uri>model://ground_plane</uri>',
+            '    </include>',
+            '    <include>',
+            '      <uri>model://sun</uri>',
+            '    </include>',
+            '  </world>',
+            '</sdf>' 
+    ]
+    # Save File
+    file_path = Path(gazebo_world_path, 'empty.world')
+    with open (file_path, 'w', encoding = 'utf-8') as file_world:
+        for item in text:
+            file_world.write(item + '\n')      
+        file_world.close()
+
+def create_urdf_description_folder(robot_description_folder_path: Path):
+    """
+    This function will create the URDF description folder with subfolders
+
+    :param robot_description_folder_path: root of the Robot Description
+    """
+    create_directory_folder(robot_description_folder_path)
+    # Create sub directories
+    for directory in const.URDF_DESCRIPTION_SUB_FOLDER_LIST:
+        sub_directory = Path(robot_description_folder_path, directory)
+        create_directory_folder(sub_directory)
+
+def save_urdf_xml(file_name: str, file_ext: str, root_xml: object, xml_directory_path: Path):
+    """
+    This function will export the URDF xml to the robot description folder
+
+    :param file_name: File Name String
+    :param file_ext: File Ext String
+    :param root_xml: Root XML Object
+    :param xml_directory_path: File path for file directory
+    """
+    # Build Path
+    xml_path = Path(xml_directory_path, f'{file_name}.{file_ext}')
+    # XML Tree
+    tree = xml_et.ElementTree(root_xml)
+    xml_et.indent(tree, space="\t", level=0)
+    # Write XML
+    tree.write(xml_path, encoding = "UTF-8", xml_declaration = True)
+
+    dump = xml_et.dump(root_xml)

+ 244 - 0
Gems/O3DE/UrdfExporter/README.md

@@ -0,0 +1,244 @@
+# urdf-exporter-gem
+O3DE to URDF Exporter Gem
+![InO3DE](https://user-images.githubusercontent.com/87207603/206539263-a9d45d0c-9799-4843-b343-83ffa05cb535.png)
+
+
+# Requirements: ROS2 Humble, Linux OS
+
+    Ubuntu 20.04 or 22.04. Other Ubuntu versions and Linux distros could also work as long as they can support ROS 2.
+    O3DE development branch. The Gem does not work with a release version of O3DE yet.
+    Modern version of ROS 2. This instruction assumes that the desktop version is installed. Otherwise some packages might be missing. We support and tested with:
+        ROS 2 Galactic with Ubuntu 20.04.
+        ROS 2 Humble with Ubuntu 22.04.
+
+
+#### Additional ros packages required
+
+Once the desired version of ROS 2 is installed, you will need to install additional ROS 2 packages. 
+Before running the following commands, make sure that the ROS 2 environment is setup. Replace \<distro\> with the ROS 2 distribution name (galactic, humble, ..) below and run the following command:
+```
+source /opt/ros/<distro>/setup.bash
+```
+
+* gazebo_msgs: `sudo apt install ros-${ROS_DISTRO}-gazebo-msgs`
+* Ackermann messages: `sudo apt install ros-${ROS_DISTRO}-ackermann-msgs`
+* Control toolbox `sudo apt install ros-${ROS_DISTRO}-control-toolbox`
+* Xacro (XML Macros) `sudo apt install ros-${ROS_DISTRO}-xacro`
+ALSO:
+* joint-state-publisher: 'sudo apt install ros-${ROS_DISTRO}-joint-state-publisher'
+* joint-state-publisher-gui: 'sudo apt install ros-${ROS_DISTRO}-joint-state-publisher-gui'
+
+If a `desktop` installation of ROS 2 distro was selected, everything else should be there.
+
+Use this helpful command to install:
+
+```
+sudo apt install ros-${ROS_DISTRO}-ackermann-msgs ros-${ROS_DISTRO}-control-toolbox ros-${ROS_DISTRO}-nav-msgs ros-${ROS_DISTRO}-gazebo-msgs
+```
+
+# sudo apt install python3-colcon-common-extensions
+# ROS2 Required Packages: 
+- gazebo-ros-pkgs
+- joint_state_publisher
+- joint_state_publisher_gui
+- robot_state_publisher
+- xacro
+
+sudo apt install ros-galactic-joint-state-publisher
+
+
+# INSTRUCTIONS:
+1. Download the URDF Exporter gem.
+2. Enable the GEM in a project. Learn more about O3DE Gems: https://www.o3de.org/docs/user-guide/gems/reference/aws/
+3. In O3DE Editor open the URDF Exporter Tool Panel
+4. Select the ROS2 Distro to Source
+5. Select the ROS2 Workspace to Source and save URDF
+6. Export URDF
+7. (Optional) View URDF in ROS2 rVIS
+8. (Optional) View SDF in Gazebo
+
+# INSTALL GEM
+1. Download and install the gem in your project gem settings:
+
+Use this Github Repo: https://github.com/shawstar/urdf-exporter-gem
+
+2. Start a new O3DE Project:
+![image](https://user-images.githubusercontent.com/87207603/215607459-15a08735-0893-4810-8c8d-d532d7517307.png)
+
+3. Name your new robotics project:
+![image](https://user-images.githubusercontent.com/87207603/215607854-d6b26e1a-303c-45d4-93c8-c37af0e561d4.png)
+
+4. Add the urdf-exporter-gem to your project:
+
+On the far right top of the project gem manager window
+there is a hamburger menu button, click Add Existing Gem.
+Select the downloaded urdf-exporter-gem folder.
+![image](https://user-images.githubusercontent.com/87207603/215608167-cea2c072-e8f9-48d2-8580-78da75995e68.png)
+
+5. Turn on and activate the urdf-exporter-gem Gem:
+![image](https://user-images.githubusercontent.com/87207603/215609362-a3292199-4a58-4e43-b1f6-dcd5f5fbcbdb.png)
+
+6. You must also have QT for Python Gem activated:
+![image](https://user-images.githubusercontent.com/87207603/215609693-95a17906-1d10-411f-8ef2-575569520a4d.png)
+
+7. Create your project. This menu will just remind you of the ROS2 Distro Requirments.
+![image](https://user-images.githubusercontent.com/87207603/215610453-7b805088-78f9-4924-8790-45d29eaf5c9d.png)
+
+8. Build your project:
+![image](https://user-images.githubusercontent.com/87207603/215610722-5c3b5b0f-dd82-4efd-b170-68e46da56748.png)
+
+9. Create a new level:
+![image](https://user-images.githubusercontent.com/87207603/215819105-bbdfca88-2c34-4e05-8dad-ad989f10c3f1.png)
+
+
+10. O3DE Menu Tools > Examples > urdf_exporter_gem:
+Also the o3de Menu Bar will have a new Robot Icon.
+![image](https://user-images.githubusercontent.com/87207603/215824488-3cccd8f3-277a-4ddf-9751-65d8bb9835f0.png)
+
+11. Lets make a very simple urdf test:
+Create a new Entity and name it base_link. This will be your frist link. Please leave this empty.
+![image](https://user-images.githubusercontent.com/87207603/215825173-8e06191b-e326-450e-89ca-627730154465.png)
+
+12. Lets add a simple mesh and add to the project:
+Please note, you must have the meshes in your project to be found by exporter, also meshs need to be in lower case.
+Add a mew Entity under base_link and add a mesh, lets add the box mesh.
+![image](https://user-images.githubusercontent.com/87207603/215832185-9a2eaffc-08cf-4958-b487-d30be79151b6.png)
+
+13. Next lets add some Components:
+Lets add a PhysX Collider. Currently only Shapes are supported. In the future mesh PhysicsAssest will be supported.
+Lets make a Box Shape around the cube.
+![image](https://user-images.githubusercontent.com/87207603/215832906-a4e27055-a238-4618-8a79-61bf1b7da840.png)
+
+14. Next lets add a PhysX Rigid Body
+![image](https://user-images.githubusercontent.com/87207603/215834755-98650b6c-4ec3-4015-8cae-a65b68f79479.png)
+
+15. Now lets add a joint target, we will use this as the lead target for our joint on are next Entity
+Place the Pivot location where you would like the Pivot axis to be for your joint.
+![image](https://user-images.githubusercontent.com/87207603/215835590-9453c589-8f04-40b7-9aa8-6304c1396531.png)
+
+16. Create a new Entity, lets add a Hinge Joint
+Add a new mesh component, PhysX Rigid Body, PhysX Hinge Joint, PhysX Collider. Make the joint Lead Entity pointed to the joint_lead_target.
+![image](https://user-images.githubusercontent.com/87207603/215837759-0cff6d2c-82f7-401b-9ffc-2652028c29ac.png)
+
+17. Lets use the URDF Exporter Tools:
+Set your ROS2 Location, Set your ROS2 Workspace Source Location, this can also point to your projects assets.
+![image](https://user-images.githubusercontent.com/87207603/216105902-2b2f94c0-2826-4dab-a16f-c4a6df6e1ccb.png)
+
+18. Click Export Robot Package
+![image](https://user-images.githubusercontent.com/87207603/216106266-ae1ab57d-5eba-4f98-9aa7-e7b5caf18c0a.png)
+# You will see some shell windows build your URDF Package. On disk it will look like this:
+![image](https://user-images.githubusercontent.com/87207603/216107243-611fb0b9-e3bc-45e2-ab7b-a882132f514c.png)
+Also these files will autobuild with colcon build be placed in your workspace install folder. 
+
+19. Preview your URDF in ROS2 RViz
+Next, lets click the LAUNCH RVIS Button, this will Launch your ros package in Rvis.
+![image](https://user-images.githubusercontent.com/87207603/216108467-48e91969-83ab-46fe-a239-ca801e9ce49f.png)
+
+20. Move your URDF in Joint State Publisher:
+We made a joint in our robot, you can move it by sliding the joint exposed.
+![image](https://user-images.githubusercontent.com/87207603/216108687-c9c5a489-60d7-47dd-817f-13646029b168.png)
+
+21. Preview your SDF in Gazebo.
+We automaticly convert your URDF into an SDF for Gazebo, Click LAUNCH GAZEBO to view.
+![image](https://user-images.githubusercontent.com/87207603/216109269-720ac941-e5df-479b-a18c-9b87ee57800b.png)
+
+# Robot Arm Sample
+## Lets try a more advanced sample that comes with this gem.
+## Frist Step, Move sample Prefab into your project.
+
+1. You must copy the contents of the Prefabs folder itself into your Projects Prefabs folder for o3de to find the meshs properly.
+![image](https://user-images.githubusercontent.com/87207603/215591984-756f630d-5020-45a2-86ce-06500c1dc381.png)
+
+2. Move to your projects prefabs:
+![image](https://user-images.githubusercontent.com/87207603/215591676-b814f395-8822-48e4-a540-debd92947da5.png)
+ ![image](https://user-images.githubusercontent.com/87207603/215592150-ede2d8a9-2157-465f-9d97-5cefdef85693.png)
+
+3. Instantiate Prefab of the robotic_arm model.
+![image](https://user-images.githubusercontent.com/87207603/216175892-31c662a3-b762-49bc-bc47-10a06b2f9ffa.png)
+![image](https://user-images.githubusercontent.com/87207603/216176222-d1b225aa-50d7-4141-90c8-4c3a53513644.png)
+
+4. Set your ROS2 Location and your Export Workspace Location, this can be in O3DE Assets.
+![image](https://user-images.githubusercontent.com/87207603/216176680-9921a0ae-5ab7-4ab8-9412-2435202dfc4d.png)
+
+5. Export your Robot URDF Package and Launch RViz to test your robot.
+![image](https://user-images.githubusercontent.com/87207603/216177076-559fd0e4-3064-4a06-9be0-d139471700ef.png)
+
+
+# Known Limitations:
+ 
+1. You must use Collada .DAE for your meshes:
+![image (12)](https://user-images.githubusercontent.com/87207603/206542719-ea50d79c-7e32-409f-bd4a-8674f5b90882.png)
+ 
+2. You must have you robot under a Entity called base_link:
+![image (13)](https://user-images.githubusercontent.com/87207603/206543064-54ea9fae-cb4f-436b-bebb-4d0900c6c5be.png)
+ The base_link Entity needs to have no components
+ 
+3. You must Add Material Component to meshes:
+![image](https://user-images.githubusercontent.com/87207603/216165411-9ecb1955-bff3-433a-bcee-ea620f010120.png)
+
+4. Pivots must be added into your mesh:
+![image](https://user-images.githubusercontent.com/87207603/216097547-d9bdb95a-4cd6-46f3-90b2-447a215997c6.png)
+When exporting your 3D meshes, you must have your mesh and pivot you wish at worldspace (0.0, 0.0, 0.0)
+![image](https://user-images.githubusercontent.com/87207603/216104718-dea5609d-1bc3-4f39-94fa-9fb3bde43a96.png)
+Your ground mesh must have the Pivot at the bottom, math transforms will calculate from the pivot.
+
+5. You must name your meshes lowercase
+![image](https://user-images.githubusercontent.com/87207603/216098989-749e669c-fb77-4b4a-98df-8ec4b7ac40d2.png)
+
+6. PhysX Collider is supported, but Shape PhysicsAsst Meshes are not yet supported.
+![image](https://user-images.githubusercontent.com/87207603/216100506-f9e2dd3a-fc04-4cc2-b659-9498ce688652.png)
+O3DE PhysX Shape Collider Component not yet supported.
+
+7. O3DE Materials are not yet supported.
+O3DE Materials and Textures are not yet fully supported. The Material component is added when it is on an entity, but colors and or textures are not yet added to the URDF.
+
+8. Gazebo importing, you must have your 3D model correctly assembled with the proper physics and colliders. Currently, the sample arm can be seen when time and gravity are paused. The colliders and settings need more work to work correctly in Gaze
+![image](https://user-images.githubusercontent.com/87207603/220388049-556dc95d-0e97-4b10-9e31-05c1f7ddc694.png)
+
+9. Missing Joint Types
+![image](https://user-images.githubusercontent.com/87207603/220390455-515b2366-476d-493d-93ba-33200bab55db.png)
+
+10. Mesh Paths must be in the Assets folder of the Project.
+When building your 3D model in O3DE, make sure your meshes are located in the project assets folder and the meshes are named in lower case. If you would like to import your exported URDF with the O3DE Ros2 Gem, make sure you export your URDF in the project assets folder to import the mesh paths.
+
+
+# Backlog:
+
+## euler_yzx_to_axis_angle in utilities:
+https://github.com/o3de/o3de-technicalart/pull/5#discussion_r1107913594
+Do we have any math utils exposed to do this? If we can offload this to o3de optimized C++ libraries, we should.
+
+## create_directory_folder in utilities:
+https://github.com/o3de/o3de-technicalart/pull/5#discussion_r1107919397
+You should have access to the LYTestTools in any O3DE project IIRC. If you do, I'd use the LyTestTools file_system
+
+## create_gazebo_launch_file in utilities:
+https://github.com/o3de/o3de-technicalart/pull/5#discussion_r1107933647
+Have you considered using Jinja2 for all these template files?
+The o3de install Python has Jinja2.11.3 installed in its site-packages.
+https://jinja.palletsprojects.com/en/3.1.x/
+
+## create_empty_world_file in utilities:
+https://github.com/o3de/o3de-technicalart/pull/5#discussion_r1107953028
+Since this is a file that doesn't use any updated strings, we could store a physical template file in the gem then just copy that file to the target destination.
+
+## Moving editor_entity_utils to the EditorPythonBindings 
+cgalvan mentioned this pull request Feb 16, 2023
+Proposed RFC Suggestion: Moving editor_entity_utils to the EditorPythonBindings gem o3de/sig-testing#67 
+
+## Linear Velocity to look at in export.py:
+https://github.com/o3de/o3de-technicalart/pull/5#discussion_r1107012545
+
+Linear velocity is not a row of inertia matrix.
+The inertia matrix is 9 dimensions equivalent to mass for rotation motion (huge simplification).
+In o3de only the diagonal inertia matrix is supported (AFAIK).
+Please adjust the code here.
+
+## PhysX in O3DE vs URDF
+https://github.com/o3de/o3de-technicalart/pull/5#discussion_r1107011206
+
+Note that PhysX and o3de has completely different direction of joints:
+Please refer to my comment in URDF importer on that : https://github.com/o3de/o3de-extras/blob/8069a342837b8bb696d9089b67d3dd5349fe231d/Gems/ROS2/Code/Source/RobotImporter/URDF/JointsMaker.cpp#L28
+
+## Rotation Matrix and how its constructed in o3de:
+https://github.com/o3de/o3de-technicalart/pull/5#discussion_r1107011024

+ 18 - 0
Gems/O3DE/UrdfExporter/Registry/assetprocessor_settings.setreg

@@ -0,0 +1,18 @@
+{
+    "Amazon": {
+        "AssetProcessor": {
+            "Settings": {
+                "ScanFolder UrdfExporter/Assets": {
+                    "watch": "@GEMROOT:UrdfExporter@/Assets",
+                    "recursive": 1,
+                    "order": 101
+                },
+                "ScanFolder UrdfExporter/Registry": {
+                    "watch": "@GEMROOT:UrdfExporter@/Registry",
+                    "recursive": 1,
+                    "order": 102
+                }
+            }
+        }
+    }
+}

+ 40 - 0
Gems/O3DE/UrdfExporter/Registry/sceneassetimporter.setreg

@@ -0,0 +1,40 @@
+{
+	"O3DE":
+	{
+		"SceneAPI":
+		{
+			"AssetImporter":
+			{
+				"SupportedFileTypeExtensions":
+				[
+					".fbx",
+					".stl",
+					".gltf",
+					".glb",
+					".dae"
+				]
+			},
+			"MaterialConverter": 
+			{
+				"Enable": true,
+				"DefaultMaterial": "Materials/Presets/PBR/default_grid.material"
+			},
+			"TangentGenerateComponent":
+			{
+				"DefaultGenerationMethod": "FromSourceScene",
+				"DebugBitangentFlip": false
+			},
+			"SkinRule":
+			{
+				"DefaultMaxSkinInfluencesPerVertex": 8,
+				"DefaultWeightThreshold": 0.001
+			},
+			"ModelBuilder": 
+			{
+				// When false, scenes with multiple meshes assigned to the same material but with different vertex layouts will successfully process
+				// When true, stricter error checking will cause the asset to fail to process with an error message indicating why
+				"MismatchedVertexLayoutsAreErrors": false 
+			}
+		}
+	}
+}

+ 30 - 0
Gems/O3DE/UrdfExporter/gem.json

@@ -0,0 +1,30 @@
+{
+    "gem_name": "UrdfExporter",
+    "version": "1.0.0",
+    "display_name": "UrdfExporter",
+    "license": "License used i.e. Apache-2.0 or MIT",
+    "license_url": "Link to the license web site i.e. https://opensource.org/licenses/Apache-2.0",
+    "origin": "The name of the originator or creator",
+    "origin_url": "The website for this Gem",
+    "type": "Code",
+    "summary": "A short description of this Gem",
+    "canonical_tags": [
+        "Gem"
+    ],
+    "user_tags": [
+        "UrdfExporter"
+    ],
+    "platforms": [
+        ""
+    ],
+    "icon_path": "preview.png",
+    "requirements": "Notice of any requirements for this Gem i.e. This requires X other gem",
+    "documentation_url": "Link to any documentation of your Gem",
+    "dependencies": [
+        "QtForPython"
+    ],
+    "repo_uri": "",
+    "compatible_engines": [],
+    "engine_api_dependencies": [],
+    "restricted": "UrdfExporter"
+}

+ 3 - 0
Gems/O3DE/UrdfExporter/preview.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bb016801843ff07de13531e3fa4141ac27671933687abd3176e777dab87bb08f
+size 25031

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно