Beispiel #1
0
        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();
        }
Beispiel #2
0
        // 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();
        }
Beispiel #3
0
        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();
        }
Beispiel #4
0
        // 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();
            }
        }