Exemple #1
0
        /// <summary>
        /// Compute the sin in radians.
        /// </summary>
        /// <returns></returns>
        public Codual Sin()
        {
            var lhs = this;

            return(new Codual(Math.Sin(Magnitude), CreateNode,
                              CreateNode(Id, IGNORE, dx => (dx * Math.Cos(lhs.Magnitude), NONE))));
        }
Exemple #2
0
 private void Awake()
 {
     if (Instance == null)
     {
         Instance = this;
     }
 }//end of Awake()
    internal void DoDuplicateNode(string id, Vector3 position)
    {
        var old     = GameObject.Find(id);
        var oldNode = (old.GetComponent(typeof(NodePhysX)) as NodePhysX);
        var links   = GameObject.FindGameObjectsWithTag("link").Select(p => p.GetComponent <Link>());

        links = links.Where(p => p.source == old || p.target == old).ToArray();
        var createAction = new CreateNode()
        {
            name = oldNode.Text, position = SVector3.FromVector3(position)
        };

        DoAction(createAction);
        foreach (var l in links)
        {
            DoAction(new CreateLink()
            {
                SourceId = l.target == old ? l.source.name : createAction.nodeId, TargetId = l.target == old ? createAction.nodeId  : l.source.name
            });
        }
        DoAction(new CreateLink()
        {
            SourceId = old.name, TargetId = createAction.nodeId
        });
    }
Exemple #4
0
 private void CreateSpriteAnimatedImage(List <string> files)
 {
     onBeforeDrop?.Invoke();
     using (Document.Current.History.BeginTransaction()) {
         var node = CreateNode.Perform(typeof(Image));
         SetProperty.Perform(node, nameof(Widget.Pivot), Vector2.Half);
         SetProperty.Perform(node, nameof(Widget.Id), "Temp");
         postProcessNode?.Invoke(node);
         var      i     = 0;
         ITexture first = null;
         foreach (var file in files)
         {
             if (!Utils.ExtractAssetPathOrShowAlert(file, out var assetPath, out var assetType))
             {
                 continue;
             }
             var text = new SerializableTexture(assetPath);
             first = first ?? text;
             SetKeyframe.Perform(node, nameof(Widget.Texture), Document.Current.AnimationId,
                                 new Keyframe <ITexture> {
                 Value    = text,
                 Frame    = i++,
                 Function = KeyFunction.Steep,
             });
         }
         SetProperty.Perform(node, nameof(Widget.Size), (Vector2)first.ImageSize);
         Document.Current.History.CommitTransaction();
     }
 }
Exemple #5
0
 public void Create(CreateNode req)
 {
     using (var scope = ScopeFactory.CreateWithTransaction(IsolationLevel.ReadCommitted))
     {
         scope.SaveChanges();
     }
 }
Exemple #6
0
        CreateMesh(CreateNode <TNode> createNode)
        {
            TNode[] nodes = CreateNodes(createNode);
            IReadOnlyList <CellConnectivity <TNode> > elementConnectivity = CreateElements(nodes);

            return(nodes, elementConnectivity);
        }
        public static void Create(string assetPath, string assetType, Action <Node> onNodeCreated)
        {
            var fileName = Path.GetFileNameWithoutExtension(assetPath);
            var menu     = new Menu()
            {
                new Command("Open in New Tab", () => Project.Current.OpenDocument(assetPath)),
                new Command("Add As External Scene", () => Document.Current.History.DoTransaction(
                                () => {
                    var scene = Node.CreateFromAssetBundle(assetPath, yuzu: TangerineYuzu.Instance.Value);
                    var node  = CreateNode.Perform(scene.GetType());
                    SetProperty.Perform(node, nameof(Widget.ContentsPath), assetPath);
                    SetProperty.Perform(node, nameof(Node.Id), fileName);
                    if (scene is Widget)
                    {
                        SetProperty.Perform(node, nameof(Widget.Pivot), Vector2.Half);
                        SetProperty.Perform(node, nameof(Widget.Size), ((Widget)scene).Size);
                    }
                    onNodeCreated?.Invoke(node);
                    node.LoadExternalScenes();
                })),
                new Command("Cancel")
            };

            menu[0].Enabled = assetType != ".model";
            menu.Popup();
        }
