public SkeletalAnimation()
        {
            InitializeComponent();

            // Use helper class (defined in this sample project) to load the native assimp libraries
            // IMPORTANT: See commend in the AssimpLoader class for details on how to prepare your project to use assimp library.
            AssimpLoader.LoadAssimpNativeLibrary();

            string fileName = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources\\soldier.X");

            LoadFileWithSkinnedAnimation(fileName);

            var dragAndDropHelper = new DragAndDropHelper(ViewportBorder, ".*");

            dragAndDropHelper.FileDropped += (sender, e) =>
            {
                LoadFileWithSkinnedAnimation(e.FileName);
            };

            // Stop the animation when user leaves this sample.
            this.Unloaded += delegate(object sender, RoutedEventArgs args)
            {
                if (_assimpAnimationController != null)
                {
                    _assimpAnimationController.StopAnimation();
                    _assimpAnimationController = null;
                }
            };
        }
        public PBRRobotModel()
        {
            InitializeComponent();

            _disposables = new DisposeList();

            AssimpLoader.LoadAssimpNativeLibrary();

            _dxMaterials   = new Dictionary <AssimpMaterial, PhysicallyBasedMaterial>();
            _texturesCache = new Dictionary <string, ShaderResourceView>();

            _textureFiles = new Dictionary <TextureMapTypes, string>();

            // Load scene when we have the DXDevice ready
            MainDXViewportView.DXSceneInitialized += delegate(object sender, EventArgs args)
            {
                if (MainDXViewportView.DXScene == null) // Probably WPF 3D rendering
                {
                    return;
                }

                _rootFolder = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory + @"Resources\RobotModel\");

                LoadRobotPart(RobotParts.Main);
                LoadRobotPart(RobotParts.Claw);
            };



            UpdateLights();

            this.Unloaded += delegate(object sender, RoutedEventArgs args) { Dispose(); };
        }
