![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
|
Welcome to Vista Forums we are your forum to discuss Windows Vista x64 and x86 systems. Whether you need help or just want to post an idea you have on Vista, this is the forum for you.
br> br> |
| |||||||
![]() |
| | Thread Tools | Display Modes |
| | #1 (permalink) |
| Guest | Simple Grid Rendering Hi there, I need to render a simple 50x50 grid / table, each cell in the table should highlight when the mouse is hovering over it. The hard part is: I really need to be able to tilt the grid, within the 3D world.... I hear the Viewport would support the 3D view - but how can I render the grid within the Viewport? Any advice would be great! thanks for your time Kristan |
My System Specs![]() |
| | #2 (permalink) |
| Guest | Re: Simple Grid Rendering Hi Kristan, i ran into a similar problem. since everything is triangles in 3D, there is no 'line' as such. there is a class called ScreenSpaceLine3D which you can find online, but it didn't really work for me so i rolled my own. essentially i created a very long and thin cuboid, to effect a grid. here is a bunch of code i use in my hobby app attempting to create a 3d modelling tool to help with construction projects. i use the TrackBall class to allow 3d fly/zoom around the world. there are a few helper methods to help with the 3d objects. i can mail you the whole thing if you want. good luck tim double scale = .05; // i use mm measurements and this is a useful scale, e.g. to render a 1500mm square on screen void mmSceneDrawGrid_Click(object sender, RoutedEventArgs e) { double thick = .03; double outsideThickFactor = 5; double len = 2000 * scale; double size = 5; // number of parellel lines in one side of the grid Color c = Colors.Red; double interval = len / size; for (int i = 0; i <= size; i++) { for (int j = 0; j <= size; j++) { // convert the loop iterators into the required grid cell size interval, relative to len double a = i * interval; double b = j * interval; // draw all the lines in the x-direction, size x size all starting at 0x, moving to 'len' for each y, for each z this.CreateLine(new Point3D(0, a, b), new Point3D(len, a, b), thick * ((a % len) / size == 0 && (b % len) / size == 0 ? outsideThickFactor : 1), c); // draw all the lines in the y-direction, size x size all starting at 0y, moving to 'len' for each x, for each z this.CreateLine(new Point3D(a, 0, b), new Point3D(a, len, b), thick * ((a % len) / size == 0 && (b % len) / size == 0 ? outsideThickFactor : 1), c); // draw all the lines in the z-direction, size x size all starting at 0z, moving to 'len' for each x, for each y this.CreateLine(new Point3D(a, b, 0), new Point3D(a, b, len), thick * ((a % len) / size == 0 && (b % len) / size == 0 ? outsideThickFactor : 1), c); } } } private Model3DGroup CreateTriangleModel(Point3D p0, Point3D p1, Point3D p2, Color c) { MeshGeometry3D mesh = new MeshGeometry3D(); mesh.Positions.Add(p0); mesh.Positions.Add(p1); mesh.Positions.Add(p2); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(2); Vector3D normal = CalculateNormal(p0, p1, p2); mesh.Normals.Add(normal); mesh.Normals.Add(normal); mesh.Normals.Add(normal); Material material = new DiffuseMaterial(new SolidColorBrush(c)); GeometryModel3D model = new GeometryModel3D(mesh, material); Model3DGroup group = new Model3DGroup(); group.Children.Add(model); return group; } private Vector3D CalculateNormal(Point3D p0, Point3D p1, Point3D p2) { Vector3D v0 = new Vector3D( p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z); Vector3D v1 = new Vector3D( p2.X - p1.X, p2.Y - p1.Y, p2.Z - p1.Z); return Vector3D.CrossProduct(v0, v1); } private void CreateLine(Point3D a, Point3D b, double t, Color c) { Model3DGroup cube = new Model3DGroup(); Point3D p0 = new Point3D(a.X, a.Y, a.Z); Point3D p1 = new Point3D(a.X + t, a.Y, a.Z); Point3D p2 = new Point3D(b.X + t, b.Y, b.Z); Point3D p3 = new Point3D(b.X, b.Y, b.Z); Point3D p4 = new Point3D(a.X, a.Y + t, a.Z); Point3D p5 = new Point3D(a.X + t, a.Y + t, a.Z); Point3D p6 = new Point3D(b.X + t, b.Y + t, b.Z); Point3D p7 = new Point3D(b.X, b.Y + t, b.Z); //front side triangles cube.Children.Add(CreateTriangleModel(p3, p2, p6, c)); cube.Children.Add(CreateTriangleModel(p3, p6, p7, c)); //right side triangles cube.Children.Add(CreateTriangleModel(p2, p1, p5, c)); cube.Children.Add(CreateTriangleModel(p2, p5, p6, c)); //back side triangles cube.Children.Add(CreateTriangleModel(p1, p0, p4, c)); cube.Children.Add(CreateTriangleModel(p1, p4, p5, c)); //left side triangles cube.Children.Add(CreateTriangleModel(p0, p3, p7, c)); cube.Children.Add(CreateTriangleModel(p0, p7, p4, c)); //top side triangles cube.Children.Add(CreateTriangleModel(p7, p6, p5, c)); cube.Children.Add(CreateTriangleModel(p7, p5, p4, c)); //bottom side triangles cube.Children.Add(CreateTriangleModel(p2, p3, p0, c)); cube.Children.Add(CreateTriangleModel(p2, p0, p1, c)); ModelVisual3D model = new ModelVisual3D(); model.Content = cube; this.mainViewport.Children.Add(model); } "Kristan" <kristan@NOSPAMhotmail.co.uk> wrote in message news:484580AC-A26F-45F2-8698-5A5D9AEE3F01@microsoft.com... > Hi there, I need to render a simple 50x50 grid / table, each cell in the > table should highlight when the mouse is hovering over it. > The hard part is: I really need to be able to tilt the grid, within the > 3D world.... I hear the Viewport would support the 3D view - but how can I > render the grid within the Viewport? > > Any advice would be great! > thanks for your time > Kristan > |
My System Specs![]() |
| | #3 (permalink) |
| Guest | Re: Simple Grid Rendering Hi there, I had a go at using the code, with the following XAML <Window x:Class="WindowsApplication4.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="WindowsApplication4" Height="418" Width="626" > <Grid> <Button Width="100" Height="100" Name="mmSceneDrawGrid" Click="mmSceneDrawGrid_Click" HorizontalAlignment="Left" Margin="86,44.5,0,0" VerticalAlignment="Top">Hello, XAML!</Button> <Viewport3D Name="mainViewport"></Viewport3D> </Grid> </Window> The mmSceneDrawGrid_Click() handler does execute, but nothing is rendered onto the screen... hmmmm any ideas what I might be doing wrong? It would be good to get something showing up - then it'll be easier to play with it and work everything out! ![]() thanks, Kristan "Tim Mackey" <tim.mackey@community.nospam> wrote in message news:4EA9968D-61E1-4E45-808E-4AE8E95A92F5@microsoft.com... > Hi Kristan, > i ran into a similar problem. since everything is triangles in 3D, there > is no 'line' as such. there is a class called ScreenSpaceLine3D which you > can find online, but it didn't really work for me so i rolled my own. > essentially i created a very long and thin cuboid, to effect a grid. here > is a bunch of code i use in my hobby app attempting to create a 3d > modelling tool to help with construction projects. i use the TrackBall > class to allow 3d fly/zoom around the world. there are a few helper > methods to help with the 3d objects. i can mail you the whole thing if > you want. > good luck > tim > > double scale = .05; // i use mm measurements and this is a useful scale, > e.g. to render a 1500mm square on screen > void mmSceneDrawGrid_Click(object sender, RoutedEventArgs e) > { > double thick = .03; > double outsideThickFactor = 5; > double len = 2000 * scale; > double size = 5; // number of parellel lines in one side of the > grid > Color c = Colors.Red; > double interval = len / size; > > for (int i = 0; i <= size; i++) > { > for (int j = 0; j <= size; j++) > { > // convert the loop iterators into the required grid cell size > interval, relative to len > double a = i * interval; > double b = j * interval; > > // draw all the lines in the x-direction, size x size all starting at > 0x, moving to 'len' for each y, for each z > this.CreateLine(new Point3D(0, a, b), new Point3D(len, a, b), thick * > ((a % len) / size == 0 && (b % len) / size == 0 ? outsideThickFactor : 1), > c); > // draw all the lines in the y-direction, size x size all starting at > 0y, moving to 'len' for each x, for each z > this.CreateLine(new Point3D(a, 0, b), new Point3D(a, len, b), thick * > ((a % len) / size == 0 && (b % len) / size == 0 ? outsideThickFactor : 1), > c); > // draw all the lines in the z-direction, size x size all starting at > 0z, moving to 'len' for each x, for each y > this.CreateLine(new Point3D(a, b, 0), new Point3D(a, b, len), thick * > ((a % len) / size == 0 && (b % len) / size == 0 ? outsideThickFactor : 1), > c); > } > } > } > > > private Model3DGroup CreateTriangleModel(Point3D p0, Point3D p1, Point3D > p2, Color c) > { > MeshGeometry3D mesh = new MeshGeometry3D(); > mesh.Positions.Add(p0); > mesh.Positions.Add(p1); > mesh.Positions.Add(p2); > mesh.TriangleIndices.Add(0); > mesh.TriangleIndices.Add(1); > mesh.TriangleIndices.Add(2); > Vector3D normal = CalculateNormal(p0, p1, p2); > mesh.Normals.Add(normal); > mesh.Normals.Add(normal); > mesh.Normals.Add(normal); > Material material = new DiffuseMaterial(new SolidColorBrush(c)); > GeometryModel3D model = new GeometryModel3D(mesh, material); > Model3DGroup group = new Model3DGroup(); > group.Children.Add(model); > > return group; > } > > private Vector3D CalculateNormal(Point3D p0, Point3D p1, Point3D p2) > { > Vector3D v0 = new Vector3D( > p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z); > Vector3D v1 = new Vector3D( > p2.X - p1.X, p2.Y - p1.Y, p2.Z - p1.Z); > return Vector3D.CrossProduct(v0, v1); > } > > private void CreateLine(Point3D a, Point3D b, double t, Color c) > { > Model3DGroup cube = new Model3DGroup(); > Point3D p0 = new Point3D(a.X, a.Y, a.Z); > Point3D p1 = new Point3D(a.X + t, a.Y, a.Z); > Point3D p2 = new Point3D(b.X + t, b.Y, b.Z); > Point3D p3 = new Point3D(b.X, b.Y, b.Z); > Point3D p4 = new Point3D(a.X, a.Y + t, a.Z); > Point3D p5 = new Point3D(a.X + t, a.Y + t, a.Z); > Point3D p6 = new Point3D(b.X + t, b.Y + t, b.Z); > Point3D p7 = new Point3D(b.X, b.Y + t, b.Z); > //front side triangles > cube.Children.Add(CreateTriangleModel(p3, p2, p6, c)); > cube.Children.Add(CreateTriangleModel(p3, p6, p7, c)); > //right side triangles > cube.Children.Add(CreateTriangleModel(p2, p1, p5, c)); > cube.Children.Add(CreateTriangleModel(p2, p5, p6, c)); > //back side triangles > cube.Children.Add(CreateTriangleModel(p1, p0, p4, c)); > cube.Children.Add(CreateTriangleModel(p1, p4, p5, c)); > //left side triangles > cube.Children.Add(CreateTriangleModel(p0, p3, p7, c)); > cube.Children.Add(CreateTriangleModel(p0, p7, p4, c)); > //top side triangles > cube.Children.Add(CreateTriangleModel(p7, p6, p5, c)); > cube.Children.Add(CreateTriangleModel(p7, p5, p4, c)); > //bottom side triangles > cube.Children.Add(CreateTriangleModel(p2, p3, p0, c)); > cube.Children.Add(CreateTriangleModel(p2, p0, p1, c)); > > ModelVisual3D model = new ModelVisual3D(); > model.Content = cube; > this.mainViewport.Children.Add(model); > } > > "Kristan" <kristan@NOSPAMhotmail.co.uk> wrote in message > news:484580AC-A26F-45F2-8698-5A5D9AEE3F01@microsoft.com... >> Hi there, I need to render a simple 50x50 grid / table, each cell in the >> table should highlight when the mouse is hovering over it. >> The hard part is: I really need to be able to tilt the grid, within the >> 3D world.... I hear the Viewport would support the 3D view - but how can >> I render the grid within the Viewport? >> >> Any advice would be great! >> thanks for your time >> Kristan >> > |
My System Specs![]() |
| | #4 (permalink) |
| Guest | Re: Simple Grid Rendering hi kristan. here is the full code i'm using. hopefully it will work for you. sorry i don't have time to trim it down to a minimal solution, there is a lot of stuff that may not interest you. it's poorly commented (if at all) and the object rotations don't work well, but it's my first wpf application so i'm just using it as a learning tool. here's the xaml: <?Mapping XmlNamespace="local" ClrNamespace="WPF_Test" ?> <Window x:Class="WPF_Test.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="WPF_Test" WindowState="Maximized" xmlns:my="clr-namespace:System;assembly=mscorlib" Height="336" Width="351"> <Grid Name="WorldGrid" > <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> </Grid.RowDefinitions> <Menu HorizontalAlignment="Stretch" Name="menu1" VerticalAlignment="Top" Grid.Row="0" Grid.Column="0" Focusable="True"> <MenuItem Header="_File"> <MenuItem Header="_Open" Name="mmOpen" ></MenuItem> <MenuItem Header="_Save" Name="mmSave"></MenuItem> <MenuItem Header="E_xit" Name="mmExit"></MenuItem> </MenuItem> <MenuItem Header="_Lights"> <MenuItem Header="Add _Ambient Lights" Name="mmAddAmbientLights" ></MenuItem> <MenuItem Header="Add _Directional Lights" Name="mmAddDirectionalLights" ></MenuItem> <MenuItem Header="_Clear Lights" Name="mmClearLights" ></MenuItem> </MenuItem> <MenuItem Header="_Camera"> <MenuItem Header="_Reset Camera" Name="mmResetCamera" ></MenuItem> <MenuItem Header="_Clear Scene" Name="mmClearObjects"></MenuItem> </MenuItem> <MenuItem Header="_Action"> <MenuItem Header="Draw _Grid" Name="mmDrawGrid" ></MenuItem> <MenuItem Header="Deselect _Object" Name="mmDeselectObject" ></MenuItem> <MenuItem Header="View _Key Commands" Name="mmViewKeyCommands" ></MenuItem> </MenuItem> </Menu> <Viewport3D Name="mainViewport" ClipToBounds="True" Grid.Row="1" Grid.Column="0" > <Viewport3D.Camera> <PerspectiveCamera FarPlaneDistance="100" NearPlaneDistance="0" LookDirection="0,0,-1" UpDirection="0,1,0" Position="5,5,75" FieldOfView="70" /> </Viewport3D.Camera> <ModelVisual3D> <ModelVisual3D.Content> <AmbientLight Color="White" /> </ModelVisual3D.Content> </ModelVisual3D> </Viewport3D> <Border Name="Border1" Background="Transparent" Grid.Row="1" Grid.Column="0" Focusable="True" ForceCursor="True" KeyboardNavigation.AcceptsReturn="True" KeyboardNavigation.TabNavigation="Local" KeyboardNavigation.DirectionalNavigation="Local" KeyboardNavigation.ControlTabNavigation="Local" /> <DockPanel Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"> <TextBlock Text=" Length " VerticalAlignment="Center" /> <TextBox Name="txtPlankLength" Width="70" Focusable="True" /> <Button Click="AddPlank" Content="Add Plank" Width="70" Focusable="True" /> </DockPanel> <StatusBar Name="statusBar1" Grid.Row="3" Grid.Column="0" > <StatusBarItem HorizontalAlignment="Left" Name="statusBarItem1" Content="Ready" ></StatusBarItem> </StatusBar> </Grid> </Window> and, the lengthy code behind. using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; using System.Windows.Markup; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Windows.Media.Media3D; using System.Xml; using System.Xml.Serialization; using _3DTools; using Microsoft.Win32; namespace WPF_Test { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : System.Windows.Window { private List<Model3DGroup> FormObjects = new List<Model3DGroup>(); // a list of all 3d objects added to the viewport private Material previousMaterial; private Model3DGroup currentModel; double scale = .05; // 1mm : screen private Trackball trackball = new Trackball(); public Window1() { InitializeComponent(); this.Loaded += new RoutedEventHandler(Window1_Loaded); this.KeyDown += new KeyEventHandler(Window1_KeyDown); this.Border1.MouseDown += new MouseButtonEventHandler(ViewPort_MouseDown); this.mmOpen.Click += new RoutedEventHandler(mmFileOpen_Click); this.mmSave.Click += new RoutedEventHandler(mmFileSave_Click); this.mmExit.Click += new RoutedEventHandler(mmFileExit_Click); this.mmClearObjects.Click += new RoutedEventHandler(mmSceneClearObjects_Click); this.mmResetCamera.Click += new RoutedEventHandler(mmSceneResetCamera_Click); this.mmDrawGrid.Click += new RoutedEventHandler(mmSceneDrawGrid_Click); this.mmViewKeyCommands.Click += new RoutedEventHandler(mmSceneViewKeyCommands_Click); this.mmDeselectObject.Click += new RoutedEventHandler(mmSceneDeselect_Click); this.mmAddAmbientLights.Click += new RoutedEventHandler(mmSceneAddAmbientLights_Click); this.mmAddDirectionalLights.Click += new RoutedEventHandler(mmSceneAddDirectionalLights_Click); this.mmClearLights.Click += new RoutedEventHandler(mmClearLights_Click); } void Window1_Loaded(object sender, RoutedEventArgs e) { this.mmSceneResetCamera_Click(sender, e); this.mmSceneDrawGrid_Click(sender, e); } #region util shape grouping methods private List<GeometryModel3D> GetChildGeometryModels(Model3DGroup parent) { List<GeometryModel3D> list = new List<GeometryModel3D>(); Queue<Model3DGroup> q = new Queue<Model3DGroup>(); foreach (object o in parent.Children) if (o is Model3DGroup) q.Enqueue(o as Model3DGroup); while (q.Count > 0) { Model3DGroup m = q.Dequeue(); foreach (object o in m.Children) { if (o is Model3DGroup) q.Enqueue(o as Model3DGroup); else list.Add(o as GeometryModel3D); } } return list; } private Model3DGroup FindParentModel(object find) { int hash = find.GetHashCode(); System.Diagnostics.Trace.WriteLine("Searching for " + hash); // iterative approach to recursively scan child objects of the parent model foreach (Model3DGroup mod in FormObjects) foreach (GeometryModel3D geo in GetChildGeometryModels(mod)) if (geo.GetHashCode() == hash) return mod; System.Diagnostics.Trace.WriteLine("Not found\n\n"); return null; } private void HighlightObject(Model3DGroup parent, Color c) { this.mmSceneDeselect_Click(null, new RoutedEventArgs()); Material m = new DiffuseMaterial(new SolidColorBrush(c)); foreach (GeometryModel3D geo in GetChildGeometryModels(parent)) { previousMaterial = geo.Material.Clone(); // overwritten but that doesn't matter. geo.Material = m; } // save the current Material to and Model for later reverting back currentModel = parent; // set local transformation variable if(!(currentModel.Transform is Transform3DGroup)) { tg = new Transform3DGroup(); tg.Children.Add(new TranslateTransform3D()); tg.Children.Add(new RotateTransform3D(new AxisAngleRotation3D())); tg.Children.Add(new ScaleTransform3D()); this.currentModel.Transform = tg; } else tg = currentModel.Transform as Transform3DGroup; } #endregion #region keyboard events private Transform3DGroup tg; void Window1_KeyDown(object sender, KeyEventArgs e) { PerspectiveCamera cam = (this.mainViewport.Camera as PerspectiveCamera); // TODO: bullet-time-cam, slide and look. if (Keyboard.Modifiers == ModifierKeys.Control) { // control the look direction via Ctrl-arrows / pg Up/down switch (e.Key) { case Key.Left: cam.LookDirection = new Vector3D(cam.LookDirection.X - .1, cam.LookDirection.Y, cam.LookDirection.Z); break; case Key.Right: cam.LookDirection = new Vector3D(cam.LookDirection.X + .1, cam.LookDirection.Y, cam.LookDirection.Z); break; case Key.Up: cam.LookDirection = new Vector3D(cam.LookDirection.X, cam.LookDirection.Y + .1, cam.LookDirection.Z); break; case Key.Down: cam.LookDirection = new Vector3D(cam.LookDirection.X, cam.LookDirection.Y - .1, cam.LookDirection.Z); break; case Key.PageDown: cam.LookDirection = new Vector3D(cam.LookDirection.X, cam.LookDirection.Y, cam.LookDirection.Z + .1); break; case Key.PageUp: cam.LookDirection = new Vector3D(cam.LookDirection.X, cam.LookDirection.Y, cam.LookDirection.Z - .1); break; default: return; } e.Handled = true; } else if (Keyboard.Modifiers == ModifierKeys.Shift) { if (this.currentModel == null) { this.statusBarItem1.Content = "No object selected!"; return; } // shift moves the object via Ctrl-arrows / pg Up/down TranslateTransform3D t = tg.Children[0] as TranslateTransform3D; switch (e.Key) { case Key.Left: t.OffsetX--; break; case Key.Right: t.OffsetX++; break; case Key.Up: t.OffsetY++; break; case Key.Down: t.OffsetY--; break; case Key.PageDown: t.OffsetZ--; break; case Key.PageUp: t.OffsetZ++; break; default: return; } e.Handled = true; } else if (Keyboard.Modifiers == (ModifierKeys.Shift | ModifierKeys.Control)) { // shift+control = rotate if (this.currentModel == null) { this.statusBarItem1.Content = "No object selected!"; return; } RotateTransform3D t = tg.Children[1] as RotateTransform3D; AxisAngleRotation3D a = t.Rotation as AxisAngleRotation3D; switch (e.Key) { case Key.Left: a.Angle--; break; case Key.Right: a.Angle++; break; default: return; } e.Handled = true; } else // no modifiers, just move the camera { switch (e.Key) { case Key.Left: cam.Position = new Point3D(cam.Position.X - 1, cam.Position.Y, cam.Position.Z); break; case Key.Right: cam.Position = new Point3D(cam.Position.X + 1, cam.Position.Y, cam.Position.Z); break; case Key.Up: cam.Position = new Point3D(cam.Position.X, cam.Position.Y + 1, cam.Position.Z); break; case Key.Down: cam.Position = new Point3D(cam.Position.X, cam.Position.Y - 1, cam.Position.Z); break; case Key.PageDown: cam.Position = new Point3D(cam.Position.X, cam.Position.Y, cam.Position.Z + 1); break; case Key.PageUp: cam.Position = new Point3D(cam.Position.X, cam.Position.Y, cam.Position.Z - 1); break; case Key.Add: cam.FieldOfView++; break; case Key.Subtract: cam.FieldOfView--; break; default: return; } e.Handled = true; } this.statusBarItem1.Content = String.Format("Camera: x{0:0}, y{1:0}, z{2:0}. Look: x{3:0.0}, y{4:0.0}, z{5:0.0}. Field of view: {6}", cam.Position.X, cam.Position.Y, cam.Position.Z, this.trackball.CameraLookDirection.X, this.trackball.CameraLookDirection.Y, this.trackball.CameraLookDirection.Z, cam.FieldOfView); } #endregion void AddPlank(object sender, EventArgs e) { try { double length = Convert.ToDouble(this.txtPlankLength.Text)*scale; this.CreateCuboid(new Point3D(0,0,0), 140*scale, length, 30*scale, Colors.Brown); } catch { MessageBox.Show("Please enter a milimetre measurement, decimal points are allowed, no letters etc. ", "Not a number"); } } #region menu void mmSceneResetCamera_Click(object sender, RoutedEventArgs e) { this.mainViewport.Camera.Transform = null; // remove the trackball (this.mainViewport.Camera as PerspectiveCamera).Position = new Point3D(5, 5, 75); (this.mainViewport.Camera as PerspectiveCamera).LookDirection = new Vector3D(0, 0, -1); trackball = new Trackball(); trackball.EventSource = this.Border1; this.mainViewport.Camera.Transform = trackball.Transform; } void mmSceneClearObjects_Click(object sender, RoutedEventArgs e) { for(int i=this.mainViewport.Children.Count-1; i>=0; i--) { ModelVisual3D m = this.mainViewport.Children[i] as ModelVisual3D; if(m is Model3DGroup) this.mainViewport.Children.RemoveAt(i); } } void mmSceneAddAmbientLights_Click(object sender, RoutedEventArgs e) { ModelVisual3D lights = new ModelVisual3D(); lights.Content = new AmbientLight(Colors.White); this.mainViewport.Children.Add(lights); } void mmClearLights_Click(object sender, RoutedEventArgs e) { for(int i=this.mainViewport.Children.Count-1; i>=0; i--) { ModelVisual3D m = this.mainViewport.Children[i] as ModelVisual3D; if(m.Content.GetType().Name.EndsWith("Light")) this.mainViewport.Children.RemoveAt(i); } } void mmSceneAddDirectionalLights_Click(object sender, RoutedEventArgs e) { ModelVisual3D lights = new ModelVisual3D(); lights.Content = new DirectionalLight(Colors.Yellow, (this.mainViewport.Camera as PerspectiveCamera).LookDirection); this.mainViewport.Children.Add(lights); } void mmSceneDeselect_Click(object sender, RoutedEventArgs e) { if (this.currentModel != null) { // restore previous material foreach (GeometryModel3D geo in GetChildGeometryModels(currentModel)) geo.Material = previousMaterial; } this.currentModel = null; this.previousMaterial = null; } void mmSceneDrawGrid_Click(object sender, RoutedEventArgs e) { double thick = .03; double outsideThickFactor = 5; double len = 2000 * scale; double size = 5; Color c = Colors.Red; //.FromRgb(220, 220, 220); double interval = len / size; for (int i = 0; i <= size; i++) { for (int j = 0; j <= size; j++) { // convert the loop iterators into the required grid cell size interval, relative to len double a = i * interval; double b = j * interval; // draw all the lines in the x-direction, size x size all starting at 0x, moving to 'len' for each y, for each z this.CreateLine(new Point3D(0, a, b), new Point3D(len, a, b), thick * ((a % len) / size == 0 && (b % len) / size == 0 ? outsideThickFactor : 1), c); // draw all the lines in the y-direction, size x size all starting at 0y, moving to 'len' for each x, for each z this.CreateLine(new Point3D(a, 0, b), new Point3D(a, len, b), thick * ((a % len) / size == 0 && (b % len) / size == 0 ? outsideThickFactor : 1), c); // draw all the lines in the z-direction, size x size all starting at 0z, moving to 'len' for each x, for each y this.CreateLine(new Point3D(a, b, 0), new Point3D(a, b, len), thick * ((a % len) / size == 0 && (b % len) / size == 0 ? outsideThickFactor : 1), c); } } /* 3dLine class not working.... * * ScreenSpaceLines3D ssl3D = new ScreenSpaceLines3D(); Point3DCollection gridLines = new Point3DCollection(); for (int i = 0; i <= size; i++) { for (int j = 0; j <= size; j++) { // convert the loop iterators into the required grid cell size interval, relative to len double a = i * interval; double b = j * interval; // x line gridLines.Add(new Point3D(0, a, b)); gridLines.Add(new Point3D(len, a, b)); // y line gridLines.Add(new Point3D(a, 0, b)); gridLines.Add(new Point3D(a, len, b)); // z line gridLines.Add(new Point3D(a, b, 0)); gridLines.Add(new Point3D(a, b, len)); } } ssl3D.Points = gridLines; ssl3D.Color = Colors.Red; ssl3D.Thickness = 5; this.mainViewport.Children.Add(ssl3D);*/ } void mmSceneViewKeyCommands_Click(object sender, RoutedEventArgs e) { MessageBox.Show(@"Use arrows to move camera in x and y directions. Page up/down to move camera in/out in z direction. Ctrl+Arrow keys to change camera look vector in x and y direction. Ctrl+Page up/down to change camera look vector in z direction. + Increase Field of View - Decrease Field of View Click on an object to select Shift+Arrow keys to move the selected object Ctrl+Shift+Arrow left/right to rotate", "Key Commands"); } void mmFileExit_Click(object sender, RoutedEventArgs e) { throw new Exception("The method or operation is not implemented."); } void mmFileOpen_Click(object sender, RoutedEventArgs e) { OpenFileDialog d = new OpenFileDialog(); if (!d.ShowDialog().Value) return; this.statusBarItem1.Content = "Loading file, please wait..."; this.Cursor = Cursors.Wait; Visual3DCollection controls; using (FileStream fs = File.OpenRead(d.FileName)) controls = XamlReader.Load(fs) as Visual3DCollection; this.mainViewport.Children.Clear(); foreach (Visual3D v in controls) this.mainViewport.Children.Add(v); this.Cursor = Cursors.Arrow; this.statusBarItem1.Content = "Ready"; } void mmFileSave_Click(object sender, RoutedEventArgs e) { SaveFileDialog d = new SaveFileDialog(); d.Filter = "XAML | *.xaml"; if (!d.ShowDialog().Value) return; this.statusBarItem1.Content = "Saving, please wait..."; this.Cursor = Cursors.Wait; using (FileStream fs = File.OpenWrite(d.SafeFileName)) XamlWriter.Save(this.mainViewport.Children, fs); this.Cursor = Cursors.Arrow; this.statusBarItem1.Content = "Saved"; } #endregion #region create shape methods private Model3DGroup CreateTriangleModel(Point3D p0, Point3D p1, Point3D p2, Color c) { MeshGeometry3D mesh = new MeshGeometry3D(); mesh.Positions.Add(p0); mesh.Positions.Add(p1); mesh.Positions.Add(p2); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(2); Vector3D normal = CalculateNormal(p0, p1, p2); mesh.Normals.Add(normal); mesh.Normals.Add(normal); mesh.Normals.Add(normal); Material material = new DiffuseMaterial(new SolidColorBrush(c)); GeometryModel3D model = new GeometryModel3D(mesh, material); Model3DGroup group = new Model3DGroup(); group.Children.Add(model); return group; } private Vector3D CalculateNormal(Point3D p0, Point3D p1, Point3D p2) { Vector3D v0 = new Vector3D( p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z); Vector3D v1 = new Vector3D( p2.X - p1.X, p2.Y - p1.Y, p2.Z - p1.Z); return Vector3D.CrossProduct(v0, v1); } private void CreateLine(Point3D a, Point3D b, double t, Color c) { Model3DGroup cube = new Model3DGroup(); Point3D p0 = new Point3D(a.X, a.Y, a.Z); Point3D p1 = new Point3D(a.X + t, a.Y, a.Z); Point3D p2 = new Point3D(b.X + t, b.Y, b.Z); Point3D p3 = new Point3D(b.X, b.Y, b.Z); Point3D p4 = new Point3D(a.X, a.Y + t, a.Z); Point3D p5 = new Point3D(a.X + t, a.Y + t, a.Z); Point3D p6 = new Point3D(b.X + t, b.Y + t, b.Z); Point3D p7 = new Point3D(b.X, b.Y + t, b.Z); //front side triangles cube.Children.Add(CreateTriangleModel(p3, p2, p6, c)); cube.Children.Add(CreateTriangleModel(p3, p6, p7, c)); //right side triangles cube.Children.Add(CreateTriangleModel(p2, p1, p5, c)); cube.Children.Add(CreateTriangleModel(p2, p5, p6, c)); //back side triangles cube.Children.Add(CreateTriangleModel(p1, p0, p4, c)); cube.Children.Add(CreateTriangleModel(p1, p4, p5, c)); //left side triangles cube.Children.Add(CreateTriangleModel(p0, p3, p7, c)); cube.Children.Add(CreateTriangleModel(p0, p7, p4, c)); //top side triangles cube.Children.Add(CreateTriangleModel(p7, p6, p5, c)); cube.Children.Add(CreateTriangleModel(p7, p5, p4, c)); //bottom side triangles cube.Children.Add(CreateTriangleModel(p2, p3, p0, c)); cube.Children.Add(CreateTriangleModel(p2, p0, p1, c)); ModelVisual3D model = new ModelVisual3D(); model.Content = cube; this.mainViewport.Children.Add(model); } private Model3DGroup CreateCuboid(Point3D pos, double w, double l, double d, Color c) { Model3DGroup cuboid = new Model3DGroup(); Point3D p0 = new Point3D(pos.X, pos.Y, pos.Z); Point3D p1 = new Point3D(pos.X + w, pos.Y, pos.Z); Point3D p2 = new Point3D(pos.X + w, pos.Y, pos.Z + d); Point3D p3 = new Point3D(pos.X, pos.Y, pos.Z + d); Point3D p4 = new Point3D(pos.X, pos.Y + l, pos.Z); Point3D p5 = new Point3D(pos.X + w, pos.Y + l, pos.Z + 0); Point3D p6 = new Point3D(pos.X + w, pos.Y + l, pos.Z + d); Point3D p7 = new Point3D(pos.X, pos.Y + l, pos.Z + d); cuboid.Children.Add(CreateTriangleModel(p3, p2, p6, c)); cuboid.Children.Add(CreateTriangleModel(p3, p6, p7, c)); //right side triangles cuboid.Children.Add(CreateTriangleModel(p2, p1, p5, c)); cuboid.Children.Add(CreateTriangleModel(p2, p5, p6, c)); //back side triangles cuboid.Children.Add(CreateTriangleModel(p1, p0, p4, c)); cuboid.Children.Add(CreateTriangleModel(p1, p4, p5, c)); //left side triangles cuboid.Children.Add(CreateTriangleModel(p0, p3, p7, c)); cuboid.Children.Add(CreateTriangleModel(p0, p7, p4, c)); //top side triangles cuboid.Children.Add(CreateTriangleModel(p7, p6, p5, c)); cuboid.Children.Add(CreateTriangleModel(p7, p5, p4, c)); //bottom side triangles cuboid.Children.Add(CreateTriangleModel(p2, p3, p0, c)); cuboid.Children.Add(CreateTriangleModel(p2, p0, p1, c)); ModelVisual3D model = new ModelVisual3D(); model.Content = cuboid; this.mainViewport.Children.Add(model); // add the cube to the 3d object tracker array (for grouping, hit test etc) this.FormObjects.Add(cuboid); return cuboid; } #endregion #region hit test public HitTestResultBehavior HTResult(System.Windows.Media.HitTestResult rawresult) { RayHitTestResult rayResult = rawresult as RayHitTestResult; if (rayResult != null) { RayMeshGeometry3DHitTestResult rayMeshResult = rayResult as RayMeshGeometry3DHitTestResult; if (rayMeshResult != null) { GeometryModel3D hitGeo = rayMeshResult.ModelHit as GeometryModel3D; // currentModel is just a triangle, try to identify the parent group and select the entire group Model3DGroup parent = FindParentModel(hitGeo); if (parent != null) HighlightObject(parent, Colors.Yellow); } } return HitTestResultBehavior.Stop; } void ViewPort_MouseDown(object sender, MouseButtonEventArgs e) { Point mouseposition = e.GetPosition(mainViewport); Point3D testpoint3D = new Point3D(mouseposition.X, mouseposition.Y, 0); Vector3D testdirection = new Vector3D(mouseposition.X, mouseposition.Y, 10); PointHitTestParameters pointparams = new PointHitTestParameters(mouseposition); RayHitTestParameters rayparams = new RayHitTestParameters(testpoint3D, testdirection); //test for a result in the Viewport3D VisualTreeHelper.HitTest(mainViewport, null, HTResult, pointparams); } #endregion } } i also made a slight modification to the TrackBall class, to provide access to the look direction of the camera. but you could use the existing 3dTools dll and just remove the bit of code that uses this new property. public Vector3D CameraLookDirection { get { return this._rotation.Axis; } } any q's give me a shout! tim |
My System Specs![]() |
![]() |
| Thread Tools | |
| Display Modes | |
| |
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| consent.exe not rendering | bstoppel | Vista security | 0 | 06-06-2008 09:00 PM |
| games Rendering everywhere! | mikadee | Vista Games | 5 | 05-10-2008 03:30 PM |
| Vista not rendering 3D... | wrobes21 | Vista General | 3 | 04-06-2008 09:32 AM |
| Page Rendering | REE | Vista mail | 0 | 12-11-2007 08:59 AM |
| Grid.Row Grid.Column set programatically at runtime | craig kelly-soens www.XpectWorld.com | Avalon | 0 | 01-10-2006 03:52 PM |