public unsafe void PartEditor()
 {
     if (editingPart == null) return;
     if(editingPart != null && !partEditorOpen) {
         partEditorOpen = true;
         partFirst = true;
         SetPartValues();
     }
     if(ImGui.Begin("Part Editor##" + editingPart.ChildName,ref partEditorOpen,partFirst ? ImGuiWindowFlags.AlwaysAutoResize : ImGuiWindowFlags.None)) {
         partFirst = false;
         ImGui.Text(editingPart.ChildName);
         ImGui.Text("Type: " + ModelViewer.ConType(editingPart));
         if (ImGui.Button("Reset")) SetPartValues();
         ImGui.Separator();
         ImGui.Text("Position");
             ImGui.InputFloat("X##posX", ref partX, 0.01f, 0.25f, "%.5f", ImGuiInputTextFlags.CharsDecimal);
             ImGui.InputFloat("Y##posY", ref partY, 0.01f, 0.25f, "%.5f", ImGuiInputTextFlags.CharsDecimal);
             ImGui.InputFloat("Z##posZ", ref partZ, 0.01f, 0.25f, "%.5f", ImGuiInputTextFlags.CharsDecimal);
         ImGui.Separator();
         ImGui.Text("Rotation");
             ImGui.InputFloat("Pitch", ref partPitch, 0.1f, 1f, "%.7f", ImGuiInputTextFlags.CharsDecimal);
             ImGui.InputFloat("Yaw", ref partYaw, 0.1f, 1f, "%.7f", ImGuiInputTextFlags.CharsDecimal);
             ImGui.InputFloat("Roll", ref partRoll, 0.1f, 1f, "%.7f", ImGuiInputTextFlags.CharsDecimal);
         ImGui.Separator();
         if (!(editingPart is FixConstruct))
         {
             ImGui.Text("Offset");
                 ImGui.InputFloat("X##offX", ref partOX, 0.01f, 0.25f, "%.5f", ImGuiInputTextFlags.CharsDecimal);
                 ImGui.InputFloat("Y##offY", ref partOY, 0.01f, 0.25f, "%.5f", ImGuiInputTextFlags.CharsDecimal);
                 ImGui.InputFloat("Z##offZ", ref partOZ, 0.01f, 0.25f, "%.5f", ImGuiInputTextFlags.CharsDecimal);
             ImGui.Separator();
         }
         if((editingPart is RevConstruct) || (editingPart is PrisConstruct)) {
             ImGui.Text("Axis");
                 ImGui.InputFloat("X##axX", ref partAxX, 0.01f, 0.25f, "%.5f", ImGuiInputTextFlags.CharsDecimal);
                 ImGui.InputFloat("Y##axY", ref partAxY, 0.01f, 0.25f, "%.5f", ImGuiInputTextFlags.CharsDecimal);
                 ImGui.InputFloat("Z##axZ", ref partAxZ, 0.01f, 0.25f, "%.5f", ImGuiInputTextFlags.CharsDecimal);
                 ImGui.InputFloat("Min", ref partMin, 0.1f, 1f, "%.4f", ImGuiInputTextFlags.CharsDecimal);
                 ImGui.InputFloat("Max", ref partMax, 0.1f, 1f, "%.4f", ImGuiInputTextFlags.CharsDecimal);
             if (ImGui.Button("0")) partPreview = 0;
             ImGui.SameLine();
             ImGui.PushItemWidth(-1);
             if (partMax > partMin)
                 ImGui.SliderFloat("Preview", ref partPreview, partMin, partMax, "%f", 1);
             else
                 ImGui.SliderFloat("Preview", ref partPreview, partMax, partMin, "%f", 1);
             ImGui.PopItemWidth();
             ImGui.Separator();
         }
         if(editingPart is SphereConstruct) {
                 ImGui.InputFloat("Min1", ref min1, 0.01f, 0.25f, "%.5f", ImGuiInputTextFlags.CharsDecimal);
                 ImGui.InputFloat("Max1", ref max1, 0.01f, 0.25f, "%.5f", ImGuiInputTextFlags.CharsDecimal);
                 ImGui.InputFloat("Min2", ref min2, 0.01f, 0.25f, "%.5f", ImGuiInputTextFlags.CharsDecimal);
                 ImGui.InputFloat("Max2", ref max2, 0.01f, 0.25f, "%.5f", ImGuiInputTextFlags.CharsDecimal);
                 ImGui.InputFloat("Min3", ref min3, 0.01f, 0.25f, "%.5f", ImGuiInputTextFlags.CharsDecimal);
                 ImGui.InputFloat("Max3", ref max3, 0.01f, 0.25f, "%.5f", ImGuiInputTextFlags.CharsDecimal);
             ImGui.Separator();
         }
         var jointPreview = Matrix4x4.Identity;
         if(editingPart is RevConstruct) {
             jointPreview = Matrix4x4.CreateFromAxisAngle(
             new Vector3(partAxX, partAxY, partAxZ),
                 MathHelper.DegreesToRadians(partPreview));
         } else if (editingPart is PrisConstruct) {
             var translate = new Vector3(partAxX, partAxY, partAxZ).Normalized() * partPreview;
             jointPreview = Matrix4x4.CreateTranslation(translate);
         }
         editingPart.OverrideTransform = Matrix4x4.CreateFromYawPitchRoll(
         MathHelper.DegreesToRadians(partPitch),
         MathHelper.DegreesToRadians(partYaw),
         MathHelper.DegreesToRadians(partRoll)) * jointPreview *
             Matrix4x4.CreateTranslation(new Vector3(partX, partY, partZ) + new Vector3(partOX, partOY, partOZ));
         if(ImGui.Button("Apply")) {
             editingPart.Origin = new Vector3(partX, partY, partZ);
             editingPart.Rotation = Matrix4x4.CreateFromYawPitchRoll(
                 MathHelper.DegreesToRadians(partYaw),
                 MathHelper.DegreesToRadians(partPitch),
                 MathHelper.DegreesToRadians(partRoll)
             );
             if(editingPart is RevConstruct) {
                 var rev = (RevConstruct)editingPart;
                 rev.Offset = new Vector3(partOX, partOY, partOZ);
                 rev.AxisRotation = new Vector3(partAxX, partAxY, partAxZ);
                 rev.Min = MathHelper.DegreesToRadians(partMin);
                 rev.Max = MathHelper.DegreesToRadians(partMax);
             }
             if(editingPart is PrisConstruct) {
                 var pris = (PrisConstruct)editingPart;
                 pris.Offset = new Vector3(partOX, partOY, partOZ);
                 pris.AxisTranslation = new Vector3(partAxX, partAxY, partAxZ);
                 pris.Min = partMin;
                 pris.Max = partMax;
             }
             if(editingPart is SphereConstruct) {
                 var sphere = (SphereConstruct)editingPart;
                 sphere.Offset = new Vector3(partOX, partOY, partOZ);
                 sphere.Min1 = min1;
                 sphere.Max1 = max1;
                 sphere.Min2 = min2;
                 sphere.Max2 = max2;
                 sphere.Min3 = min3;
                 sphere.Max3 = max3;
             }
             mv.OnDirtyPart();
         }
         ImGui.SameLine();
         if (ImGui.Button("Cancel")) partEditorOpen = false;
         ImGui.End();
     }
     if (!partEditorOpen) {
         editingPart.OverrideTransform = null;
         editingPart = null;
     }
 }
 public HardpointEditor(AbstractConstruct part, ModelViewer mv)
 {
     editingPart = part;
     this.mv = mv;
 }