Exemple #8
0
        CreateMesh(CreateNode <TNode> createNode)
        {
            double[] coordinatesX  = FindNodalCoordinates(0);
            double[] coordinatesY  = FindNodalCoordinates(1);
            var      baseGenerator = new RectilinearMeshGenerator2D <TNode>(coordinatesX, coordinatesY);

            return(baseGenerator.CreateMesh(createNode));
        }
Exemple #9
0
        CreateMesh(CreateNode <TNode> createNode)
        {
            // Vertices must be listed before cells
            TNode[] nodes = ReadNodes(createNode);
            IReadOnlyList <CellConnectivity <TNode> > elements = ReadElements(nodes);

            return(nodes, elements);
        }
Exemple #10
0
        public ActionResult CreateNode([Bind] CreateNode Node, int InstanceID)
        {
            if (ModelState.IsValid)
            {
                //make sure the layer exists in this instance.
                var Layer = db.Layers.DefaultIfEmpty(null).FirstOrDefault(x => x.InstanceID == Node.InstanceID && x.LayerID == Node.LayerID);
                if (Layer == null)
                {
                    ModelState.AddModelError("Layer", "Unable to find Layer.");
                    return(Json(new { error = Generic.GetValidationErrors(ModelState) }));
                }
                //

                Node node = new Node(Node);
                db.Nodes.Add(node);
                node.Links = new List <Link>();
                db.SaveChanges();
                Link Link = null;
                //create a link if needed.
                if (Node.ParentNodeID != null)
                {
                    CreateLink l = new CreateLink
                    {
                        OriginID = (int)Node.ParentNodeID,
                        TargetID = node.NodeID,
                        Type     = "Parent"
                    };
                    Link = new Link(l);
                    db.Links.Add(Link);
                    db.SaveChanges();
                }


                if (Node.SiblingNodeID != null)
                {
                    CreateLink l = new CreateLink
                    {
                        OriginID = (int)Node.ParentNodeID,
                        TargetID = node.NodeID,
                        Type     = "Sibling"
                    };
                    Link = new Link(l);
                    db.Links.Add(Link);
                    //node.Links.Add(l);
                    db.SaveChanges();
                }

                //link to the layer.
                var layerLink = new LayerLink(new CreateLayerLink {
                    NodeID = node.NodeID, LayerID = Node.LayerID
                });
                db.LayerLinks.Add(layerLink);
                db.SaveChanges();
                return(Json(new { node = node, layerlink = new JsonLayerLink(layerLink), link = Link }));
            }

            return(Json(new { error = Generic.GetValidationErrors(ModelState) }));
        }
        protected ITransactionOperation CreateTransactionOperation(TransactionType transactionType)
        {
            ITransactionOperation transactionOperation;

            switch (transactionType)
            {
            case TransactionType.CreateNode:
                transactionOperation = new CreateNode(MapObjects.Parameters);
                break;

            case TransactionType.DeleteNode:
                transactionOperation = new DeleteNode(MapObjects.Parameters);
                break;

            case TransactionType.CreateRelationship:
                transactionOperation = new CreateRelationship(MapObjects.Parameters);
                break;

            case TransactionType.DeleteRelationship:
                transactionOperation = new DeleteRelationship(MapObjects.Parameters);
                break;

            case TransactionType.CreateDescriptor:
                transactionOperation = new CreateDescriptor(MapObjects.Parameters);
                break;

            case TransactionType.CreateMetadata:
                transactionOperation = new CreateMetadata(MapObjects.Parameters);
                break;

            case TransactionType.UpdateMetadata:
                transactionOperation = new UpdateMetadata(MapObjects.Parameters);
                break;

            case TransactionType.DeleteMetadata:
                transactionOperation = new DeleteMetadata(MapObjects.Parameters);
                break;

            case TransactionType.UpdateNode:
                transactionOperation = new UpdateNode(MapObjects.Parameters);
                break;

            case TransactionType.UpdateRelationship:
                transactionOperation = new UpdateRelationship(MapObjects.Parameters);
                break;

            case TransactionType.UpdateDescriptor:
                transactionOperation = new UpdateDescriptor(MapObjects.Parameters);
                break;

            default:
                throw new NotSupportedException("The requested transaction type doesn't exist.");
            }

            return(transactionOperation);
        }
