Windows Vista Forums
Vista Forums Home Join Vista Forums Webcasts Vista Tutorials Tags

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.
Register at Vista forums...the world biggest Windows Vista resource Join Vista Forums Now

Go Back   Vista Forums > Microsoft Technical Newsgroups > Avalon

Simple Grid Rendering

Update your Vista Drivers Update Your Drivers Now!!
Closed Thread
 
Thread Tools Display Modes
Old 02-22-2007   #1 (permalink)
Kristan
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 SpecsSystem Spec
Old 02-22-2007   #2 (permalink)
Tim Mackey
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 SpecsSystem Spec
Old 02-22-2007   #3 (permalink)
Kristan
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 SpecsSystem Spec
Old 02-24-2007   #4 (permalink)
Tim Mackey
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 SpecsSystem Spec
Closed Thread

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


Vistax64.com is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media 2005-2008

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51