コード例 #1
0
        // Creates a ScreenSpaceLineNode with multiple positions and with different colors for positions.
        public static ScreenSpaceLineNode CreateColoredLineNode(Vector3[] positions,
                                                                Color4[] lineColors,
                                                                float lineThickness,
                                                                DisposeList disposables,
                                                                bool isPolyLine = true) // when false we create a multi-line line (each individual line is defined by 2 position)
        {
            var lineMaterial = new PositionColoredLineMaterial()
            {
                LineColor      = Color4.White, // When PositionColors are used, then LineColor is used as a mask - each color is multiplied by LineColor - use White to preserve PositionColors
                LineThickness  = lineThickness,
                PositionColors = lineColors,
                IsPolyLine     = isPolyLine
            };

            // NOTE: When rendering multi-lines we need to set isLineStrip to false
            var screenSpaceLineNode = new ScreenSpaceLineNode(positions, isLineClosed: false, isLineStrip: isPolyLine, lineMaterial: lineMaterial);

            if (disposables != null)
            {
                disposables.Add(screenSpaceLineNode);
                disposables.Add(lineMaterial);
            }

            return(screenSpaceLineNode);
        }
コード例 #2
0
        private void CreateTest3DObjects()
        {
            TestObjectsModelVisual3D.Children.Clear();


            // Reset ReadZBuffer to its default value
            _dxLineMaterial.ReadZBuffer = true;

            var objectMaterial = new DiffuseMaterial(Brushes.Silver);

            // Uncomment the following line to test drawing hidden lines behind transparent objects:
            //objectMaterial = new DiffuseMaterial(new SolidColorBrush(Color.FromArgb(230, 100, 100, 100)));


            CreateCylinderWithCircles(new Point3D(0, 0, -5), 10, 30, objectMaterial);

            CreateBoxWithEdgeLines(new Point3D(0, 10, 40), new Size3D(20, 20, 20), objectMaterial);

            CreateTeapotWireframeModel(new Point3D(0, 10, -50), new Size3D(50, 50, 50), objectMaterial);


            // The following code shows how to create a DXEngine's ScreenSpaceLineNode directly (see DXEngineAdvanced/ScreenSpaceLineNodeSample for more info):
            var positions = new Vector3[2];

            positions[0] = new Vector3(-70, -3, 60);
            positions[1] = new Vector3(70, -3, 60);

            _screenSpaceLineNode = new ScreenSpaceLineNode(positions, isLineStrip: false, isLineClosed: false, lineMaterial: _dxLineMaterial);

            // To add ScreenSpaceLineNode into WPF's objects hierarchy we use SceneNodeVisual3D
            var sceneNodeVisual3D = new SceneNodeVisual3D(_screenSpaceLineNode);

            TestObjectsModelVisual3D.Children.Add(sceneNodeVisual3D);
        }
コード例 #3
0
        private void ChangePositions(ScreenSpaceLineNode screenSpaceLineNode)
        {
            ChangePositions(screenSpaceLineNode.Positions);

            screenSpaceLineNode.UpdatePositions();
            screenSpaceLineNode.UpdateBounds();
        }
コード例 #4
0
        public ScreenSpaceLineNodeSample()
        {
            InitializeComponent();

            _disposables = new DisposeList();

            var linePositions = CreateLinePositions(xOffset: 0, zOffset: -50);

            _screenSpaceLineNode1 = CreateLinesWithPositions(linePositions, isLineStrip: false, isPolyLine: false, isLineClosed: false, lineColor: Colors.Blue, xOffset: -90);
            AddTextBlockVisual3D(xOffset: -90, isLineStrip: false, isPolyLine: false);

            _screenSpaceLineNode2 = CreateLinesWithPositions(linePositions, isLineStrip: true, isPolyLine: false, isLineClosed: false, lineColor: Colors.Green, xOffset: -30);
            AddTextBlockVisual3D(xOffset: -30, isLineStrip: true, isPolyLine: false);

            _screenSpaceLineNode3 = CreateLinesWithPositions(linePositions, isLineStrip: true, isPolyLine: true, isLineClosed: false, lineColor: Colors.Red, xOffset: 30);
            AddTextBlockVisual3D(xOffset: 30, isLineStrip: true, isPolyLine: true);

            _screenSpaceLineNode4 = CreateLinesWithLineMesh(linePositions, isLineStrip: false, isLineClosed: false, isPolyLine: false, lineColor: Colors.Orange, xOffset: 90, screenSpaceLineMesh: out _screenSpaceLineMesh);
            AddTextBlockVisual3D(xOffset: 90, "using\r\nScreenSpaceLineMesh");

            Unloaded += delegate
            {
                Dispose();
            };
        }
