Esempio n. 1
0
            public void CreatesTestScene(int[] randomIndexes)
            {
                for (int i = 0; i < randomIndexes.Length; i++)
                {
                    int index = randomIndexes[i];

                    var textBlockVisual3D = new TextBlockVisual3D()
                    {
                        Text                   = "TextBlockVisual3D_" + (index + 1).ToString(),
                        Position               = new Point3D(0, 0, -200 + index * 40),
                        PositionType           = PositionTypes.Center,
                        Size                   = new Size(200, 50),
                        Foreground             = Brushes.Yellow,
                        RenderBitmapSize       = new Size(512, 128), // Rendering text to bitmap will run the code much faster (when rendered by WPF, then by default (RenderBitmapSize is Empty) VisualBrush is used to show the text - this gives more details when text is closer to the camera, but it is much slower and requires much more cpu time; When rendered by DXEngine, then RenderBitmapSize is set to 512x256 by default)
                        IsBackSidedTextFlipped = true
                    };

                    TargetViewport3D.Children.Add(textBlockVisual3D);
                }


                // Adding ambient light can help to prevent darkening the TextBlockVisual3D too much,
                // but it also reduces the shading effect and when adding too much ambient light
                // the objects may not appear shaded anymore.
                //
                //var ambientLight = new AmbientLight(Color.FromRgb(50, 50, 50));
                //TargetViewport3D.Children.Add(ambientLight.CreateModelVisual3D());
            }
        private void AddMiterLimitsSample(double miterLimit, double zOffset)
        {
            var sampleModelVisual3D = new ModelVisual3D();

            sampleModelVisual3D.Transform = new TranslateTransform3D(0, 0, zOffset);


            var positions        = CreateSnakePositions(new Point3D(-100, 0, 0), 50, 20, 80);
            var polyLineVisual3D = new Ab3d.Visuals.PolyLineVisual3D()
            {
                Positions     = positions,
                LineColor     = Colors.White,
                LineThickness = 15,
                MiterLimit    = miterLimit
            };

            sampleModelVisual3D.Children.Add(polyLineVisual3D);


            var textBlockVisual3D = new TextBlockVisual3D()
            {
                Position      = new Point3D(-120, 0, 0),
                PositionType  = PositionTypes.Right,
                TextDirection = new Vector3D(1, 0, 0),
                UpDirection   = new Vector3D(0, 0, -1),
                Size          = new Size(200, 40),
                Foreground    = Brushes.White,
                Text          = string.Format("MiterLimit = {0}", miterLimit)
            };

            sampleModelVisual3D.Children.Add(textBlockVisual3D);


            MainViewport.Children.Add(sampleModelVisual3D);
        }
Esempio n. 3
0
        private void AddAxisLines()
        {
            double zPos = -0.5; // Move axis slightly away from camera so other lines will be always on top of axis

            var axisRootVisual3D = new ContentVisual3D();

            var xAxisLineVisual3D = new LineVisual3D()
            {
                StartPosition = new Point3D(0, 0, zPos),
                EndPosition   = new Point3D(100, 0, zPos),
                LineColor     = Colors.Red,
                EndLineCap    = LineCap.ArrowAnchor
            };

            axisRootVisual3D.Children.Add(xAxisLineVisual3D);


            var yAxisLineVisual3D = new LineVisual3D()
            {
                StartPosition = new Point3D(0, 0, zPos),
                EndPosition   = new Point3D(0, 100, zPos),
                LineColor     = Colors.Green,
                EndLineCap    = LineCap.ArrowAnchor
            };

            axisRootVisual3D.Children.Add(yAxisLineVisual3D);

            var xTextBlockVisual3D = new TextBlockVisual3D()
            {
                Text          = "X",
                Position      = new Point3D(110, 0, zPos),
                PositionType  = PositionTypes.Center,
                Size          = new Size(10, 10),
                TextDirection = new Vector3D(1, 0, 0),
                UpDirection   = new Vector3D(0, 1, 0),
                Foreground    = Brushes.Red,
                FontWeight    = FontWeights.Bold
            };

            axisRootVisual3D.Children.Add(xTextBlockVisual3D);

            var yTextBlockVisual3D = new TextBlockVisual3D()
            {
                Text          = "Y",
                Position      = new Point3D(0, 110, zPos),
                PositionType  = PositionTypes.Center,
                Size          = new Size(10, 10),
                TextDirection = new Vector3D(1, 0, 0),
                UpDirection   = new Vector3D(0, 1, 0),
                Foreground    = Brushes.Green,
                FontWeight    = FontWeights.Bold
            };

            axisRootVisual3D.Children.Add(yTextBlockVisual3D);

            MainViewport.Children.Add(axisRootVisual3D);
        }
