• wpf 3D学习


    最近在看一些关于wpf 3d的效果,研究了一些代码特效,现在和广大博友共享一下.

    首先用到的是MeshGeometry3D,msdn上介绍:用于生成三维形状的三角形基元。
    主要有4个依赖属性:NormalsProperty,PositionsProperty,TextureCoordinatesProperty,
    TriangleIndicesProperty。4中属性具体含义大家可以直接参考msdn上。

    具体代码如下:

    MeshGeometry3D meshGeometry3D = new MeshGeometry3D();
    
                    Point3DCollection positions = new Point3DCollection();
                    positions.Add(new Point3D(0, 0, 1));
                    positions.Add(new Point3D(0, 0, 0));
                    positions.Add(new Point3D(1, 0, 0));
                    positions.Add(new Point3D(1, 0, 1));
                    positions.Add(new Point3D(0, 1, 1));
                    positions.Add(new Point3D(0, 1, 0));
                    positions.Add(new Point3D(1, 1, 0));
                    positions.Add(new Point3D(1, 1, 1));
                    positions.Freeze();
    
                    Int32Collection triangleIndices = new Int32Collection();
                    triangleIndices.Add(0);
                    triangleIndices.Add(1);
                    triangleIndices.Add(2);
    
                    triangleIndices.Add(2);
                    triangleIndices.Add(3);
                    triangleIndices.Add(0);
    
                    triangleIndices.Add(4);
                    triangleIndices.Add(7);
                    triangleIndices.Add(6);
    
                    triangleIndices.Add(6);
                    triangleIndices.Add(5);
                    triangleIndices.Add(4);
    
                    triangleIndices.Add(0);
                    triangleIndices.Add(3);
                    triangleIndices.Add(7);
    
                    triangleIndices.Add(7);
                    triangleIndices.Add(4);
                    triangleIndices.Add(0);
    
                    triangleIndices.Add(1);
                    triangleIndices.Add(5);
                    triangleIndices.Add(6);
    
                    triangleIndices.Add(6);
                    triangleIndices.Add(2);
                    triangleIndices.Add(1);
    
                    triangleIndices.Add(3);
                    triangleIndices.Add(2);
                    triangleIndices.Add(6);
    
                    triangleIndices.Add(6);
                    triangleIndices.Add(7);
                    triangleIndices.Add(3);
    
                    triangleIndices.Add(0);
                    triangleIndices.Add(4);
                    triangleIndices.Add(5);
    
                    triangleIndices.Add(5);
                    triangleIndices.Add(7);
                    triangleIndices.Add(0);
    
                    triangleIndices.Freeze();
    
                    // finally set the data
                    meshGeometry3D.TriangleIndices = triangleIndices;
                    meshGeometry3D.Positions = positions;

    然后定义GeometryModel3D,代码:

    // create the geometry model
                    GeometryModel3D geom3D = new GeometryModel3D();
                    geom3D.Geometry = meshGeometry3D;
    
                    Color color = WpfUtil.HsbToRgb(index / (float)count, .9f, 1f);
                    SolidColorBrush solidColorBrush = new SolidColorBrush(color);
                    solidColorBrush.Freeze();
    
                    geom3D.Material = new DiffuseMaterial(solidColorBrush);

    然后将GeometryModel3D归入Model3DGroup中,代码:

    Model3DGroup group = new Model3DGroup();
                    group.Children.Add(geom3D);
                    ModelVisual3D model = new ModelVisual3D();
                    model.Content = group;
                    DirectionalLight dl = new DirectionalLight();
    
                    dl.Color = Colors.White; dl.Direction = new Vector3D(-1, -1, -3);
                    group.Children.Add(dl);
                    AmbientLight al = new AmbientLight();
                    al.Color = (Color)ColorConverter.ConvertFromString("#555555");
                    group.Children.Add(al);

    xaml如下:

    <ModelVisual3D>
                    <ModelVisual3D.Content>
                        <Model3DGroup>
                            <DirectionalLight Direction="1 0 -2"
                                     Color="White"/>
                            <GeometryModel3D>
                                <GeometryModel3D.Geometry>
                                    <!--Positions获取或设置 meshgeometry3d 的顶点位置的集合
                                    TextureCoordinates获取或设置 meshgeometry3d 的纹理坐标的集合
                                    TriangleIndices获取或设置 meshgeometry3d 的三角形索引的集合-->
                                    <MeshGeometry3D Positions="-1 1 0, 0 1 1, -1 0 0, 0 0 1, 0 1 1, 1 
    
    1 0, 0 0 1, 1 0 0"
                                           TriangleIndices="2 1 0, 2 3 1, 6 5 4, 6 7 5"/>
                                </GeometryModel3D.Geometry>
                                <GeometryModel3D.Material>
                                    <DiffuseMaterial Brush="Green"/>
                                </GeometryModel3D.Material>
                            </GeometryModel3D>
                        </Model3DGroup>
                    </ModelVisual3D.Content>
                </ModelVisual3D>

    上面已经设置了灯光,接下来要设置摄像机,代码如下:

    var camera=new PerspectiveCamera( new Point3D(0,3,3),
                    new Vector3D(0,-3,-3),
                    new Vector3D(0,0,1),
                    45););

    xmal:

    <Viewport3D.Camera>
                    <!--<PerspectiveCamera Position="0,0,10"/>-->
                    <PerspectiveCamera  LookDirection = " 0,  -3, -3"
                                    UpDirection   = " 0,  0,  1"
                                    Position      = "0,  3,  3"
                                    FieldOfView   = "45" />
                </Viewport3D.Camera>

    最后可以把它们一起归入Viewport3D

    Viewport3D view3D=new Viewport3D();
    view3D.Camera = camera;
    view3D.Children.Add(group);

    当然我们也可以在指定灯光时,只定义DirectionalLight (方向光)

      <ModelVisual3D>
                    <ModelVisual3D.Content>
                        <Model3DGroup>
                            <!--<AmbientLight Color="White"/>-->
                            <DirectionalLight Color="#FFFFFF" Direction="0,0,-10" />
                            <DirectionalLight Color="#FFFFFF" Direction="1,0,0" />
                        </Model3DGroup>
                    </ModelVisual3D.Content>
                </ModelVisual3D>

    然后自定义3D模型

    <local:TreeMap3D x:Name="_treeMap3D" WeightBindingPath="CustomerCount">
                    <local:TreeMap3D.Transform>
                        <Transform3DGroup>
                            <ScaleTransform3D ScaleX="1.2" ScaleY="1.2" ScaleZ="1.2" />
                            <RotateTransform3D>
                                <RotateTransform3D.Rotation>
                                    <AxisAngleRotation3D Angle="30" Axis="0, 0, 1" />
                                </RotateTransform3D.Rotation>
                            </RotateTransform3D>
                            <TranslateTransform3D OffsetZ="0.6" OffsetX="-0.3"/>
                        </Transform3DGroup>
                    </local:TreeMap3D.Transform>
                </local:TreeMap3D>

    添加TreeMap3D类

    public class TreeMap3D : UIElement3D
    {
    private string m_weightBindingPath;
            private IList m_itemsSource;
            private TreeMap3DElement m_selectedElement;
            private int[] m_weightMap;
            private TreeMap3DElement m_lastClickedElement;
    
            private readonly List<TreeMap3DElement> m_elements = new List<TreeMap3DElement>();
    }
    }

    定义ItemSource

    public IList ItemsSource
            {
                get
                {
                    VerifyAccess();
                    return m_itemsSource;
                }
                set
                {
                    if (m_itemsSource != value)
                    {
                        VerifyAccess();
    
                        refresh(value);
                        m_itemsSource = value;
                    }
                }

    定义其子元素:

    private class TreeMap3DElement : UIElement3D
    {
    public TreeMap3DElement(int index, int count)
                {
                    this.Visual3DModel = GenerateTreeMap3DModel(index, count);
                    
                    m_translate = new TranslateTransform3D();
                    m_scale = new ScaleTransform3D();
                    Transform3DGroup t3DGroup = new Transform3DGroup();
                    t3DGroup.Children.Add(m_scale);
                    t3DGroup.Children.Add(m_translate);
                    base.Transform = t3DGroup;
    
                }
    private object m_data;
                private string m_weightBindingPath;
                private bool m_isSelected;
                private double m_scaleZ;
    
                private readonly ScaleTransform3D m_scale;
                private readonly TranslateTransform3D m_translate;
    }

    加入动画设计:

    public bool IsSelected
                {
                    get { return m_isSelected; }
                    set
                    {
                        if (value != m_isSelected)
                        {
                            DoubleAnimation animation = new DoubleAnimation();
    
                            if (value)
                            {
                                animation.From = m_scale.ScaleZ;
                                animation.To = m_scaleZ;
                            }
                            else
                            {
                                animation.From = m_scale.ScaleZ;
                                animation.To = 0;
                            }
    
                            m_isSelected = value;
    
                            animation.Duration = new Duration(TimeSpan.FromSeconds(0.2));
                            m_scale.BeginAnimation(ScaleTransform3D.ScaleZProperty, animation);
                        }
    
                    }
                }

    最后运行如下:

    代码下载:https://files.cnblogs.com/gavinhuang/3DViewTest.rar

  • 相关阅读:
    Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '1288372549423476738' for key 'PRIMARY'
    环形数组循环
    less命令
    ln命令
    Vue中$refs的理解
    cut命令
    除数博弈
    find命令
    file命令
    最长公共前缀
  • 原文地址:https://www.cnblogs.com/gavinhuang/p/2971187.html
Copyright © 2020-2023  润新知