• WPF 2D纹理的准确映射


    TextureCoordinates定义了如何将一副2D纹理映射到所建立的3D网格上,TextureCoordinates为Positions集合中的每一个3D顶点提供了一个2D顶点。
    映射时方向确定比较麻烦,需要3D每个面映射都为正确的方向,在baidu上找了很多,映射基本是乱的。
    通过归纳测试,有了准确的参数,需要的可参考使用,不必再费劲计算。
    里面注销掉的部分,可以恢复并注销调自动转动部分,为手动点击对象转动。
    通过VisualBrush写入的 image可以换为UserControl等组件。
    代码不长,就100多行,仅供参考,如有错误,自行修正。

    MainWindow.xaml

    <Window x:Class="Test3.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            mc:Ignorable="d"
            Title="MainWindow" Height="768" Width="1024">
        <Grid x:Name="main">
            <Button Content="纵向" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
            <Button Content="横向" HorizontalAlignment="Left" Margin="10,48,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
            <Button Content="纵横" HorizontalAlignment="Left" Margin="10,85.74,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_2"/>
            <Button Content="横纵" HorizontalAlignment="Left" Margin="10,124.5,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_3"/>
     
        </Grid>
    </Window>
    

     MainWindow.xaml.cs

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Media.Imaging;
    using System.Windows.Media.Media3D;
     
    namespace Test3
    {
        public partial class MainWindow : Window
        {
            private AxisAngleRotation3D axisAngleRotation3D;
     
            public MainWindow()
            {
                InitializeComponent();
                main.MouseDown += Main_MouseDown;
     
                init_draw();
            }
     
            public void init_draw()
            {
                Point3DCollection[] positions = new Point3DCollection[6]
                {
                    new Point3DCollection(new Point3D[] {
                        new Point3D(0.5, 0.5, -0.5), new Point3D(- 0.5, 0.5, -0.5), new Point3D(- 0.5, 0.5, 0.5),
                        new Point3D(- 0.5, 0.5, 0.5),new Point3D(0.5, 0.5, 0.5), new Point3D(0.5, 0.5, -0.5)
                    }),
                    new Point3DCollection(new Point3D[] {
                        new Point3D(-0.5,0.5,-0.5),new Point3D(-0.5,-0.5,-0.5), new Point3D(-0.5,-0.5,0.5),
                        new Point3D(-0.5,-0.5,0.5),new Point3D(-0.5,0.5,0.5),new Point3D(-0.5,0.5,-0.5)
                    }),
                    new Point3DCollection(new Point3D[] {
                        new Point3D(-0.5,-0.5,0.5),new Point3D(0.5,-0.5,0.5),new Point3D(0.5,0.5,0.5),
                        new Point3D(0.5,0.5,0.5),new Point3D(-0.5,0.5,0.5), new Point3D(-0.5,-0.5,0.5)
                    }),
                    new Point3DCollection( new Point3D[] {
                        new Point3D(-0.5,-0.5,-0.5),new Point3D(-0.5,0.5,-0.5),new Point3D(0.5,0.5,-0.5),
                        new Point3D(0.5,0.5,-0.5), new Point3D(0.5,-0.5,-0.5),new Point3D(-0.5,-0.5,-0.5)
                    }),
                    new Point3DCollection( new Point3D[] {
                        new Point3D(-0.5,-0.5,-0.5), new Point3D(0.5,-0.5,-0.5), new Point3D(0.5,-0.5,0.5),
                        new Point3D(0.5,-0.5,0.5),new Point3D(-0.5,-0.5,0.5), new Point3D(-0.5,-0.5,-0.5)
                    }),
                    new Point3DCollection( new Point3D[] {
                        new Point3D(0.5,-0.5,-0.5),new Point3D(0.5,0.5,-0.5),new Point3D(0.5,0.5,0.5),
                        new Point3D(0.5,0.5,0.5), new Point3D(0.5,-0.5,0.5), new Point3D(0.5,-0.5,-0.5)
                    })
                };
                 
                PointCollection[] texturepoints = new PointCollection[6]
                {
                    new PointCollection {new Point(1,0), new Point(0,0), new Point(0,1), new Point(0,1), new Point(1,1),new Point(1,0) },
                    new PointCollection { new Point(0,0),new Point(0,1),new Point(1,1),  new Point(1,1),new Point(1,0),new Point(0,0) },
                    new PointCollection { new Point(0,1), new Point(1,1),new Point(1,0), new Point(1,0),new Point(0,0),new Point(0,1) },
                    new PointCollection { new Point(1,1), new Point(1,0),new Point(0,0), new Point(0,0), new Point(0,1), new Point(1,1) },
                    new PointCollection { new Point(0,1), new Point(1,1), new Point(1,0),new Point(1,0), new Point(0,0), new Point(0,1)},
                    new PointCollection{ new Point(1,1), new Point(1,0),new Point(0,0),new Point(0,0), new Point(0,1),new Point(1,1)}
                };
     
                string[] filename = new string[6] //430251
                {
                    "pack://application:,,,/Images/4.jpg",
                    "pack://application:,,,/Images/3.jpg",
                    "pack://application:,,,/Images/0.jpg",
                    "pack://application:,,,/Images/2.jpg",
                    "pack://application:,,,/Images/5.jpg",
                    "pack://application:,,,/Images/1.jpg"
                };
     
                Viewport3D viewport3D = new Viewport3D();
                 
                PerspectiveCamera perspectiveCamera = new PerspectiveCamera()
                {
                    Position = new Point3D(0, 0, 3),
                    LookDirection = new Vector3D(0, 0, -3),
                    FieldOfView = 50,
                    UpDirection = new Vector3D(0, 1, 0),
                    FarPlaneDistance = 20,
                    NearPlaneDistance = 0,
                };
                viewport3D.Camera = perspectiveCamera;
     
                ModelVisual3D modelVisual3D = new ModelVisual3D();
                Model3DGroup model3DGroup = new Model3DGroup();
     
                for (int i = 0; i < 6; i++)
                {
                    GeometryModel3D geometryModel3D = new GeometryModel3D();
     
                    DiffuseMaterial diffuse = new DiffuseMaterial();
                    VisualBrush visualBrush = new VisualBrush();
                    Image image = new Image();
                    image.Source = new BitmapImage(new Uri(filename[i]));
                    visualBrush.Visual = image;
                    diffuse.Brush = visualBrush;
                    geometryModel3D.Material = diffuse;
     
                    MeshGeometry3D meshGeometry3D = new MeshGeometry3D()
                    {
                        Positions = positions[i],
                        TextureCoordinates = texturepoints[i],
                    };
                    geometryModel3D.Geometry = meshGeometry3D;
                    model3DGroup.Children.Add(geometryModel3D);
                }
                AmbientLight ambientLight = new AmbientLight();
                model3DGroup.Children.Add(ambientLight);
     
                modelVisual3D.Content = model3DGroup;
                viewport3D.Children.Add(modelVisual3D);
     
                main.Children.Add(viewport3D);
     
                /*
                axisAngleRotation3D = new AxisAngleRotation3D(new Vector3D(1, 1, 0), 0);
                RotateTransform3D rotateTransform3D = new RotateTransform3D(axisAngleRotation3D);
                rotateTransform3D.Rotation = axisAngleRotation3D;
                modelVisual3D.Transform = rotateTransform3D;
                */
                // 如恢复上面,以下可以注销
                axisAngleRotation3D = new AxisAngleRotation3D(new Vector3D(0, 1, 0), 0);
                RotateTransform3D rotate = new RotateTransform3D(axisAngleRotation3D);
                modelVisual3D.Transform = rotate;
                DoubleAnimation animation = new DoubleAnimation();
                animation.From = 0;
                animation.To = 360;
                animation.Duration = new Duration(TimeSpan.FromSeconds(10.0));
                animation.RepeatBehavior = RepeatBehavior.Forever;
                NameScope.SetNameScope(main, new NameScope());
                main.RegisterName("cubeaxis", axisAngleRotation3D);
                Storyboard.SetTargetName(animation, "cubeaxis");
                Storyboard.SetTargetProperty(animation, new PropertyPath(AxisAngleRotation3D.AngleProperty));
                Storyboard RotCube = new Storyboard();
                RotCube.Children.Add(animation);
                RotCube.Begin(main);
            }
     
            double tmp = 0;
     
            private void Main_MouseDown(object sender, MouseButtonEventArgs e)
            {
                // 点击对象手动转动
                /*
                tmp = axisAngleRotation3D.Angle;
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    tmp -= 5;
                }
                if (e.RightButton == MouseButtonState.Pressed)
                {
                    tmp += 5;
                }
                axisAngleRotation3D.Angle = tmp;
                */
            }
     
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                axisAngleRotation3D.Axis = new Vector3D(1,0,0);
                axisAngleRotation3D.Angle = 0;
            }
     
            private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                axisAngleRotation3D.Axis = new Vector3D(0,1,0);
                axisAngleRotation3D.Angle = 0;
            }
     
            private void Button_Click_2(object sender, RoutedEventArgs e)
            {
                axisAngleRotation3D.Axis = new Vector3D(1, 1, 0);
                axisAngleRotation3D.Angle = 0;
            }
     
            private void Button_Click_3(object sender, RoutedEventArgs e)
            {
                axisAngleRotation3D.Axis = new Vector3D(0, 1, 1);
                axisAngleRotation3D.Angle = 0;
            }
        }
    }
    

    下载:https://pan.baidu.com/s/1yJGS1_jJPL68nPX28NTl4g

  • 相关阅读:
    马士兵Java学习之路
    @Component, @Repository, @Service的区别
    编译器警告:CGContextSaveGState: invalid context 0x0
    Other Linker Flags到底是什么
    Xcode常用快捷键(持续更新-20160811)
    iOS应用文件夹
    iOS compare 字符串比较
    去掉UITableView多余的空白行分割线
    iOS 查询数组中的对象
    UISearchController使用
  • 原文地址:https://www.cnblogs.com/qiaoke/p/11790545.html
Copyright © 2020-2023  润新知