コード例 #5
0
 public WLineRenderData(ScreenSpaceLineNode _node, LineSelectorData _selectData,
                        PositionColoredLineMaterial mtl, List <SharpDX.Color4> _colors)
 {
     node       = _node;
     selectData = _selectData;
     material   = mtl;
     colors     = _colors;
 }
コード例 #6
0
        void CreateColoredPolyLine(int count, int layer)
        {
            Vector3 preV    = new Vector3(0, layer, 0);
            Color4  preC    = Color4.White;
            var     points  = new List <Point3D>();
            var     vectors = new List <Vector3>();
            var     colors  = new List <SharpDX.Color4>();

            for (int i = 0; i < count; i++)
            {
                float   max = 1f;
                Vector3 v   = new Vector3(1, layer, 0);
                v.X += preV.X;
                //Console.WriteLine("{0} : {1} {2} {3}", i, v.X, v.Y, v.Z);
                colors.Add(preC);
                points.Add(new Point3D((double)v.X, (double)v.Y, (double)v.Z));
                vectors.Add(v);
                preV = v;
            }

            DisposeList disposables   = new DisposeList();
            float       lineThickness = 5;
            bool        isPolyLine    = false;
            var         lineMaterial  = new PositionColoredLineMaterial()
            {
                LineColor      = Color4.White, // When PositionColors are used, then LineColor is used as a mask - each color is multiplied by LineColor - use White to preserve PositionColors
                LineThickness  = lineThickness,
                PositionColors = colors.ToArray(),
                IsPolyLine     = isPolyLine
            };

            // NOTE: When rendering multi-lines we need to set isLineStrip to false
            var screenSpaceLineNode = new ScreenSpaceLineNode(vectors.ToArray(), isLineClosed: false, isLineStrip: true, lineMaterial: lineMaterial);

            if (disposables != null)
            {
                disposables.Add(screenSpaceLineNode);
                disposables.Add(lineMaterial);
            }

            var sceneNodeVisual = new SceneNodeVisual3D(screenSpaceLineNode);

            MainViewport.Children.Add(sceneNodeVisual);
            bool isVisualConnected;
            var  lineSelectorData = new LineSelectorData(points, true);

            lineSelectorData.PositionsTransform3D = Ab3d.Utilities.TransformationsHelper.GetVisual3DTotalTransform(sceneNodeVisual, true, out isVisualConnected);
            _lineSelectorData.Add(lineSelectorData);
            var _data = new WLineRenderData(screenSpaceLineNode, lineSelectorData, lineMaterial, colors);

            lrData.Add(_data);
        }
コード例 #7
0
        private ScreenSpaceLineNode CreateLinesWithLineMesh(Vector3[] linePositions, bool isLineStrip, bool isLineClosed, Color lineColor, float xOffset, out ScreenSpaceLineMesh screenSpaceLineMesh)
        {
            if (linePositions == null || linePositions.Length < 2)
            {
                screenSpaceLineMesh = null;
                return(null);
            }

            // If line is closed but the first position is not the same as the last position, then add the first position as the last one
            if (isLineClosed && linePositions[0] != linePositions[linePositions.Length - 1])
            {
                Array.Resize(ref linePositions, linePositions.Length + 1);
                linePositions[linePositions.Length - 1] = linePositions[0];
            }


            // If we can easily calculate the bounding box from line positions
            // it is recommended to specify it in the ScreenSpaceLineMesh constructor.
            // If boundingBox is not specified, it will be calculated in the ScreenSpaceLineMesh constructor with checking all the positions.
            //
            // NOTE: If bounding box is not correct then camera's near and far planes can be invalid and this can cut some 3D objects at near or far plane (when DXScene.OptimizeNearAndFarCameraPlanes is true - by default)
            //var boundingBox = new BoundingBox(new Vector3(startX, 0, startZ), new Vector3(startX + linesCount * margin, 0, endZ));

            // Create ScreenSpaceLineMesh - it is used to create DirectX vertex buffer from positions
            screenSpaceLineMesh = new ScreenSpaceLineMesh(linePositions, isLineStrip);

            // When the line positions are changed many times, it is recommended to set CreateDynamicVertexBuffer to true.
            screenSpaceLineMesh.CreateDynamicVertexBuffer = true;

            var lineMaterial = new LineMaterial()
            {
                LineColor     = lineColor.ToColor4(),
                LineThickness = 2
            };

            var screenSpaceLineNode = new ScreenSpaceLineNode(screenSpaceLineMesh, lineMaterial);

            screenSpaceLineNode.Transform = new Transformation(SharpDX.Matrix.Translation(xOffset, 0, 0));

            // To show ScreenSpaceLineNode in DXViewportView we need to put it inside a SceneNodeVisual3D
            var sceneNodeVisual3D = new SceneNodeVisual3D(screenSpaceLineNode);

            MainViewport.Children.Add(sceneNodeVisual3D);

            _disposables.Add(screenSpaceLineMesh);
            _disposables.Add(screenSpaceLineNode);
            _disposables.Add(lineMaterial);

            return(screenSpaceLineNode);
        }