Exemple #12
0
 public ContextMenuItem(Type type, string name, string category, string description, KeyCode shortcut, CreateNode funcPtr)
 {
     m_name             = name;
     m_nameWithShortcut = shortcut != KeyCode.None ? (name + " [ " + UIUtils.KeyCodeToString(shortcut) + " ]") : name;
     m_paletteName      = PALETTE_NAME_MOD_STR + m_name;
     m_type             = type;
     m_category         = category;
     m_description      = description;
     m_guiContent       = new GUIContent(m_nameWithShortcut, m_description);
     CreateNodeFuncPtr  = funcPtr;
 }
        private TNode[] CreateNodes(CreateNode <TNode> createNode)
        {
            var vertices = new TNode[verticesPerY * verticesPerX];
            int id       = 0;

            for (int j = 0; j < verticesPerY; ++j)
            {
                for (int i = 0; i < verticesPerX; ++i)
                {
                    vertices[id] = createNode(id, minX + i * dx, minY + j * dy, 0.0);
                    ++id;
                }
            }
            return(vertices);
        }
Exemple #14
0
        private TNode[] CreateNodes(CreateNode <TNode> createNode)
        {
            var nodes = new TNode[NodeColumns * NodeRows];
            int id    = 0;

            for (int row = 0; row < NodeRows; ++row)
            {
                for (int col = 0; col < NodeColumns; ++col)
                {
                    nodes[id] = createNode(id, coordinatesX[col], coordinatesY[row], 0.0);
                    ++id;
                }
            }
            return(nodes);
        }
Exemple #15
0
        public async Task CreateNodeAsync(CreateNode node)
        {
            var uri = string.Empty;

            if (node.UseRootNode)
            {
                uri = await GetCurrentUserRootUriAsync();
            }
            else
            {
                uri = $"{SmugMugConstants.Addresses.SmugMug}{node.NodeUri}";
            }

            var requestUri = uri + "!children";
            await apiService.PostRequestAsync(requestUri, node);
        }
Exemple #16
0
        private TNode[] CreateNodes(CreateNode <TNode> createNode)
        {
            var vertices = new TNode[verticesPerX * verticesPerY * verticesPerZ];
            int id       = 0;
            int start    = StartIDsAt0 ? 0 : 1;

            for (int k = 0; k < verticesPerZ; ++k)
            {
                for (int j = 0; j < verticesPerY; ++j)
                {
                    for (int i = 0; i < verticesPerX; ++i)
                    {
                        vertices[id] = createNode(start + id, minX + i * dx, minY + j * dy, minZ + k * dz);
                        ++id;
                    }
                }
            }
            return(vertices);
        }
Exemple #17
0
 public void HandleDropImage()
 {
     foreach (var kv in imageDropCommands.Commands)
     {
         if (pendingImages != null && kv.Key.WasIssued())
         {
             kv.Key.Consume();
             using (Document.Current.History.BeginTransaction()) {
                 foreach (var assetPath in pendingImages)
                 {
                     var node     = CreateNode.Perform(kv.Value);
                     var texture  = new SerializableTexture(assetPath);
                     var nodeSize = (Vector2)texture.ImageSize;
                     var nodeId   = Path.GetFileNameWithoutExtension(assetPath);
                     if (node is Widget)
                     {
                         SetProperty.Perform(node, nameof(Widget.Texture), texture);
                         SetProperty.Perform(node, nameof(Widget.Pivot), Vector2.Half);
                         SetProperty.Perform(node, nameof(Widget.Size), nodeSize);
                         SetProperty.Perform(node, nameof(Widget.Id), nodeId);
                     }
                     else if (node is ParticleModifier)
                     {
                         SetProperty.Perform(node, nameof(ParticleModifier.Texture), texture);
                         SetProperty.Perform(node, nameof(ParticleModifier.Size), nodeSize);
                         SetProperty.Perform(node, nameof(ParticleModifier.Id), nodeId);
                     }
                     OnNodeCreated(node);
                 }
                 Document.Current.History.CommitTransaction();
                 pendingImages = null;
             }
         }
         else
         {
             kv.Key.Consume();
         }
     }
 }