Esempio n. 4
0
        private void AddTextBlockVisual3D(double xOffset, string text)
        {
            var textBlockVisual3D = new TextBlockVisual3D()
            {
                Position     = new Point3D(xOffset, -5, 100),
                PositionType = PositionTypes.Center,
                UpDirection  = new Vector3D(0, 0.5, -0.5), // text is shown at slight angle
                Size         = new Size(45, 20),           // set width to 60; height is automatically calculated
                //BorderSize = new Size(45, 20),
                TextPadding     = new Thickness(5, 3, 5, 3),
                BorderBrush     = Brushes.Black,
                BorderThickness = new Thickness(1, 1, 1, 1),
                Text            = text,
            };

            MainViewport.Children.Add(textBlockVisual3D);
        }
Esempio n. 5
0
        private void AddLinesFan(ModelVisual3D parentModelVisual3D, Point3D startPosition, double lineThickness, double linesLength, string titleText = null)
        {
            if (titleText == null)
            {
                titleText = string.Format(System.Globalization.CultureInfo.InvariantCulture, "LineThickness {0:0.0}:", lineThickness);
            }


            var textBlockVisual3D = new TextBlockVisual3D()
            {
                Position         = startPosition + new Vector3D(-2, linesLength + 5, 0),
                PositionType     = PositionTypes.Bottom | PositionTypes.Left,
                FontSize         = 11,
                RenderBitmapSize = new Size(1024, 256),
                Text             = titleText
            };

            parentModelVisual3D.Children.Add(textBlockVisual3D);


            var linePositions = new Point3DCollection();

            for (int a = 0; a <= 90; a += 5)
            {
                Point3D endPosition = startPosition + new Vector3D(linesLength * Math.Cos(a / 180.0 * Math.PI), linesLength * Math.Sin(a / 180.0 * Math.PI), 0);

                linePositions.Add(startPosition);
                linePositions.Add(endPosition);
            }

            var multiLineVisual3D = new MultiLineVisual3D()
            {
                Positions     = linePositions,
                LineColor     = Colors.Black,
                LineThickness = lineThickness
            };

            parentModelVisual3D.Children.Add(multiLineVisual3D);
        }
        private void CreateTestSemiTransparentObjects()
        {
            if (_disposables != null)
            {
                _disposables.Dispose();
            }

            _disposables = new DisposeList();

            SemiTransparentRootVisual3D.Children.Clear();

            string texturesFolder = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\");

            AddSmallForest(new Point3D(0, 20, -100), texturesFolder + @"AlphaTextures\tree0.dds");

            AddSmallForest(new Point3D(-100, 20, -100), texturesFolder + "TreeTexture.png");


            var wireFenceMaterial = CreateDiffuseMaterial(texturesFolder + @"AlphaTextures\WireFence.dds");

            SetMaterialsDXAttributes(wireFenceMaterial);

            var boxVisual3D = new BoxVisual3D()
            {
                CenterPosition = new Point3D(100, 20, -100),
                Size           = new Size3D(40, 40, 40),
                Material       = wireFenceMaterial,
                BackMaterial   = wireFenceMaterial
            };

            SemiTransparentRootVisual3D.Children.Add(boxVisual3D);


            AddPlaneGroup(new Point3D(0, 30, 70), new Vector3D(0, 0, 20), 5, texturesFolder + "SemiTransparentFrame.png");


            var textBlockVisual1 = new TextBlockVisual3D()
            {
                Text             = "ABCDE\r\nFGHIJ",
                Position         = new Point3D(-100, 20, 0),
                PositionType     = PositionTypes.Bottom,
                Size             = new Size(60, 40),
                Background       = Brushes.Transparent,
                RenderBitmapSize = new Size(256, 128),
                TextPadding      = new Thickness(5, 0, 5, 0),
                BorderBrush      = Brushes.Yellow,
                BorderThickness  = new Thickness(0, 2, 0, 2)
            };

            SetMaterialsDXAttributes(textBlockVisual1.Material);
            SetMaterialsDXAttributes(textBlockVisual1.BackMaterial);

            SemiTransparentRootVisual3D.Children.Add(textBlockVisual1);



            var textBlockVisual2 = new TextBlockVisual3D()
            {
                Text             = "12345\r\n67890",
                Position         = new Point3D(100, 20, 0),
                PositionType     = PositionTypes.Bottom,
                Size             = new Size(60, 40),
                Background       = Brushes.Transparent,
                RenderBitmapSize = new Size(256, 128),
                TextPadding      = new Thickness(5, 0, 5, 0),
                BorderBrush      = Brushes.Yellow,
                BorderThickness  = new Thickness(0, 2, 0, 2)
            };

            SetMaterialsDXAttributes(textBlockVisual2.Material);
            SetMaterialsDXAttributes(textBlockVisual2.BackMaterial);


            SemiTransparentRootVisual3D.Children.Add(textBlockVisual2);


            var gradientBrush    = new RadialGradientBrush(Colors.White, Color.FromArgb(0, 255, 255, 255)); // Gradient from White to fully transparent
            var gradientMaterial = new DiffuseMaterial(gradientBrush);

            SetMaterialsDXAttributes(gradientMaterial);

            var planeVisual3D = new PlaneVisual3D()
            {
                CenterPosition  = new Point3D(0, 60, 0),
                Size            = new Size(80, 80),
                Normal          = new Vector3D(0, 0, 1),
                HeightDirection = new Vector3D(0, 1, 0),
                Material        = gradientMaterial,
                BackMaterial    = gradientMaterial
            };

            SemiTransparentRootVisual3D.Children.Add(planeVisual3D);

            AlignBillboards();


            _originalObjects = SemiTransparentRootVisual3D.Children.ToList();

            // if there was a saved objects order because of previous sorting or randomizing, we apply that same objects order now
            ApplySavedObjectsOrder();
        }