コード例 #8
0
        private void ChangePositions(ScreenSpaceLineNode screenSpaceLineNode, ScreenSpaceLineMesh screenSpaceLineMesh)
        {
            ChangePositions(screenSpaceLineMesh.Positions);

            // Recreate vertex buffer that is defined with ScreenSpaceLineMesh
            screenSpaceLineMesh.RecreateMesh();


            // Update bounds of the mesh and SceneNode.
            BoundingBox boundingBox;

            BoundingBox.FromPoints(screenSpaceLineMesh.Positions, out boundingBox); // We could set boundingBox manually, but for demonstration purpose we calculate it from the positions

            screenSpaceLineMesh.Bounds.SetBoundingBox(ref boundingBox);

            screenSpaceLineNode.UpdatePositions();
            screenSpaceLineNode.UpdateBounds();
        }
コード例 #9
0
        private ScreenSpaceLineNode CreateLinesWithPositions(Vector3[] linePositions, bool isLineStrip, bool isPolyLine, bool isLineClosed, Color lineColor, float xOffset)
        {
            var lineMaterial = CreateLineMaterial(isPolyLine, lineColor);

            var screenSpaceLineNode = new ScreenSpaceLineNode(linePositions, isLineStrip, isLineClosed, lineMaterial);

            screenSpaceLineNode.Transform = new Transformation(SharpDX.Matrix.Translation(xOffset, 0, 0));

            // To show ScreenSpaceLineNode in DXViewportView we need to put it inside a SceneNodeVisual3D
            var sceneNodeVisual3D = new SceneNodeVisual3D(screenSpaceLineNode);

            MainViewport.Children.Add(sceneNodeVisual3D);

            _disposables.Add(screenSpaceLineNode);
            _disposables.Add(lineMaterial);

            return(screenSpaceLineNode);
        }
コード例 #10
0
        private void AddLines(Point3D startPosition, int positionsCount, Color lineColor, bool readZBuffer = true, bool writeZBuffer = true, RenderingQueue customRenderingQueue = null)
        {
            Vector3[] positions = new Vector3[positionsCount * 2];
            Vector3   position  = startPosition.ToVector3();

            int index = 0;

            for (int i = 0; i < positionsCount; i++)
            {
                positions[index]     = position;
                positions[index + 1] = position + new Vector3(40, 0, 0);

                index    += 2;
                position += new Vector3(0, 0, 10);
            }

            // ThickLineEffect that renders the 3D lines can use the ReadZBuffer and WriteZBuffer values from LineMaterial.
            //
            // When ReadZBuffer is false (true by default), then line is rendered without checking the depth buffer -
            // so it is always rendered even it is is behind some other 3D object and should not be visible from the camera).
            //
            // When WriteZBuffer is false (true by default), then when rendering the 3D line, the depth of the line is not
            // written to the depth buffer. So No other object will be made hidden by the line even if that object is behind the line.
            var lineMaterial = new LineMaterial()
            {
                LineColor     = lineColor.ToColor4(),
                LineThickness = 2,
                ReadZBuffer   = readZBuffer,
                WriteZBuffer  = writeZBuffer
            };

            _disposables.Add(lineMaterial);


            var screenSpaceLineNode = new ScreenSpaceLineNode(positions, isLineStrip: false, isLineClosed: false, lineMaterial: lineMaterial);

            // It is also needed that the 3D line is put to the Background or Overlay rendering queue so that it is rendered before or after other 3D objects.
            screenSpaceLineNode.CustomRenderingQueue = customRenderingQueue;

            var sceneNodeVisual3D = new SceneNodeVisual3D(screenSpaceLineNode);

            MainViewport.Children.Add(sceneNodeVisual3D);
        }