Exemple #18
0
 private void CreateImageTypeInstance(Type type, List <string> files)
 {
     onBeforeDrop?.Invoke();
     using (Document.Current.History.BeginTransaction()) {
         var nodes = new List <Node>(files.Count);
         foreach (var file in files)
         {
             if (!Utils.ExtractAssetPathOrShowAlert(file, out var assetPath, out var assetType))
             {
                 continue;
             }
             var node = CreateNode.Perform(type);
             nodes.Add(node);
             var texture  = new SerializableTexture(assetPath);
             var nodeSize = (Vector2)texture.ImageSize;
             var nodeId   = Path.GetFileNameWithoutExtension(assetPath);
             if (node is Widget)
             {
                 SetProperty.Perform(node, nameof(Widget.Texture), texture);
                 SetProperty.Perform(node, nameof(Widget.Pivot), Vector2.Half);
                 SetProperty.Perform(node, nameof(Widget.Size), nodeSize);
                 SetProperty.Perform(node, nameof(Widget.Id), nodeId);
             }
             else if (node is ParticleModifier)
             {
                 SetProperty.Perform(node, nameof(ParticleModifier.Texture), texture);
                 SetProperty.Perform(node, nameof(ParticleModifier.Size), nodeSize);
                 SetProperty.Perform(node, nameof(ParticleModifier.Id), nodeId);
             }
             postProcessNode?.Invoke(node);
         }
         foreach (var node in nodes)
         {
             SelectNode.Perform(node);
         }
         Document.Current.History.CommitTransaction();
     }
 }
Exemple #19
0
        private TNode[] ReadNodes(CreateNode <TNode> createNode)
        {
            string line;

            // Find node segment
            while (true)
            {
                line = reader.ReadLine();
                if (line[0] == '$')
                {
                    if (line.Equals("$Nodes"))
                    {
                        break;                        // Next line will be the nodes count.
                    }
                }
            }

            // Read the vertices
            int numVertices = int.Parse(reader.ReadLine());
            var vertices    = new TNode[numVertices];
            while (true)
            {
                line = reader.ReadLine();
                if (line[0] == '$')
                {
                    break;                 // This line is "$EndNodes". Next line will be the next segment.
                }
                else
                {
                    // Line = nodeID x y z
                    string[] words = line.Split(new char[] { ' ' });
                    int      id    = int.Parse(words[0]) - 1; // MSolve uses 0-based indexing
                    vertices[id] = createNode(id, double.Parse(words[1]), double.Parse(words[2]), double.Parse(words[3]));
                }
            }

            return(vertices);
        }
        public ITransactionOperation CreateTransactionOperation(TransactionType transactionType, MapParameters parameters)
        {
            ITransactionOperation transactionOperation;

            switch (transactionType)
            {
                case TransactionType.CreateNode:
                    transactionOperation = new CreateNode(_connection, parameters);
                    break;
                case TransactionType.DeleteNode:
                    transactionOperation = new DeleteNode(_connection, parameters);
                    break;
                case TransactionType.CreateRelationship:
                    transactionOperation = new CreateRelationship(_connection, parameters);
                    break;
                case TransactionType.DeleteRelationship:
                    transactionOperation = new DeleteRelationship(_connection, parameters);
                    break;
                case TransactionType.CreateDescriptor:
                    transactionOperation = new CreateDescriptor(_connection, parameters);
                    break;
                case TransactionType.CreateMetadata:
                    transactionOperation = new CreateMetadata(_connection, parameters);
                    break;
                case TransactionType.UpdateMetadata:
                    transactionOperation = new UpdateMetadata(_connection, parameters);
                    break;
                case TransactionType.DeleteMetadata:
                    transactionOperation = new DeleteMetadata(_connection, parameters);
                    break;
                default:
                    throw new NotSupportedException("The requested transaction type doesn't exist.");
            }

            return transactionOperation;
        }
