WPF 3D MeshGeometry3D类的Positions和TriangleIndices属性研究

1 MeshGeometry3D 类

MeshGeometry3D 类,用于生成三维形状的三角形基元;
类的参考在此;
https://learn.microsoft.com/zh-cn/dotnet/api/system.windows.media.media3d.meshgeometry3d?view=windowsdesktop-7.0

写在xaml语法里面是<MeshGeometry3D Positions=...... TriangleIndices=....../> ,如果写到C#语言里面就要new一个此类的对象;

Positions属性就是来表示组成3D图形的所有三角形的顶点的;

TriangleIndices通过将Positions的顶点集合按一定顺序组合起来,组成所需要的三角形;

就是如果画一个三角形,需要3个顶点;如果画一个面,正方形面,并不是4个顶点;因为基元是三角形,只能由三角形构成其他形状;画一个正方形面,需要六个顶点,指定2个三角形来构成一个正方形面;

先看基本的三角形;按照这个示意的图来画一个基本三角形;顶点的顺序如下图的0、1、2;

三角形的三个顶点是:(0,0,0),(1,0,0),(0,1,0);把摄像机放到呈现区域的中心,屏幕外面10个值的地方,往屏幕里边看,如下图;

    这时只有Positions属性,TriangleIndices将按默认;

    如果增加TriangleIndices="0,1,2",加和不加都是一样;如果调整TriangleIndices点的顺序,三角形将不可见;

此时点的顺序是如下图标记;

 如果画一个正方形面,四个顶点是0,0,0  1,0,0   1,1,0    0,1,0;此时需要6个顶点,画2个三角形,来组成正方形面;但是2个三角形可以共享一条边,有2个顶点是重合的;

通过给出4个顶点的坐标,然后用TriangleIndices来指定2个三角形的顶点顺序,

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

TriangleIndices,0,1,2 指定一个三角形,2,3,0 指定另一个三角形,这样来绘出此正方形面;

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Grid>  
  
  <Viewport3D>
        <Viewport3D.Camera>
            <PerspectiveCamera Position="0,0,10" LookDirection="0,0,-2" UpDirection="0,1,0"/>
        </Viewport3D.Camera>
        <Viewport3D.Children>                                          
            <ModelVisual3D x:Name="Light">
                <ModelVisual3D.Content>
                    <AmbientLight/>
                </ModelVisual3D.Content>
            </ModelVisual3D>
 
        <ModelVisual3D> 
          <ModelVisual3D.Content> 
            <GeometryModel3D> 
                <GeometryModel3D.Geometry>
                  <MeshGeometry3D Positions="0,0,0,1,0,0,1,1,0,0,1,0" TriangleIndices="0,1,2 2,3,0"/> 
                </GeometryModel3D.Geometry> 
                <GeometryModel3D.Material> 
                  <DiffuseMaterial Brush="Yellow" /> 
                </GeometryModel3D.Material> 
              </GeometryModel3D>
            </ModelVisual3D.Content>
        </ModelVisual3D>
       </Viewport3D.Children> 
</Viewport3D>
 
  </Grid>
</Page>

2 从C#代码使用MeshGeometry3D类

前面了解了 MeshGeometry3D 类是生成三维形状的基元;前面的代码是在xaml里;
下面看一下从C#代码里生成三维场景和图形,以及使用MeshGeometry3D类;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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.Media3D;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace jiyuan
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // Declare scene objects.
            Viewport3D myViewport3D = new Viewport3D();
            Model3DGroup myModel3DGroup = new Model3DGroup();
            GeometryModel3D myGeometryModel = new GeometryModel3D();
            ModelVisual3D myModelVisual3D = new ModelVisual3D();

            PerspectiveCamera myPCamera = new PerspectiveCamera();

            myPCamera.Position = new Point3D(0, 0, 2);

            myPCamera.LookDirection = new Vector3D(0, 0, -1);

            myPCamera.FieldOfView = 60;

            myViewport3D.Camera = myPCamera;

            DirectionalLight myDirectionalLight = new DirectionalLight();
            myDirectionalLight.Color = Colors.White;
            myDirectionalLight.Direction = new Vector3D(-0.61, -0.5, -0.61);

            myModel3DGroup.Children.Add(myDirectionalLight);

            MeshGeometry3D myMeshGeometry3D = new MeshGeometry3D();

            Vector3DCollection myNormalCollection = new Vector3DCollection();
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myMeshGeometry3D.Normals = myNormalCollection;

            Point3DCollection myPositionCollection = new Point3DCollection();
            myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5));
            myPositionCollection.Add(new Point3D(0.5, -0.5, 0.5));
            myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5));
            myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5));
            myPositionCollection.Add(new Point3D(-0.5, 0.5, 0.5));
            myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5));
            myMeshGeometry3D.Positions = myPositionCollection;

            PointCollection myTextureCoordinatesCollection = new PointCollection();
            myTextureCoordinatesCollection.Add(new Point(0, 0));
            myTextureCoordinatesCollection.Add(new Point(1, 0));
            myTextureCoordinatesCollection.Add(new Point(1, 1));
            myTextureCoordinatesCollection.Add(new Point(1, 1));
            myTextureCoordinatesCollection.Add(new Point(0, 1));
            myTextureCoordinatesCollection.Add(new Point(0, 0));
            myMeshGeometry3D.TextureCoordinates = myTextureCoordinatesCollection;

            Int32Collection myTriangleIndicesCollection = new Int32Collection();
            myTriangleIndicesCollection.Add(0);
            myTriangleIndicesCollection.Add(1);
            myTriangleIndicesCollection.Add(2);
            myTriangleIndicesCollection.Add(3);
            myTriangleIndicesCollection.Add(4);
            myTriangleIndicesCollection.Add(5);
            myMeshGeometry3D.TriangleIndices = myTriangleIndicesCollection;

            myGeometryModel.Geometry = myMeshGeometry3D;
   
            LinearGradientBrush myHorizontalGradient = new LinearGradientBrush();
            myHorizontalGradient.StartPoint = new Point(0, 0.5);
            myHorizontalGradient.EndPoint = new Point(1, 0.5);
            myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0));
            myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Red, 0.25));
            myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Blue, 0.75));
            myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.LimeGreen, 1.0));

            DiffuseMaterial myMaterial = new DiffuseMaterial(myHorizontalGradient);
            myGeometryModel.Material = myMaterial;

            RotateTransform3D myRotateTransform3D = new RotateTransform3D();
            AxisAngleRotation3D myAxisAngleRotation3d = new AxisAngleRotation3D();
            myAxisAngleRotation3d.Axis = new Vector3D(0, 3, 0);
            myAxisAngleRotation3d.Angle = 40;
            myRotateTransform3D.Rotation = myAxisAngleRotation3d;
            myGeometryModel.Transform = myRotateTransform3D;

            myModel3DGroup.Children.Add(myGeometryModel);

            myModelVisual3D.Content = myModel3DGroup;
            myViewport3D.Children.Add(myModelVisual3D);

            this.Content = myViewport3D;
        }
    }
}

首先生成几个wpf元素,和xaml里的对应;
然后生成一个摄像机,赋值一些参数;把摄像机加入场景;
然后把光源也加入;

然后生成一个MeshGeometry3D类的对象;
然后生成向量来设置此对象的法线;
然后生成一些Point3D点来赋值给此对象的Positions属性;前面是在xaml里赋值的;
然后设置此对象的纹理坐标;
然后设置此对象的TriangleIndices属性;前面是在xaml里赋值的;
把此对象加入场景;

然后添加画刷和材质,添加一个变换;

运行,

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值