一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

WPF 3D 小小小小引擎

 xyjackxjw 2013-05-09

WPF 3D 小小小小引擎 - ·WPF 3D變換應(yīng)用

時(shí)間:2011-04-15 03:50來源:博客園 作者:Kevin Pan 點(diǎn)擊: 1718次
  WPF可以提供的3D模型使我們可以輕松地創(chuàng)建3D實(shí)體,雖然目前來看還很有一些性能上的問題,不過對于一些簡單的3D應(yīng)用應(yīng)該是可取的,畢竟其開發(fā)效率高,而且也容易上手。

  下面給大家演示的是使用在WPF 3D上實(shí)現(xiàn)視角變換,通過鼠標(biāo)拖動來變換觀察視角,通過滾輪來放縮視距。

  

 

  有關(guān)3D的基礎(chǔ)知識可以參考MSDN文檔:三維圖形概述

  首先創(chuàng)建一個(gè)3D立方體,立方體是由六個(gè)面構(gòu)成(F1, F2 ....F6)其XAML代碼如下:

<Viewport3D>

    <Viewport3D.Camera>

        <PerspectiveCamera Position="8,8,8" LookDirection="-1 -1 -1"
 FieldOfView="75" UpDirection="-1 1 -1" x:Name="camera"></PerspectiveCamera>

    </Viewport3D.Camera>

    <Viewport3D.Children>

        <ModelVisual3D x:Name="light">

            <ModelVisual3D.Content>

                <AmbientLight />

            </ModelVisual3D.Content>

        </ModelVisual3D>

        <ModelVisual3D x:Name="magicCube">

            <ModelVisual3D.Content>

                <!--    0: 0,0,0    1: 0,0,2    2: 2,0,2    
3: 2,0,0    4: 2,2,0    5: 0,2,0    6: 0,2,2    7: 2,2,2    -->


                <Model3DGroup x:Name="cube">

                    <Model3DGroup.Transform>

                        <TranslateTransform3D OffsetX="-1" OffsetY="-1" OffsetZ="-1" />

                    </Model3DGroup.Transform>

                    <!--F1: 0,3,2,1-->

                    <GeometryModel3D x:Name="F1">

                        <GeometryModel3D.Material>

                            <DiffuseMaterial Brush="Blue"/>

                        </GeometryModel3D.Material>

                        <GeometryModel3D.Geometry>

                            <MeshGeometry3D Positions="0,0,0 2,0,0 2,0,2 0,0,2" 
TriangleIndices=
"0,1,2 0,2,3"></MeshGeometry3D>

                        </GeometryModel3D.Geometry>

                    </GeometryModel3D>

                    <!--F2: 0,1,6,5-->

                    <GeometryModel3D x:Name="F2">

                        <GeometryModel3D.Material>

                            <DiffuseMaterial Brush="Green"/>

                        </GeometryModel3D.Material>

                        <GeometryModel3D.Geometry>

                            <MeshGeometry3D Positions="0,0,0 0,0,2 0,2,2 0,2,0" 
TriangleIndices=
"0 1 2 0 2 3"></MeshGeometry3D>

                        </GeometryModel3D.Geometry>

                    </GeometryModel3D>

                    <!--F3: 4,5,6,7-->

                    <GeometryModel3D x:Name="F3">

                        <GeometryModel3D.Material>

                            <DiffuseMaterial Brush="Red"/>

                        </GeometryModel3D.Material>

                        <GeometryModel3D.Geometry>

                            <MeshGeometry3D Positions="2,2,0 0,2,0 0,2,2 2,2,2" 
TriangleIndices=
"0 1 2 0 2 3"></MeshGeometry3D>

                        </GeometryModel3D.Geometry>

                    </GeometryModel3D>

                    <!--F4: 2,3,4,7-->

                    <GeometryModel3D x:Name="F4">

                        <GeometryModel3D.Material>

                            <DiffuseMaterial Brush="Yellow"/>

                        </GeometryModel3D.Material>

                        <GeometryModel3D.Geometry>

                            <MeshGeometry3D Positions="2,0,2 2,0,0 2,2,0 2,2,2" 