Пример #3
0
        private void AddHouseWithTreesModel()
        {
            // Use assimp importer to load house with trees.3DS
            AssimpLoader.LoadAssimpNativeLibrary();

            var assimpWpfImporter   = new AssimpWpfImporter();
            var houseWithTreesModel = (Model3DGroup)assimpWpfImporter.ReadModel3D(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\Models\house with trees.3DS"));

            // Add AmbientLight
            var ambientLight = new AmbientLight(Color.FromRgb(80, 80, 80));

            houseWithTreesModel.Children.Add(ambientLight);

            // Show the loaded 3d scene
            var modelVisual3D = houseWithTreesModel.CreateModelVisual3D();

            _masterDXViewportView.Viewport3D.Children.Add(modelVisual3D);

            // Save the man01 model for animation (when clicked on "Change scene" button)
            _animatedPersonModel = assimpWpfImporter.NamedObjects["man01"] as Model3DGroup;


            // Add base green plate and the house models to a CustomRenderingQueue.
            // This is done with setting value of CustomRenderingQueue (custom DXAttribute) on some parts of the 3D scene.
            // This will add the specified models to the custom rendering queue (created in the OnMasterDXSceneCreated method).
            var modelNames = new string[] { "Box01", "Box02", "roof01" };

            foreach (var modelName in modelNames)
            {
                var model3D = assimpWpfImporter.NamedObjects[modelName] as Model3D;

                // Note that CustomRenderingQueue can be set to an instance of RenderingQueue or to a name (as string) of the RenderingQueue
                model3D.SetDXAttribute(DXAttributeType.CustomRenderingQueue, "CustomRenderingQueue");
            }
        }
        public AssimpWpfImporterSample()
        {
            InitializeComponent();


            // Use helper class (defined in this sample project) to load the native assimp libraries.
            // IMPORTANT: See commend in the AssimpLoader class for details on how to prepare your project to use assimp library.
            AssimpLoader.LoadAssimpNativeLibrary();


            var assimpWpfImporter = new AssimpWpfImporter();

            string[] supportedImportFormats = assimpWpfImporter.SupportedImportFormats;

            var assimpWpfExporter = new AssimpWpfExporter();

            string[] supportedExportFormats = assimpWpfExporter.ExportFormatDescriptions.Select(f => f.FileExtension).ToArray();

            FileFormatsTextBlock.Text = string.Format("Using native Assimp library version {0}.\r\n\r\nSupported import formats:\r\n{1}\r\n\r\nSupported export formats:\r\n{2}",
                                                      assimpWpfImporter.AssimpVersion,
                                                      string.Join(", ", supportedImportFormats),
                                                      string.Join(", ", supportedExportFormats));


            var dragAndDropHelper = new DragAndDropHelper(this, ".*");

            dragAndDropHelper.FileDropped += (sender, args) => LoadModel(args.FileName);


            string startUpFileName = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\Collada\duck.dae");

            LoadModel(startUpFileName);
        }
Пример #5
0
        public AssimpModelVisual3D()
        {
            // Use helper class (defined in this sample project) to load the native assimp libraries
            // IMPORTANT: See commend in the AssimpLoader class for details on how to prepare your project to use assimp library.
            AssimpLoader.LoadAssimpNativeLibrary();

            InitializeComponent();
        }
Пример #6
0
        public DynamicEdgeLinesSample()
        {
            InitializeComponent();

            AssimpLoader.LoadAssimpNativeLibrary();

            LoadRobotArm();

            this.Unloaded += delegate(object sender, RoutedEventArgs args)
            {
                Ab3d.Utilities.CompositionRenderingHelper.Instance.Unsubscribe(this);
            };
        }
        public PBRModelViewer()
        {
            InitializeComponent();

            _disposables = new DisposeList();

            AssimpLoader.LoadAssimpNativeLibrary();

            _dxMaterials   = new Dictionary <AssimpMaterial, PhysicallyBasedMaterial>();
            _texturesCache = new Dictionary <string, ShaderResourceView>();
            _textureFiles  = new Dictionary <TextureMapTypes, string>();

            // Support dragging .obj files to load the 3D models from obj file
            var dragAndDropHelper = new DragAndDropHelper(ViewportBorder, ".*");

            dragAndDropHelper.FileDroped += delegate(object sender, FileDropedEventArgs e)
            {
                FileNameTextBox.Text   = e.FileName;
                FolderPathTextBox.Text = System.IO.Path.GetDirectoryName(e.FileName);

                LoadFile(e.FileName, null);
            };

            MainDXViewportView.DXSceneInitialized += delegate(object sender, EventArgs args)
            {
                if (MainDXViewportView.DXScene == null) // Probably WPF 3D rendering
                {
                    return;
                }

                string rootFolder     = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory + @"Resources\RobotModel\");
                string fileName       = rootFolder + @"Robot_Claw.FBX";
                string texturesFolder = rootFolder + @"Robot_Claw_Maps\";

                FileNameTextBox.Text   = fileName;
                FolderPathTextBox.Text = texturesFolder;

                LoadFile(fileName, texturesFolder);
                UpdateEnvironmentMap();
            };

            this.Loaded += delegate(object sender, RoutedEventArgs args)
            {
                UpdateLights();
            };

            this.Unloaded += delegate(object sender, RoutedEventArgs args)
            {
                Dispose();
            };
        }
        public StaticEdgeLinesCreationSample()
        {
            InitializeComponent();

            AssimpLoader.LoadAssimpNativeLibrary();

            var dragAndDropHelper = new DragAndDropHelper(this, ".*");

            dragAndDropHelper.FileDropped += (sender, args) => LoadModelWithEdgeLines(args.FileName);

            string startupFileName = AppDomain.CurrentDomain.BaseDirectory + @"Resources\ObjFiles\house with trees.obj";

            LoadModelWithEdgeLines(startupFileName);
        }
        public AssimpIntroPage()
        {
            InitializeComponent();

            // We create an instance of AssimpWpfImporter to read all supported file formats
            // and set that to the FileFormatsTextBlock

            // Use helper class (defined in this sample project) to load the native assimp libraries
            // IMPORTANT: See commend in the AssimpLoader class for details on how to prepare your project to use assimp library.
            AssimpLoader.LoadAssimpNativeLibrary();

            var assimpWpfImporter = new AssimpWpfImporter();

            string[] supportedImportFormats = assimpWpfImporter.SupportedImportFormats;
            FileFormatsTextBlock.Text = string.Join(", ", supportedImportFormats);
        }
        private Model3D LoadModel3D()
        {
            AssimpLoader.LoadAssimpNativeLibrary();

            string fileName = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\Models\robotarm-upper-part.3ds");

            var assimpWpfImporter = new AssimpWpfImporter();
            var robotModel3D      = assimpWpfImporter.ReadModel3D(fileName);

            // To get object names execute the following in Visual Studio Immediate window:
            // robotModel3D.DumpHierarchy();

            var hand2Group = assimpWpfImporter.NamedObjects["Hand2__Group"] as Model3DGroup;

            _originalModelAxisAngleRotation3D = new AxisAngleRotation3D(new Vector3D(0, 0, -1), 0);
            var rotateTransform3D = new RotateTransform3D(_originalModelAxisAngleRotation3D);

            Ab3d.Utilities.TransformationsHelper.AddTransformation(hand2Group, rotateTransform3D);


            // By default all objects cast shadow, so to prevent that we need to set the IsCastingShadow to false.
            // This can be done in two ways:
            //
            // 1) Set DXAttributeType.IsCastingShadow on GeometryModel3D
            //    (only GeometryModel3D support that attribute;
            //     this need to be set before the WpfGeometryModel3DNode object is created from GeometryModel3D)
            //
            // 2) After the WpfGeometryModel3DNode is created from GeometryModel3D,
            // then we can set the IsCastingShadow on that SceneNode object - see commented code below.
            //
            // When we change the value of IsCastingShadow, we also need to enable checking this property with
            // setting the PlanarShadowRenderingProvider.IsCheckingIsCastingShadow property to true.
            // By default this property is set to false so improve performance
            // (prevent using FilterObjectsFunction in RenderObjectsRenderingStep that render shadow).

            _teapotGeometryModel3D = assimpWpfImporter.NamedObjects["Teapot"] as GeometryModel3D;
            _teapotGeometryModel3D.SetDXAttribute(DXAttributeType.IsCastingShadow, false);

            // If we want to change the value of IsCastingShadow when the object is already shown,
            // we need to change that in the WpfGeometryModel3DNode - for example:
            //var teapotSceneNode = MainDXViewportView.GetSceneNodeForWpfObject(_teapotGeometryModel3D) as WpfGeometryModel3DNode; // we can get the teapotSceneNode in MainDXViewportView.DXSceneInitialized
            //if (teapotSceneNode != null)
            //    teapotSceneNode.IsCastingShadow = false;

            return(robotModel3D);
        }
Пример #11
0
        public AdvancedEdgeLinesSample()
        {
            InitializeComponent();


            PowerToysFeaturesInfoControl.InfoText =
                @"With Ab3d.PowerToys library it is possible to show 3D lines (this is not possible when only WPF 3D is used). But the problem is that the geometry for 3D lines (2 triangles for each line) need to be generated on the CPU. Because 3D lines need to face the camera, the geometry needs to be regenerated on each camera change. This can slow the performance of the application when a lot of 3D lines need to be shown.

The Ab3d.PowerToys library can also generate edge lines based on the angle between triangles (if angle is bigger then the specified angle, then an edge line is created).";


            DXEngineFeaturesInfoControl.InfoText =
                @"Ab3d.DXEngine can use hardware acceleration to create the geometry for 3D lines in the geometry shader. This can render millions on 3D lines on a modern GPU.

What is more, as shown in this sample, the following additional features are available when using Ab3d.DXEngine:
1) It is possible to set line depth bias that moves the lines closer to the camera so that they are rendered on top of the 3D shape. This way the lines are not partially occluded by the 3D shape because they occupy the same 3D space. The depth bias processing is done in the vertex shader.

2) It is possible to render object's outlines. Here a technique is used that first renders the scene with black color and with expanded geometry. Then the scene is rendered normally on top of the black scene. For other techniques to render object outlines see the 'Object outlines rendering' sample.

