private void buttonOK_Click(object sender, EventArgs e) { Close(); //get new value string[] newValue = null; { var list = new List <string>(); foreach (var property in objectImpl.properties) { if (!(bool)property.Value) { switch (property.objectType) { case ObjectTypeEnum.Component: list.Add(property.component.GetPathFromParent()); //list.Add( "$" + property.Name ); break; case ObjectTypeEnum.Property: list.Add(property.Name); break; } } } if (list.Count != 0) { newValue = list.ToArray(); } } var oldValue = component.TypeSettingsPrivateObjects; //update property component.TypeSettingsPrivateObjects = newValue; //undo var undoItem = new UndoActionPropertiesChange.Item(component, (Metadata.Property)MetadataManager.GetTypeOfNetType(typeof(Component)).MetadataGetMemberBySignature("property:TypeSettingsPrivateObjects"), oldValue, null); document.UndoSystem.CommitAction(new UndoActionPropertiesChange(undoItem)); document.Modified = true; }
private void buttonTypeSettingsDefaultValue_Click(object sender, EventArgs e) { var component = GetTypeSettingsComponent(); if (component != null) { var text = EditorLocalization.Translate("SettingsWindow", "Reset to default?"); if (EditorMessageBox.ShowQuestion(text, EMessageBoxButtons.YesNo) == EDialogResult.Yes) { var oldValue = component.TypeSettingsPrivateObjects; component.TypeSettingsPrivateObjects = null; var undoItem = new UndoActionPropertiesChange.Item(component, (Metadata.Property)MetadataManager.GetTypeOfNetType(typeof(Component)).MetadataGetMemberBySignature("property:TypeSettingsPrivateObjects"), oldValue, null); ObjectSettingsWindow.Document.UndoSystem.CommitAction(new UndoActionPropertiesChange(undoItem)); ObjectSettingsWindow.Document.Modified = true; } } }
private void ButtonResizeMasks_Click(ProcedureUI.Button sender) { var terrain = GetTerrain(); if (terrain == null) { return; } var layers = GetLayersToResizeMask(terrain); if (layers.Count == 0) { return; } var text = string.Format(EditorLocalization.Translate("Terrain", "Resize masks of selected layers to {0}x{0}?"), terrain.GetPaintMaskSizeInteger()); if (EditorMessageBox.ShowQuestion(text, EMessageBoxButtons.OKCancel) == EDialogResult.OK) { var undoMultiAction = new UndoMultiAction(); foreach (var layer in layers) { var oldValue = layer.Mask; layer.Mask = Component_PaintLayer.ResizeMask(layer.Mask, terrain.GetPaintMaskSizeInteger()); var property = (Metadata.Property)layer.MetadataGetMemberBySignature("property:Mask"); var undoItem = new UndoActionPropertiesChange.Item(layer, property, oldValue); undoMultiAction.AddAction(new UndoActionPropertiesChange(undoItem)); } if (undoMultiAction.Actions.Count != 0) { Provider.DocumentWindow.Document.CommitUndoAction(undoMultiAction); } } }
private void ButtonImport_Click(ProcedureUI.Button sender) { var sky = GetFirstObject <Component_Skybox>(); if (sky == null) { return; } var scene = sky.FindParent <Component_Scene>(); if (scene == null) { return; } var link = editLink.Text; var notification = ScreenNotifications.ShowSticky("Importing..."); try { string destVirtualFileName; { string name = sky.GetPathFromRoot(); foreach (char c in new string( Path.GetInvalidFileNameChars()) + new string( Path.GetInvalidPathChars())) { name = name.Replace(c.ToString(), "_"); } name = name.Replace(" ", "_"); destVirtualFileName = Path.Combine(ComponentUtility.GetOwnedFileNameOfComponent(scene) + "_Files", name); destVirtualFileName += Path.GetExtension(link); } var destRealFileName = VirtualPathUtility.GetRealPathByVirtual(destVirtualFileName); if (File.Exists(destRealFileName)) { if (EditorMessageBox.ShowQuestion($"Overwrite \'{destRealFileName}\'?", EMessageBoxButtons.OKCancel) == EDialogResult.Cancel) { return; } } Directory.CreateDirectory(Path.GetDirectoryName(destRealFileName)); if (File.Exists(link)) { File.Copy(link, destRealFileName, true); } else { //if( Uri.IsWellFormedUriString( link, UriKind.Absolute ) ) //{ using (var client = new WebClient()) client.DownloadFile(link, destRealFileName); //} } var oldValue = sky.Cubemap; sky.Cubemap = ReferenceUtility.MakeReference(destVirtualFileName); //undo var property = (Metadata.Property)sky.MetadataGetMemberBySignature("property:Cubemap"); var undoItem = new UndoActionPropertiesChange.Item(sky, property, oldValue); var undoAction = new UndoActionPropertiesChange(undoItem); Provider.DocumentWindow.Document.CommitUndoAction(undoAction); } catch (Exception e) { EditorMessageBox.ShowWarning(e.Message); } finally { notification.Close(); } }
private void ButtonAddEventHandler_Click(object sender, EventArgs e) { var items = new List <KryptonContextMenuItemBase>(); var subscribeTo = GetOneControlledObject <Component>(); if (subscribeTo == null) { return; } //add handler to C# class { bool enable = false; string className = null; string csharpFileName = null; var fileName = subscribeTo.ParentRoot.HierarchyController?.CreatedByResource?.Owner.Name; if (!string.IsNullOrEmpty(fileName)) { className = subscribeTo.ParentRoot.GetType().Name; try { //find by same class name if (string.Compare(Path.GetFileNameWithoutExtension(fileName), className, true) == 0) //if( Path.GetFileNameWithoutExtension( fileName ) == className ) { csharpFileName = VirtualPathUtility.GetRealPathByVirtual(Path.ChangeExtension(fileName, "cs")); if (File.Exists(csharpFileName)) { enable = true; } } //find by same file name if (!enable) { csharpFileName = VirtualPathUtility.GetRealPathByVirtual(Path.Combine(Path.GetDirectoryName(fileName), className + ".cs")); if (File.Exists(csharpFileName)) { enable = true; } } } catch { } } var item = new KryptonContextMenuItem(Translate("Add Handler to C# File"), null, delegate(object s, EventArgs e2) { AddHandlerToSharpClass(subscribeTo, csharpFileName, className); }); item.Enabled = enable; items.Add(item); } //add handler to C# script { var groupItem = new KryptonContextMenuItem(Translate("Add Handler to C# Script"), null); var childItems = new List <KryptonContextMenuItemBase>(); //create new C# script { var itemsData = new List <(string, Component)>(); itemsData.Add((Translate("Add C# Script in This Component"), subscribeTo)); if (subscribeTo != subscribeTo.ParentRoot) { itemsData.Add((Translate("Add C# Script in the Root Component"), subscribeTo.ParentRoot)); } foreach (var itemData in itemsData) { var childItem = new KryptonContextMenuItem(itemData.Item1, null, delegate(object s, EventArgs e2) { var parent = (Component)((KryptonContextMenuItem)s).Tag; var document = Owner.DocumentWindow.Document; //create script var script = parent.CreateComponent <Component_CSharpScript>(enabled: false); script.Name = script.BaseType.GetUserFriendlyNameForInstance(); script.Code = "class _Temp{\r\n}"; script.Enabled = true; //activate flow graph window var scriptDocumentWindow = EditorAPI.OpenDocumentWindowForObject(document, script) as Component_CSharpScript_DocumentWindow; Owner.DocumentWindow.SelectObjects(new object[] { script }); GetMethodInfo(subscribeTo, out var parameters, out var parametersSignature); var methodNameNotUnique = subscribeTo.Name.Replace(" ", "") + "_" + _event.Name; var methodName = methodNameNotUnique; var methodSignature = $"method:{methodName}({parametersSignature})"; if (!scriptDocumentWindow.ScriptEditorControl.AddMethod(methodName, parameters, out var error)) { Log.Warning("Unable to add a code of the method. " + error); //!!!! } //fix code try { scriptDocumentWindow.ScriptEditorControl.GetCode(out var code); code = code.Replace("class _Temp{", ""); var index = code.LastIndexOf('}'); code = code.Substring(0, index); string newCode = ""; var lines = code.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { newCode += line.Trim() + "\r\n"; } script.Code = newCode; } catch (Exception e3) { Log.Warning("Unable to fix code of the method. " + e3.Message); //!!!! } //create event handler { var handler = script.CreateComponent <Component_EventHandler>(enabled: false); handler.Name = handler.BaseType.GetUserFriendlyNameForInstance() + " " + _event.Name; handler.Event = ReferenceUtility.MakeReference <ReferenceValueType_Event>(null, ReferenceUtility.CalculateThisReference(handler, subscribeTo, _event.Signature)); handler.HandlerMethod = ReferenceUtility.MakeReference <ReferenceValueType_Method>(null, ReferenceUtility.CalculateThisReference(handler, script, methodSignature)); handler.Enabled = true; } //undo var action = new UndoActionComponentCreateDelete(document, new Component[] { script }, true); document.UndoSystem.CommitAction(action); document.Modified = true; }); childItem.Tag = itemData.Item2; childItems.Add(childItem); } } //add handler to one of already created C# scripts foreach (var script in subscribeTo.ParentRoot.GetComponents <Component_CSharpScript>(false, true)) { if (script.TypeSettingsIsPublic()) { var text = string.Format(Translate("Add Handler to \'{0}\'"), script.GetPathFromRoot(true)); var item = new KryptonContextMenuItem(text, null, delegate(object s, EventArgs e2) { var script2 = (Component_CSharpScript)((KryptonContextMenuItem)s).Tag; var document = Owner.DocumentWindow.Document; var oldCode = script2.Code; script2.Code = "class _Temp{\r\n}"; //activate flow graph window var scriptDocumentWindow = EditorAPI.OpenDocumentWindowForObject(document, script2) as Component_CSharpScript_DocumentWindow; Owner.DocumentWindow.SelectObjects(new object[] { script2 }); GetMethodInfo(subscribeTo, out var parameters, out var parametersSignature); //get unique method name string methodName; string methodSignature; { var methodNameNotUnique = subscribeTo.Name.Replace(" ", "") + "_" + _event.Name; for (int n = 1; ; n++) { methodName = methodNameNotUnique; if (n != 1) { methodName += n.ToString(); } methodSignature = $"method:{methodName}({parametersSignature})"; bool found = false; if (script2.CompiledScript != null) { foreach (var m in script2.CompiledScript.Methods) { if (m.Name == methodName) { found = true; } } } if (!found) { break; } //if( subscribeTo.ParentRoot.MetadataGetMemberBySignature( methodSignature ) == null ) // break; } } //GetMethodInfo( subscribeTo, out var parameters, out var methodName, out var methodSignature ); if (!scriptDocumentWindow.ScriptEditorControl.AddMethod(methodName, parameters, out var error)) { Log.Warning("Unable to add a code of the method. " + error); //!!!! } //set Code try { scriptDocumentWindow.ScriptEditorControl.GetCode(out var code); code = code.Replace("class _Temp{", ""); var index = code.LastIndexOf('}'); code = code.Substring(0, index); string newCode = ""; var lines = code.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { newCode += line.Trim() + "\r\n"; } script2.Code = oldCode + "\r\n" + newCode; } catch (Exception e3) { Log.Warning("Unable to fix code of the method. " + e3.Message); //!!!! } //create event handler Component_EventHandler handler; { handler = script2.CreateComponent <Component_EventHandler>(enabled: false); handler.Name = handler.BaseType.GetUserFriendlyNameForInstance() + " " + _event.Name; handler.Event = ReferenceUtility.MakeReference <ReferenceValueType_Event>(null, ReferenceUtility.CalculateThisReference(handler, subscribeTo, _event.Signature)); handler.HandlerMethod = ReferenceUtility.MakeReference <ReferenceValueType_Method>(null, ReferenceUtility.CalculateThisReference(handler, script2, methodSignature)); handler.Enabled = true; } //undo { var property = (Metadata.Property)script2.MetadataGetMemberBySignature("property:Code"); var undoItem = new UndoActionPropertiesChange.Item(script2, property, oldCode, new object[0]); var action1 = new UndoActionPropertiesChange(new UndoActionPropertiesChange.Item[] { undoItem }); var action2 = new UndoActionComponentCreateDelete(document, new Component[] { handler }, true); document.UndoSystem.CommitAction(new UndoMultiAction(new UndoSystem.Action[] { action1, action2 })); document.Modified = true; } }); item.Tag = script; childItems.Add(item); } } groupItem.Items.Add(new KryptonContextMenuItems(childItems.ToArray())); items.Add(groupItem); } //Add Handler to Flow Graph { var groupItem = new KryptonContextMenuItem(Translate("Add Handler to Flow Graph"), null); var childItems = new List <KryptonContextMenuItemBase>(); //create new flow graph { var itemsData = new List <(string, Component)>(); itemsData.Add((Translate("Add Flow Graph in This Component"), subscribeTo)); if (subscribeTo != subscribeTo.ParentRoot) { itemsData.Add((Translate("Add Flow Graph in the Root Component"), subscribeTo.ParentRoot)); } foreach (var itemData in itemsData) { var childItem = new KryptonContextMenuItem(itemData.Item1, null, delegate(object s, EventArgs e2) { var parent = (Component)((KryptonContextMenuItem)s).Tag; //create flow graph var graph = parent.CreateComponent <Component_FlowGraph>(enabled: false); graph.Name = graph.BaseType.GetUserFriendlyNameForInstance(); graph.Enabled = true; //create node with handler var node = AddFlowGraphNode(graph, subscribeTo); node.Position = new Vector2I(-20, -10); //undo var document = Owner.DocumentWindow.Document; var action = new UndoActionComponentCreateDelete(document, new Component[] { graph }, true); document.UndoSystem.CommitAction(action); document.Modified = true; //activate flow graph window EditorAPI.OpenDocumentWindowForObject(document, graph); }); childItem.Tag = itemData.Item2; childItems.Add(childItem); } } //add handler to one of already created flow graph foreach (var graph in subscribeTo.ParentRoot.GetComponents <Component_FlowGraph>(false, true)) { if (graph.TypeSettingsIsPublic()) { var text = string.Format(Translate("Add Handler to \'{0}\'"), graph.GetPathFromRoot(true)); var item = new KryptonContextMenuItem(text, null, delegate(object s, EventArgs e2) { var graph2 = (Component_FlowGraph)((KryptonContextMenuItem)s).Tag; //create node with handler var node = AddFlowGraphNode(graph2, subscribeTo); //undo var document = Owner.DocumentWindow.Document; var action = new UndoActionComponentCreateDelete(document, new Component[] { node }, true); document.UndoSystem.CommitAction(action); document.Modified = true; //activate flow graph window EditorAPI.OpenDocumentWindowForObject(document, graph2); }); item.Tag = graph; childItems.Add(item); } } groupItem.Items.Add(new KryptonContextMenuItems(childItems.ToArray())); items.Add(groupItem); } ////add handler (component only) //{ // var item = new KryptonContextMenuItem( Translate( "Add handler (component only)" ), null, delegate ( object s, EventArgs e2 ) // { // var newObjects = new List<Component>(); // var handler = subscribeTo.CreateComponent<Component_EventHandler>( enable: false ); // handler.Name = handler.BaseType.GetUserFriendlyNameForInstance() + " " + _event.Name; // handler.Event = ReferenceUtility.MakeReference<ReferenceValueType_Event>( null, // ReferenceUtility.CalculateThisReference( handler, subscribeTo, _event.Signature ) ); // handler.Enabled = true; // newObjects.Add( handler ); // var document = Owner.DocumentWindow.Document; // var action = new UndoActionComponentCreateDelete( document, newObjects, true ); // document.UndoSystem.CommitAction( action ); // document.Modified = true; // Owner.DocumentWindow.SelectObjects( newObjects.ToArray() ); // } ); // item.Enabled = GetOneControlledObject<Component>() != null; // items.Add( item ); //} EditorContextMenu.Show(items, Owner); }
public override void Register() { //Add Collision { const string bodyName = "Collision Body"; var a = new EditorAction(); a.Name = "Add Collision"; a.Description = "Adds a collision body to selected objects."; a.ImageSmall = Properties.Resources.Add_16; a.ImageBig = Properties.Resources.MeshCollision_32; a.ActionType = EditorAction.ActionTypeEnum.DropDown; a.QatSupport = true; //a.qatAddByDefault = true; a.ContextMenuSupport = EditorContextMenuWinForms.MenuTypeEnum.Document; a.GetState += delegate(EditorAction.GetStateContext context) { if (context.ObjectsInFocus.DocumentWindow != null) { object[] selectedObjects = context.ObjectsInFocus.Objects; if (selectedObjects.Length != 0 && Array.TrueForAll(selectedObjects, obj => obj is Component_MeshInSpace)) { context.Enabled = Array.Exists(selectedObjects, delegate(object obj) { var c = ((Component)obj).GetComponent(bodyName); if (c != null) { if (c is Component_RigidBody) { return(false); } if (c is Component_RigidBody2D) { return(false); } } return(true); }); } a.DropDownContextMenu.Tag = (context.ObjectsInFocus.DocumentWindow.Document, selectedObjects); } }; //context menu { a.DropDownContextMenu = new KryptonContextMenu(); a.DropDownContextMenu.Opening += delegate(object sender, CancelEventArgs e) { var menu = (KryptonContextMenu)sender; var tuple = ((DocumentInstance, object[]))menu.Tag; //"Collision Body of the Mesh" { var items2 = (KryptonContextMenuItems)menu.Items[0]; var item2 = (KryptonContextMenuItem)items2.Items[0]; bool enabled = false; foreach (var obj in tuple.Item2) { var meshInSpace = obj as Component_MeshInSpace; if (meshInSpace != null) { Component_RigidBody collisionDefinition = null; { var mesh = meshInSpace.Mesh.Value; if (mesh != null) { collisionDefinition = mesh.GetComponent("Collision Definition") as Component_RigidBody; } } if (collisionDefinition != null) { enabled = true; } } } item2.Enabled = enabled; } }; EventHandler clickHandler = delegate(object s, EventArgs e2) { var item = (KryptonContextMenuItem)s; var itemTag = ((KryptonContextMenu, string))item.Tag; var menu = itemTag.Item1; var collisionName = itemTag.Item2; var menuTag = ((DocumentInstance, object[]))menu.Tag; var document = menuTag.Item1; var selectedObjects = menuTag.Item2; List <UndoSystem.Action> undoActions = new List <UndoSystem.Action>(); foreach (var obj in selectedObjects) { if (obj is Component_MeshInSpace meshInSpace && meshInSpace.GetComponent(bodyName) as Component_RigidBody == null && meshInSpace.GetComponent(bodyName) as Component_RigidBody2D == null) { var mesh = meshInSpace.MeshOutput; if (mesh == null) { continue; } Component body = null; bool skip = false; if (collisionName == "Use Collision of the Mesh") { var collisionDefinition = mesh.GetComponent("Collision Definition") as Component_RigidBody; if (collisionDefinition != null) { var body2 = (Component_RigidBody)collisionDefinition.Clone(); body = body2; body2.Enabled = false; body2.Name = bodyName; body2.MotionType = Component_RigidBody.MotionTypeEnum.Static; body2.Transform = meshInSpace.Transform; meshInSpace.AddComponent(body2); } else { skip = true; } } else { Component_RigidBody CreateRigidBody() { var body2 = meshInSpace.CreateComponent <Component_RigidBody>(enabled: false); body2.Name = bodyName; body2.Transform = meshInSpace.Transform; return(body2); } Component_RigidBody2D CreateRigidBody2D() { var body2 = meshInSpace.CreateComponent <Component_RigidBody2D>(enabled: false); body2.Name = bodyName; body2.Transform = meshInSpace.Transform; return(body2); } switch (collisionName) { case "Box": { body = CreateRigidBody(); var shape = body.CreateComponent <Component_CollisionShape_Box>(); var bounds = mesh.Result.SpaceBounds.CalculatedBoundingBox; shape.TransformRelativeToParent = new Transform(bounds.GetCenter(), Quaternion.Identity); shape.Dimensions = bounds.GetSize(); } break; case "Sphere": { body = CreateRigidBody(); var shape = body.CreateComponent <Component_CollisionShape_Sphere>(); var sphere = mesh.Result.SpaceBounds.CalculatedBoundingSphere; shape.TransformRelativeToParent = new Transform(sphere.Origin, Quaternion.Identity); shape.Radius = sphere.Radius; } break; case "Capsule": { body = CreateRigidBody(); var shape = body.CreateComponent <Component_CollisionShape_Capsule>(); var bounds = mesh.Result.SpaceBounds.CalculatedBoundingBox; shape.TransformRelativeToParent = new Transform(bounds.GetCenter(), Quaternion.Identity); shape.Radius = Math.Max(bounds.GetSize().X, bounds.GetSize().Y) / 2; shape.Height = Math.Max(bounds.GetSize().Z - shape.Radius * 2, 0); } break; case "Cylinder": { body = CreateRigidBody(); var shape = body.CreateComponent <Component_CollisionShape_Cylinder>(); var bounds = mesh.Result.SpaceBounds.CalculatedBoundingBox; shape.TransformRelativeToParent = new Transform(bounds.GetCenter(), Quaternion.Identity); shape.Radius = Math.Max(bounds.GetSize().X, bounds.GetSize().Y) / 2; shape.Height = bounds.GetSize().Z; } break; case "Convex": { body = CreateRigidBody(); var shape = body.CreateComponent <Component_CollisionShape_Mesh>(); shape.ShapeType = Component_CollisionShape_Mesh.ShapeTypeEnum.Convex; shape.Mesh = ReferenceUtility.MakeThisReference(shape, meshInSpace, "Mesh"); } break; case "Convex Decomposition": { body = CreateRigidBody(); var settings = new ConvexDecomposition.Settings(); var form = new SpecifyParametersForm("Convex Decomposition", settings); form.CheckHandler = delegate(ref string error2) { return(true); }; if (form.ShowDialog() != DialogResult.OK) { skip = true; } else { var clusters = ConvexDecomposition.Decompose(mesh.Result.ExtractedVerticesPositions, mesh.Result.ExtractedIndices, settings); if (clusters == null) { Log.Warning("Unable to decompose."); skip = true; } else { foreach (var cluster in clusters) { var shape = body.CreateComponent <Component_CollisionShape_Mesh>(); shape.Vertices = cluster.Vertices; shape.Indices = cluster.Indices; shape.ShapeType = Component_CollisionShape_Mesh.ShapeTypeEnum.Convex; } } } } break; case "Mesh": { body = CreateRigidBody(); var shape = body.CreateComponent <Component_CollisionShape_Mesh>(); shape.Mesh = ReferenceUtility.MakeThisReference(shape, meshInSpace, "Mesh"); } break; case "Box 2D": { body = CreateRigidBody2D(); var shape = body.CreateComponent <Component_CollisionShape2D_Box>(); var bounds = mesh.Result.SpaceBounds.CalculatedBoundingBox; shape.TransformRelativeToParent = new Transform(bounds.GetCenter(), Quaternion.Identity); shape.Dimensions = bounds.GetSize().ToVector2(); } break; case "Circle 2D": { body = CreateRigidBody2D(); var shape = body.CreateComponent <Component_CollisionShape2D_Ellipse>(); var bounds = mesh.Result.SpaceBounds.CalculatedBoundingBox; shape.TransformRelativeToParent = new Transform(bounds.GetCenter(), Quaternion.Identity); var size = bounds.GetSize().ToVector2().MaxComponent(); shape.Dimensions = new Vector2(size, size); } break; case "Ellipse 2D": { body = CreateRigidBody2D(); var shape = body.CreateComponent <Component_CollisionShape2D_Ellipse>(); var bounds = mesh.Result.SpaceBounds.CalculatedBoundingBox; shape.TransformRelativeToParent = new Transform(bounds.GetCenter(), Quaternion.Identity); shape.Dimensions = bounds.GetSize().ToVector2(); } break; case "Capsule 2D": { body = CreateRigidBody2D(); var shape = body.CreateComponent <Component_CollisionShape2D_Capsule>(); var bounds = mesh.Result.SpaceBounds.CalculatedBoundingBox; shape.TransformRelativeToParent = new Transform(bounds.GetCenter(), Quaternion.Identity); var size = bounds.GetSize(); if (size.X > size.Y) { shape.Axis = 0; shape.Radius = size.Y / 2; shape.Height = Math.Max(size.X - shape.Radius * 2, 0); } else { shape.Axis = 0; shape.Radius = size.X / 2; shape.Height = Math.Max(size.Y - shape.Radius * 2, 0); } } break; case "Convex 2D": { body = CreateRigidBody2D(); var meshPoints = new Vector2[mesh.Result.ExtractedVerticesPositions.Length]; for (int n = 0; n < meshPoints.Length; n++) { meshPoints[n] = mesh.Result.ExtractedVerticesPositions[n].ToVector2(); } var points = MathAlgorithms.GetConvexByPoints(meshPoints); var vertices = new Vector3F[points.Count]; var indices = new int[(points.Count - 2) * 3]; { for (int n = 0; n < points.Count; n++) { vertices[n] = new Vector3F(points[n].ToVector2F(), 0); } for (int nTriangle = 0; nTriangle < points.Count - 2; nTriangle++) { indices[nTriangle * 3 + 0] = 0; indices[nTriangle * 3 + 1] = nTriangle + 1; indices[nTriangle * 3 + 2] = nTriangle + 2; } } var shape = body.CreateComponent <Component_CollisionShape2D_Mesh>(); shape.Vertices = vertices; shape.Indices = indices; shape.ShapeType = Component_CollisionShape2D_Mesh.ShapeTypeEnum.Convex; //var polygons = new List<List<Vector2>>(); //{ // var currentList = new List<Vector2>(); // for( int vertex = 0; vertex < points.Count; vertex++ ) // { // currentList.Add( points[ vertex ] ); // if( currentList.Count == Settings.MaxPolygonVertices ) // { // polygons.Add( currentList ); // currentList = new List<Vector2>(); // currentList.Add( points[ 0 ] ); // currentList.Add( points[ vertex ] ); // } // } // if( currentList.Count >= 3 ) // polygons.Add( currentList ); //} //foreach( var points2 in polygons ) //{ // var vertices = new Vector3F[ points2.Count ]; // var indices = new int[ ( points2.Count - 2 ) * 3 ]; // { // for( int n = 0; n < points2.Count; n++ ) // vertices[ n ] = new Vector3F( points2[ n ].ToVector2F(), 0 ); // for( int nTriangle = 0; nTriangle < points2.Count - 2; nTriangle++ ) // { // indices[ nTriangle * 3 + 0 ] = 0; // indices[ nTriangle * 3 + 1 ] = nTriangle + 1; // indices[ nTriangle * 3 + 2 ] = nTriangle + 2; // } // } // var shape = body.CreateComponent<Component_CollisionShape2D_Mesh>(); // shape.Vertices = vertices; // shape.Indices = indices; // shape.ShapeType = Component_CollisionShape2D_Mesh.ShapeTypeEnum.Convex; //} } break; //case "Convex Decomposition 2D": // { // body = CreateRigidBody2D(); // var settings = new ConvexDecomposition.Settings(); // var form = new SpecifyParametersForm( "Convex Decomposition 2D", settings ); // form.CheckHandler = delegate ( ref string error2 ) // { // return true; // }; // if( form.ShowDialog() != DialogResult.OK ) // skip = true; // else // { // //var sourceVertices = (Vector3F[])mesh.Result.ExtractedVerticesPositions.Clone(); // ////reset Z // //for( int n = 0; n < sourceVertices.Length; n++ ) // // sourceVertices[ n ] = new Vector3F( sourceVertices[ n ].ToVector2(), 0 ); // //var sourceIndices = mesh.Result.ExtractedIndices; // //var epsilon = 0.0001f; // //MathAlgorithms.MergeEqualVerticesRemoveInvalidTriangles( sourceVertices, sourceIndices, epsilon, out var processedVertices, out var processedIndices, out var processedTrianglesToSourceIndex ); // //var vertices = new Vector3F[ mesh.Result.ExtractedVerticesPositions.Length ]; // ////reset Z // //for( int n = 0; n < vertices.Length; n++ ) // // vertices[ n ] = new Vector3F( mesh.Result.ExtractedVerticesPositions[ n ].ToVector2(), 0 ); // //var clusters = ConvexDecomposition.Decompose( processedVertices, processedIndices, settings ); // var vertices = new Vector3F[ mesh.Result.ExtractedVerticesPositions.Length ]; // //reset Z // for( int n = 0; n < vertices.Length; n++ ) // vertices[ n ] = new Vector3F( mesh.Result.ExtractedVerticesPositions[ n ].ToVector2(), 0 ); // var clusters = ConvexDecomposition.Decompose( vertices, mesh.Result.ExtractedIndices, settings ); // if( clusters == null ) // { // Log.Warning( "Unable to decompose." ); // skip = true; // } // else // { // foreach( var cluster in clusters ) // { // var shape = body.CreateComponent<Component_CollisionShape2D_Mesh>(); // shape.Vertices = cluster.Vertices; // shape.Indices = cluster.Indices; // shape.ShapeType = Component_CollisionShape2D_Mesh.ShapeTypeEnum.Convex; // } // } // } // //var sourceVertices = new Vertices(); // //foreach( var p in mesh.Result.ExtractedVerticesPositions ) // // sourceVertices.Add( Physics2DUtility.Convert( p.ToVector2() ) ); // //var list = Triangulate.ConvexPartition( sourceVertices, TriangulationAlgorithm.Seidel, tolerance: 0.001f ); // //body = CreateRigidBody2D(); // //foreach( var convexVertices in list ) // //{ // // var shape = body.CreateComponent<Component_CollisionShape2D_Mesh>(); // // var points = new List<Vector2>(); // // foreach( var p in convexVertices ) // // points.Add( Physics2DUtility.Convert( p ) ); // // //var meshPoints = new Vector2[ mesh.Result.ExtractedVerticesPositions.Length ]; // // //for( int n = 0; n < meshPoints.Length; n++ ) // // // meshPoints[ n ] = mesh.Result.ExtractedVerticesPositions[ n ].ToVector2(); // // //var points = MathAlgorithms.GetConvexByPoints( meshPoints ); // // var vertices = new Vector3F[ points.Count + 1 ]; // // var indices = new int[ points.Count * 3 ]; // // { // // var center = Vector2.Zero; // // foreach( var p in points ) // // center += p; // // center /= points.Count; // // vertices[ 0 ] = new Vector3F( center.ToVector2F(), 0 ); // // for( int n = 0; n < points.Count; n++ ) // // { // // vertices[ 1 + n ] = new Vector3F( points[ n ].ToVector2F(), 0 ); // // indices[ n * 3 + 0 ] = 0; // // indices[ n * 3 + 1 ] = 1 + n; // // indices[ n * 3 + 2 ] = 1 + ( ( n + 1 ) % points.Count ); // // } // // } // // shape.Vertices = vertices; // // shape.Indices = indices; // // shape.ShapeType = Component_CollisionShape2D_Mesh.ShapeTypeEnum.Convex; // //} // //body = CreateRigidBody2D(); // //var shape = body.CreateComponent<Component_CollisionShape2D_Mesh>(); // //var meshPoints = new Vector2[ mesh.Result.ExtractedVerticesPositions.Length ]; // //for( int n = 0; n < meshPoints.Length; n++ ) // // meshPoints[ n ] = mesh.Result.ExtractedVerticesPositions[ n ].ToVector2(); // //var points = MathAlgorithms.GetConvexByPoints( meshPoints ); // //var vertices = new Vector3F[ points.Count + 1 ]; // //var indices = new int[ points.Count * 3 ]; // //{ // // var center = Vector2.Zero; // // foreach( var p in points ) // // center += p; // // center /= points.Count; // // vertices[ 0 ] = new Vector3F( center.ToVector2F(), 0 ); // // for( int n = 0; n < points.Count; n++ ) // // { // // vertices[ 1 + n ] = new Vector3F( points[ n ].ToVector2F(), 0 ); // // indices[ n * 3 + 0 ] = 0; // // indices[ n * 3 + 1 ] = 1 + n; // // indices[ n * 3 + 2 ] = 1 + ( ( n + 1 ) % points.Count ); // // } // //} // //shape.Vertices = vertices; // //shape.Indices = indices; // //shape.ShapeType = Component_CollisionShape2D_Mesh.ShapeTypeEnum.Convex; // //var bounds = mesh.Result.SpaceBounds.CalculatedBoundingBox; // //shape.TransformRelativeToParent = new Transform( bounds.GetCenter(), Quaternion.Identity ); // //shape.Mesh = ReferenceUtility.MakeThisReference( shape, meshInSpace, "Mesh" ); // //var shapeVertices = new Vector3F[ points.Count ]; // //for( int n = 0; n < shapeVertices.Length; n++ ) // // shapeVertices[ n ] = new Vector3F( points[ n ].ToVector2F(), 0 ); // //shape.Vertices = shapeVertices; // } // break; case "Mesh 2D": { body = CreateRigidBody2D(); var shape = body.CreateComponent <Component_CollisionShape2D_Mesh>(); shape.Mesh = ReferenceUtility.MakeThisReference(shape, meshInSpace, "Mesh"); shape.ShapeType = Component_CollisionShape2D_Mesh.ShapeTypeEnum.TriangleMesh; //var bounds = mesh.Result.SpaceBounds.CalculatedBoundingBox; //shape.TransformRelativeToParent = new Transform( bounds.GetCenter(), Quaternion.Identity ); //var halfSize = bounds.GetSize().ToVector2() * 0.5; //var meshPoints = new List<Vector2>( mesh.Result.ExtractedVerticesPositions.Length ); //foreach( var p in mesh.Result.ExtractedVerticesPositions ) // meshPoints.Add( p.ToVector2() ); //var convexPoints = MathAlgorithms.GetConvexByPoints( meshPoints ); //var points = shape.PropertyGet( "Points" ); //foreach( var p in convexPoints ) // points.MethodInvoke( "Add", p ); //points.MethodInvoke( "Add", new Vector2( -halfSize.X, -halfSize.Y ) ); //points.MethodInvoke( "Add", new Vector2( halfSize.X, -halfSize.Y ) ); //points.MethodInvoke( "Add", new Vector2( halfSize.X, halfSize.Y ) ); //points.MethodInvoke( "Add", new Vector2( -halfSize.X, halfSize.Y ) ); } break; //case "Polygon 2D": // { // body = CreateRigidBody2D(); // if( body != null ) // { // var shapeType = MetadataManager.GetType( "NeoAxis.Component_CollisionShape2D_Polygon" ); // if( shapeType != null ) // { // var shape = body.CreateComponent( shapeType ); // var bounds = mesh.Result.SpaceBounds.CalculatedBoundingBox; // shape.PropertySet( "TransformRelativeToParent", new Transform( bounds.GetCenter(), Quaternion.Identity ) ); // var halfSize = bounds.GetSize().ToVector2() * 0.5; // var meshPoints = new List<Vector2>( mesh.Result.ExtractedVerticesPositions.Length ); // foreach( var p in mesh.Result.ExtractedVerticesPositions ) // meshPoints.Add( p.ToVector2() ); // var convexPoints = MathAlgorithms.GetConvexByPoints( meshPoints ); // var points = shape.PropertyGet( "Points" ); // foreach( var p in convexPoints ) // points.MethodInvoke( "Add", p ); // //points.MethodInvoke( "Add", new Vector2( -halfSize.X, -halfSize.Y ) ); // //points.MethodInvoke( "Add", new Vector2( halfSize.X, -halfSize.Y ) ); // //points.MethodInvoke( "Add", new Vector2( halfSize.X, halfSize.Y ) ); // //points.MethodInvoke( "Add", new Vector2( -halfSize.X, halfSize.Y ) ); // } // else // skip = true; // } // } // break; default: Log.Warning("No implementation."); skip = true; continue; } } if (skip) { body?.Dispose(); continue; } if (body != null) { body.Enabled = true; undoActions.Add(new UndoActionComponentCreateDelete(document, new Component[] { body }, true)); //change Transform { //undo action var property = (Metadata.Property)meshInSpace.MetadataGetMemberBySignature("property:Transform"); var undoItem = new UndoActionPropertiesChange.Item(meshInSpace, property, meshInSpace.Transform, new object[0]); undoActions.Add(new UndoActionPropertiesChange(new UndoActionPropertiesChange.Item[] { undoItem })); //configure reference meshInSpace.Transform = ReferenceUtility.MakeReference <Transform>(null, ReferenceUtility.CalculateThisReference(meshInSpace, body, "Transform")); } } } } if (undoActions.Count != 0) { document.UndoSystem.CommitAction(new UndoMultiAction(undoActions)); document.Modified = true; ScreenNotifications.Show(Translate("The collision was added successfully.")); } }; var items = new List <KryptonContextMenuItemBase>(); var names = new string[] { "Use Collision of the Mesh", "", "Box", "Sphere", "Capsule", "Cylinder", "Convex", "Convex Decomposition", "Mesh", "", "Box 2D", "Circle 2D", "Ellipse 2D", "Capsule 2D", "Convex 2D", /*"Convex Decomposition 2D", */ "Mesh 2D" }; foreach (var name in names) { if (name == "") { items.Add(new KryptonContextMenuSeparator()); } else { var item = new KryptonContextMenuItem(name, null, clickHandler); item.Tag = (a.DropDownContextMenu, name); items.Add(item); } } a.DropDownContextMenu.Items.Add(new KryptonContextMenuItems(items.ToArray())); } EditorActions.Register(a); } //Delete Collision { const string bodyName = "Collision Body"; var a = new EditorAction(); a.Name = "Delete Collision"; a.Description = "Deletes the collision body of selected objects."; a.ImageSmall = Properties.Resources.Delete_16; a.ImageBig = Properties.Resources.Delete_32; a.QatSupport = true; //a.qatAddByDefault = true; a.ContextMenuSupport = EditorContextMenuWinForms.MenuTypeEnum.Document; a.GetState += delegate(EditorAction.GetStateContext context) { if (context.ObjectsInFocus.DocumentWindow != null) { object[] selectedObjects = context.ObjectsInFocus.Objects; if (selectedObjects.Length != 0 && Array.TrueForAll(selectedObjects, obj => obj is Component_MeshInSpace)) { context.Enabled = Array.Exists(selectedObjects, delegate(object obj) { var c = ((Component)obj).GetComponent(bodyName); if (c != null) { if (c is Component_RigidBody) { return(true); } if (c is Component_RigidBody2D) { return(true); } } return(false); }); } } }; a.Click += delegate(EditorAction.ClickContext context) { var text = string.Format(Translate("Delete \'{0}\'?"), bodyName); if (EditorMessageBox.ShowQuestion(text, EMessageBoxButtons.YesNo) == EDialogResult.Yes) { List <UndoSystem.Action> undoActions = new List <UndoSystem.Action>(); foreach (Component_MeshInSpace meshInSpace in context.ObjectsInFocus.Objects) { Component body = null; { var c = meshInSpace.GetComponent(bodyName); if (c != null && (c is Component_RigidBody || c is Component_RigidBody2D)) { body = c; } } if (body != null) { var restoreValue = meshInSpace.Transform; undoActions.Add(new UndoActionComponentCreateDelete(context.ObjectsInFocus.DocumentWindow.Document, new Component[] { body }, false)); //change Transform if (meshInSpace.Transform.GetByReference == string.Format("this:${0}\\Transform", bodyName)) { //undo action var property = (Metadata.Property)meshInSpace.MetadataGetMemberBySignature("property:Transform"); var undoItem = new UndoActionPropertiesChange.Item(meshInSpace, property, restoreValue, new object[0]); undoActions.Add(new UndoActionPropertiesChange(new UndoActionPropertiesChange.Item[] { undoItem })); //reset reference meshInSpace.Transform = restoreValue.Value; } } } if (undoActions.Count != 0) { context.ObjectsInFocus.DocumentWindow.Document.UndoSystem.CommitAction(new UndoMultiAction(undoActions)); context.ObjectsInFocus.DocumentWindow.Document.Modified = true; ScreenNotifications.Show(Translate("The collision was deleted.")); } } }; EditorActions.Register(a); } }
protected virtual void ToolPutTickPaint(Viewport viewport, double delta) { if (!GetToolPosition(viewport, out var selectedTerrain, out var position)) { return; } var layer = DocumentWindow.TerrainPaintLayersGetSelected(); if (layer == null) { return; } var toolRadius = (float)Component_Scene_DocumentWindow.TerrainToolRadius; var toolHardness = (float)Component_Scene_DocumentWindow.TerrainToolHardness; var toolShapeType = Component_Scene_DocumentWindow.TerrainToolShape; float strength = (float)(delta * Component_Scene_DocumentWindow.TerrainToolStrength * toolRadius * 0.5 * 2.0); Vector2 positionMin = position.ToVector2() - new Vector2(toolRadius, toolRadius); Vector2 positionMax = position.ToVector2() + new Vector2(toolRadius, toolRadius); List <Component_Terrain> terrains; //!!!! //if( selectedTerrain.HeightmapTerrainManager != null && HeightmapTerrainManager.Instance != null ) //{ // terrains = HeightmapTerrainManager.Instance.GetTerrainsByArea( positionMin, positionMax, true ); //} //else //{ terrains = new List <Component_Terrain>(); terrains.Add(selectedTerrain); //} foreach (var terrain in terrains) { UndoActionPropertiesChange undoSetPropertyAction = paintSetPropertyUndoActions.Find(a => a.Items[0].Obj == layer); var undoChangeAction = paintChangeUndoActions.Find(a => a.Terrain == terrain); Vector2I indexMin = terrain.GetMaskIndexByPosition(positionMin); Vector2I indexMax = terrain.GetMaskIndexByPosition(positionMax) + new Vector2I(1, 1); terrain.ClampMaskIndex(ref indexMin); terrain.ClampMaskIndex(ref indexMax); for (int y = indexMin.Y; y <= indexMax.Y; y++) { for (int x = indexMin.X; x <= indexMax.X; x++) { Vector2 point = terrain.GetPositionXYByMaskIndex(new Vector2I(x, y)); float coef; { double length; if (toolShapeType == ToolShape.Circle) { length = (point - position.ToVector2()).Length(); } else { length = Math.Max(Math.Abs(point.X - position.X), Math.Abs(point.Y - position.Y)); } if (length >= toolRadius) { coef = 0; } else if (length == 0) { coef = 1; } else if (length <= toolHardness * toolRadius) { coef = 1; } else { double c; if (toolRadius - toolRadius * toolHardness != 0) { c = (length - toolRadius * toolHardness) / (toolRadius - toolRadius * toolHardness); } else { c = 0; } coef = (float)Math.Cos(Math.PI / 2 * c); } } if (coef != 0) { float oldValue = layer.GetMaskValue(new Vector2I(x, y)); float value = oldValue; //near corner (x == 0 or y == 0) take value from near terrain. bool takeValueFromNearTerrain = false; //!!!! //if( selectedTerrain.HeightmapTerrainManager != null && HeightmapTerrainManager.Instance != null ) //{ // if( x == 0 ) // { // HeightmapTerrain terrain2 = // FindTerrainWithIndex( terrains, terrain.HeightmapTerrainManagerIndex - new Vector2I( 1, 0 ) ); // if( terrain2 != null ) // { // value = terrain2.GetHeight( terrain.GetPositionXY( new Vector2I( x, y ) ), false ) + terrain2.Position.Z; // value -= terrain.Position.Z; // takeValueFromNearTerrain = true; // } // } // else if( y == 0 ) // { // HeightmapTerrain terrain2 = // FindTerrainWithIndex( terrains, terrain.HeightmapTerrainManagerIndex - new Vector2I( 0, 1 ) ); // if( terrain2 != null ) // { // value = terrain2.GetHeight( terrain.GetPositionXY( new Vector2I( x, y ) ), false ) + terrain2.Position.Z; // value -= terrain.Position.Z; // takeValueFromNearTerrain = true; // } // } //} if (!takeValueFromNearTerrain) { switch (mode) { case ModeEnum.PaintPaint: case ModeEnum.PaintClear: { bool paint = mode == ModeEnum.PaintPaint; if ((Form.ModifierKeys & Keys.Shift) != 0) { paint = !paint; } if (paint) { value = oldValue + strength * coef; } else { value = oldValue - strength * coef; } } break; case ModeEnum.PaintSmooth: { float needValue = 0; { needValue += layer.GetMaskValue(new Vector2I(x - 1, y)); needValue += layer.GetMaskValue(new Vector2I(x + 1, y)); needValue += layer.GetMaskValue(new Vector2I(x, y - 1)); needValue += layer.GetMaskValue(new Vector2I(x, y + 1)); //needValue += layer.GetMaskValue( GetClampedMaskIndex( terrain, new Vec2I( x - 1, y ) ) ); //needValue += layer.GetMaskValue( GetClampedMaskIndex( terrain, new Vec2I( x + 1, y ) ) ); //needValue += layer.GetMaskValue( GetClampedMaskIndex( terrain, new Vec2I( x, y - 1 ) ) ); //needValue += layer.GetMaskValue( GetClampedMaskIndex( terrain, new Vec2I( x, y + 1 ) ) ); needValue /= 4; } if (oldValue < needValue) { value = oldValue + strength * coef; if (value > needValue) { value = needValue; } } else if (oldValue > needValue) { value = oldValue - strength * coef; if (value < needValue) { value = needValue; } } } break; case ModeEnum.PaintFlatten: { float needValue = toolModifyStartMaskValue; if (oldValue < needValue) { value = oldValue + strength * coef; if (value > needValue) { value = needValue; } } else if (oldValue > needValue) { value = oldValue - strength * coef; if (value < needValue) { value = needValue; } } } break; } } MathEx.Clamp(ref value, 0, 1); if (oldValue != value) { //undo if (layer.Mask.Value == null || layer.Mask.Value.Length == 0 || undoSetPropertyAction != null) { if (undoSetPropertyAction == null) { var oldValue2 = layer.Mask; layer.Mask = new byte[terrain.GetPaintMaskSizeInteger() * terrain.GetPaintMaskSizeInteger()]; var property = (Metadata.Property)layer.MetadataGetMemberBySignature("property:Mask"); var undoItem = new UndoActionPropertiesChange.Item(layer, property, oldValue2); undoSetPropertyAction = new UndoActionPropertiesChange(undoItem); paintSetPropertyUndoActions.Add(undoSetPropertyAction); } } else { if (undoChangeAction == null) { undoChangeAction = new Component_Terrain_PaintChangeUndoAction(terrain); paintChangeUndoActions.Add(undoChangeAction); } undoChangeAction.SaveValue(layer, new Vector2I(x, y), oldValue); } //update terrain layer.SetMaskValue(new Vector2I(x, y), value); } } } } //!!!!use mask indexes //var updateRectangle = new RectangleI( indexMin, indexMax ); //terrain.UpdateRenderingData( updateRectangle, false ); //bool foundItemForTerrain = false; //foreach( var updateItem in needUpdateRectangle ) //{ // if( updateItem.Terrain == terrain ) // { // updateItem.Rectangle.Add( updateRectangle ); // foundItemForTerrain = true; // break; // } //} //if( !foundItemForTerrain ) //{ // NeedUpdateRectangleItem item = new NeedUpdateRectangleItem(); // item.Terrain = terrain; // item.Rectangle = updateRectangle; // needUpdateRectangle.Add( item ); //} } }
bool SetProperty() { //!!!!multiselection //!!!!!!also this support for different objects string referenceValue = SelectedReference; var netType = setReferenceModeData.property.Type.GetNetType(); var underlyingType = ReferenceUtility.GetUnderlyingType(netType); List <UndoActionPropertiesChange.Item> undoItems = null; if (documentWindow != null) { undoItems = new List <UndoActionPropertiesChange.Item>(); } //!!!!try, catch? где еще foreach (var obj in setReferenceModeData.propertyOwners) { //object oldValue = null; //if( undoItems != null ) var oldValue = setReferenceModeData.property.GetValue(obj, setReferenceModeData.propertyIndexes); object value = null; if (referenceValue == "") { //reset reference with saving value for not components var unrefOldValue = ReferenceUtility.GetUnreferencedValue(oldValue); //Component specific: set null for Component if (unrefOldValue as Component != null) { unrefOldValue = null; } value = ReferenceUtility.MakeReference(underlyingType, unrefOldValue, ""); } else { value = ReferenceUtility.MakeReference(underlyingType, null, referenceValue); } setReferenceModeData.property.SetValue(obj, value, setReferenceModeData.propertyIndexes); if (undoItems != null) { var undoItem = new UndoActionPropertiesChange.Item(obj, setReferenceModeData.property, oldValue, setReferenceModeData.propertyIndexes); undoItems.Add(undoItem); } } //undo if (undoItems != null && undoItems.Count != 0) { var action = new UndoActionPropertiesChange(undoItems.ToArray()); documentWindow.Document.UndoSystem.CommitAction(action); documentWindow.Document.Modified = true; } return(true); }
public static void AddCollision(DocumentWindow documentWindow, string collisionName) { const string bodyName = "Collision Definition"; var mesh = documentWindow.ObjectOfWindow as Component_Mesh; var body = mesh.CreateComponent <Component_RigidBody>(enabled: false); body.Name = bodyName; //collision.CanCreate = false; body.MotionType = Component_RigidBody.MotionTypeEnum.Static; string error = null; //!!!!plugin support to add new or override current implementations switch (collisionName) { case "Box": { var shape = body.CreateComponent <Component_CollisionShape_Box>(); var bounds = mesh.Result.SpaceBounds.CalculatedBoundingBox; shape.TransformRelativeToParent = new Transform(bounds.GetCenter(), Quaternion.Identity); shape.Dimensions = bounds.GetSize(); } break; case "Sphere": { var shape = body.CreateComponent <Component_CollisionShape_Sphere>(); var sphere = mesh.Result.SpaceBounds.CalculatedBoundingSphere; shape.TransformRelativeToParent = new Transform(sphere.Origin, Quaternion.Identity); shape.Radius = sphere.Radius; } break; case "Capsule": { var shape = body.CreateComponent <Component_CollisionShape_Capsule>(); var bounds = mesh.Result.SpaceBounds.CalculatedBoundingBox; shape.TransformRelativeToParent = new Transform(bounds.GetCenter(), Quaternion.Identity); shape.Radius = Math.Max(bounds.GetSize().X, bounds.GetSize().Y) / 2; shape.Height = Math.Max(bounds.GetSize().Z - shape.Radius * 2, 0); } break; case "Cylinder": { var shape = body.CreateComponent <Component_CollisionShape_Cylinder>(); var bounds = mesh.Result.SpaceBounds.CalculatedBoundingBox; shape.TransformRelativeToParent = new Transform(bounds.GetCenter(), Quaternion.Identity); shape.Radius = Math.Max(bounds.GetSize().X, bounds.GetSize().Y) / 2; shape.Height = bounds.GetSize().Z; } break; case "Convex": { var shape = body.CreateComponent <Component_CollisionShape_Mesh>(); shape.ShapeType = Component_CollisionShape_Mesh.ShapeTypeEnum.Convex; shape.Mesh = ReferenceUtility.MakeThisReference(shape, mesh); } break; case "Convex Decomposition": { var settings = new ConvexDecomposition.Settings(); var form = new SpecifyParametersForm("Convex Decomposition", settings); form.CheckHandler = delegate(ref string error2) { //!!!! return(true); }; if (form.ShowDialog() != DialogResult.OK) { mesh.RemoveComponent(body, false); return; } var clusters = ConvexDecomposition.Decompose(mesh.Result.ExtractedVerticesPositions, mesh.Result.ExtractedIndices, settings); if (clusters == null) { mesh.RemoveComponent(body, false); Log.Warning("Unable to decompose."); return; } foreach (var cluster in clusters) { var shape = body.CreateComponent <Component_CollisionShape_Mesh>(); shape.Vertices = cluster.Vertices; shape.Indices = cluster.Indices; shape.ShapeType = Component_CollisionShape_Mesh.ShapeTypeEnum.Convex; } } break; case "Mesh": { var shape = body.CreateComponent <Component_CollisionShape_Mesh>(); shape.Mesh = ReferenceUtility.MakeThisReference(shape, mesh); } break; default: error = "No implementation."; break; } if (!string.IsNullOrEmpty(error)) { mesh.RemoveComponent(body, false); Log.Warning(error); return; } body.Enabled = true; var undoActions = new List <UndoSystem.Action>(); undoActions.Add(new UndoActionComponentCreateDelete(documentWindow.Document, new Component[] { body }, true)); //enable EditorDisplayCollision if (!mesh.EditorDisplayCollision) { mesh.EditorDisplayCollision = true; var property = (Metadata.Property)mesh.MetadataGetMemberBySignature("property:EditorDisplayCollision"); var undoItem = new UndoActionPropertiesChange.Item(mesh, property, false, new object[0]); undoActions.Add(new UndoActionPropertiesChange(new UndoActionPropertiesChange.Item[] { undoItem })); } documentWindow.Document.UndoSystem.CommitAction(new UndoMultiAction(undoActions)); documentWindow.Document.Modified = true; }