Exemple #21
0
    public static void BuildRecursively(CQuadTreeNode node)
    {
        float subWidth   = node.Bound.width * 0.5f;
        float subHeight  = node.Bound.height * 0.5f;
        bool  isPartible = subWidth >= CQuadTreeConfig.CellSizeThreshole && subHeight >= CQuadTreeConfig.CellSizeThreshole;

        CreateNode _nodeCreator = (bnd) => { return(new CQuadTreeNode(bnd)); };
        CreateNode creator      = _nodeCreator;

        node.SetChildrenNode(new CQuadTreeNode[CQuadTreeNode.chilren] {
            creator(new Rect(node.Bound.xMin, node.Bound.yMin, subWidth, subHeight)),
            creator(new Rect(node.Bound.xMin + subWidth, node.Bound.yMin, subWidth, subHeight)),
            creator(new Rect(node.Bound.xMin, node.Bound.yMin + subHeight, subWidth, subHeight)),
            creator(new Rect(node.Bound.xMin + subWidth, node.Bound.yMin + subHeight, subWidth, subHeight)),
        });

        if (isPartible)
        {
            foreach (var sub in node._chilren)
            {
                BuildRecursively(sub);
            }
        }
    }
Exemple #22
0
 /// <summary>
 /// Handles files drop.
 /// </summary>
 /// <param name="files">Dropped files.</param>
 public void Handle(List <string> files)
 {
     using (Document.Current.History.BeginTransaction()) {
         foreach (var file in files.Where(f => Path.GetExtension(f) == ".ogg").ToList())
         {
             files.Remove(file);
             if (!Utils.ExtractAssetPathOrShowAlert(file, out var assetPath, out var assetType))
             {
                 continue;
             }
             var node   = CreateNode.Perform(typeof(Audio));
             var sample = new SerializableSample(assetPath);
             SetProperty.Perform(node, nameof(Audio.Sample), sample);
             SetProperty.Perform(node, nameof(Node.Id), Path.GetFileNameWithoutExtension(assetPath));
             SetProperty.Perform(node, nameof(Audio.Volume), 1);
             var key = new Keyframe <AudioAction> {
                 Frame = Document.Current.AnimationFrame,
                 Value = AudioAction.Play
             };
             SetKeyframe.Perform(node, nameof(Audio.Action), Document.Current.AnimationId, key);
         }
         Document.Current.History.CommitTransaction();
     }
 }
Exemple #23
0
        private void Handle(IEnumerable <string> files)
        {
            Handling?.Invoke();
            using (Document.Current.History.BeginTransaction()) {
                pendingImages = new List <string>();
                foreach (var file in files)
                {
                    try {
                        string assetPath, assetType;
                        if (!Utils.ExtractAssetPathOrShowAlert(file, out assetPath, out assetType) ||
                            !Utils.AssertCurrentDocument(assetPath, assetType))
                        {
                            continue;
                        }

                        var nodeCreatingEventArgs = new NodeCreatingEventArgs(assetPath, assetType);
                        NodeCreating?.Invoke(nodeCreatingEventArgs);
                        if (nodeCreatingEventArgs.Cancel)
                        {
                            continue;
                        }

                        var fileName = Path.GetFileNameWithoutExtension(assetPath);
                        switch (assetType)
                        {
                        case ".png":
                            pendingImages.Add(assetPath);
                            break;

                        case ".ogg": {
                            var node   = CreateNode.Perform(typeof(Audio));
                            var sample = new SerializableSample(assetPath);
                            SetProperty.Perform(node, nameof(Audio.Sample), sample);
                            SetProperty.Perform(node, nameof(Node.Id), fileName);
                            SetProperty.Perform(node, nameof(Audio.Volume), 1);
                            var key = new Keyframe <AudioAction> {
                                Frame = Document.Current.AnimationFrame,
                                Value = AudioAction.Play
                            };
                            SetKeyframe.Perform(node, nameof(Audio.Action), Document.Current.AnimationId, key);
                            OnNodeCreated(node);
                            break;
                        }

                        case ".tan":
                        case ".model":
                        case ".scene":
                            DropSceneContextMenu.Create(assetPath, assetType, NodeCreated);
                            break;
                        }
                    } catch (System.Exception e) {
                        AlertDialog.Show(e.Message);
                    }
                }

                if (pendingImages.Count > 0)
                {
                    var menu = new Menu();
                    foreach (var kv in imageDropCommands.Commands)
                    {
                        if (NodeCompositionValidator.Validate(Document.Current.Container.GetType(), kv.Value))
                        {
                            menu.Add(kv.Key);
                        }
                    }
                    menu.Popup();
                }
                Document.Current.History.CommitTransaction();
            }
        }
 public void Destroy()
 {
     CreateNodeFuncPtr = null;
     m_guiContent      = null;
     m_nodeAttributes  = null;
 }