Esempio n. 7
0
        private void AddModel(Model3D originalModel3D, Point3D position, PositionTypes positionType, Size3D size, bool preserveAspectRatio = true)
        {
            // Create a new Model3DGroup that will hold the originalModel3D.
            // This allows us to have different transformation for each originalModel3D (transformation is on Model3DGroup)
            var model3DGroup = new Model3DGroup();

            model3DGroup.Children.Add(originalModel3D);

            Ab3d.Utilities.ModelUtils.PositionAndScaleModel3D(model3DGroup, position, positionType, size, preserveAspectRatio);

            // Add the model
            var modelVisual3D = new ModelVisual3D()
            {
                Content = model3DGroup
            };

            SolidObjectsVisual3D.Children.Add(modelVisual3D);



            // Now add red WireCrossVisual3D at the specified position
            var wireCrossVisual3D = new Ab3d.Visuals.WireCrossVisual3D()
            {
                Position    = position,
                LinesLength = 30,
                LineColor   = Colors.Red
            };

            SolidObjectsVisual3D.Children.Add(wireCrossVisual3D);


            // Now show a WireBoxVisual3D (box from 3D lines) that would represent the position, positionType and size.

            // To get the correct CenterPosition of the WireBoxVisual3D,
            // we start with creating a bounding box (Rect3D) that would be used when CenterPosition would be set to (0, 0, 0):
            var wireboxInitialBounds = new Point3D(-size.X * 0.5, -size.Y * 0.5, -size.Z * 0.5);

            // Then we use that bounding box and call GetModelTranslationVector3D method
            // that will tell us how much we need to move the bounding box so that it will be positioned at position and for positionType:
            var wireboxCenterOffset = Ab3d.Utilities.ModelUtils.GetModelTranslationVector3D(new Rect3D(wireboxInitialBounds, size), position, positionType);

            // Now we can use the result wireboxCenterOffset as a CenterPosition or a WireBoxVisual3D

            var wireBoxVisual3D = new WireBoxVisual3D()
            {
                CenterPosition = new Point3D(wireboxCenterOffset.X, wireboxCenterOffset.Y, wireboxCenterOffset.Z),
                Size           = size,
                LineColor      = Colors.Green,
                LineThickness  = 1
            };

            SolidObjectsVisual3D.Children.Add(wireBoxVisual3D);


            // Finally we add TextBlockVisual3D to show position and size information for this model
            // Note that the TextBlockVisual3D is added to the TransparentObjectsVisual3D.
            // The reason for this is that TextBlockVisual3D uses semi-transparent background.
            // To correctly show other object through semi-transparent, the semi-transparent must be added to the scene after solid objects.
            var infoText = string.Format("Position: {0:0}\r\nPositionType: {1}\r\nSize: {2:0}", position, positionType, size);

            if (!preserveAspectRatio)
            {
                infoText += "\r\npreserveAspectRatio: false";
            }

            var textBlockVisual3D = new TextBlockVisual3D()
            {
                Position      = new Point3D(model3DGroup.Bounds.GetCenterPosition().X, -15, 55), // Show so that X center position is the same as model center position
                PositionType  = PositionTypes.Center,
                TextDirection = new Vector3D(1, 0, 0),
                UpDirection   = new Vector3D(0, 1, -1), // angled at 45 degrees
                Size          = new Size(80, 0),        // y size will be calculated automatically based on x size (80) and size of the text

                Text            = infoText,
                BorderBrush     = Brushes.DimGray,
                BorderThickness = new Thickness(1, 1, 1, 1),
                Background      = new SolidColorBrush(Color.FromArgb(180, 200, 200, 200)),
                TextPadding     = new Thickness(5, 2, 5, 2)
            };

            TransparentObjectsVisual3D.Children.Add(textBlockVisual3D);
        }
        private void AddTextBlockVisuals(Point3D startPosition, string text, string fontFamily = null)
        {
            Point3D  position = startPosition;
            Vector3D charAdvancementVector = new Vector3D(30, 0, 0);

            foreach (var oneChar in text)
            {
                var textBlockVisual3D = new TextBlockVisual3D()
                {
                    Text                   = oneChar.ToString(),
                    Position               = position,
                    PositionType           = PositionTypes.Center,
                    TextDirection          = new Vector3D(1, 0, 0),
                    UpDirection            = new Vector3D(0, 1, 0),
                    Size                   = new Size(20, 40),
                    Foreground             = Brushes.LightGray,
                    IsTwoSidedText         = true,
                    IsBackSidedTextFlipped = false
                };

                if (!string.IsNullOrEmpty(fontFamily))
                {
                    textBlockVisual3D.FontFamily = new FontFamily(fontFamily);
                }

                MainViewport.Children.Add(textBlockVisual3D);


                var visualEventSource3D = new VisualEventSource3D(textBlockVisual3D);
                visualEventSource3D.MouseEnter += delegate(object sender, Mouse3DEventArgs e)
                {
                    var hitTextBlockVisual3D = e.HitObject as TextBlockVisual3D;
                    if (hitTextBlockVisual3D != null && hitTextBlockVisual3D.Foreground != Brushes.Red)
                    {
                        hitTextBlockVisual3D.Foreground = Brushes.Orange;
                    }

                    Mouse.OverrideCursor = Cursors.Hand;
                };

                visualEventSource3D.MouseLeave += delegate(object sender, Mouse3DEventArgs e)
                {
                    var hitTextBlockVisual3D = e.HitObject as TextBlockVisual3D;
                    if (hitTextBlockVisual3D != null && hitTextBlockVisual3D.Foreground != Brushes.Red)
                    {
                        hitTextBlockVisual3D.Foreground = Brushes.LightGray;
                    }

                    Mouse.OverrideCursor = null;
                };

                visualEventSource3D.MouseClick += delegate(object sender, MouseButton3DEventArgs e)
                {
                    var hitTextBlockVisual3D = e.HitObject as TextBlockVisual3D;
                    if (hitTextBlockVisual3D != null)
                    {
                        if (hitTextBlockVisual3D.Foreground != Brushes.Red)
                        {
                            hitTextBlockVisual3D.Foreground = Brushes.Red;
                        }
                        else
                        {
                            hitTextBlockVisual3D.Foreground = Brushes.Orange;
                        }
                    }
                };

                _eventManager3D.RegisterEventSource3D(visualEventSource3D);


                position += charAdvancementVector;
            }
        }