TriangleIndices=
"0 1 2 0 2 3" TextureCoordinates="0,0 0,1 1,1 1,0">

                            </MeshGeometry3D>

                        </GeometryModel3D.Geometry>

                    </GeometryModel3D>

                    <!--F5: 1,2,7,6-->

                    <GeometryModel3D x:Name="F5">

                        <GeometryModel3D.Material>

                            <DiffuseMaterial Brush="White"/>

                        </GeometryModel3D.Material>

                        <GeometryModel3D.Geometry>

                            <MeshGeometry3D Positions=" 0,0,2 2,0,2 2,2,2 0,2,2" 
TriangleIndices=
"0 1 2 0 2 3"></MeshGeometry3D>

                        </GeometryModel3D.Geometry>

                    </GeometryModel3D>

                    <!--F6: 0,5,4,3-->

                    <GeometryModel3D x:Name="F6">

                        <GeometryModel3D.Material>

                            <DiffuseMaterial Brush="Orange"/>

                        </GeometryModel3D.Material>

                        <GeometryModel3D.Geometry>

                            <MeshGeometry3D Positions=" 0,0,0 0,2,0 2,2,0 2,0,0" 
TriangleIndices=
"0 1 2 0 2 3"></MeshGeometry3D>

                        </GeometryModel3D.Geometry>

                    </GeometryModel3D>

                </Model3DGroup>

            </ModelVisual3D.Content>

        </ModelVisual3D>

    </Viewport3D.Children>

</Viewport3D>
     nbsp;

在Viewport中用六個(gè)面構(gòu)成一個(gè)立方體, 每一個(gè)面都是一個(gè)GeometryModel3D。

  下面就是如何來實(shí)現(xiàn)通過鼠標(biāo)拖動來變換視角的功能。首先給Window對象添加幾個(gè)有關(guān)的鼠標(biāo)的事件:MouseMove、MouseLeftButtonDown和MouseWheel。

<Window x:Class="MagicCube.MainWindow"
xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x=
"http://schemas.microsoft.com/winfx/2006/xaml"

Title=
"MainWindow" Height="295" Width="525" Background="Black"

MouseMove=
"Viewport3D_MouseMove"

MouseLeftButtonDown=
"Viewport3D_MouseLeftButtonDown"

MouseWheel=
"Viewport3D_MouseWheel"

KeyDown=
"Window_KeyDown">

<Viewport3D …>

</Window>

  說明一下使用到的幾個(gè)變量:

  其中MouseLeftButtonDown是用來獲取鼠標(biāo)在進(jìn)入拖動狀態(tài)之前的位置,這樣我們就可以根據(jù)鼠標(biāo)位置的改變類變換視角。

Point mouseLastPosition;
private void Viewport3D_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

mouseLastPosition = e.GetPosition(this);

}

  下面是MouseMove事件,實(shí)現(xiàn)視角的變換。首先鼠標(biāo)在拖動的過程中,可能發(fā)生水平方向上的變化和垂直方向上的變化,所以,我們將對不同的變化方向進(jìn)行不同的變換。這里我將水平變換和垂直變換已經(jīng)分別封裝至兩個(gè)方法中:HorizontalTransform(水平變換)和VerticalTransform(垂直變換)

private void Viewport3D_MouseMove(object sender, MouseEventArgs e)

{

if (Mouse.LeftButton == MouseButtonState.Pressed)

{

Point newMousePosition = e.GetPosition(this);

if (mouseLastPosition.X != newMousePosition.X)

{

HorizontalTransform(mouseLastPosition.X < newMousePosition.X, mouseDeltaFactor);//水平變換

}

if (mouseLastPosition.Y != newMousePosition.Y)// change position in the horizontal direction

{

VerticalTransform(mouseLastPosition.Y > newMousePosition.Y, mouseDeltaFactor);//垂直變換

}

mouseLastPosition = newMousePosition;

}

}

  接下來我們就來看一下這兩個(gè)變換方法的具體實(shí)現(xiàn):

  垂直變換:

private void VerticalTransform(bool upDown, double angleDeltaFactor)
{
Vector3D postion = new Vector3D(camera.Position.X, camera.Position.Y, camera.Position.Z);
Vector3D rotateAxis = Vector3D.CrossProduct(postion, camera.UpDirection);
RotateTransform3D rt3d = new RotateTransform3D();
AxisAngleRotation3D rotate = new AxisAngleRotation3D(rotateAxis, angleDeltaFactor * (upDown ? -1 : 1));
rt3d.Rotation = rotate;
Matrix3D matrix = rt3d.Value;
Point3D newPostition = matrix.Transform(camera.Position);
camera.Position = newPostition;
camera.LookDirection = new Vector3D(-newPostition.X, -newPostition.Y, -newPostition.Z);

//update the up direction
Vector3D newUpDirection = Vector3D.CrossProduct(camera.LookDirection, rotateAxis);
newUpDirection.Normalize();
camera.UpDirection = newUpDirection;
}

  水平變換:

