/// <summary> /// Create a new JointEditorPane and register actions for the right click menu /// </summary> public JointEditorPane() { InitializeComponent(); RegisterContextAction("Edit Driver", editDriver_Internal); RegisterContextAction("Edit Sensors", listSensors_Internal); RegisterContextAction("Edit Limits", (List <RigidNode_Base> nodes) => { if (nodes.Count != 1) { return; } RigidNode_Base node = nodes[0]; if (node != null && node.GetSkeletalJoint() != null) { EditLimits limitEditor = new EditLimits(node.GetSkeletalJoint()); limitEditor.StartPosition = FormStartPosition.Manual; limitEditor.Location = new System.Drawing.Point(Cursor.Position.X - 10, Cursor.Position.Y - 10); limitEditor.ShowDialog(ParentForm); } }); lstJoints.Activation = ItemActivation.Standard; lstJoints.ItemActivate += (object sender, EventArgs e) => { editDriver_Internal(getSelectedNodes()); }; }
/// <summary> /// Create a new JointEditorPane and register actions for the right click menu /// </summary> public JointEditorPane() { InitializeComponent(); RegisterContextAction("Edit Driver", EditDriver_Internal); RegisterContextAction("Edit Sensors", ListSensors_Internal); RegisterContextAction("Edit Limits", (List <RigidNode_Base> nodes) => { try // prevent the user from just left clicking on the black joint pane and trying to edit nothing { if (nodes.Count != 1) { return; } RigidNode_Base node = nodes[0]; if (node != null && node.GetSkeletalJoint() != null) // prevents the user from trying to edit a null joint { EditLimits limitEditor = new EditLimits(node.GetSkeletalJoint()); // show the limit editor form limitEditor.ShowDialog(ParentForm); } } catch (NullReferenceException) //catch when the user clicks on the pane without a node selected { MessageBox.Show("Please select a node!"); } }); lstJoints.Activation = ItemActivation.Standard; lstJoints.ItemActivate += (object sender, EventArgs e) => { EditDriver_Internal(GetSelectedNodes()); }; }
/// <summary> /// The <see cref="JointEditorEvent"/> to open up a <see cref="SensorListForm"/> /// </summary> /// <param name="node">The node connected to the joint to edit the sensors on</param> private void listSensors_Internal(List <RigidNode_Base> nodes) { if (nodes == null || nodes.Count != 1) { return; } RigidNode_Base node = nodes[0]; if (node == null) { return; } currentlyEditing = true; SensorListForm listForm = new SensorListForm(node.GetSkeletalJoint()); listForm.StartPosition = FormStartPosition.Manual; listForm.Location = new System.Drawing.Point(Cursor.Position.X - 10, Cursor.Position.Y - 10); listForm.ShowDialog(ParentForm); if (ModifiedJoint != null) { ModifiedJoint(nodes); } this.UpdateJointList(); currentlyEditing = false; }
/// <summary> /// The <see cref="JointEditorEvent"/> to open up a <see cref="SensorListForm"/> /// </summary> /// <param name="node">The node connected to the joint to edit the sensors on</param> private void ListSensors_Internal(List <RigidNode_Base> nodes) { if (nodes == null || nodes.Count != 1) { return; } RigidNode_Base node = nodes[0]; if (node == null) { return; } currentlyEditing = true; SensorListForm listForm = new SensorListForm(node.GetSkeletalJoint()); listForm.ShowDialog(ParentForm); ModifiedJoint?.Invoke(nodes); this.UpdateJointList(); currentlyEditing = false; }
/// <summary> /// Merges a node into the parent. Used during the one click export and the wizard. /// </summary> /// <param name="node"></param> public void MergeNodeIntoParent(RigidNode_Base node) { if (node.GetParent() == null) { throw new ArgumentException("ERROR: Root node passed to MergeNodeIntoParent(RigidNode_Base)", "node"); } node.GetParent().ModelFullID += node.ModelFullID; //Get meshes for each node var childMesh = GetMesh(node); var parentMesh = GetMesh(node.GetParent()); //Merge submeshes and colliders parentMesh.meshes.AddRange(childMesh.meshes); parentMesh.colliders.AddRange(childMesh.colliders); //Merge physics parentMesh.physics.Add(childMesh.physics.mass, childMesh.physics.centerOfMass); //Remove node from the children of its parent node.GetParent().Children.Remove(node.GetSkeletalJoint()); Meshes.Remove(childMesh); }
public void LoadValues() { advancedSettingsForm = new AdvancedJointSettingsForm(node.GetSkeletalJoint()); var joint = node.GetSkeletalJoint(); var typeOptions = JointDriver.GetAllowedDrivers(joint); // TODO: This doesn't protect multi-edit jointTypeComboBox.Items.Clear(); if (typeOptions.Contains(JointDriverType.MOTOR)) { jointTypeComboBox.Items.AddRange(new object[] { "(Select an option)", "Drivetrain Wheel", "Mechanism Joint" }); } else { jointTypeComboBox.Items.AddRange(new object[] { "(Select an option)", "Mechanism Joint" }); } driverTypeComboBox.Items.Clear(); var textInfo = new CultureInfo("en-US", true).TextInfo; foreach (var type in typeOptions) { var name = Enum.GetName(typeof(JointDriverType), type); if (name != null) // TODO: Get rid of this mess { driverTypeComboBox.Items.Add(textInfo.ToTitleCase(name.Replace('_', ' ').ToLowerInvariant())); } } jointName.Text = ToStringUtils.NodeNameString(node); // Defaults when switched: weightInput.Value = 0; dtSideComboBox.SelectedIndex = 0; wheelTypeComboBox.SelectedIndex = 0; driverTypeComboBox.SelectedIndex = 0; var jointDriver = joint.cDriver; // sometimes null if (jointDriver == null) { jointTypeComboBox.SelectedItem = "(Select an option)"; } else if (jointDriver.port1 <= 2) // Drivetrain wheel { jointTypeComboBox.SelectedItem = "Drivetrain Wheel"; dtSideComboBox.SelectedIndex = jointDriver.port1; var wheelDriverMeta = jointDriver.GetInfo <WheelDriverMeta>(); if (wheelDriverMeta != null) { wheelTypeComboBox.SelectedIndex = (int)wheelDriverMeta.type - 1; } } else // Mechanism joint { jointTypeComboBox.SelectedItem = "Mechanism Joint"; weightInput.Value = (decimal)Math.Max(joint.weight, 0); driverTypeComboBox.SelectedIndex = Array.IndexOf(typeOptions, joint.cDriver.GetDriveType()); } }
public static T GetDriverMeta <T>(this RigidNode_Base node) where T : JointDriverMeta { return(node != null && node.GetSkeletalJoint() != null && node.GetSkeletalJoint().cDriver != null?node.GetSkeletalJoint().cDriver.GetInfo <T>() : null); }
public void ApplyToNode() { Node.GetSkeletalJoint().cDriver = new JointDriver(JointDriverType.MOTOR); Node.GetSkeletalJoint().cDriver.SetPort(PWMPort); WheelDriverMeta wheelDriver = new WheelDriverMeta(); switch (FrictionLevel) { case WizardFrictionLevel.HIGH: wheelDriver.forwardExtremeSlip = 1; //Speed of max static friction force. wheelDriver.forwardExtremeValue = 10; //Force of max static friction force. wheelDriver.forwardAsympSlip = 1.5f; //Speed of leveled off kinetic friction force. wheelDriver.forwardAsympValue = 8; //Force of leveld off kinetic friction force. if (WheelType == WizardWheelType.OMNI) //Set to relatively low friction, as omni wheels can move sidways. { wheelDriver.sideExtremeSlip = 1; //Same as above, but orthogonal to the movement of the wheel. wheelDriver.sideExtremeValue = .01f; wheelDriver.sideAsympSlip = 1.5f; wheelDriver.sideAsympValue = .005f; } else { wheelDriver.sideExtremeSlip = 1; wheelDriver.sideExtremeValue = 10; wheelDriver.sideAsympSlip = 1.5f; wheelDriver.sideAsympValue = 8; } break; case WizardFrictionLevel.MEDIUM: wheelDriver.forwardExtremeSlip = 1f; wheelDriver.forwardExtremeValue = 7; wheelDriver.forwardAsympSlip = 1.5f; wheelDriver.forwardAsympValue = 5; if (WheelType == WizardWheelType.OMNI) { wheelDriver.sideExtremeSlip = 1; wheelDriver.sideExtremeValue = .01f; wheelDriver.sideAsympSlip = 1.5f; wheelDriver.sideAsympValue = .005f; } else { wheelDriver.sideExtremeSlip = 1; wheelDriver.sideExtremeValue = 7; wheelDriver.sideAsympSlip = 1.5f; wheelDriver.sideAsympValue = 5; } break; case WizardFrictionLevel.LOW: wheelDriver.forwardExtremeSlip = 1; wheelDriver.forwardExtremeValue = 5; wheelDriver.forwardAsympSlip = 1.5f; wheelDriver.forwardAsympValue = 3; if (WheelType == WizardWheelType.OMNI) { wheelDriver.sideExtremeSlip = 1; wheelDriver.sideExtremeValue = .01f; wheelDriver.sideAsympSlip = 1.5f; wheelDriver.sideAsympValue = .005f; } else { wheelDriver.sideExtremeSlip = 1; wheelDriver.sideExtremeValue = 5; wheelDriver.sideAsympSlip = 1.5f; wheelDriver.sideAsympValue = 3; } break; } wheelDriver.type = (global::WheelType)WheelType; wheelDriver.isDriveWheel = true; Utilities.GUI.LoadMeshes(); Node.GetSkeletalJoint().cDriver.AddInfo(wheelDriver); wheelDriver = (WheelDriverMeta)Node.GetSkeletalJoint().cDriver.GetInfo(typeof(WheelDriverMeta)); (Node as OGLViewer.OGL_RigidNode).GetWheelInfo(out float radius, out float width, out BXDVector3 center); wheelDriver.radius = radius; wheelDriver.center = center; wheelDriver.width = width; Node.GetSkeletalJoint().cDriver.AddInfo(wheelDriver); }
/// <summary> /// The lite equivalent of the 'Start Exporter' <see cref="Button"/> in the <see cref="ExporterForm"/>. Used in <see cref="ExporterWorker_DoWork(Object, "/> /// </summary> /// <seealso cref="ExporterWorker_DoWork"/> /// <param name="baseNode"></param> /// <returns></returns> public List <BXDAMesh> ExportMeshesLite(RigidNode_Base baseNode, float totalMassKg) { SurfaceExporter surfs = new SurfaceExporter(); BXDJSkeleton.SetupFileNames(baseNode); List <RigidNode_Base> nodes = new List <RigidNode_Base>(); baseNode.ListAllNodes(nodes); List <BXDAMesh> meshes = new List <BXDAMesh>(); SetProgress(0, "Exporting Model"); for (int i = 0; i < nodes.Count; i++) { RigidNode_Base node = nodes[i]; if (node is RigidNode && node.GetModel() != null && node.ModelFileName != null && node.GetModel() is CustomRigidGroup) { try { CustomRigidGroup group = (CustomRigidGroup)node.GetModel(); BXDAMesh output = surfs.ExportAll(group, node.GUID, (long progress, long total) => { SetProgress(((double)progress / total) / nodes.Count + (double)i / nodes.Count); }); output.colliders.Clear(); output.colliders.AddRange(ConvexHullCalculator.GetHull(output)); meshes.Add(output); } catch (Exception e) { throw new Exception("Error exporting mesh: " + node.GetModelID(), e); } } } // Apply custom mass to mesh if (totalMassKg > 0) // Negative value indicates that default mass should be left alone (TODO: Make default mass more accurate) { float totalDefaultMass = 0; foreach (BXDAMesh mesh in meshes) { totalDefaultMass += mesh.physics.mass; } for (int i = 0; i < meshes.Count; i++) { meshes[i].physics.mass = totalMassKg * (float)(meshes[i].physics.mass / totalDefaultMass); } } // Add meshes to all nodes for (int i = 0; i < meshes.Count; i++) { ((OGL_RigidNode)nodes[i]).loadMeshes(meshes[i]); } // Get wheel information (radius, center, etc.) for all wheels foreach (RigidNode_Base node in nodes) { SkeletalJoint_Base joint = node.GetSkeletalJoint(); // Joint will be null if the node has no connection. // cDriver will be null if there is no driver connected to the joint. if (joint != null && joint.cDriver != null) { WheelDriverMeta wheelDriver = (WheelDriverMeta)joint.cDriver.GetInfo(typeof(WheelDriverMeta)); // Drivers without wheel metadata do not need radius, center, or width info. if (wheelDriver != null) { (node as OGLViewer.OGL_RigidNode).GetWheelInfo(out float radius, out float width, out BXDVector3 center); wheelDriver.radius = radius; wheelDriver.center = center; wheelDriver.width = width; joint.cDriver.AddInfo(wheelDriver); } } } return(meshes); }