コード例 #11
0
        public ScreenSpaceLineNodeSample()
        {
            InitializeComponent();

            _disposables = new DisposeList();

            var linePositions = CreateLinePositions(0, 0);

            _screenSpaceLineNode1 = CreateLinesWithPositions(linePositions, isLineStrip: false, isLineClosed: false, lineColor: Colors.Blue, xOffset: -100);

            // To create poly-lines we need to set isLineStrip to true
            _screenSpaceLineNode2 = CreateLinesWithPositions(linePositions, isLineStrip: true, isLineClosed: false, lineColor: Colors.Green, xOffset: 0);

            _screenSpaceLineNode3 = CreateLinesWithLineMesh(linePositions, isLineStrip: false, isLineClosed: false, lineColor: Colors.Red, xOffset: 100, screenSpaceLineMesh: out _screenSpaceLineMesh);

            Unloaded += delegate
            {
                Dispose();
            };
        }
コード例 #12
0
        public static SceneNode CreateLineSceneNodes(Point3D center, Size3D size, bool useSingleColor, int xCount, int yCount, int zCount, DisposeList disposables)
        {
            var rootSceneNode = new SceneNode();

            float xStep = (float)(size.X / xCount);
            float yStep = (float)(size.Y / yCount);
            float zStep = (float)(size.Z / zCount);

            float xHalfLineSize = xStep * 0.3f;
            //float yHalfLineSize = xStep * 0.3f;
            float zHalfLineSize = xStep * 0.3f;

            var singleColorLineMaterial = new LineMaterial()
            {
                LineColor     = Colors.Orange.ToColor4(),
                LineThickness = 2
            };

            if (disposables != null)
            {
                disposables.Add(singleColorLineMaterial);
            }



            for (int z = 0; z < zCount; z++)
            {
                float zPos     = (float)(center.Z - (size.Z / 2.0) + (z * zStep));
                float zPercent = (float)z / (float)zCount;

                for (int y = 0; y < yCount; y++)
                {
                    float yPos     = (float)(center.Y - (size.Y / 2.0) + (y * yStep));
                    float yPercent = (float)y / (float)yCount;

                    for (int x = 0; x < xCount; x++)
                    {
                        float xPos = (float)(center.X - (size.X / 2.0) + (x * xStep));

                        var linePositions = new Vector3[]
                        {
                            new Vector3(xPos - xHalfLineSize, yPos, zPos - zHalfLineSize),
                            new Vector3(xPos + xHalfLineSize, yPos, zPos + zHalfLineSize),
                            new Vector3(xPos - xHalfLineSize, yPos, zPos + zHalfLineSize),
                            new Vector3(xPos + xHalfLineSize, yPos, zPos - zHalfLineSize),
                        };

                        LineMaterial usedLineMaterial;

                        if (useSingleColor)
                        {
                            // Using single color improved performance by 30% because we do not need to update per-object constant buffer for each line.
                            usedLineMaterial = singleColorLineMaterial;
                        }
                        else
                        {
                            usedLineMaterial = new LineMaterial()
                            {
                                LineColor     = new Color4((float)x / (float)xCount, yPercent, zPercent, 1),
                                LineThickness = 2
                            };

                            if (disposables != null)
                            {
                                disposables.Add(usedLineMaterial);
                            }
                        }

                        // NOTE:
                        // The sample can also show many instances of ScreenSpaceLineNode to simulate showing many different 3D lines.
                        // It would be much better to use a single ScreenSpaceLineNode and set all line positions to that object.

                        var screenSpaceLineNode = new ScreenSpaceLineNode(linePositions, isLineStrip: false, isLineClosed: false, lineMaterial: usedLineMaterial);

                        rootSceneNode.AddChild(screenSpaceLineNode);
                    }
                }
            }

            return(rootSceneNode);
        }