3) To reduce anti-aliasing the WPF 3D can use multi-sampling (MSAA). With Ab3d.DXEngine it is possible to further reduce the aliasing and produce super-smooth 3D lines with using super-sampling (SSAA). This renders the scene to a higher resolution (4 times higher when 4xSSAA is used). Then the rendered image is down-sampled to the final resolution with using a smart filter. This can be combined with multi-sampling to produce much better results that using multi-sampling alone.";


            DepthBiasComboBox.ItemsSource  = PossibleEdgeLineDepthBiases;
            DepthBiasComboBox.SelectedItem = 0.05;


            AssimpLoader.LoadAssimpNativeLibrary();

            var dragAndDropHelper = new DragAndDropHelper(this, ".*");

            dragAndDropHelper.FileDropped += (sender, args) => LoadModelWithEdgeLines(args.FileName);


            CreateDXViewportView();


            var startupFileName = AppDomain.CurrentDomain.BaseDirectory + @"Resources\Models\planetary-gear.fbx";

            LoadModelWithEdgeLines(startupFileName);


            this.Unloaded += delegate(object sender, RoutedEventArgs args)
            {
                Dispose();
            };
        }
        public AssimpWpfExporterSample()
        {
            InitializeComponent();

            AssimpWpfImporter.LoadAssimpNativeLibrary(AppDomain.CurrentDomain.BaseDirectory);


            var assimpWpfExporter = new AssimpWpfExporter();

            _exportFormatDescriptions = assimpWpfExporter.ExportFormatDescriptions;


            for (int i = 0; i < _exportFormatDescriptions.Length; i++)
            {
                var comboBoxItem = new ComboBoxItem()
                {
                    Content = string.Format("{0} (.{1})", _exportFormatDescriptions[i].Description, _exportFormatDescriptions[i].FileExtension),
                    Tag     = _exportFormatDescriptions[i].FormatId
                };

                ExportTypeComboBox.Items.Add(comboBoxItem);
            }


            ExportTypeComboBox.SelectedIndex = 0; // Use Collada file format by default
            _selectedExportFormatId          = _exportFormatDescriptions[ExportTypeComboBox.SelectedIndex].FormatId;


            // Use helper class (defined in this sample project) to load the native assimp libraries
            // IMPORTANT: See commend in the AssimpLoader class for details on how to prepare your project to use assimp library.
            AssimpLoader.LoadAssimpNativeLibrary();

            _assimpWpfImporter = new AssimpWpfImporter();
            _assimpWpfImporter.AssimpPostProcessSteps = PostProcessSteps.Triangulate;

            CreateTestScene();

            // Set initial output file name
            OutputFileName.Text = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "AssimpExport.dae");

            // Add drag and drop handler for all file extensions
            var dragAndDropHelper = new DragAndDropHelper(ViewportBorder, "*");

            dragAndDropHelper.FileDroped += (sender, e) => LoadModel(e.FileName);
        }
        private Model3D LoadModel()
        {
            AssimpLoader.LoadAssimpNativeLibrary();

            string fileName = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\robotarm-upper-part.3ds");

            var assimpWpfImporter = new AssimpWpfImporter();
            var robotModel3D      = assimpWpfImporter.ReadModel3D(fileName);

            var hand2Group = assimpWpfImporter.NamedObjects["Hand2__Group"] as Model3DGroup;

            _axisAngleRotation3D = new AxisAngleRotation3D(new Vector3D(0, 0, -1), 0);
            var rotateTransform3D = new RotateTransform3D(_axisAngleRotation3D);

            Ab3d.Utilities.TransformationsHelper.AddTransformation(hand2Group, rotateTransform3D);

            return(robotModel3D);
        }
        public ObjectOutlinesRenderingSample()
        {
            InitializeComponent();


            OutlineThicknessComboBox.ItemsSource  = new float[] { 0f, 0.1f, 0.5f, 1f, 2f, 3f, 4f, 5f, 10f, 20f };
            OutlineThicknessComboBox.SelectedItem = 3.0f;

            OutlineDepthBiasComboBox.ItemsSource  = new float[] { 0f, 0.0001f, 0.0005f, 0.001f, 0.005f, 0.01f, 0.02f, 0.01f, 0.1f, 0.2f, 0.3f, 0.5f, 0.8f, 0.9f, 1f, 2f, 5f, 10f };
            OutlineDepthBiasComboBox.SelectedItem = 0.005f;

            EdgeThresholdComboBox.ItemsSource  = new float[] { 0f, 0.01f, 0.02f, 0.01f, 0.1f, 0.2f, 0.3f, 0.5f, 0.8f, 0.9f, 1f };
            EdgeThresholdComboBox.SelectedItem = 0.1f;

            OutlineWidthComboBox.ItemsSource  = new int[] { 1, 2, 3, 4, 5, 7, 10, 12, 16 };
            OutlineWidthComboBox.SelectedItem = 3;



            ShowObjectOutlineInfoControl.InfoText =
                @"A new RenderObjectsRenderingStep is created that renders all objects with SolidColorEffect with black color. The SolidColorEffect has the OutlineThickness property set and this expands the object's geometry in the direction of triangle normals (this is done in vertex shader). Then the scene is rendered again with standard effects on top of the black expanded scene.

To render outline around each object uncheck the 'Outline CullNone' and 'WriteMaxDepthValue' CheckBoxes. But on simpler objects with less triangles this may not render outlines in all directions.

To render silhouette around the whole 3D scene and not around each object, then check the 'Outline CullNone' and 'WriteMaxDepthValue' CheckBoxes. The first CheckBox will render back and front triangles. The second will render the objects to the back of the 3D scene (after all other objects).

This technique works well on objects that have a lot of smooth shaded positions and do not have sharp edges with big angles - for example rendering box with bigger OutlineThickness can show that the black sides are rendered away from the actual 3D object.
When 3D scene has many 3D objects, then using the technique can affect performance because the scene needs to be rendered 2 times (once for black background and once for standard rendering). This technique works with multi-sampling and super-sampling.";


            ExpandPostProcessInfoControl.InfoText =
                @"This technique is similar than the previous technique because it also first renders the scene with a black SolidColorEffect. But instead of expanding the object's geometry, the scene is rendered normally with black color. Then an ExpandPostProcess is used to expand the rendered black scene for the specified amount.

This technique can produce more accurate results then using SolidColorEffect with OutlineThickness (especially for objects with sharp edges). But it is the slowest because it requires to render the scene again and then perform a two pass post-processing. This technique is not support when multi-sampling is used.";


            EdgeDetectionPostProcessInfoControl.InfoText =
                @"EdgeDetectionPostProcess is a 2D texture post process that uses Sobel edge detection algorithm to detect edges based on the changes of color in the rendered 3D scene - if colors are different enough then a black edge is added to the rendered image.

If the rendered scene has many 3D objects, then this algorithm is the fastest because it does not require to render the 3D scene again. This technique does not support multi-sampling and super-sampling (executed after back-buffer is resolved).";



            AssimpLoader.LoadAssimpNativeLibrary();

            var dragAndDropHelper = new DragAndDropHelper(this, ".*");

            dragAndDropHelper.FileDropped += (sender, args) => LoadModel(args.FileName);

            string startupFileName = AppDomain.CurrentDomain.BaseDirectory + @"Resources\Models\house with trees.3ds";

            LoadModel(startupFileName);


            _disposables = new DisposeList();

            MainDXViewportView.DXSceneInitialized += delegate(object sender, EventArgs args)
            {
                // Wait until DXScene is created and then setup custom rendering steps to render outlines
                if (MainDXViewportView.DXScene == null)
                {
                    return;                                                            // WPF 3D rendering
                }
                if (MainDXViewportView.DXScene.UsedMultisamplingDescription.Count > 1) // Expand post process is available only without multi-sampling (MSAA)
                {
                    ExpandPostProcessCheckBox.IsChecked = false;
                    ExpandPostProcessCheckBox.IsEnabled = false;
                    OutlineWidthComboBox.IsEnabled      = false;

                    ExpandNotSupportedTextBlock.Visibility = Visibility.Visible;
                }

                UpdateUsedOutlineTechnique();
            };

            this.Unloaded += delegate(object sender, RoutedEventArgs args)
            {
                if (_disposables != null)
                {
                    _disposables.Dispose();
                    _disposables = null;
                }

                MainDXViewportView.Dispose();
            };
        }