Esempio n. 9
0
        private void CreateSimpleDemoScene()
        {
            // When using Ab3d.PowerToys and Ab3d.DXEngine, then the standard way to render text is to use TextBlockVisual3D.
            // It provides many options and easy positioning with Position / PositionType properties. See sample in the Ab3d.PowerToys samples project for more info.
            //
            // Here we also show how to setup the alpha-clip threshold that can be used when rendering with Ab3d.DXEngine.
            // This way we do not need to sort the TextBlockVisual3D by their distance to render them correctly.

            var textBlockVisual3D = new TextBlockVisual3D()
            {
                Text                   = "TextBlockVisual3D",
                Position               = new Point3D(-190, -50, 0),
                PositionType           = PositionTypes.BottomLeft,
                TextDirection          = new Vector3D(1, 0, 0),
                UpDirection            = new Vector3D(0, 1, 0),
                Size                   = new Size(80, 40),
                Background             = Brushes.Transparent,
                RenderBitmapSize       = new Size(256, 128),
                TextPadding            = new Thickness(5, 0, 5, 0),
                BorderBrush            = Brushes.Yellow,
                BorderThickness        = new Thickness(0, 2, 0, 2),
                IsBackSidedTextFlipped = true
            };

            // Because TextBlockVisual3D usually use transparent background the rules and limitations of rendering transparent objects apply when using multiple TextBlockVisual3D objects (see Alpha clipping sample for more info).
            // With Ab3d.DXEngine a very fast transparent objects sorting can be enabled by:
            // MainDXViewportView.DXScene.IsTransparencySortingEnabled
            //
            // But instead of using transparency sorting, we enable alpha-clipping (see Alpha clipping sample for more info):
            textBlockVisual3D.SetDXAttribute(DXAttributeType.Texture_AlphaClipThreshold, 0.15f);

            MainViewport.Children.Add(textBlockVisual3D);


            // It is also possible to show 3D text with using TextVisual3D.
            // This objects renders text with using 3D lines.
            // Its disadvantage is that it supports only an old style font that was used for plotters and cannot render all the characters.


            // TextBlockVisual3D renders the text with first rendering the text with the specified border to a texture.
            // This this texture is rendered into a plane 3D object.
            // This works very well when there are not a lot of texts.
            // But if many texts need to be rendered, then the it takes long to render all texts to textures and also they take a lot of memory.
            //
            // In this case the InstancedTextNode can be used because it only rendered individual characters and then reuses
            // the textures with rendered characters to show the texts. To make rendering even more efficient object instancing is used.
            //
            //
            // The first set in using the InstancedTextNode is to create its instance.
            //
            // There we define the FontFamily and FontWeight that will be the same for all added texts.
            //
            // We also define the size of the texture that will be used to render the characters.
            // It is recommended to use size that is power of 2 - for example 64, 128, 256, etc.
            // By default the fontBitmapSize is set to 128 that rendered characters to 128 x 128 texture.
            //
            // We can also set the useDynamicInstanceBuffer to true. This would create dynamic instance buffer.
            // This is recommended when the text data is changed very ofter (color, position or visibility is changed in each frame or similar).
            // Here we change data only occasionally, so preserve the useDynamicInstanceBuffer in its default value (this is better for GPU access to the buffer)
            _instancedTextNode = new InstancedTextNode(fontFamily: new FontFamily("Arial"),
                                                       fontWeight: FontWeights.Normal,
                                                       fontBitmapSize: 128,
                                                       useDynamicInstanceBuffer: false);


            // Than we can call AddText to add individual text to the InstancedTextNode.
            // Note that to be able to show text from the back side, we need to set hasBackSide to true (this rendered twice as many objects).
            // AddText method returns an instance of InstancedText object that can be used to change the color, position, show or hide text.
            _instancedText = _instancedTextNode.AddText("Ab3d.DXEngine", Colors.Orange, new Point3D(-190, 0, 0), size: 25, hasBackSide: true);

            // To change direction and orientation of text, we can call the SetTextDirection method.
            _instancedTextNode.SetTextDirection(textDirection: new Vector3D(1, 0, 0), upDirection: new Vector3D(0, 0, -1));

            // All characters from font are supported. Also new line is supported.
            _instancedTextNode.AddText("All chars:\n@üßščžç☯", Colors.Black, new Point3D(-100, 1, 50), size: 30, hasBackSide: true);


            _instancedTextNode.SetTextDirection(textDirection: new Vector3D(1, 0, 0), upDirection: new Vector3D(0, 1, 0));
            _instancedTextNode.AddText("Right->", Colors.Red, new Point3D(0, 30, 0), size: 30, hasBackSide: true);

            _instancedTextNode.SetTextDirection(textDirection: new Vector3D(0, 0, -1), upDirection: new Vector3D(0, 1, 0));
            _instancedTextNode.AddText("Forward->", Colors.Blue, new Point3D(0, 30, 0), size: 30, hasBackSide: true);

            _instancedTextNode.SetTextDirection(textDirection: new Vector3D(0, 1, 0), upDirection: new Vector3D(-1, 0, 0));
            _instancedTextNode.AddText("UP->", Colors.Green, new Point3D(0, 70, 0), size: 30, hasBackSide: true);


            // Sample on how to create text that is flipped on the back side (so it can be correctly read from the back side)
            var startPosition = new Point3D(10, 0, 0);

            _instancedTextNode.SetTextDirection(textDirection: new Vector3D(1, 0, 0), upDirection: new Vector3D(0, 1, 0));
            var flippedFrontFaceInstancedText = _instancedTextNode.AddText("FlippedBackSideText", Colors.Green, startPosition, size: 25, hasBackSide: false);

            // Based on size of previous text (instancedText.TextBounds), we can calculate the start position for the flipped back face text:
            var backFaceStartPosition = new Point3D(startPosition.X + flippedFrontFaceInstancedText.TextBounds.SizeX, startPosition.Y, startPosition.Z);

            _instancedTextNode.SetTextDirection(textDirection: new Vector3D(-1, 0, 0), upDirection: new Vector3D(0, 1, 0)); // flip textDirection, preserve upDirection
            var flippedBackFaceInstancedText = _instancedTextNode.AddText(flippedFrontFaceInstancedText.Text, flippedFrontFaceInstancedText.Color, backFaceStartPosition, size: 25, hasBackSide: false);


            // It is also possible to call AddText that takes transformation matrix instead of position and scale.
            // This method does not use current text direction that is set with SetTextDirection:

            var transform3DGroup = new Transform3DGroup();

            transform3DGroup.Children.Add(new ScaleTransform3D(20, 70, 20)); // Note that initially the font size is 1, so we need to scale it !!!
            transform3DGroup.Children.Add(new TranslateTransform3D(-120, -120, 0));

            _instancedTextNode.AddText("Custom transform", Colors.Gray, transform3DGroup.Value, hasBackSide: true);


            // If we want to immediately create character textures, we can call the InitializeResources method.
            // Note that MainDXViewportView.DXScene must not be null (this can be called in MainDXViewportView.DXSceneDeviceCreated or MainDXViewportView.DXSceneInitialized event handler)
            //_instancedTextNode.InitializeResources(MainDXViewportView.DXScene);


            // Show the InstancedTextNode as any other DXEngine's SceneNode:
            var sceneNodeVisual1 = new SceneNodeVisual3D(_instancedTextNode);

            MainViewport.Children.Add(sceneNodeVisual1);


            // To show text with other font or with other font weight, we need to create another InstancedTextNode
            _instancedTextNode2 = new InstancedTextNode(new FontFamily("Times New Roman"), FontWeights.Bold, fontBitmapSize: 128);
            _instancedTextNode2.AddText("Text with any font", Colors.Gold, new Point3D(100, -100, 0), 30, true);

            var sceneNodeVisual2 = new SceneNodeVisual3D(_instancedTextNode2);

            MainViewport.Children.Add(sceneNodeVisual2);


            SetupDemoSceneButtons(isDemoSceneShown: true);

            UpdateCharactersCountInfo();
        }