コード例 #13
0
        private void ShowVisibleAndHiddenLines()
        {
            // To show both visible and hidden lines we need to render each line twice:
            // once with standard settings to shew visible part of the one,
            // once with using HiddenLineMaterial to show the hidden part of the line.


            // Now we will clone the existing 3D lines
            var existingLineVisuals = TestObjectsModelVisual3D.Children.OfType <BaseLineVisual3D>().ToList();

            var newLineVisuals = new List <BaseLineVisual3D>();

            foreach (var lineVisual3D in existingLineVisuals)
            {
                var clonedLineVisual = CloneLineVisuals(lineVisual3D);

                // To correctly show hidden lines, then need to be rendered after the objects in front of the lines
                // (they are rendered only in case when there are already some objects in front of them - line's depth is bigger then current depth value).
                // In case you want to show the hidden lines behind semi-transparent objects, you need to make sure that
                // the lines are put into the OverlayRenderingQueue.
                // This is needed because TransparentRenderingQueue is defined after LineGeometryRenderingQueue
                // and therefore all transparent objects are rendered after all 3D lines (this is needed so the lines are visible through transparent objects).
                // This can be done with using the SetDXAttribute method and setting the CustomRenderingQueue value.
                // Note that this value need to be set before the line is initialized by the DXEngine - so before the MainDXViewportView.Update call a few lines below.
                // (in case of using ScreenSpaceLineNode, you can set its CustomRenderingQueue).
                //clonedLineVisual.SetDXAttribute(DXAttributeType.CustomRenderingQueue, MainDXViewportView.DXScene.OverlayRenderingQueue);

                TestObjectsModelVisual3D.Children.Add(clonedLineVisual);
                newLineVisuals.Add(clonedLineVisual);
            }

            // After adding new WPF objects to the scene, we need to manually call Update to create DXEngine's SceneNode objects that will be needed later
            MainDXViewportView.Update();

            // We need to update the _sceneNodesDictionary because we have changed the scene
            CreateSceneNodesDictionary();

            // Now change the materials of the clones lines to hiddenLineMaterial
            foreach (var newLineVisual3D in newLineVisuals)
            {
                // Now we can change the material to _hiddenLineMaterial.
                //
                // We also need to put the hidden line to the OverlayRenderingQueue.
                // This is needed because to correctly show hidden lines, they need to be rendered after the objects in front of the lines
                // (they are rendered only in case when there are already some objects in front of them - line's depth is bigger then current depth value).
                // In case you want to show the hidden lines behind semi-transparent objects, you need to make sure that
                // the lines are put into the OverlayRenderingQueue.
                // This is needed because TransparentRenderingQueue is defined after LineGeometryRenderingQueue
                // and therefore all transparent objects are rendered after all 3D lines (this is needed so the lines are visible through transparent objects).
                //
                // Here this is done with setting the CustomRenderingQueue on the ScreenSpaceLineNode (see ChangeLineMaterial method).

                ChangeLineMaterial(newLineVisual3D, _hiddenLineMaterial, MainDXViewportView.DXScene.OverlayRenderingQueue);

                // We could also call SetDXAttribute and set the CustomRenderingQueue to OverlayRenderingQueue.
                // This can be done with uncommenting the following line
                // (but this is less efficient than setting the CustomRenderingQueue on the ScreenSpaceLineNode as done in the ChangeLineMaterial):
                //newLineVisual3D.SetDXAttribute(DXAttributeType.CustomRenderingQueue, MainDXViewportView.DXScene.OverlayRenderingQueue);
            }


            if (_wireframeGeometryModel3D != null)
            {
                // Clone the GeometryModel3D that shows teapot wireframe and use hiddenLineMaterial to render it
                var newWpfWireframeMaterial = new DiffuseMaterial(Brushes.Red);
                newWpfWireframeMaterial.SetUsedDXMaterial(_hiddenLineMaterial);

                var geometryModel3D = new GeometryModel3D(_wireframeGeometryModel3D.Geometry, newWpfWireframeMaterial);
                geometryModel3D.Transform = _wireframeGeometryModel3D.Transform;
                var modelVisual3D = new ModelVisual3D()
                {
                    Content = geometryModel3D
                };

                TestObjectsModelVisual3D.Children.Add(modelVisual3D);
            }


            // Create a new ScreenSpaceLineNode from the data for _screenSpaceLineNode
            // Set its material to _hiddenLineMaterial and move it to the OverlayRenderingQueue:
            var hiddenScreenSpaceLineNode = new ScreenSpaceLineNode(_screenSpaceLineNode.Positions, _screenSpaceLineNode.IsLineStrip, _screenSpaceLineNode.IsLineClosed, _hiddenLineMaterial);

            hiddenScreenSpaceLineNode.CustomRenderingQueue = MainDXViewportView.DXScene.OverlayRenderingQueue;

            var sceneNodeVisual3D = new SceneNodeVisual3D(hiddenScreenSpaceLineNode);

            TestObjectsModelVisual3D.Children.Add(sceneNodeVisual3D);
        }