private void HorizontalTransform(bool leftRight, double angleDeltaFactor)
{
Vector3D postion = new Vector3D(camera.Position.X, camera.Position.Y, camera.Position.Z);
Vector3D rotateAxis = camera.UpDirection;
RotateTransform3D rt3d = new RotateTransform3D();
AxisAngleRotation3D rotate = new AxisAngleRotation3D(rotateAxis, angleDeltaFactor * (leftRight ? -1 : 1));
rt3d.Rotation = rotate;
Matrix3D matrix = rt3d.Value;
Point3D newPostition = matrix.Transform(camera.Position);
camera.Position = newPostition;
camera.LookDirection = new Vector3D(-newPostition.X, -newPostition.Y, -newPostition.Z);
}

  最后還有一個(gè)鼠標(biāo)滾輪調(diào)節(jié)視距的變換,如下:

private void Viewport3D_MouseWheel(object sender, MouseWheelEventArgs e)
{
double scaleFactor = 3;
//120 near , -120 far
System.Diagnostics.Debug.WriteLine(e.Delta.ToString());
Point3D currentPosition = camera.Position;
Vector3D lookDirection = camera.LookDirection;//new Vector3D(camera.LookDirection.X, camera.LookDirection.Y, camera.LookDirection.Z);
lookDirection.Normalize();

lookDirection *= scaleFactor;

if (e.Delta == 120)//getting near
{
if ((currentPosition.X + lookDirection.X) * currentPosition.X > 0)
{
currentPosition += lookDirection;
}
}
if (e.Delta == -120)//getting far
{
currentPosition -= lookDirection;
}

Point3DAnimation positionAnimation = new Point3DAnimation();
positionAnimation.BeginTime = new TimeSpan(0, 0, 0);
positionAnimation.Duration = TimeSpan.FromMilliseconds(100);
positionAnimation.To = currentPosition;
positionAnimation.From = camera.Position;
positionAnimation.Completed += new EventHandler(positionAnimation_Completed);
camera.BeginAnimation(PerspectiveCamera.PositionProperty, positionAnimation, HandoffBehavior.Compose);
}

  有了這個(gè)小程序之后,我們以后如果需要制作WPF 3D實(shí)體,也可以通過它來360度全方位地觀測構(gòu)建的3D實(shí)體。

演示程序

源碼下載

本文來自Kevin Pan的博客,原文地址:http://www.cnblogs.com/KevinPan/archive/2011/04/14/1834080.html

  

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    欧美精品亚洲精品一区| 中文字幕亚洲精品乱码加勒比| 99国产高清不卡视频| 九九九热视频免费观看| 国产在线一区二区三区不卡| 色婷婷在线精品国自产拍| 欧美野外在线刺激在线观看| 午夜精品黄片在线播放| 91亚洲国产成人久久| 偷拍美女洗澡免费视频| 99久久国产综合精品二区| 久草热视频这里只有精品| 熟女乱一区二区三区丝袜| 91人妻人人澡人人人人精品| 久久国产精品熟女一区二区三区| 欧美一区二区三区播放| 在线免费国产一区二区三区| 小草少妇视频免费看视频| 欧美色欧美亚洲日在线| 狠狠亚洲丁香综合久久| 色哟哟精品一区二区三区| 亚洲国产丝袜一区二区三区四| 国产色偷丝袜麻豆亚洲| 在线免费观看一二区视频| 在线九月婷婷丁香伊人| 大香蕉大香蕉手机在线视频| 亚洲中文字幕人妻系列| 亚洲一区二区三区三区| 亚洲av熟女一区二区三区蜜桃| 日本不卡视频在线观看| 国产综合香蕉五月婷在线| 99久热只有精品视频最新| 日本不卡视频在线观看| 亚洲中文在线中文字幕91| 狠色婷婷久久一区二区三区| 国产老熟女乱子人伦视频| 成人国产一区二区三区精品麻豆 | 国产亚洲成av人在线观看| 精品视频一区二区三区不卡| 久久国产精品热爱视频| 少妇被粗大进猛进出处故事|