WPF 使用WavefrontObjLoader类显示obj格式的三维图元

前言:毕业设计中需要用WPF展示三维图元,不适合使用XAML也不方便用Blend。于是在网上搜索相关内容找到一些资料,主要参考以下两位的博客:

http://www.cnblogs.com/enjoyeclipse/archive/2012/03/21/2410439.html

http://blog.sina.com.cn/s/blog_633d0e170100yte3.html

总结如下(18::2—20:00):

1.环境:vs2010,使用pro/e生成的obj模型,网上下载的WavefrontObjLoader.cs代码(前面给出的第一个文章中有下载http://www.cnblogs.com/enjoyeclipse/archive/2012/03/21/2410439.html)。

2.步骤:

    vs2010中创建wpf项目,MainWindow.xaml的XAML代码如下

MainWindow。xaml
 1 <Window x:Class="TestWpfObjLoader.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="MainWindow" Height="445" Width="678">
 5     <Grid x:Name="lay">
 6         <Viewport3D x:Name="vp" Margin="0,0,12,0">
 7         </Viewport3D>
 8         <Slider Height="23" HorizontalAlignment="Left" Margin="220,288,0,0" Name="slider1" VerticalAlignment="Top" Width="100" Maximum="2000" />
 9         <Slider Height="23" HorizontalAlignment="Left" Margin="49,288,0,0" Name="slider2" VerticalAlignment="Top" Width="100" Maximum="1000" />
10         <Slider Height="23" HorizontalAlignment="Left" Margin="367,288,0,0" Name="slider3" VerticalAlignment="Top" Width="100" Minimum="200" Maximum="2000" />
11         <Slider Height="23" HorizontalAlignment="Left" Margin="528,288,0,0" Name="slider4" VerticalAlignment="Top" Width="100" Minimum="200" Maximum="2000" />
12     </Grid>
13 </Window>

    解决方案中加入下载的WavefrontObjLoader.cs文件。

    打开WavefrontObjLoader,在WavefrontObjLoader类之前定义类:

 ModelVisual3DWithName
 public class ModelVisual3DWithName : ModelVisual3D
    {
        public string Name { get; set; }

        public object Tag { get; set; }
    }

    在MainWindow.xaml.cs中增加几个命名空间的引用:如下图所示分别是三维、动画、和WavefrontObjLoader的名称空间。

    MainWindow.xaml.cs完整代码:

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Media3D;
using System.Windows.Media.Animation;
using Bridge_WPF.UserControls;

namespace TestWpfObjLoader
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    /// 

    public partial class MainWindow : Window
    {
        PerspectiveCamera myPCamera;
        DirectionalLight myDirectionalLight;
        Model3DGroup myModel3DGroup;
        WavefrontObjLoader wfl;
        ModelVisual3DWithName mv3dw;
        public MainWindow()
        {
            InitializeComponent();
            wfl = new WavefrontObjLoader(); 
            slider1.ValueChanged += new RoutedPropertyChangedEventHandler<double>(slider1_ValueChanged);
            slider2.ValueChanged += new RoutedPropertyChangedEventHandler<double>(slider2_ValueChanged);
            slider3.ValueChanged += new RoutedPropertyChangedEventHandler<double>(slider3_ValueChanged);
            slider4.ValueChanged += new RoutedPropertyChangedEventHandler<double>(slider4_ValueChanged);
            createCamera();
            createLight();
            createModel3D();
            create360();
            //createAnimation();
        }
        #region //光源
        private void createLight()
        {
            myDirectionalLight = new DirectionalLight();
            myDirectionalLight.Color = Colors.White;
            myDirectionalLight.Direction = new Vector3D(-0.61, -0.5, -0.61);
        }
        #endregion
        #region //摄像机
        private void createCamera()
        {
            myPCamera = new PerspectiveCamera();
            //myPCamera.Position = new Point3D(0,-1743,-4000);//看的方向
            myPCamera.Position = new Point3D(0, 0, 1000);
            myPCamera.LookDirection = new Vector3D(0, 0, -1000);//摄影机看的方向
            myPCamera.UpDirection = new Vector3D(0, 1, -0);
            myPCamera.FieldOfView = 45;//法向量摄影机上下颠倒,左转右转            
            myPCamera.NearPlaneDistance = 0.1;
            myPCamera.FarPlaneDistance = 11050;

            vp.Camera = myPCamera;
        }
        #endregion
        #region //模型
        private void createModel3D()
        {
            myModel3DGroup = new Model3DGroup();
            myModel3DGroup.Children.Add(myDirectionalLight);

            var m = wfl.LoadObjFile(@"D:prt0006.obj");//此处为obj文件的路径
            m.Content = myModel3DGroup;

            vp.Children.Add(m);
        }
        #endregion
        #region //360旋转动作
        RotateTransform3D rtf3D;
        AxisAngleRotation3D aar;
        private void create360()
        {
            rtf3D = new RotateTransform3D();
            aar = new AxisAngleRotation3D();
            this.RegisterName("myAngleRotation", aar);
            aar.Angle = 0;
            aar.Axis = new Vector3D(0, 3, 0);
            rtf3D.Rotation = aar;
            myModel3DGroup.Transform = rtf3D;
            myPCamera.Transform = rtf3D;
        }
        Storyboard sbd;
        DoubleAnimation dan;
        private void createAnimation()
        {
            sbd = new Storyboard();
            dan = new DoubleAnimation(0, 360, new Duration(TimeSpan.FromSeconds(10)));
            dan.RepeatBehavior = RepeatBehavior.Forever;
            Storyboard.SetTargetName(dan, "myAngleRotation");
            Storyboard.SetTargetProperty(dan, new PropertyPath(AxisAngleRotation3D.AngleProperty));
            sbd.Children.Add(dan);
            sbd.BeginTime = TimeSpan.FromSeconds(5);//开始时间
            sbd.Begin(this);
        }
        #endregion
        void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            myPCamera.Position = new Point3D(slider1.Value, slider2.Value, slider3.Value);
        }
        void slider2_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            myPCamera.Position = new Point3D(slider1.Value, slider2.Value, slider3.Value);
        }
        void slider3_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            myPCamera.Position = new Point3D(slider1.Value, slider2.Value, slider3.Value);
        }
        void slider4_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            aar.Angle = slider4.Value;
        }

    }
}

    

    运行效果:


 

后记:任务完成,接下来研究一下代码。

posted @ 2013-02-26 18:50  zscflying  阅读(2101)  评论(0编辑  收藏  举报