Exemple #25
0
 private void Awake()
 {
     _boardManager = GameObject.FindGameObjectWithTag("BoardManager").GetComponent <BoardManager>();
     _aiManager    = GameObject.FindGameObjectWithTag("AIManager").GetComponent <AIManager>();
     _createNode   = new CreateNode();
 }
 public void CreateNode(CreateNode req)
 {
     _nodeService.Create(req);
 }
Exemple #27
0
 internal Codual(double x, CreateNode dx, int id)
 {
     this.Magnitude  = x;
     this.Id         = id;
     this.CreateNode = dx;
 }
        public void Handle(List <string> files)
        {
            var grid = Timeline.Instance.Grid;
            var rowLocationUnderMouseOnFilesDrop =
                SelectAndDragRowsProcessor.MouseToRowLocation(grid.RootWidget.Input.MousePosition);
            var handled = new List <string>();
            var cellUnderMouseOnFilesDrop = grid.CellUnderMouse();
            var animateTextureCellOffset  = 0;

            using (Document.Current.History.BeginTransaction()) {
                foreach (var file in files.ToList())
                {
                    if (Document.Current.Animation.IsCompound)
                    {
                        try {
                            // Dirty hack: using a file drag&drop mechanics for dropping animation clips on the grid.
                            var decodedAnimationId = Encoding.UTF8.GetString(Convert.FromBase64String(file));
                            AddAnimationClip.Perform(
                                new IntVector2(
                                    cellUnderMouseOnFilesDrop.X + animateTextureCellOffset,
                                    cellUnderMouseOnFilesDrop.Y),
                                decodedAnimationId);
                            return;
                        } catch { }
                    }
                    if (!Utils.ExtractAssetPathOrShowAlert(file, out var assetPath, out var assetType))
                    {
                        continue;
                    }
                    switch (assetType)
                    {
                    case ".png": {
                        if (Document.Current.Rows.Count == 0)
                        {
                            continue;
                        }
                        var widget = Document.Current.Rows[cellUnderMouseOnFilesDrop.Y].Components.Get <NodeRow>()?.Node as Widget;
                        if (widget == null)
                        {
                            continue;
                        }
                        var key = new Keyframe <ITexture> {
                            Frame    = cellUnderMouseOnFilesDrop.X + animateTextureCellOffset,
                            Value    = new SerializableTexture(assetPath),
                            Function = KeyFunction.Steep,
                        };
                        SetKeyframe.Perform(widget, nameof(Widget.Texture), Document.Current.AnimationId, key);
                        animateTextureCellOffset++;
                        break;
                    }

                    case ".ogg": {
                        var node = CreateNode.Perform(typeof(Audio));
                        if (rowLocationUnderMouseOnFilesDrop.HasValue)
                        {
                            var location = rowLocationUnderMouseOnFilesDrop.Value;
                            var row      = Document.Current.Rows.FirstOrDefault(r => r.Components.Get <Core.Components.NodeRow>()?.Node == node);
                            if (row != null)
                            {
                                if (location.Index >= row.Index)
                                {
                                    location.Index++;
                                }
                                SelectAndDragRowsProcessor.Probers.Any(p => p.Probe(row, location));
                            }
                        }
                        var sample = new SerializableSample(assetPath);
                        SetProperty.Perform(node, nameof(Audio.Sample), sample);
                        SetProperty.Perform(node, nameof(Node.Id), assetPath);
                        SetProperty.Perform(node, nameof(Audio.Volume), 1);
                        var key = new Keyframe <AudioAction> {
                            Frame = cellUnderMouseOnFilesDrop.X,
                            Value = AudioAction.Play
                        };
                        SetKeyframe.Perform(node, nameof(Audio.Action), Document.Current.AnimationId, key);
                        break;
                    }
                    }
                    files.Remove(file);
                }
                Document.Current.History.CommitTransaction();
            }
        }
