/// <summary> /// Finds the nearest point and its normal. /// </summary> /// <param name="viewport"> /// The viewport. /// </param> /// <param name="position"> /// The position. /// </param> /// <param name="point"> /// The point. /// </param> /// <param name="normal"> /// The normal. /// </param> /// <param name="model"> /// The model. /// </param> /// <returns> /// The find nearest. /// </returns> public static bool FindNearest(this Viewport3DX viewport, Point position, out Point3D point, out Vector3D normal, out Element3D model) { point = new Point3D(); normal = new Vector3D(); model = null; var camera = viewport.Camera as ProjectionCamera; if (camera == null) { return(false); } var hits = FindHits(viewport, position); if (hits.Count > 0) { point = hits[0].PointHit.ToPoint3D(); normal = hits[0].NormalAtHit.ToVector3D(); model = hits[0].ModelHit as Element3D; return(true); } else { // check for nearest points in the scene // TODO!! return(false); } }
private void BindPlacement(ObjectPlacement placement, Helix.Element3D model) { IMultiValueConverter converter = EulerTransformConverter.Instance; var rotationPath = nameof(ObjectPlacement.Rotation); if (placement.PaletteKey == PaletteType.Decal) { converter = QuaternionTransformConverter.Instance; rotationPath = nameof(ObjectPlacement.QRotation); } var binding = new MultiBinding { Converter = converter, Mode = BindingMode.TwoWay }; binding.Bindings.Add(new Binding(nameof(ObjectPlacement.Position)) { Mode = BindingMode.TwoWay }); binding.Bindings.Add(new Binding(rotationPath) { Mode = BindingMode.TwoWay }); binding.Bindings.Add(new Binding(nameof(ObjectPlacement.Scale)) { Mode = BindingMode.TwoWay }); model.DataContext = placement; BindingOperations.SetBinding(model, Helix.Element3D.TransformProperty, binding); }
/// <summary> /// Remove object highlight after deselection. /// </summary> /// <param name="oldSelection"></param> private void removeHighlight(Element3D oldSelection) { // remove highlight from meshes MeshGeometryModel3D meshSel = oldSelection as MeshGeometryModel3D; meshSel.PostEffects = null; }
public override int GetElementIndex(SceneNodeModel treeNode, Helix.Element3D element) { var nodeTag = treeNode.Tag; if (treeNode.NodeType == NodeType.AiFiringPositions) { return((nodeTag as AiZone).FiringPositions.IndexOf(element.DataContext as AiFiringPosition)); } else if (treeNode.NodeType == NodeType.AiZoneAreas) { return((nodeTag as AiZone).Areas.IndexOf(element.DataContext as AiArea)); } else if (treeNode.NodeType == NodeType.AiStartingLocations) { return((nodeTag as AiEncounter).StartingLocations.IndexOf(element.DataContext as AiStartingLocation)); } else if (treeNode.NodeType == NodeType.AiGroupStartingLocations) { return((nodeTag as AiSquad).GroupStartLocations.IndexOf(element.DataContext as AiStartingLocation)); } else if (treeNode.NodeType == NodeType.AiSoloStartingLocations) { return((nodeTag as AiSquad).SoloStartLocations.IndexOf(element.DataContext as AiStartingLocation)); } else { throw new ArgumentException(); } }
public void SetSelectedElement(Helix.Element3D model) { if (model != null && model.IsDescendentOf(manipulator)) { return; } else { model = model?.FindInstanceParent(); } if (model is BoxManipulator3D || model == selector.Target) { return; } if (model != null) { manipulator.CenterOffset = model.GetTotalBounds(true).Center; manipulator.Visibility = Visibility.Visible; } else { manipulator.Visibility = Visibility.Collapsed; } manipulator.Target = selector.Target = model; highlighter.Target = null; GetHost()?.OnElementSelected(model); }
private void ClearChildren() { element = null; foreach (var element in modelGroup.Children.ToList()) { modelGroup.Children.Remove(element); element.Dispose(); } }
public static Helix.Element3D FindInstanceParent(this Helix.Element3D element) { if (element is IMeshNode) { return(element); } return(element.EnumerateAncestors().Reverse().FirstOrDefault(e => e is IMeshNode)); }
private void BindFiringPosition(AiFiringPosition fpos, Helix.Element3D model) { var binding = new Binding(nameof(AiFiringPosition.Position)) { Converter = TranslationTransformConverter.Instance, Mode = BindingMode.TwoWay }; model.DataContext = fpos; BindingOperations.SetBinding(model, Helix.Element3D.TransformProperty, binding); }
private void SetLod(int index) { TreeViewItems.Clear(); ClearChildren(); element = modelFactory.CreateRenderModel(modelId, index); modelGroup.Children.Add(element); AddRenderModelNodes(renderModel.Regions, r => r.Permutations); AddRenderModelNodes(renderModel.InstanceGroups, g => g.Instances); }
/// <summary> /// Binds this manipulator to a given Model3D. /// </summary> /// <param name="source"> /// Source Visual3D which receives the manipulator transforms. /// </param> public void Bind(Element3D source) { BindingOperations.SetBinding(this, TargetTransformProperty, new Binding("Transform") { Source = source }); BindingOperations.SetBinding(this, TransformProperty, new Binding("Transform") { Source = source }); }
public void OnElementSelected(Helix.Element3D element) { if (element?.DataContext == null) { return; } var handler = scenario.GetNodeTypeHandler(scenario.SelectedNodeType); if (handler != null) { scenario.SelectedItemIndex = handler.GetElementIndex(scenario.SelectedNode, element); } }
public static IEnumerable <Helix.Element3D> EnumerateAncestors(this Helix.Element3D element) { while (element.Parent != null) { var parent = element.Parent as Helix.Element3D; if (parent == null) { break; } yield return(parent); element = parent; } }
public static bool IsDescendentOf(this Helix.Element3D element, Helix.Element3D target) { var parent = element.Parent as Helix.Element3D; if (parent == null) { return(false); } else if (parent == target) { return(true); } else { return(IsDescendentOf(parent, target)); } }
/// <summary> /// Reverts any temporary material previews upon deselection /// </summary> private void revertMaterial(Element3D oldSelection) { // remove any temp preview colors Type objectType = oldSelection?.GetType(); if (objectType == typeof(MeshGeometryModel3D)) { MeshGeometryModel3D meshSel = oldSelection as MeshGeometryModel3D; if (oldSelection.DataContext.GetType() == typeof(cubeDataModel)) { // get the pdm cubeDataModel pdm = oldSelection.DataContext as cubeDataModel; // reset the color meshSel.Material = projectMatToHelixMatConverter.Convert(pdm.material) as Material; } } }
public override bool AddPendingItem(Element3D item) { if (Enabled && item is GeometryModel3D) { var model = item as GeometryModel3D; model.OnTransformBoundChanged -= GeometryModel3DOctreeManager_OnBoundInitialized; model.OnTransformBoundChanged += GeometryModel3DOctreeManager_OnBoundInitialized; if (model.Bounds != ZeroBound) { AddItem(model); } return(true); } else { return(false); } }
//public void RefreshObject(string paletteKey, ObjectPlacement placement, string fieldId) //{ // var holder = InstanceHolders[paletteKey]; // var index = holder.Definition.Placements.IndexOf(placement); // if (fieldId == FieldId.Variant) // (holder.Elements[index] as ObjectModel3D)?.SetVariant(placement.Variant); // else if (fieldId == FieldId.PaletteIndex) // { // ConfigurePlacement(holder, index); // var info = holder.GetInfoForIndex(index); // info.TreeItem.Header = info.Placement.GetDisplayName(); // info.TreeItem.Tag = info.Element; // var listItem = bspModel.Items.FirstOrDefault(i => i.Tag == info.Placement); // if (listItem != null) // listItem.Content = info.TreeItem.Header; // } //} private void BindPlacement(InstancePlacement placement, Helix.Element3D model) { var binding = new MultiBinding { Converter = MatrixTransformConverter.Instance, Mode = BindingMode.TwoWay }; binding.Bindings.Add(new Binding(nameof(InstancePlacement.TransformScale)) { Mode = BindingMode.TwoWay }); binding.Bindings.Add(new Binding(nameof(InstancePlacement.Transform)) { Mode = BindingMode.TwoWay }); model.DataContext = placement; BindingOperations.SetBinding(model, Helix.Element3D.TransformProperty, binding); }
private void BindStartLocation(AiStartingLocation pos, Helix.Element3D model) { var binding = new MultiBinding { Converter = EulerTransformConverter.Instance, Mode = BindingMode.TwoWay }; binding.Bindings.Add(new Binding(nameof(AiStartingLocation.Position)) { Mode = BindingMode.TwoWay }); binding.Bindings.Add(new Binding(nameof(AiStartingLocation.Rotation)) { Mode = BindingMode.TwoWay }); model.DataContext = pos; BindingOperations.SetBinding(model, Helix.Element3D.TransformProperty, binding); }
private void AddItem(Element3D item) { if (Enabled && item is GeometryModel3D) { var tree = mOctree; UpdateOctree(null); var model = item as GeometryModel3D; if (tree == null) { RequestRebuild(); } else { bool succeed = true; int counter = 0; while (!tree.Add(model)) { var direction = (model.Bounds.Minimum + model.Bounds.Maximum) - (tree.Bound.Minimum + tree.Bound.Maximum); tree = tree.Expand(ref direction) as GeometryModel3DOctree; ++counter; if (counter > 10) { #if DEBUG throw new Exception("Expand tree failed"); #else succeed = false; break; #endif } } if (succeed) { UpdateOctree(tree); SubscribeBoundChangeEvent(model); } else { RequestRebuild(); } } } }
public override void RemoveItem(Element3D item) { if (Enabled && Octree != null && item is GeometryModel3D) { var tree = mOctree; UpdateOctree(null); var model = item as GeometryModel3D; model.OnTransformBoundChanged -= GeometryModel3DOctreeManager_OnBoundInitialized; UnsubscribeBoundChangeEvent(model); if (!tree.RemoveByBound(model)) { Console.WriteLine("Remove failed."); } else { tree = tree.Shrink() as GeometryModel3DOctree; } UpdateOctree(tree); } }
public void LoadGeometry(IIndexItem modelTag, string fileName) { if (!CanOpenTag(modelTag)) { throw new NotSupportedException($"{modelTag.ClassName} tags are not supported."); } if (DirectContentTags.Any(t => modelTag.ClassCode.ToLower() == t)) { IRenderGeometry geometry; if (ContentFactory.TryGetGeometryContent(modelTag, out geometry)) { LoadGeometry(geometry, fileName); return; } else { throw new ArgumentException($"Could not load geometry from tag", nameof(modelTag)); } } TabModel.ToolTip = fileName; TabModel.Header = Utils.GetFileName(fileName); ClearChildren(); modelId = modelTag.Id; modelFactory.LoadTag(modelTag, false); element = modelFactory.CreateObjectModel(modelId); AvailableLods = objectModel.Variants; modelGroup.Children.Add(element); SetVariant(Math.Max(0, AvailableLods.ToList().IndexOf(objectModel.DefaultVariant))); renderGeometry = null; IsExportable = false; }
/// <summary> /// Finds the nearest point and its normal. /// </summary> /// <param name="viewport"> /// The viewport. /// </param> /// <param name="position"> /// The position. /// </param> /// <param name="point"> /// The point. /// </param> /// <param name="normal"> /// The normal. /// </param> /// <param name="model"> /// The model. /// </param> /// <param name="node"></param> /// <returns> /// The find nearest. /// </returns> public static bool FindNearest(this Viewport3DX viewport, Point position, out Point3D point, out Vector3D normal, out Element3D model, out SceneNode node) { var succ = viewport.FindNearest(position.ToVector2(), out var p, out var n, out var m); point = p.ToPoint3D(); normal = n.ToVector3D(); if (m is Element3D ele) { model = ele; node = ele.SceneNode; } else if (m is SceneNode nd) { node = nd; model = null; } else { model = null; node = null; } return(succ); }
public void OnElementSelected(Helix.Element3D element) { bspModel.PropertyView.CurrentItem = element?.DataContext as InstancePlacement; }
/// <summary> /// Traverses the Visual3D/Element3D tree and invokes the specified action on each Element3D of the specified type. /// </summary> /// <typeparam name="T"> /// The type filter. /// </typeparam> /// <param name="element"> /// The element. /// </param> /// <param name="action"> /// The action. /// </param> public static void Traverse <T>(this Element3D element, Action <T, Transform3D> action) where T : Element3D { var sceneNode = new SceneNode[] { element.SceneNode }; Traverse(element, action); }
public override bool AddPendingItem(Element3D item) { throw new NotImplementedException(); }
public override void RemoveItem(Element3D item) { throw new NotImplementedException(); }
public abstract bool AddPendingItem(Element3D item);
public override int GetElementIndex(SceneNodeModel treeNode, Helix.Element3D element) { return(scenario.StartingPositions.IndexOf(element.DataContext as StartPosition)); }
public abstract void RemoveItem(Element3D item);
/// <summary> /// Traverses the Visual3D/Element3D tree and invokes the specified action on each Element3D of the specified type. /// </summary> /// <typeparam name="T"> /// The type filter. /// </typeparam> /// <param name="element"> /// The element. /// </param> /// <param name="action"> /// The action. /// </param> public static void Traverse <T>(this Element3D element, Action <T, Transform3D> action) where T : Element3D { Traverse(element, action); }
//only called if HandlesNodeType, called when an element is clicked in the viewport public virtual int GetElementIndex(SceneNodeModel treeNode, Helix.Element3D element) { throw new NotImplementedException(); }