private void AddTestModel() { var boxMesh3D = new Ab3d.Meshes.BoxMesh3D(new Point3D(0, 0, 0), new Size3D(1, 1, 1), 1, 1, 1).Geometry; int positionsCount = boxMesh3D.Positions.Count; var bounds = boxMesh3D.Bounds; // Create positionColorsArray that will define colors for each position var positionColorsArray = new Color4[positionsCount]; for (int i = 0; i < positionsCount; i++) { var position = boxMesh3D.Positions[i]; // Get colors based on the relative position inside the Bounds - in range from (0, 0, 0) to (1, 1, 1) float red = (float)((position.X - bounds.X) / bounds.SizeX); float green = (float)((position.Y - bounds.Y) / bounds.SizeY); float blue = (float)((position.Z - bounds.Z) / bounds.SizeZ); // Set Color this position positionColorsArray[i] = new Color4(red, green, blue, alpha: 1.0f); } // Now create the VertexColorMaterial that will be used instead of standard material // and will make the model render with special effect where each vertex can have its own color. _vertexColorMaterial = new VertexColorMaterial() { PositionColors = positionColorsArray, // The PositionColors property is used to specify colors for each vertex // To show specular effect set the specular data here: //SpecularPower = 16, //SpecularColor = Color3.White, //HasSpecularColor = true // If we would update the positionColorsArray very often, then set CreateDynamicBuffer to true //CreateDynamicBuffer = true, }; // Create standard WPF material and set the _vertexColorMaterial to be used when the model is rendered in DXEngine. var vertexColorDiffuseMaterial = new DiffuseMaterial(); vertexColorDiffuseMaterial.SetUsedDXMaterial(_vertexColorMaterial); // Create a GeometryModel3D that will be rendered with _vertexColorMaterial var vertexColorGeometryModel3D = new GeometryModel3D(boxMesh3D, vertexColorDiffuseMaterial); vertexColorGeometryModel3D.Transform = new ScaleTransform3D(100, 50, 80); // Scale the box var vertexColorModelVisual3D = new ModelVisual3D() { Content = vertexColorGeometryModel3D }; MainViewport.Children.Add(vertexColorModelVisual3D); }
public VertexColorRenderingSample() { InitializeComponent(); AddTestModel(); Camera1.StartRotation(45, 0); // Cleanup this.Unloaded += delegate(object sender, RoutedEventArgs args) { // We need to dispose all DXEngine objects that are created here - in this case _vertexColorMaterial if (_vertexColorMaterial != null) { _vertexColorMaterial.Dispose(); _vertexColorMaterial = null; } MainDXViewportView.Dispose(); }; }
public VertexColorRenderingSample() { InitializeComponent(); CreateGradientColorsArray(); // Use CameraControllerInfo to show that we can use left mouse button to set custom beam destination on the 3D model CameraControllerInfo.AddCustomInfoLine(0, MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, "SET BEAM DESTINATION"); // When the ViewportBorder size is change the size of the overlay Canvas (drawn over the 3D scene) ViewportBorder.SizeChanged += delegate(object sender, SizeChangedEventArgs args) { UpdateOverlayCanvasSize(); }; // Process mouse events ViewportBorder.MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e) { // Start user beam control _isUserBeamControl = true; ViewportBorder.CaptureMouse(); var position = e.GetPosition(ViewportBorder); ProcessMouseHit(position); }; ViewportBorder.MouseLeftButtonUp += delegate(object sender, MouseButtonEventArgs e) { // Stop user beam control _isUserBeamControl = false; ViewportBorder.ReleaseMouseCapture(); ProcessMouseOutOfModel(); }; // Subscribe to MouseMove to allow user to specify the beam target ViewportBorder.MouseMove += delegate(object sender, MouseEventArgs e) { if (_isUserBeamControl) { ProcessMouseHit(e.GetPosition(ViewportBorder)); } else { ProcessMouseOutOfModel(); } }; // Start animating the beam position CompositionTarget.Rendering += CompositionTargetOnRendering; // We add test models after the DXScene is initialized (this is required because specifal effects require DirectX device) MainDXViewportView.DXSceneInitialized += delegate(object sender, EventArgs e) { if (MainDXViewportView.DXScene == null) { return; // Probably WPF 3D rendering } // Get _vertexColorEffect that will be used to render model with vertex colors (note that this field must be disposed when it is not used any more - here in Unloaded event handler) AddTestModels(); }; // Cleanup this.Unloaded += delegate(object sender, RoutedEventArgs args) { CompositionTarget.Rendering -= CompositionTargetOnRendering; if (_vertexColorMaterial != null) { _vertexColorMaterial.Dispose(); _vertexColorMaterial = null; } if (_lineMaterial != null) { _lineMaterial.Dispose(); _lineMaterial = null; } MainDXViewportView.Dispose(); }; }
private void CreateLandscape(int gridSize, float noise, int randomSeed = 0) // is randomSeed is 0 or less, then random seed is used { _lastUsedGridSize = gridSize; // Generate height data with using DiamondSquare algorithm float[,] floatHeightData = DiamondSquareGrid(gridSize, seed: randomSeed, rMin: 0, rMax: 1, noise: noise); // To show height map we will use HeightMapMesh3D from Ab3d.PowerToys library // This class requires data in array of doubles. // NOTE: In the future version of DXEngine there will be an optimized version of HeightMesh that will take floats _heightData = new double[gridSize, gridSize]; for (int rowIndex = 0; rowIndex < gridSize; rowIndex++) { for (int columnIndex = 0; columnIndex < gridSize; columnIndex++) { _heightData[rowIndex, columnIndex] = (double)floatHeightData[rowIndex, columnIndex]; } } // We can use HeightMapMesh3D object from Ab3d.PowerToys library to create a MeshGeometry3D object from 2D array // We create Mesh with size 1 x 1 x 1 // This will allow us to scale it later to any size with ScaleTransform3D _heightMapMesh3D = new Meshes.HeightMapMesh3D(new Point3D(0, 0, 0), new Size3D(1, 1, 1), _heightData).Geometry; var vertexColorDiffuseMaterial = new DiffuseMaterial(); int positionsCount = _heightMapMesh3D.Positions.Count; // Create vertexColorsArray var vertexColorsArray = new Color4[positionsCount]; // Fill the vertexColorsArray with color values based on the data from _heightData CalculateVertexColors(_heightData, vertexColorsArray); // To show per-vertex color, we need to use a special VertexColorMaterial // Reuse VertexColorMaterial if possible. // Dispose old VertexColorMaterial and create a new one if (_vertexColorMaterial != null) { _vertexColorMaterial.Dispose(); } _vertexColorMaterial = new VertexColorMaterial() { PositionColors = vertexColorsArray }; // This material needs to be set to the WPF vertexColorDiffuseMaterial as UsedDXMaterial. // This means that when DXEngine will need to show WPF vertexColorDiffuseMaterial, it will use the vertexColorMaterial. vertexColorDiffuseMaterial.SetUsedDXMaterial(_vertexColorMaterial); // Now create GeometryModel3D and ModelVisual3D var vertexColorGeometryModel3D = new GeometryModel3D(_heightMapMesh3D, vertexColorDiffuseMaterial); vertexColorGeometryModel3D.Transform = new ScaleTransform3D(200, 200, 200); // To make the landscape colors visible from front and also back side, uncomment the line below (and comment the GeometryModel3D generation a few lines below): //vertexColorGeometryModel3D.BackMaterial = vertexColorDiffuseMaterial; var vertexColorModelVisual3D = new ModelVisual3D() { Content = vertexColorGeometryModel3D }; MainViewport.Children.Add(vertexColorModelVisual3D); // Add a new GeometryModel3D with the same _heightMapMesh3D // But this time render only back faces with gray material var backGeometryModel3D = new GeometryModel3D { Geometry = vertexColorGeometryModel3D.Geometry, // Same geometry as vertexColorGeometryModel3D Material = null, // Do not render front-faced triangles BackMaterial = new DiffuseMaterial(Brushes.DimGray), // Render only back faces Transform = vertexColorGeometryModel3D.Transform // Same scale transform as vertexColorGeometryModel3D }; var backModelVisual3D = new ModelVisual3D() { Content = backGeometryModel3D }; MainViewport.Children.Add(backModelVisual3D); // Refresh the camera in case we have removed the camera's light with MainViewport.Children.Clear(); Camera1.Refresh(); }
private void AddTestModels() { // Load teapot model from obj file var readerObj = new ReaderObj(); var geometryModel3D = readerObj.ReadModel3D(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\Models\teapot.obj")) as GeometryModel3D; if (geometryModel3D == null) { return; } _objectGeometry3D = (MeshGeometry3D)geometryModel3D.Geometry; int positionsCount = _objectGeometry3D.Positions.Count; // Create and fill the _positionColorsArray with the last color (light blue) _positionColorsArray = new Color4[positionsCount]; var lastColor = _gradientColor4Array[_gradientColor4Array.Length - 1]; FillPositionColorsArray(lastColor); // Now create the VertexColorMaterial that will be used instead of standard material // and will make the model render with special effect where each vertex can have its own color. _vertexColorMaterial = new VertexColorMaterial() { PositionColors = _positionColorsArray, // The PositionColors property is used to specify colors for each vertex CreateDynamicBuffer = true, // Because we will update the _positionColorsArray on each frame, it is better to create a dynamic DirectX buffer // To show specular effect set the specular data here: //SpecularPower = 16, //SpecularColor = Color3.White, //HasSpecularColor = true }; // Create standard WPF material and set the _vertexColorMaterial to be used when the model is rendered in DXEngine. var vertexColorDiffuseMaterial = new DiffuseMaterial(); vertexColorDiffuseMaterial.SetUsedDXMaterial(_vertexColorMaterial); // Create a GeometryModel3D that will be rendered with _vertexColorMaterial _vertexColorGeometryModel3D = new GeometryModel3D(_objectGeometry3D, vertexColorDiffuseMaterial); var vertexColorModelVisual3D = new ModelVisual3D() { Content = _vertexColorGeometryModel3D }; MainViewport.Children.Add(vertexColorModelVisual3D); // Show the same MeshGeometry3D but this time with wireframe material var wireframeWpfMaterial = new DiffuseMaterial(); _lineMaterial = new LineMaterial() { LineThickness = 1, LineColor = Color4.Black, DepthBias = 0.1f, }; wireframeWpfMaterial.SetUsedDXMaterial(_lineMaterial); var wireframeGeometryModel3D = new GeometryModel3D(_objectGeometry3D, wireframeWpfMaterial); var wireframeModelVisual3D = new ModelVisual3D() { Content = wireframeGeometryModel3D }; MainViewport.Children.Add(wireframeModelVisual3D); }