Any chance of some help?

May 11, 2010 at 8:19 PM
Hi Rene, You have some really useful 'Ex' projects - I have only just discovered this one :-) Anyhow, I would like to ask for a bit of help. I have a pretty simple need, but have not been able to navigate my way around viewports , transforms etc... (it is a long time since I studies maths!) I have a pretty simple scenario which can be summarised as follows: I have a Rectangle with a width of 500 that I wish to rotate about the Y axis (using a perspective viewport) <UserControl ... Width="683" Height="197"> <Canvas x:Name="LayoutRoot"> <Rectangle Width="500" Height="50" Fill="Blue" Canvas.Top="10" Canvas.Left="10"> </Rectangle> </Canvas> </UserControl> I would like to be able to position this axis of rotation at different x positions along the rectangle (i.e. rotating about a Y-axis located at various x positions along the rectangle). But I would also like to ensure that the camera also has the same x location. I have tried using PlaneProjection, which allows you to change the CenterOfLocationX property, but you cannot shift the camera location so I did not achieve the result I wanted (see: http://groups.google.com/group/wpf-disciples/browse_frm/thread/2bcbc96277820b84). I tried to set up the correct matrix / viewport using your API but didn't get anywhere with it. I would really appreciate a few pointers. Thank you, Colin E.
May 11, 2010 at 8:20 PM
Hmmm... I bet my linebreaks being removed is a bug due to my using FireFox!
Coordinator
May 12, 2010 at 7:49 PM

You should use the "Insert Code Snippet" feature from the toolbox to paste code / xml.

The Camera Position has to be synced. You can try something like this:

var translate = Matrix3DFactory.CreateTranslation(TranslateX, 0, 0);         
var rotateY = Matrix3DFactory.CreateRotationY(MathHelper.ToRadians(RotateY));
var world = translate * rotateY;

var projectionMatrix = Matrix3DFactory.CreatePerspectiveFieldOfViewLH(MathHelper.ToRadians(FieldOfView), LayoutRoot.Width / LayoutRoot.Height, NearPlane, FarPlane);
var lookAt = Matrix3DFactory.CreateLookAtLH(TranslateX, 0, 10, 0, 0, 0);
var viewport = Matrix3DFactory.CreateViewportTransformation(LayoutRoot.Width, LayoutRoot.Height);

m = Matrix3DFactory.CreateViewportProjection(world, lookAt, projectionMatrix, viewport);
myRectangle.Projection = new Matrix3DProjection { ProjectionMatrix = m };

Please see the example in the source code repository.

// Create global transformations
var vw = Viewport.Width;
var vh = Viewport.Height;
var invertYAxis = Matrix3DFactory.CreateScale(1, -1, 1);
var translate = Matrix3DFactory.CreateTranslation(TranslateX, TranslateY, TranslateZ);
var rotateX = Matrix3DFactory.CreateRotationX(MathHelper.ToRadians(RotateX));
var rotateY = Matrix3DFactory.CreateRotationY(MathHelper.ToRadians(RotateY));
var rotateZ = Matrix3DFactory.CreateRotationZ(MathHelper.ToRadians(RotateZ));
var scale = Matrix3DFactory.CreateScale(ScaleX, ScaleY, ScaleZ);
var lookAt = Matrix3DFactory.CreateLookAtLH(CameraX, CameraY, CameraZ, CameraLookAtX, CameraLookAtY, CameraLookAtZ);
var viewport = Matrix3DFactory.CreateViewportTransformation(vw, vh);
var projectionMatrix = Matrix3D.Identity;
if (ChkPerspective.IsChecked.Value)
{
projectionMatrix = Matrix3DFactory.CreatePerspectiveFieldOfViewLH(MathHelper.ToRadians(FieldOfView), vw / vh, NearPlane, FarPlane);
}
else
{
projectionMatrix = Matrix3DFactory.CreateOrthographicLH(vw, vh, NearPlane, FarPlane);
}

// Transform all elements
var selectedMatrix = Matrix3D.Identity;
foreach (var elem in this.Elements)
{
// The UIElement
var e = elem.Element;

// Create basic transformation matrices
var centerAtOrigin = Matrix3DFactory.CreateTranslation(-e.ActualWidth * 0.5, -e.ActualHeight * 0.5, 0);
var baseTranslate = Matrix3DFactory.CreateTranslation(elem.PositionX, elem.PositionY, elem.PositionZ);

// Combine the transformation matrices
var m = Matrix3D.Identity;
m = m * centerAtOrigin;
m = m * invertYAxis;

// Apply the world transformation to the selected element
if (elem == SelectedElement)
{
m = m * scale;
m = m * rotateX * rotateY * rotateZ;
m = m * translate;

// Should the camera target be fixed at the selected element?
if (ChkLookAtSelected.IsChecked.Value)
{
lookAt = Matrix3DFactory.CreateLookAtLH(CameraX, CameraY, CameraZ, elem.PositionX, elem.PositionY, elem.PositionZ);
}
}

// Calculate the final view projection matrix
m = m * baseTranslate;
m = Matrix3DFactory.CreateViewportProjection(m, lookAt, projectionMatrix, viewport);

if (elem == SelectedElement)
{
selectedMatrix = m;
}

// Apply the transformation to the UIElement
e.Projection = new Matrix3DProjection { ProjectionMatrix = m };
}