private void CreateRandomScene() { SceneObjectsContainer.Children.Clear(); for (int i = 0; i < 10; i++) { // Create simple box that user will be able to rotate // In order to support rotation, we need to create the box at (0,0,0) // and then after performing rotation, translate the object to its final location. // If we would create the object at its final rotation (basically applying translation before rotation), // then the box would not be rotated around its center but around the coordinate axes center. var boxModel = new Ab3d.UIElements.BoxUIElement3D() { CenterPosition = new Point3D(0, 0, 0), Size = new Size3D(50, 20, 50), Material = _normalMaterial }; // Create a StandardTransform3D // StandardTransform3D is a class that generates a MatrixTransform3D based on the translate, rotate and scale transform. // Note that because it is not possible to derive from WPF's Transform3D, the StandardTransform3D is a standalone class // that provides its own MatrixTransform3D object that can be assigned to the 3D model. // Its static SetStandardTransform3D and GetStandardTransform3D use a custom StandardTransform3DProperty // to "attach" the StandardTransform3D object to Model3D or Visual3D. But this does not automatically set the // object's transformation. var standardTransform3D = new StandardTransform3D() { TranslateX = _rnd.NextDouble() * 400 - 200, TranslateY = _rnd.NextDouble() * 40 - 20, TranslateZ = _rnd.NextDouble() * 400 - 200, }; // SetStandardTransform3D method will set the StandardTransform3DProperty to the standardTransform3D // The updateTransform3D argument will also set the boxModel.Transform to standardTransform3D.Transform StandardTransform3D.SetStandardTransform3D(boxModel, standardTransform3D, updateTransform3D: true); SceneObjectsContainer.Children.Add(boxModel); // Use EventManager from Ab3d.PowerToys to add support for click event on the box model var visualEventSource3D = new Ab3d.Utilities.VisualEventSource3D(boxModel); visualEventSource3D.MouseClick += delegate(object sender, MouseButton3DEventArgs e) { var selectedBoxModel = e.HitObject as Ab3d.UIElements.BoxUIElement3D; SelectObject(selectedBoxModel); }; _eventManager.RegisterEventSource3D(visualEventSource3D); // Automatically select first box if (_selectedBoxModel == null) { boxModel.Refresh(); // Force creating the model SelectObject(boxModel); } } }
private void ShowWireframeDuck() { _standardTransform3D = new StandardTransform3D(); WireframeDuckVisual3D.OriginalModel = _duckModel3D.Clone(); WireframeDuckVisual3D.IsVisible = true; StandardTransform3D.SetStandardTransform3D(WireframeDuckVisual3D, _standardTransform3D, updateTransform3D: true); TransformEditor.StandardTransform3D = _standardTransform3D; _selectedVisual3D = WireframeDuckVisual3D; }
public StandardTransformSample() { InitializeComponent(); // Read a teapot from wpf3d file string fileName = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\wpf3d\teapot-hires.wpf3d"); var wpf3DFile = new Ab3d.Utilities.Wpf3DFile(); var teapotModel3D = wpf3DFile.ReadFile(fileName); Ab3d.Utilities.ModelUtils.ChangeMaterial(teapotModel3D, new DiffuseMaterial(Brushes.Gold), newBackMaterial: null); // Create a single StandardTransform3D that will be able to translate, rotate and scale the read teapot. _standardTransform3D = new StandardTransform3D(); // We could also create a new StandardTransform3D with some initial transformations: //_standardTransform3D = new StandardTransform3D() //{ // RotateY = 30, // TranslateX = 100, // ScaleX = 1.3 //}; // To assign the _standardTransform3D to teapotModel3D we use the static SetStandardTransform3D method StandardTransform3D.SetStandardTransform3D(teapotModel3D, _standardTransform3D, updateTransform3D: true); // In some other location in the application we can read the StandardTransform3D from the teapotModel3D by: //var standardTransform3D = StandardTransform3D.GetStandardTransform3D(teapotModel3D); // Assign the _standardTransform3D to the editor control: TransformEditor.StandardTransform3D = _standardTransform3D; var contentVisual3D = teapotModel3D.CreateContentVisual3D(); MainViewport.Children.Add(contentVisual3D); _rnd = new Random(); }
private void GenerateRandomDucks(int ducksCount) { var rnd = new Random(); double lakeRadius = LakeCircleVisual3D.Radius; Point3D lakeCenter = LakeCircleVisual3D.CenterPosition; _duckModels = new List <ModelVisual3D>(ducksCount); RootDucksVisual3D.Children.Clear(); for (int i = 0; i < ducksCount; i++) { bool findNewPosition; do { var position = new Point3D(rnd.NextDouble() * lakeRadius * 2 - lakeRadius, 0, rnd.NextDouble() * lakeRadius * 2 - lakeRadius); // If position is outside of 80% of lake radius double distanceToLakeCenter = (position - lakeCenter).Length; findNewPosition = distanceToLakeCenter > (lakeRadius * 0.8); if (!findNewPosition) { // Now check if too close to any other duck foreach (var duckModel in _duckModels) { var standardTransform3D = StandardTransform3D.GetStandardTransform3D(duckModel); var distanceToDuck = (position - standardTransform3D.GetTranslateVector3D().ToPoint3D()).Length; if (distanceToDuck < DuckSize * 4) { findNewPosition = true; break; } } } if (!findNewPosition) { // The position is ok double scale = rnd.NextDouble() + 1; var standardTransform3D = new StandardTransform3D() { TranslateX = position.X, TranslateY = position.Y, TranslateZ = position.Z, RotateY = rnd.NextDouble() * 360, ScaleX = scale, ScaleY = scale, ScaleZ = scale }; var duckVisual3D = new ModelVisual3D() { Content = _duckModel3D, }; StandardTransform3D.SetStandardTransform3D(duckVisual3D, standardTransform3D, updateTransform3D: true); _duckModels.Add(duckVisual3D); RootDucksVisual3D.Children.Add(duckVisual3D); var visualEventSource3D = new VisualEventSource3D(duckVisual3D); visualEventSource3D.MouseEnter += OnDuckMouseEnter; visualEventSource3D.MouseLeave += OnDuckMouseLeave; visualEventSource3D.MouseDown += OnDuckMouseDown; visualEventSource3D.MouseUp += OnDuckMouseUp; _eventManager3D.RegisterEventSource3D(visualEventSource3D); } } while (findNewPosition); } }