private void AddInstancedSpirals(int xCount, int yCount, int spiralLength) { double circleRadius = 10; int spiralCircles = spiralLength / 20; // One circle in the spiral is created from 20 lines var spiralPositions = CreateSpiralPositions(startPosition: new Point3D(0, 0, 0), circleXDirection: new Vector3D(1, 0, 0), circleYDirection: new Vector3D(0, 1, 0), oneSpiralCircleDirection: new Vector3D(0, 0, -10), circleRadius: circleRadius, segmentsPerCircle: 20, circles: spiralCircles); var spiralPositionCollection = new Point3DCollection(spiralPositions); double xStart = -xCount * circleRadius * 3 / 2; double yStart = -yCount * circleRadius * 3 / 2; MainViewport.BeginInit(); MainViewport.Children.Clear(); var materialGroup = new MaterialGroup(); materialGroup.Children.Add(new DiffuseMaterial(Brushes.Black)); materialGroup.Children.Add(new EmissiveMaterial(Brushes.White)); for (int x = 0; x < xCount; x++) { for (int y = 0; y < yCount; y++) { // PERFORMANCE NOTICE: // The AddSpiralVisual3D creates one PolyLineVisual3D for each sphere. // When creating many PolyLineVisual3D objects, the performance would be significantly improved if instead of many PolyLineVisual3D objects, // all the spheres would be rendered with only one MultiPolyLineVisual3D. // This would allow rendering all the 3D lines with only one draw call. var instancedMeshGeometryVisual3D = AddInstancedTubePath(spiralPositionCollection, Color4.White); instancedMeshGeometryVisual3D.Transform = new TranslateTransform3D(x * circleRadius * 3 + xStart, y * circleRadius * 3 + yStart, 0); //var tubePathVisual3D = new TubePathVisual3D() //{ // PathPositions = spiralPositionCollection, // Radius = 2, // Segments = 8, // GenerateTextureCoordinates = false, //}; //tubePathVisual3D.Material = materialGroup; //tubePathVisual3D.Transform = new TranslateTransform3D(x * circleRadius * 3 + xStart, y * circleRadius * 3 + yStart, 0); //MainViewport.Children.Add(tubePathVisual3D); } } MainViewport.EndInit(); }
// Calculate button click private void Button_Click(object sender, RoutedEventArgs e) { if (Validation.GetHasError(longText) || Validation.GetHasError(latText) || Validation.GetHasError(longSatText)) { return; } double longitude = double.Parse(longText.Text, CultureInfo.CurrentCulture) * ((longEast.IsChecked == true) ? -1 : 1); double latitude = double.Parse(latText.Text, CultureInfo.CurrentCulture) * ((latSouth.IsChecked == true) ? -1 : 1); double longitudeSat = double.Parse(longSatText.Text, CultureInfo.CurrentCulture) * ((longSatEast.IsChecked == true) ? -1 : 1); MainViewport.Focus(); double elevation = SatelliteAntennaCalculator.GetElevationAngle(longitude, latitude, longitudeSat); if (elevation > 0) { azimutText.Text = SatelliteAntennaCalculator.GetAzimutAngle(longitude, latitude, longitudeSat).ToString("0#.#0°", CultureInfo.CurrentCulture); elevationText.Text = elevation.ToString("0#.#0°", CultureInfo.CurrentCulture); declinationText.Text = SatelliteAntennaCalculator.GetDeclinationAngle(longitude, latitude, longitudeSat).ToString("0#.#0°", CultureInfo.CurrentCulture); azimutText.Background = elevationText.Background = declinationText.Background = Brushes.White; azimutText.Foreground = declinationText.Foreground = elevationText.Foreground = Brushes.Black; } else { SolidColorBrush b = new SolidColorBrush(Color.FromArgb(0x99, 0xFF, 00, 00)); azimutText.Background = elevationText.Background = declinationText.Background = b; azimutText.Foreground = declinationText.Foreground = elevationText.Foreground = Brushes.White; azimutText.Text = declinationText.Text = elevationText.Text = "Nicht empfangbar!"; } DefineModel(longitude, latitude, longitudeSat); CameraPhi = -SatelliteAntennaCalculator.DegToRad(longitudeSat); CameraTheta = 0; switch (SelectedCamera) { case 1: PositionCamera2(longitude, latitude, longitudeSat); break; default: PositionCamera(); break; } if (latitude != 0) { FillElevationCurveRows(latitude, longitude, longitudeSat); angleGrid.ItemsSource = rows; ElevationCurveTab.IsEnabled = true; } else { rows.Clear(); ElevationCurveTab.IsEnabled = false; tabControl.SelectedIndex = 0; } ExportTab.IsEnabled = true; }
private void currentCamera_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (SelectedCamera == 0) { PositionCamera(); } else { PositionCamera2(double.Parse(longText.Text) * ((longEast.IsChecked == true) ? -1 : 1), double.Parse(latText.Text) * ((latSouth.IsChecked == true) ? -1 : 1), double.Parse(longSatText.Text) * ((longSatEast.IsChecked == true) ? -1 : 1)); } MainViewport.Focus(); }
// This method uses standard Ab3d.PowerToys TubePathVisual3D to create tube paths private void AddSpirals_TubePathVisual3D(int xCount, int yCount, int spiralLength) { float circleRadius = 10; int spiralCircles = spiralLength / 20; // One circle in the spiral is created from 20 lines double xStart = -xCount * circleRadius * 1.5; double yStart = -yCount * circleRadius * 1.5; MainViewport.BeginInit(); MainViewport.Children.Clear(); var materialGroup = new MaterialGroup(); materialGroup.Children.Add(new DiffuseMaterial(Brushes.Black)); materialGroup.Children.Add(new EmissiveMaterial(Brushes.White)); for (int x = 0; x < xCount; x++) { for (int y = 0; y < yCount; y++) { var spiralPositions = CreateSpiralPositions(startPosition: new Point3D(x * circleRadius * 3 + xStart, y * circleRadius * 3 + yStart, 0), circleXDirection: new Vector3D(1, 0, 0), circleYDirection: new Vector3D(0, 1, 0), oneSpiralCircleDirection: new Vector3D(0, 0, -10), circleRadius: circleRadius, segmentsPerCircle: 20, circles: spiralCircles); var tubePathVisual3D = new TubePathVisual3D() { PathPositions = new Point3DCollection(spiralPositions), Radius = 2, Segments = 8, GenerateTextureCoordinates = false, }; tubePathVisual3D.Material = materialGroup; //tubePathVisual3D.Transform = new TranslateTransform3D(x * circleRadius * 3 + xStart, y * circleRadius * 3 + yStart, 0); MainViewport.Children.Add(tubePathVisual3D); } } MainViewport.EndInit(); }
private static void EngineApp_Tick(float delta) { // Perform update viewport, attached scene, UI container. MainViewport.PerformTick(delta); // Process screen messages. ScreenMessages.PerformTick(delta); //engine console EngineConsole.PerformTick(delta); if (firstTick) { FirstTickActions(); } firstTick = false; }
private void AddSpirals(int xCount, int yCount, int spiralLength) { double circleRadius = 10; int spiralCircles = spiralLength / 20; // One circle in the spiral is created from 20 lines var spiralPositions = CreateSpiralPositions(startPosition: new Point3D(0, 0, 0), circleXDirection: new Vector3D(1, 0, 0), circleYDirection: new Vector3D(0, 1, 0), oneSpiralCircleDirection: new Vector3D(0, 0, -10), circleRadius: circleRadius, segmentsPerCircle: 20, circles: spiralCircles); var spiralPositionCollection = new Point3DCollection(spiralPositions); double xStart = -xCount * circleRadius * 3 / 2; double yStart = -yCount * circleRadius * 3 / 2; MainViewport.BeginInit(); MainViewport.Children.Clear(); for (int x = 0; x < xCount; x++) { for (int y = 0; y < yCount; y++) { // PERFORMANCE NOTICE: // The AddSpiralVisual3D creates one PolyLineVisual3D for each sphere. // When creating many PolyLineVisual3D objects, the performance would be significantly improved if instead of many PolyLineVisual3D objects, // all the spheres would be rendered with only one MultiPolyLineVisual3D. // This would allow rendering all the 3D lines with only one draw call. AddSpiralVisual3D(spiralPositionCollection, new TranslateTransform3D(x * circleRadius * 3 + xStart, y * circleRadius * 3 + yStart, 0)); } } MainViewport.EndInit(); }
private void button_Click(object sender, RoutedEventArgs e) { try { ModelVisual3D model = (ModelVisual3D)MainViewport.Children.ElementAt(1); model = null; MainViewport.Children.RemoveAt(1); } catch { } try { Coordinates coordinates = new Coordinates(float.Parse(tbNorth.Text), float.Parse(tbEast.Text)); comm.StartMap(coordinates, Int32.Parse(tbRange.Text)); markers = comm.markers; MainViewport.Visibility = Visibility.Visible; Render(); MainViewport.UpdateLayout(); } catch { MessageBox.Show("You have entered an invalid value.", "Error", MessageBoxButton.OK, MessageBoxImage.Warning); } }
public void UpdateUi() { MainViewport.Children.Clear(); //if (!this.IsLoaded) // return; if (ModelToVisualize == null) { return; } if (ElementVisualThickness == 0) { ElementVisualThickness = GetSmartElementThichness(); } if (TargetCombination == null) { return; } var elementsBuilder = new MeshBuilder(false, false); var forcesBuilder = new MeshBuilder(false, false); var internalForces = GetLocalInternalForces(); #region determining scale var max = 0.0; foreach (var internalForce in internalForces) { foreach (var point in internalForce) { max = Math.Max(max, Math.Abs(point.Y)); max = Math.Max(max, Math.Abs(point.Z)); } } var minElementLength = ModelToVisualize.Elements.Select(i => i.GetElementLength()).Where(i => i > 0).Min(); var sc = 0.33 * minElementLength / max; foreach (var internalForce in internalForces) { for (var i = 0; i < internalForce.Length; i++) { internalForce[i] = new Point(internalForce[i].X, internalForce[i].Y * sc, internalForce[i].Z * sc); } } #endregion #region Adding elements var c = ModelToVisualize.Elements.Count; for (var i = 0; i < c; i++) { var elm = ModelToVisualize.Elements[i]; switch (elm.ElementType) { case ElementType.Undefined: //throw new Exception(); break; case ElementType.FrameElement2Node: AddFrameElement(elementsBuilder, elm as FrameElement2Node); AddFrameElementLoad(forcesBuilder, elm as FrameElement2Node, internalForces[i]); break; case ElementType.TrussElement2Noded: AddTrussElement(elementsBuilder, elm as TrussElement2Node); break; default: throw new ArgumentOutOfRangeException(); } } #endregion var gradient = new LinearGradientBrush(); gradient.GradientStops.Add(new GradientStop(Colors.Blue, 0)); gradient.GradientStops.Add(new GradientStop(Colors.Cyan, 0.2)); gradient.GradientStops.Add(new GradientStop(Colors.Green, 0.4)); gradient.GradientStops.Add(new GradientStop(Colors.Yellow, 0.6)); gradient.GradientStops.Add(new GradientStop(Colors.Red, 0.8)); gradient.GradientStops.Add(new GradientStop(Colors.White, 1)); var elmMsh = elementsBuilder.ToMesh(true); var frcMsh = forcesBuilder.ToMesh(true); var modelGroup = new Model3DGroup(); var elmMat = MaterialHelper.CreateMaterial(gradient, null, null, 1, 0); var frcMat = MaterialHelper.CreateMaterial(gradient, null, null, 0.5, 0); var elmGeometry = new GeometryModel3D(elmMsh, elmMat) { BackMaterial = elmMat }; var frcGeometry = new GeometryModel3D(frcMsh, frcMat) { BackMaterial = elmMat }; modelGroup.Children.Add(elmGeometry); modelGroup.Children.Add(frcGeometry); var myModelVisual3D = new ModelVisual3D(); myModelVisual3D.Content = modelGroup; MainViewport.Children.Add(myModelVisual3D); MainViewport.Children.Add(new DefaultLights()); MainViewport.ZoomExtents(); }
// This method uses low level DXEngine objects to create tube paths. private void AddSpirals_MeshObjectNode(int xCount, int yCount, int spiralLength, bool useMultiThreading) { float circleRadius = 10; int spiralCircles = spiralLength / 20; // One circle in the spiral is created from 20 lines var dxMaterial = new Ab3d.DirectX.Materials.StandardMaterial() { DiffuseColor = Color3.Black, EmissiveColor = Color3.White, Effect = _solidColorEffect }; _disposables.Add(dxMaterial); float xStart = -xCount * circleRadius * 1.5f; float yStart = -yCount * circleRadius * 1.5f; if (useMultiThreading) { // On i7 6700 with 4 cores with hyper-threading the multi-threaded code path is almost 100% faster then single threaded solution. var initializedMeshes = new MeshBase[xCount, yCount]; var dxDevice = MainDXViewportView.DXScene.DXDevice; Parallel.For(0, xCount * yCount, xy => { int x = (int)xy / yCount; int y = (int)xy % yCount; var spiralPositions = CreateSpiralPositions(startPosition: new Vector3(x * circleRadius * 3 + xStart, y * circleRadius * 3 + yStart, 0), circleXDirection: new Vector3(1, 0, 0), circleYDirection: new Vector3(0, 1, 0), oneSpiralCircleDirection: new Vector3(0, 0, -10), circleRadius: circleRadius, segmentsPerCircle: 20, circles: spiralCircles); MeshBase tubePathMesh = CreateTubePathMesh(spiralPositions, radius: 1.0f, segmentsCount: 8, isTubeClosed: true, tubeColor: Color4.White); // Create DirectX resources in the background thread (this creates buffers on the GPU and send data there from the main memory) tubePathMesh.InitializeResources(dxDevice); // Save the mesh initializedMeshes[x, y] = tubePathMesh; }); // Now most of the work was done in multi-threaded way. // So we only need to create the MeshObjectNode and add that to the Scene. This needs to be done on the UI thread. MainViewport.BeginInit(); MainViewport.Children.Clear(); for (int x = 0; x < xCount; x++) { for (int y = 0; y < yCount; y++) { var tubePathMesh = initializedMeshes[x, y]; var meshObjectNode = new Ab3d.DirectX.MeshObjectNode(tubePathMesh, dxMaterial); var tubePathVisual3D = new SceneNodeVisual3D(meshObjectNode); // IMPORTANT: // // In this performance demo we create new spiral positions and new tubePathMesh for each spiral. // But because the spirals are the same, we could create only one spiral positions and one tubePathMesh // and then use that tubePathMesh to create multiple MeshObjectNode and SceneNodeVisual3D objects // each of them with its Transform property set - as shown in the line below. // // Sharing one mesh would provide much better performance and lower memory usage, // but for this demo we want to simulate cration of huge tube paths in the background thread. // //tubePathVisual3D.Transform = new TranslateTransform3D(x * circleRadius * 3 + xStart, y * circleRadius * 3 + yStart, 0); _disposables.Add(tubePathMesh); // We did not add that in the background thread (we would need locking for that) so we need to do that now _disposables.Add(meshObjectNode); MainViewport.Children.Add(tubePathVisual3D); } } MainViewport.EndInit(); } else { // No multi-threading MainViewport.BeginInit(); MainViewport.Children.Clear(); for (int x = 0; x < xCount; x++) { for (int y = 0; y < yCount; y++) { var spiralPositions2 = CreateSpiralPositions(startPosition: new Point3D(x * circleRadius * 3 + xStart, y * circleRadius * 3 + yStart, 0), circleXDirection: new Vector3D(1, 0, 0), circleYDirection: new Vector3D(0, 1, 0), oneSpiralCircleDirection: new Vector3D(0, 0, -10), circleRadius: circleRadius, segmentsPerCircle: 20, circles: spiralCircles); var spiralPositions = spiralPositions2.Select(p => p.ToVector3()).ToArray(); //var spiralPositions = CreateSpiralPositions(startPosition: new Vector3(x * circleRadius * 3 + xStart, y * circleRadius * 3 + yStart, 0), // circleXDirection: new Vector3(1, 0, 0), // circleYDirection: new Vector3(0, 1, 0), // oneSpiralCircleDirection: new Vector3(0, 0, -10), // circleRadius: circleRadius, // segmentsPerCircle: 20, // circles: spiralCircles); var tubePathMesh = CreateTubePathMesh(spiralPositions, radius: 2, segmentsCount: 8, isTubeClosed: true, tubeColor: Color4.White); var meshObjectNode = new Ab3d.DirectX.MeshObjectNode(tubePathMesh, dxMaterial); var tubePathVisual3D = new SceneNodeVisual3D(meshObjectNode); //tubePathVisual3D.Transform = new TranslateTransform3D(x * circleRadius * 3 + xStart, y * circleRadius * 3 + yStart, 0); _disposables.Add(meshObjectNode); MainViewport.Children.Add(tubePathVisual3D); } } MainViewport.EndInit(); } }
private void ButtonBase_OnClick(object sender, RoutedEventArgs e) { MainViewport.ZoomExtents(); }