Component_FlowGraphNode AddFlowGraphNode(Component_FlowGraph graph, Component subscribeTo) { var node = graph.CreateComponent <Component_FlowGraphNode>(enabled: false); node.Name = node.BaseType.GetUserFriendlyNameForInstance(); node.Position = graph.EditorScrollPosition.ToVector2I(); var handler = node.CreateComponent <Component_EventHandler>(); handler.Name = handler.BaseType.GetUserFriendlyNameForInstance() + " " + _event.Name; handler.Event = ReferenceUtility.MakeReference <ReferenceValueType_Event>( null, ReferenceUtility.CalculateThisReference(handler, subscribeTo, _event.Signature)); node.ControlledObject = ReferenceUtility.MakeReference <Component>(null, ReferenceUtility.CalculateThisReference(node, handler)); node.Enabled = true; return(node); }
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); }
void AddHandlerToSharpClass(Component subscribeTo, string csharpFileName, string className) { 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})"; if (subscribeTo.ParentRoot.MetadataGetMemberBySignature(methodSignature) == null) { break; } } } var newObjects = new List <Component>(); //create handler var handler = subscribeTo.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, subscribeTo.ParentRoot, methodSignature)); handler.Enabled = true; newObjects.Add(handler); //undo for 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()); //open cs file and add method var documentWindow = EditorAPI.OpenFileAsDocument(csharpFileName, true, true) as CSharpDocumentWindow; if (documentWindow != null) { if (!documentWindow.ScriptEditorControl.AddMethod(methodName, parameters, out var error)) { Log.Warning("Unable to add a code of the method. " + error); //!!!! } } else { Log.Warning("Unable to add a code of the method. Document file is not opened."); //!!!! } }
public override void Register() { //Add Constraint { var a = new EditorAction(); //!!!!"New Constraint"? a.Name = "Add Constraint"; //a.imageSmall = Properties.Resources.Save_16; //a.imageBig = Properties.Resources.Save_32; //!!!!выключить где-то? a.QatSupport = true; //a.qatAddByDefault = true; a.ContextMenuSupport = EditorContextMenuWinForms.MenuTypeEnum.Document; Component_PhysicalBody GetBody(object obj) { if (obj is Component_PhysicalBody body) { return(body); } var c = obj as Component; if (c != null) { var body2 = c.GetComponent <Component_PhysicalBody>(); if (body2 != null) { return(body2); } } return(null); } a.GetState += delegate(EditorAction.GetStateContext context) { if (context.ObjectsInFocus.DocumentWindow != null) { object[] selectedObjects = context.ObjectsInFocus.Objects; if (selectedObjects.Length == 2) { var bodyA = GetBody(selectedObjects[0]); var bodyB = GetBody(selectedObjects[1]); if (bodyA != null && bodyB != null) { context.Enabled = true; } //if( selectedObjects[ 0 ] is Component_PhysicalBody && selectedObjects[ 1 ] is Component_PhysicalBody ) // context.Enabled = true; } } }; a.Click += delegate(EditorAction.ClickContext context) { object[] selectedObjects = context.ObjectsInFocus.Objects; if (selectedObjects.Length == 2) { var bodyA = GetBody(selectedObjects[0]); var bodyB = GetBody(selectedObjects[1]); //var bodyA = (Component_PhysicalBody)context.ObjectsInFocus.Objects[ 0 ]; //var bodyB = (Component_PhysicalBody)context.ObjectsInFocus.Objects[ 1 ]; var parent = ComponentUtility.FindNearestCommonParent(new Component[] { bodyA, bodyB }); if (parent != null) { var data = new NewObjectWindow.CreationDataClass(); data.initDocumentWindow = context.ObjectsInFocus.DocumentWindow; data.initParentObjects = new List <object>(); data.initParentObjects.Add(parent); data.initLockType = MetadataManager.GetTypeOfNetType(typeof(Component_Constraint)); //data.initDemandedTypeDisableChange = true; data.additionActionBeforeEnabled = delegate(NewObjectWindow window) { var constraint = (Component_Constraint)data.createdComponentsOnTopLevel[0]; constraint.BodyA = ReferenceUtility.MakeReference <Component_PhysicalBody>( null, ReferenceUtility.CalculateThisReference(constraint, bodyA)); constraint.BodyB = ReferenceUtility.MakeReference <Component_PhysicalBody>( null, ReferenceUtility.CalculateThisReference(constraint, bodyB)); var pos = (bodyA.Transform.Value.Position + bodyB.Transform.Value.Position) * 0.5; constraint.Transform = new Transform(pos, Quaternion.Identity); }; EditorAPI.OpenNewObjectWindow(data); } } }; EditorActions.Register(a); } }
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); } }
public static void CalculateReferenceValueForComponentItem(Component from, ContentBrowserItem_Component item, out string referenceValue, out char addSeparator) { Component to = item.Component; //different hierarchy if (from == null || from.ParentRoot != to.ParentRoot) { //if( canMakeRelativeFilePath && from != null ) // ReferenceUtility.CalculateCurrentFolderReference( from, to, "", out referenceValue, out addSeparator ); //else ReferenceUtility.CalculateResourceReference(to, "", out referenceValue, out addSeparator); return; } //root:, this: { var referenceSelectionMode = GetReferenceSelectionModeInHierarchy(item); if (referenceSelectionMode == ContentBrowserItem_Component.ReferenceSelectionModeEnum.This) { ReferenceUtility.CalculateThisReference(from, to, "", out referenceValue, out addSeparator); return; } else if (referenceSelectionMode == ContentBrowserItem_Component.ReferenceSelectionModeEnum.Root) { ReferenceUtility.CalculateRootReference(to, "", out referenceValue, out addSeparator); return; } } //default { //_File //_Type //_Component var componentItemsStack = new List <ContentBrowserItem_Component>(); ContentBrowser.Item firstTypeOrFileItem = null; { ContentBrowser.Item current = item; do { if (current is ContentBrowserItem_Component) { if (current.Parent != null) { componentItemsStack.Add((ContentBrowserItem_Component)current); } } else if (current is ContentBrowserItem_Type || current is ContentBrowserItem_File) { firstTypeOrFileItem = current; break; } else { Log.Fatal("ContentBrowserUtils: CalculateReferenceValueForComponentItem: Internal error."); } current = current.Parent; } while(current != null); componentItemsStack.Reverse(); } var result = new StringBuilder(); //start item if (firstTypeOrFileItem != null) { //_File, _Type var fileItem = firstTypeOrFileItem as ContentBrowserItem_File; if (fileItem != null) { result.Append(VirtualPathUtility.GetVirtualPathByReal(fileItem.FullPath)); } var typeItem = firstTypeOrFileItem as ContentBrowserItem_Type; if (typeItem != null) { result.Append(typeItem.Type.Name); } addSeparator = '|'; } else { //_Component result.Append("root:"); addSeparator = '\0'; } //add path of components foreach (var componentItem in componentItemsStack) { if (addSeparator != '\0') { result.Append(addSeparator); } result.Append(componentItem.Component.GetPathFromParent()); addSeparator = '\\'; } referenceValue = result.ToString(); } }
public override void Register() { var types = new List <Metadata.TypeInfo>(); types.Add(MetadataManager.GetTypeOfNetType(typeof(Component_Constraint2D_Revolute))); types.Add(MetadataManager.GetTypeOfNetType(typeof(Component_Constraint2D_Prismatic))); types.Add(MetadataManager.GetTypeOfNetType(typeof(Component_Constraint2D_Distance))); types.Add(MetadataManager.GetTypeOfNetType(typeof(Component_Constraint2D_Weld))); types.Add(MetadataManager.GetTypeOfNetType(typeof(Component_Constraint2D_Fixed))); foreach (var type in types) { var displayName = TypeUtility.GetUserFriendlyNameForInstanceOfType(type.GetNetType()); var a = new EditorAction(); a.Name = "Add " + displayName; //a.ImageSmall = Properties.Resources.New_16; //a.ImageBig = Properties.Resources.New_32; a.QatSupport = true; //a.qatAddByDefault = true; a.ContextMenuSupport = EditorContextMenu.MenuTypeEnum.Document; Component_PhysicalBody2D GetBody(object obj) { if (obj is Component_PhysicalBody2D body) { return(body); } var c = obj as Component; if (c != null) { var body2 = c.GetComponent <Component_PhysicalBody2D>(); if (body2 != null) { return(body2); } } return(null); } a.GetState += delegate(EditorAction.GetStateContext context) { if (context.ObjectsInFocus.DocumentWindow != null) { object[] selectedObjects = context.ObjectsInFocus.Objects; if (selectedObjects.Length == 2) { var bodyA = GetBody(selectedObjects[0]); var bodyB = GetBody(selectedObjects[1]); if (bodyA != null && bodyB != null) { context.Enabled = true; } //if( selectedObjects[ 0 ] is Component_PhysicalBody2D && selectedObjects[ 1 ] is Component_PhysicalBody2D ) // context.Enabled = true; } } }; a.Click += delegate(EditorAction.ClickContext context) { object[] selectedObjects = context.ObjectsInFocus.Objects; if (selectedObjects.Length == 2) { var bodyA = GetBody(selectedObjects[0]); var bodyB = GetBody(selectedObjects[1]); //var bodyA = (Component_PhysicalBody2D)context.ObjectsInFocus.Objects[ 0 ]; //var bodyB = (Component_PhysicalBody2D)context.ObjectsInFocus.Objects[ 1 ]; var parent = ComponentUtility.FindNearestCommonParent(new Component[] { bodyA, bodyB }); if (parent != null) { var data = new NewObjectWindow.CreationDataClass(); data.initDocumentWindow = context.ObjectsInFocus.DocumentWindow; data.initParentObjects = new List <object>(); data.initParentObjects.Add(parent); data.initLockType = type; data.additionActionBeforeEnabled = delegate(NewObjectWindow window) { var constraint = (Component_Constraint2D)data.createdComponentsOnTopLevel[0]; constraint.BodyA = ReferenceUtility.MakeReference <Component_PhysicalBody2D>( null, ReferenceUtility.CalculateThisReference(constraint, bodyA)); constraint.BodyB = ReferenceUtility.MakeReference <Component_PhysicalBody2D>( null, ReferenceUtility.CalculateThisReference(constraint, bodyB)); if (constraint is Component_Constraint2D_Distance) { var pos = bodyA.Transform.Value.Position; var posB = bodyB.Transform.Value.Position; var distance = (posB - pos).Length(); var rot = Quaternion.FromDirectionZAxisUp((posB - pos).GetNormalize()); var scl = new Vector3(distance, distance, distance); constraint.Transform = new Transform(pos, rot, scl); } else { var pos = (bodyA.Transform.Value.Position + bodyB.Transform.Value.Position) * 0.5; constraint.Transform = new Transform(pos, Quaternion.Identity); } }; EditorAPI.OpenNewObjectWindow(data); } } }; EditorActions.Register(a); } }