标签:
先上效果图吧。
我导入了两个模型,一个汽车和一个美女,都是在网上下载的obj格式的文件。导入之后调整了2个模型之间的位置关系,又添加了鼠标滚轮缩放,旋转的功能,这样我们就可以方便查看模型的各个细节了。
C#动态读取obj文件,加载的基本思路就是打开文件,解析obj格式,生成ModelVisual3D。我这里使用的是一个网上别人写的WavefrontObjLoader.cs。代码比较复杂,我们没必要全部看懂,只要会用就够了!
将WavefrontObjLoader.cs导入项目中
在初始化事件中加载模型并显示。使用的大概方式很简单,如下。
//new一个loader对象
WavefrontObjLoader wfl = new WavefrontObjLoader();
//ModelVisual3DWithName是WavefrontObjLoader定义的继承ModelVisual3D的对象,直接使用ModelVisual3D也是可以的
//导入obj,第一个模型命名为m
ModelVisual3DWithName m = wfl.LoadObjFile(@"C:\Users\hasee\Desktop\WpfApplication2\WpfApplication2\Lancer_Evolution_10.obj");
m.Content = myModel3DGroup;
//导入obj,第二个模型命名为n
var n = wfl.LoadObjFile(@"C:\Users\hasee\Desktop\WpfApplication2\WpfApplication2\精细人体.obj");
n.Content = myModel3DGroup;
//将两个模型添加到场景中
vp.Children.Add(m);
vp.Children.Add(n);
//vp是在xaml中定义的viewport3D
xaml中也是很简单,设置如下:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
MouseMove="Window_MouseMove"
Title="MainWindow" Height="350" Width="525">
<Grid x:Name="lay" Background="Azure" MouseWheel="VP_MouseWheel">
<Viewport3D x:Name="vp"
MouseLeftButtonDown="vp_MouseLeftButtonDown" Margin="0,31,0.4,-0.2">
<Viewport3D.Camera>
<PerspectiveCamera FieldOfView="45" FarPlaneDistance="100" LookDirection="0,0,-3.4142135623731" NearPlaneDistance="0.1" Position="0,0,3.4142135623731" UpDirection="0,1,0"/>
</Viewport3D.Camera>
</Viewport3D>
</Grid>
</Window>
这样就实现了加载,下面是全部实现旋转和缩放,全部代码如下
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 System.Windows.Media.Effects;
namespace WpfApplication2
{
public partial class MainWindow : Window
{
//声明摄像头
PerspectiveCamera myPCamera;
//鼠标灵敏度调节
double mouseDeltaFactor = 0.4;
public MainWindow()
{
InitializeComponent();
//摄像头
myPCamera = new PerspectiveCamera();
myPCamera.Position = new Point3D(0, 0, 200);
myPCamera.LookDirection = new Vector3D(0, 0, -1);
myPCamera.FieldOfView = 1000;
vp.Camera = myPCamera;
Model3DGroup myModel3DGroup = new Model3DGroup();
//光源
//AmbientLight (自然光)
//DirectionalLight (方向光)
//PointLight (点光源)
//SpotLight (聚光源)
DirectionalLight myDirectionalLight = new DirectionalLight();
myDirectionalLight.Color = Colors.White;
myDirectionalLight.Direction = new Vector3D(0.61, 0.5, 0.61);
myModel3DGroup.Children.Add(myDirectionalLight);
//DirectionalLight myDirectionalLight2 = new DirectionalLight();
//myDirectionalLight2.Color = Colors.White;
//myDirectionalLight2.Direction = new Vector3D(0.61, 0.5, 0.61);
//myModel3DGroup.Children.Add(myDirectionalLight2);
//new一个loader对象
WavefrontObjLoader wfl = new WavefrontObjLoader();
//ModelVisual3DWithName是WavefrontObjLoader定义的继承ModelVisual3D的对象,直接使用ModelVisual3D也是可以的
//导入obj,第一个模型命名为m
ModelVisual3DWithName m = wfl.LoadObjFile(@"C:\Users\hasee\Desktop\WpfApplication2\WpfApplication2\Lancer_Evolution_10.obj");
m.Content = myModel3DGroup;
//导入obj,第二个模型命名为n
var n = wfl.LoadObjFile(@"C:\Users\hasee\Desktop\WpfApplication2\WpfApplication2\精细人体.obj");
n.Content = myModel3DGroup;
//下面是调整n的位置,初学者可以先注释掉。
var tt = new TranslateTransform3D();
tt.OffsetX = 110;
tt.OffsetZ = -50;
tt.OffsetY =-100;
var tr = new RotateTransform3D();
tr.Rotation = new AxisAngleRotation3D(new Vector3D(1, 0, 0), 90);
var tr2 = new RotateTransform3D();
tr2.Rotation= new AxisAngleRotation3D(new Vector3D(0, 0, 1), -45);
var ts = new ScaleTransform3D();
ts.ScaleX = 1.5;
ts.ScaleY = 1.5;
ts.ScaleZ = 1.6;
var tg = new Transform3DGroup();
tg.Children.Add(tr); tg.Children.Add(tr2); tg.Children.Add(tt); tg.Children.Add(ts);
n.Transform = tg;
//将两个模型添加到场景中
vp.Children.Add(m);
vp.Children.Add(n);
//添加鼠标事件,用于显示隐藏光晕特效
vp.MouseEnter += Vp_MouseEnter;
vp.MouseLeave += Vp_MouseLeave;
}
private void Vp_MouseLeave(object sender, MouseEventArgs e)
{
vp.Effect = null;
}
private void Vp_MouseEnter(object sender, MouseEventArgs e)
{
DropShadowEffect BlurRadius = new DropShadowEffect();
BlurRadius.BlurRadius = 20;
BlurRadius.Color = Colors.Yellow;
BlurRadius.Direction = 0;
BlurRadius.Opacity = 1;
BlurRadius.ShadowDepth = 0;
vp.Effect = BlurRadius;
}
public HitTestResultBehavior HTResult(HitTestResult rawresult)
{
//MessageBox.Show(rawresult.ToString());
// RayHitTestResult rayResult = rawresult as RayHitTestResult;
RayHitTestResult rayResult = rawresult as RayHitTestResult;
if (rayResult != null)
{
//RayMeshGeometry3DHitTestResult rayMeshResult = rayResult as RayMeshGeometry3DHitTestResult;
RayHitTestResult rayMeshResultrayResult = rayResult as RayHitTestResult;
if (rayMeshResultrayResult != null)
{
//GeometryModel3D hitgeo = rayMeshResult.ModelHit as GeometryModel3D;
var visual3D = rawresult.VisualHit as ModelVisual3D;
//do something
}
}
return HitTestResultBehavior.Continue;
}
//鼠标位置
Point mouseLastPosition;
private void vp_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
mouseLastPosition = e.GetPosition(this);
//RayHitTestParameters hitParams = new RayHitTestParameters(myPCamera.Position, myPCamera.LookDirection);
//VisualTreeHelper.HitTest(vp.Children[0], null, ResultCallback, hitParams);
//下面是进行点击触发检测,可忽略,注释
Point3D testpoint3D = new Point3D(mouseLastPosition.X, mouseLastPosition.Y, 0);
Vector3D testdirection = new Vector3D(mouseLastPosition.X, mouseLastPosition.Y, 100);
PointHitTestParameters pointparams = new PointHitTestParameters(mouseLastPosition);
RayHitTestParameters rayparams = new RayHitTestParameters(testpoint3D, testdirection);
//test for a result in the Viewport3D
VisualTreeHelper.HitTest(vp, null, HTResult, pointparams);
}
//鼠标旋转
private void Window_MouseMove(