Exemple #29
0
 CreateMesh(CreateNode <TNode> createNode)
 {
     TNode[] nodes = CreateNodes(createNode);
     CellConnectivity <TNode>[] elements = CreateElements(nodes);
     return(nodes, elements);
 }
Exemple #30
0
        IEnumerator <object> CreateSplinePoint3DTask()
        {
            command.Checked = true;
            while (true)
            {
                if (sv.InputArea.IsMouseOver())
                {
                    Utils.ChangeCursorIfDefault(MouseCursor.Hand);
                }
                CreateNodeRequestComponent.Consume <Node>(sv.Components);
                if (input.ConsumeKeyPress(Key.Mouse0))
                {
                    using (history.BeginTransaction()) {
                        SplinePoint3D point;
                        try {
                            point = (SplinePoint3D)CreateNode.Perform(typeof(SplinePoint3D), aboveSelected: false);
                        }
                        catch (InvalidOperationException e) {
                            AlertDialog.Show(e.Message);
                            yield break;
                        }
                        var spline  = (Spline3D)Document.Current.Container;
                        var vp      = spline.Viewport;
                        var ray     = vp.ScreenPointToRay(input.MousePosition);
                        var xyPlane = new Plane(new Vector3(0, 0, 1), 0).Transform(spline.GlobalTransform);
                        var d       = ray.Intersects(xyPlane);
                        if (d.HasValue)
                        {
                            var pos = (ray.Position + ray.Direction * d.Value) * spline.GlobalTransform.CalcInverted();
                            SetProperty.Perform(point, nameof(SplinePoint3D.Position), pos);
                            using (history.BeginTransaction()) {
                                while (input.IsMousePressed())
                                {
                                    history.RollbackTransaction();
                                    ray = vp.ScreenPointToRay(input.MousePosition);
                                    d   = ray.Intersects(xyPlane);
                                    if (d.HasValue)
                                    {
                                        var tangent = (ray.Position + ray.Direction * d.Value) *
                                                      spline.GlobalTransform.CalcInverted() - point.Position;
                                        SetProperty.Perform(point, nameof(SplinePoint3D.TangentA), tangent);
                                        SetProperty.Perform(point, nameof(SplinePoint3D.TangentB), -tangent);
                                    }
                                    history.CommitTransaction();
                                    yield return(null);
                                }

                                if (point.TangentA.Length < 0.01f)
                                {
                                    SetProperty.Perform(point, nameof(SplinePoint3D.TangentA), new Vector3(1, 0, 0));
                                    SetProperty.Perform(point, nameof(SplinePoint3D.TangentB), new Vector3(-1, 0, 0));
                                }
                            }
                        }
                        history.CommitTransaction();
                    }
                    history.CommitTransaction();
                }
                if (input.WasMousePressed(1) || input.WasKeyPressed(Key.Escape))
                {
                    break;
                }
                yield return(null);
            }

            command.Checked = false;
            Utils.ChangeCursorIfDefault(MouseCursor.Default);
        }