|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
Table of Contents3D BasicsThis section will explain the basics to understanding the concepts involved in creating a 3D scene in XAML. Coordinate systemAdditional links: MSDN. By this point, you should be familiar with using 2D coordinates to place XAML object. Placing an object is very similar but requires an extra value, and rather than using whole numbers, all values can be floating point numbers (uses decimal places). Below is a representation of a 2D Cartesian coordinate system, which can be used to define any point in 2D. Next to that is a 3D coordinate system, the line at an angle labeled Z generally represents depth, or distance from your point of view.
That’s the standard way to visualize things in the two coordinate systems. It's generally accepted in 2D computer graphics that 0,0 represents the top left of the screen. While that could be the case, in 3D it rarely is, where 0,0,0 is displayed in the screen depends on completely where the camera is (your point of view). Luckily, in XAML, there is an easy way to position an entire scene as you would any other 2D control, the
Setting up a sceneThe very first thing you need to setup a 3D scene is to define the <ViewPort3D Canvas.Top="50" Canvas.Left="50" Width="300" Height="300">
#Scene definition
</Viewport>
The next thing you absolutely must have is a camera. Without a camera to represent your point of view (POV), you won't be seeing much. This would fit into the above code in the scene definition section. <ViewPort3D.Camera>
<PerspectiveCamera
Position="-250,250,200"
LookAtPoint="0,0,0"
Up="0,1,0"
FieldOfView="40"
NearPlaneDistance="1"
FarPlaneDistance="500"
/>
</ViewPort3D.Camera>
This needs a little bit of explanation, but it's easiest to think of in terms of an eye. The first three sets of numbers position and orient the eye, The
A camera is no good if you don’t have any objects to look at. You need some models, but to have models, you first need a model collection. Model collections contain the models as well as lights. <ViewPort3D>
#Scene definition
<ViewPort3D.Models>
<Model3DCollection>
#models and Lights go in here
</Model3DCollection>
</ViewPort3D.Models>
</ViewPort3D>
Defining lightsA well lit scene always looks better. Without any lights, there is a default ambient light color but you really want to add some lights to create atmosphere. There are 4 basic types of lights.
Creating objectsThere are a few ways you can get an object into a scene.
Defining materialsIf you have opted to define your mesh object in XAML or you linked to an X-file with no material information, your model will most likely end up black. Defining a solid color brush is fairly simple, it just needs a color. <MeshPrimitive3D.Material>
<BrushMaterial Brush="green"/>
</MeshPrimitive3D.Material>
And here’s a more complete sample animating the solid brush color: <MeshPrimitive3D Mesh="{Box}">
<MeshPrimitive3D.Material>
<BrushMaterial>
<BrushMaterial.Brush>
<SolidColorBrush>
<SolidColorBrush.ColorAnimations>
<ColorAnimation
From="Green"
To="Red"
Begin="0.5"
Duration="1"
AutoReverse="True">
</SolidColorBrush.ColorAnimations>
</SolidColorBrush>
</BrushMaterial.Brush>
</BrushMaterial>
</MeshPrimitive3D.Material>
Aside from solid colors, you might want to texture your object with a texture. You can specify an image file, the size, and the opacity. <BrushMaterial.Brush>
<ImageBrush
ImageSource="TextureName.jpg"
ViewPort="0 0 1024 1024"
Opacity="1.0"
/>
</BrushMaterial.Brush>
Hit testingHit testing on 3D objects is fairly easy to implement, at the moment only click is supported. …
<MeshPrimitive3D Click="OnClick">
<MeshPrimitive3D.Material>
…
Camera controllersCamera controllers are handy if you want to be able to navigate a 3D scene manually. The downside here is, this is not an Avalon support tag and will not work in Longhorn. There are two types of camera controllers:
TransformsAdditional links: MSDN. At this point, you should be able to make a scene with a camera, add some objects, and light them all up. If you’ve tried it, you may have noticed all your objects start at 0,0,0 and stay there. Transforms are going to allow to define how you want objects in the scene placed, oriented, sized, as well as animated. Much like the models, transforms require a collection. All transforms must be listed within the collection, the collection itself is usually inside a mesh primitive. <MeshPrimitive3D Mesh="{Box}">
<MeshPrimitive3D.Transform>
<Transform3DCollection>
# transforms go here
</Transform3DCollection>
</MeshPrimitive3D.Transform>
</MeshPrimitive3D>
Translation<TranslateTransform3D Offset="50 0 0" /> A translation transform is used to move an object around in the world. It basically adds the listed X,Y,Z values to every point in the mesh, essentially moving the object.
Scale<ScaleTransform3D ScaleVector="2 2 2" ScaleCenter”0,0,0”/>
A scale transform is used to make an object bigger or smaller by moving all points in a mesh in or out from the supplied center point. Each value in the For example, if you are scaling a cube that is centered around 0,0,0 and you scale it by 2,1,1, all points will move to twice the distance from the center on the X axis, essentially making the box twice as wide. Since the scale values multiply the distance, any scale value less than 1 will shrink the object on that axis. If the supplied If the supplied center point is not in the center of the mesh or it is not centered around 0,0,0, the scale may appear to stretch the mesh more in one direction than another. Additionally, if the center point is completely outside the model, scaling may appear to move the object.
Rotation<RotateTransform3D Axis="0 1 0" Angle="45" Center=”0,0,0”/>
A rotation transform is used to rotate all points in a mesh around a particular point. A single rotation is limited to rotation on a single axis, but multiple rotations can be applied to achieve different results, which will be covered later. Like scaling, it will need a center point to rotate the points around by the angle specified in degrees. In the above XAML code, the axis is pointing up, so any rotation will make it to rotate much like a top. In this case, it will be 45 degrees, imagine a cube sitting on a desk that you turn 45 degrees. If the center point you are rotating on is not centered, the object will appear to spin around that point.
Defining Animation*you should be familiar with XAML 2D animation tags before continuing. When defining 3D animation, there are three main types of animated data: That was the lowest level, each transform has one or more of these available to animate: Translation:Translate exposes only one animation container, <TranslateTransform3D Offset="-1 0 0" >
<TranslateTransform3D.OffsetAnimations>
<Vector3DAnimationCollection>
<Vector3DAnimation From="-1,0,0" To="1,0,0"
Duration="3" RepeatCount="1" />
</Vector3DAnimationCollection>
</TranslateTransform3D.OffsetAnimations>
</TranslateTransform3D>
Scale:Scale exposes two animation containers: <ScaleTransform3D ScaleVector="1 1 1">
<ScaleTransform3D.ScaleVectorAnimations>
<Vector3DAnimationCollection>
<Vector3DAnimation From="1,1,1" To="2,2,2" Duration="10"/>
</Vector3DAnimationCollection>
</ScaleTransform3D.ScaleVectorAnimations>
<ScaleTransform3D. ScaleCenterAnimations >
<Point3DAnimationCollection>
<Point3DAnimation From="0,0,0" To="20,0,0" Duration="5"/>
</Point3DAnimationCollection>
</ScaleTransform3D. ScaleCenterAnimations >
</ScaleTransform3D>
Rotation:Rotation exposes two animation containers: A couple of things to remember here… First is that, a quaternion will take the shortest route to a new orientation. If you want to re-orient it to 3590 on the X-axis, the quaternion will move -10 and not +3590. Also, there is no concept of winding, so if you want an object to rotate multiple times, you have to add multiple tags. The following sample will rotate an object completely around, twice: <Transform3DCollection>
<RotateTransform3D QuaternionRotation="0,0,0,1" Angle="60">
<RotateTransform3D.QuaternionRotationAnimations>
<QuaternionAnimationCollection>
<QuaternionAnimation
From="0,0,0,1" To="0,-1,0,0"
Begin="0"
Duration="3"
RepeatDuration="1"
AutoReverse="false" />
<QuaternionAnimation
From="0,-1,0,0"
To="0,0,0,-1"
Begin="3"
Duration="3"
RepeatDuration="1"
AutoReverse="false" />
</QuaternionAnimationCollection>
<QuaternionAnimationCollection>
<QuaternionAnimation
From="0,0,0,1" To="0,-1,0,0"
Begin="6"
Duration="3"
RepeatDuration="1"
AutoReverse="false" />
<QuaternionAnimation
From="0,-1,0,0"
To="0,0,0,-1"
Begin="9"
Duration="3"
RepeatDuration="1"
AutoReverse="false" />
</QuaternionAnimationCollection>
</RotateTransform3D.QuaternionRotationAnimations>
</RotateTransform3D>
</Transform3DCollection>
The Transform CollectionMSDN. By now, you have probably noticed the Otherwise, here are a couple of examples of mixing transforms: Example A:The first image applies a rotate then translate, which rotates the object 45 degrees then moves it to the right (positive X). The second image moves the box, then rotates it. Since it's some distance from the rotation origin, it will spin 450 around the origin.
Example B:The first image applies a translate, then scale, which will enlarge the box, then move it. The second image will move the box, then scale it using the origin at the center point. Notice how it moves the box further from the origin.
2D in 3DExplainedOne way to really speed up XAML rendering is to render entirely in DirectX without using any GDI calls. Unfortunately, any third-party developer who does not have access to Windows source code has no chance of implementing XAML exactly like Avalon. There are alternative solutions however; one of them being to convert all would-be GDI drawings into triangles for rendering by the 3D pipeline. This process is referred to as triangulation or triangulating from now on. The process of triangulating 2D drawing calls can be complex, and in some cases, slightly slower than GDI. The payoff is when the 2D geometry that has been constructed is not physically changing but is animating a lot using standard transforms. This keeps the graphics process almost entirely on the video card, so the slowness of rendering in 2D (mainly waiting for the image(s) to get to the video card) is mostly avoided. The downside is that the triangulated representation may not look exactly the same as its 2D counterpart, but if speed is your goal, then this may not be an issue. At the moment, the Mobiform fully DirectX rendering mode is 98% complete. While there are noticeable differences between the same GDI drawing and the DirectX drawing, you can already see the speed difference. In time, the triangulation and rendering should be almost indistinguishable from GDI drawing, and be tremendously faster. Effective usageThe key to getting the speed increase is to reduce the amount of time spent constructing the triangulated geometry from the GDI drawing. A hugely complex drawing can be slow, but once it’s triangulated, it can be extremely fast. Using transforms to move and rotate a drawing is preferable to animating the properties of a 2D XAML object. For example, you could create a sphere and animate its position, or you could wrap it in a ToDo
ConclusionHopefully, this has given you a good overview for 3D in XAML and you are ready to start experimenting in Mobiform and or Longhorn. Although the 3D API for Avalon is still early in its development (and will most likely change heavily on the next pre-release), the basics have been covered here, and should at the very least, give you a head start on the next release. It can only get better from here on in.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||