private void CreateScene(Viewport3D parentViewport3D, double sphereRadius, double depthBias, TargetPositionCamera targetPositionCamera, bool showSphere) { parentViewport3D.Children.Clear(); if (showSphere) { var sphereVisual3D = new Ab3d.Visuals.SphereVisual3D() { CenterPosition = new Point3D(0, 0, 0), Radius = sphereRadius, Segments = 10, Material = new DiffuseMaterial(Brushes.SkyBlue), UseCachedMeshGeometry3D = false // This will create a new MeshGeometry3D and will not use the shared MeshGeometry3D with radius = 1 }; parentViewport3D.Children.Add(sphereVisual3D); var sphereMesh = ((GeometryModel3D)sphereVisual3D.Content).Geometry as MeshGeometry3D; var sphereLinePositions = CollectWireframeLinePositions(sphereMesh); var multiLineVisual3D = new Ab3d.Visuals.MultiLineVisual3D() { Positions = sphereLinePositions, LineThickness = 0.5, LineColor = Colors.Black }; // To specify line depth bias to the Ab3d.PowerToys line Visual3D objects, // we use SetDXAttribute extension method and use LineDepthBias as DXAttributeType // NOTE: This can be used only before the Visual3D is created by DXEngine. // If you want to change the line bias after the object has been rendered, use the SetDepthBias method (defined below) multiLineVisual3D.SetDXAttribute(DXAttributeType.LineDepthBias, depthBias); // It would be also possible to set the depth with changing the DepthBias on the WpfWireframeVisual3DNode. // This is done with using the SetDepthBias method //SetDepthBias(dxViewportView, wireframeVisual3D, depthBias); parentViewport3D.Children.Add(multiLineVisual3D); _shownLineVisual3D = multiLineVisual3D; } else { if (_sampleModel == null) { var readerObj = new Ab3d.ReaderObj(); _sampleModel = readerObj.ReadModel3D(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\Models\Teapot.obj"), null, new DiffuseMaterial(Brushes.SkyBlue)); _sampleModel.Freeze(); } double readObjectRadius = Math.Sqrt(_sampleModel.Bounds.SizeX * _sampleModel.Bounds.SizeX + _sampleModel.Bounds.SizeZ + _sampleModel.Bounds.SizeZ) / 2; double scaleFactor = sphereRadius / readObjectRadius; var finalModel = new Model3DGroup(); finalModel.Children.Add(_sampleModel); finalModel.Transform = new ScaleTransform3D(scaleFactor, scaleFactor, scaleFactor); finalModel.Freeze(); var wireframeVisual3D = new WireframeVisual3D() { OriginalModel = finalModel, WireframeType = WireframeVisual3D.WireframeTypes.WireframeWithOriginalSolidModel, UseModelColor = false, LineColor = Colors.Black, LineThickness = 0.5 }; // To specify line depth bias to the WireframeVisual3D, // we use SetDXAttribute extension method and use LineDepthBias as DXAttributeType wireframeVisual3D.SetDXAttribute(DXAttributeType.LineDepthBias, depthBias); // It would be also possible to set the depth with changing the DepthBias on the WpfWireframeVisual3DNode. // This is done with using the SetDepthBias method //SetDepthBias(dxViewportView, wireframeVisual3D, depthBias); parentViewport3D.Children.Add(wireframeVisual3D); _shownLineVisual3D = wireframeVisual3D; } _previousCameraDistance = sphereRadius * 4; targetPositionCamera.Distance = _previousCameraDistance; targetPositionCamera.Offset = new Vector3D(0, sphereRadius * 0.4, 0); }
private void CreateRootModel() { bool show3DLine = false; switch (ObjectComboBox.SelectedIndex) { case 0: Ab3d.Meshes.SphereMesh3D sphere = new Ab3d.Meshes.SphereMesh3D(new Point3D(0, 0, 0), 80, 10); _rootMesh = sphere.Geometry; break; case 1: Ab3d.Meshes.SphereMesh3D sphere2 = new Ab3d.Meshes.SphereMesh3D(new Point3D(0, 0, 0), 80, 5); _rootMesh = sphere2.Geometry; break; case 2: // NOTE: Here we create an optimized version of sphere but it does not have texture coordinates // If we do not need texture coordinates (do not need to show texture), than we can slightly simplify the sphere model. // When we also need to create texture coordinates, the top most position that represent the same point in space is defined multiple times // - each time with slightly different texture coordinate (so that the whole top line on the texture is shown around the top sphere position). // Also there are x + 1 position around the sphere (in one row) - one additional position is added that the first and last position in the "row" are in the same space position, // but the first position has x texture coordinate 0, the last position has x texture coordinate 1 - this shows the whole texture nicely around the sphere. // If texture coordinates are not needed, than we do not need to define more than one upper and bottom positions, // and also do not need to add another position to the row. // Optimized sphere can be created only with SphereMesh3D object (not with SphereVisual3D) Ab3d.Meshes.SphereMesh3D sphere3 = new Ab3d.Meshes.SphereMesh3D(new Point3D(0, 0, 0), 80, 12, false); // false: generateTextureCoordinates _rootMesh = sphere3.Geometry; break; case 3: Ab3d.Meshes.BoxMesh3D box = new Ab3d.Meshes.BoxMesh3D(new Point3D(0, 0, 0), new Size3D(130, 60, 100), 1, 1, 1); _rootMesh = box.Geometry; break; case 4: Ab3d.Meshes.BoxMesh3D box2 = new Ab3d.Meshes.BoxMesh3D(new Point3D(0, 0, 0), new Size3D(130, 60, 100), 4, 4, 4); _rootMesh = box2.Geometry; break; case 5: Ab3d.Meshes.CylinderMesh3D cylinder = new Ab3d.Meshes.CylinderMesh3D(new Point3D(0, -50, 0), 60, 100, 12, true); _rootMesh = cylinder.Geometry; break; case 6: Ab3d.Meshes.ConeMesh3D cone = new Ab3d.Meshes.ConeMesh3D(new Point3D(0, -50, 0), 30, 60, 100, 12, true); _rootMesh = cone.Geometry; break; case 7: Ab3d.Meshes.ConeMesh3D cone2 = new Ab3d.Meshes.ConeMesh3D(new Point3D(0, -50, 0), 30, 60, 100, 6, false); _rootMesh = cone2.Geometry; break; case 8: var readerObj = new Ab3d.ReaderObj(); var teapotModel = readerObj.ReadModel3D(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\ObjFiles\Teapot.obj")) as GeometryModel3D; if (teapotModel == null) { return; } // Get the teapot MeshGeometry3D _rootMesh = (MeshGeometry3D)teapotModel.Geometry; break; case 9: var line = new Ab3d.Visuals.LineVisual3D() { StartPosition = new Point3D(0, 0, 0), EndPosition = new Point3D(100, 0, 0), LineColor = Colors.Silver, LineThickness = 20 }; Show3DLines(line); show3DLine = true; break; case 10: var polyLineVisual3D = new Ab3d.Visuals.PolyLineVisual3D() { Positions = new Point3DCollection(new Point3D[] { new Point3D(-75, 50, 0), new Point3D(-25, 0, 0), new Point3D(25, 50, 0), new Point3D(75, 0, 0) }), LineThickness = 20 }; Show3DLines(polyLineVisual3D); show3DLine = true; break; case 11: // This is the same line as in the previous sample (PolyLineVisual3D), but this time // it is created as diconnected list of lines - note that this requires that the positions are duplicated. var multiLineVisual3D = new Ab3d.Visuals.MultiLineVisual3D() { Positions = new Point3DCollection(new Point3D[] { new Point3D(-75, 50, 0), new Point3D(-25, 0, 0), new Point3D(-25, 0, 0), new Point3D(25, 50, 0), new Point3D(25, 50, 0), new Point3D(75, 0, 0) }), LineThickness = 20 }; Show3DLines(multiLineVisual3D); show3DLine = true; break; default: _rootMesh = null; break; } // If we were looking at 3D lines before and now we are looking an standard 3D models, // we adjust the camera back to the side view (from direct front view) if (_isShowing3DLines && !show3DLine) { Camera1.Heading = 30; Camera1.Attitude = -20; Camera1.Distance = 300; } _isShowing3DLines = show3DLine; _rootModel = new GeometryModel3D(); _rootModel.Geometry = _rootMesh; _rootModel.Material = new DiffuseMaterial(Brushes.DarkBlue); ObjectModelVisual.Content = _rootModel; Ab3d.Utilities.ModelEventSource3D modelEventSource = new Ab3d.Utilities.ModelEventSource3D(); modelEventSource.TargetModel3D = _rootModel; modelEventSource.MouseClick += new Ab3d.Common.EventManager3D.MouseButton3DEventHandler(modelEventSource_MouseClick); _eventsManager.ResetEventSources3D(); _eventsManager.RegisterEventSource3D(modelEventSource); MainViewport.Cursor = Cursors.Hand; }