Пример #15
0
        public BasicWpf3dObjectsTutorial()
        {
            InitializeComponent();

            var mesh2 = new MeshGeometry3D()
            {
                Positions = new Point3DCollection(new[]
                {
                    new Point3D(5, 0, 5),
                    new Point3D(100, 0, 5),
                    new Point3D(100, 0, 50),
                    new Point3D(5, 0, 50)
                }),

                TriangleIndices = new Int32Collection(new[]
                {
                    0, 2, 1,
                    3, 2, 0
                })
            };

            var geometryModel2 = new GeometryModel3D()
            {
                Geometry     = mesh2,
                Material     = new DiffuseMaterial(Brushes.LightGreen),
                BackMaterial = new DiffuseMaterial(Brushes.Red),
            };

            var modelVisual2 = new ModelVisual3D()
            {
                Content = geometryModel2
            };

            //// Using CreateModelVisual3D extensiton method from Ab3d.PowerToys
            //var modelVisual2 = geometryModel2.CreateModelVisual3D();
            //Viewport2.Children.Add(modelVisual2);

            //// in one line:
            //Viewport2.Children.Add(geometryModel2.CreateModelVisual3D());

            Viewport2.Children.Add(modelVisual2);

            MeshInspector2.MeshGeometry3D = mesh2;

            // #############

            var mesh3 = new MeshGeometry3D()
            {
                Positions       = mesh2.Positions,
                TriangleIndices = new Int32Collection(new[]
                {
                    2, 0, 1, // changed from 0, 2, 1
                    3, 2, 0
                }),
                Normals = new Vector3DCollection(new [] { new Vector3D(0, 1, 0), new Vector3D(0, 1, 0), new Vector3D(0, 1, 0), new Vector3D(0, 1, 0) }) // We define Normals because the automatically generated normals are not correct because the two triangles are oriented differently and this produces zero length normals for the shared positions; note that for mesh2 this was not needed because triangles are correctly oriented and WPF was able to correctly calculate normals.
            };

            _geometryModel3 = new GeometryModel3D()
            {
                Geometry     = mesh3,
                Material     = new DiffuseMaterial(Brushes.LightGreen),
                BackMaterial = new DiffuseMaterial(Brushes.Red),
            };

            var modelVisual3 = new ModelVisual3D()
            {
                Content = _geometryModel3
            };

            Viewport3.Children.Add(modelVisual3);

            MeshInspector3.MeshGeometry3D = mesh3;

            // #############

            var modelVisual4 = new ModelVisual3D()
            {
                Content = _geometryModel3
            };

            Viewport4.Children.Add(modelVisual4);

            MeshInspector4.MeshGeometry3D = mesh3;

            // #############

            var mesh5 = new MeshGeometry3D()
            {
                Positions          = mesh2.Positions,
                TriangleIndices    = mesh2.TriangleIndices,
                TextureCoordinates = new PointCollection(new[]
                {
                    new Point(0, 0),
                    new Point(1, 0),
                    new Point(1, 1),
                    new Point(0, 1),
                })
            };

            var textureImage = new BitmapImage(new Uri("pack://*****:*****@"c:\images\texture.png")); // Read image from file
            //var textureImage2 = new BitmapImage(new Uri("pack://*****:*****@"Resources\robotarm-upper-part.3ds");

            var assimpWpfImporter = new AssimpWpfImporter();
            var robotModel3D      = assimpWpfImporter.ReadModel3D(fileName);

            string dumpString = Ab3d.Utilities.Dumper.GetObjectHierarchyString(robotModel3D);

            RobotArmSampleTextBox.Text = dumpString;


            //var transform3DGroup = new Transform3DGroup();
            //transform3DGroup.Children.Add(new ScaleTransform3D(2, 3, 2));
            //transform3DGroup.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 45)));
            //transform3DGroup.Children.Add(new TranslateTransform3D(100, 0, 0));

            //geometryModel2.Transform = transform3DGroup;
        }