[咱也玩一玩]WPF立方体盒子承载DataGrid可旋转可平移可编辑 本帖最后由 lizhibin11 于 2012-07-18 23:06:24 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我个人感觉动Camera会简单一些 这个是WPF 3D,想问下lz和XNA有什么关系,不是很理解 您好,您说的对,虽然尝试动Camera时效果和动Viewport2DVisual3D一样,但Camera更能体现第一人称。我昨天看一个XNA的问题时做了一个盒子,今天想用WPF做法应该一样,但WPF可以添加各种控件,如果做什么增删改查程序可能效果更玄一些能蒙蒙客户。但我是色盲,弄完这个之后老婆说象刷油漆,太丑了呵呵。 哈哈,凑个热闹我也要玩。不过说实话这个比你那些简单多了,本以为矩阵的运算可能稍微复杂一些,没想到不论是directx、xna还是wpf都把一些常用的运算直接做成API了。 对于开发人员来说,这个配色可以了,不过老婆要求很高的,试试采用Kuler的配色,其实运用颜色也是很有技巧的,如果你老婆喜欢日系,那么采用一些小清新的风格,确保取色时明度和饱和度一致,只需要动色调即可。 text editor1234567 画立方体本身八个顶点就可以,这里因为要把UserControl的六个DataGrid贴上去,会出现同一个顶点具有不同纹理坐标的情况,所以先把纹理坐标和顶点的对应关系确定下来如下图:一共需要在XAML的Positions定义14个顶点,在TextureCoordinates中定义每个顶点对应的纹理坐标,TriangleIndices中每三个顶点一组画三角形,WPF默认情况下三角形似乎要逆时针画,和XNA相反,留待以后确认。使用GeometryModel3D虽然也可以贴WPF控件,但控件只能显示无法在界面上操作,所以使用Viewport2DVisual3D。这样定义十四个顶点贴纹理我感觉有点繁琐,不知道有没有更快捷的方式。 不知道微软还会不会发展silverlight啊。wpf命运如何啊。望知情人 这里发言,表示您接受了CSDN社区的用户行为准则。 纠正一个拙劣的做法 <ModelVisual3D> <ModelVisual3D.Content> <Model3DGroup> <DirectionalLight Color="#FFFFFFFF" Direction="0, 0, -1" /> <DirectionalLight Color="#FFFFFFFF" Direction="-1, 0, 0" /> <DirectionalLight Color="#FFFFFFFF" Direction="1, 0, 0" /> <DirectionalLight Color="#FFFFFFFF" Direction="0, 1, 0" /> <DirectionalLight Color="#FFFFFFFF" Direction="0, -1, 0" /> </Model3DGroup> </ModelVisual3D.Content> </ModelVisual3D>这十一行太拙劣,改为以下: <ModelVisual3D> <ModelVisual3D.Content> <AmbientLight Color="#FFFFFFFF" /> </ModelVisual3D.Content> </ModelVisual3D>用Camera进行第一人称的变换不是想象中那么简单,旋转之后Camera的平移在WPF中比较复杂,我能想到的笨办法就是Camera的变换采用三个矩阵相乘(晚上试验),简单的办法没有找到,初学,错误和丑陋的写法很多,请高手指点。 这里附上以摄像机变换的方式来达到第一人称效果,和Viewport2DVisual3D的变幻不同,摄像机的变换在发生移动后旋转会更加真实。WPF使用Transform3DGroup还是很方便,现在越来越觉得不仅.net博大精深,单单WPF内容就实在太多了。namespace WpfApplication2{ public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } RotateTransform3D rt3dud; RotateTransform3D rt3dlr; TranslateTransform3D tl3d; Transform3DGroup t3dg; double updown = 0; double leftright = 0; private void Window_Loaded(object sender, RoutedEventArgs e) { DataGrid[] dgs = { ucontrol.dataGrid1, ucontrol.dataGrid2, ucontrol.dataGrid3, ucontrol.dataGrid4, ucontrol.dataGrid5, ucontrol.dataGrid6 }; for (int i = 0; i < 6; i++) { DataTable dt = new DataTable(); for (int j = 0; j < 4; j++) dt.Columns.Add(((char)(4 * i + j + 65)).ToString(), typeof(int)); for (int m = 0; m < 20; m++) dt.Rows.Add(m, m, m, m); dgs[i].ItemsSource = dt.DefaultView; } rt3dud = new RotateTransform3D(AxisAngleRotation3D.Identity); rt3dlr = new RotateTransform3D(AxisAngleRotation3D.Identity); tl3d = new TranslateTransform3D(new Vector3D(0, 0, 0)); t3dg = new Transform3DGroup(); t3dg.Children.Add(rt3dud); t3dg.Children.Add(rt3dlr); t3dg.Children.Add(tl3d); //这里将变幻的对象由Viewport2DVisual3D变为Camera camera.Transform = t3dg; } protected override void OnPreviewKeyDown(KeyEventArgs e) { switch (e.Key) { case Key.Up: updown += 5; rt3dud.Rotation = new AxisAngleRotation3D(new Vector3D(1, 0, 0), updown); break; case Key.Down: updown -= 5; rt3dud.Rotation = new AxisAngleRotation3D(new Vector3D(1, 0, 0), updown); break; case Key.Left: leftright += 5; rt3dlr.Rotation = new AxisAngleRotation3D(new Vector3D(0, 1, 0), leftright); break; case Key.Right: leftright -= 5; rt3dlr.Rotation = new AxisAngleRotation3D(new Vector3D(0, 1, 0), leftright); break; default: return; } e.Handled = true; } //这里改动较多,因为要考虑复杂的旋转之后,平易摄像机的路径不再是单纯的一个轴 protected override void OnPreviewMouseWheel(MouseWheelEventArgs e) { //钱进还是后退的标识 int flag = e.Delta < 0 ? -1 : 1; //得到Camera最新的Position和LookDirection Point3D position = Point3D.Multiply(camera.Position, t3dg.Value); Vector3D lookat = Vector3D.Multiply(camera.LookDirection, t3dg.Value); //设置平移的新位置,平移幅度0.02 tl3d.OffsetX = position.X + flag * lookat.X * 0.02; tl3d.OffsetY = position.Y + flag * lookat.Y * 0.02; tl3d.OffsetZ = position.Z + flag * lookat.Z * 0.02; e.Handled = true; } }} Camera平移的方法还需要修正,前面的代码平移不是匀速的,另外也不需要获得Camera最新的Position,在TranslateTransform3D已经包含了。 protected override void OnPreviewMouseWheel(MouseWheelEventArgs e) { //前进还是后退的标识 int flag = e.Delta < 0 ? -1 : 1; //得到向量长度为单位长度的LookDirection Vector3D lookat = Vector3D.Multiply(camera.LookDirection, rt3dud.Value * rt3dlr.Value); //设置平移的新位置,平移幅度0.02 tl3d.OffsetX += flag * lookat.X * 0.02; tl3d.OffsetY += flag * lookat.Y * 0.02; tl3d.OffsetZ += flag * lookat.Z * 0.02; e.Handled = true; } 在WinForms程序里实现窗体传值的最佳实践 IIS7的问题 在图片中写文字(要求文字竖直排列,默认是从左到右水平) 从文本读取unsigned char类型数据的问题 请问怎么将Excel表的数据导入到Oracle数据库中,那位大哥指点指点,谢谢! 如何把一个两列表的数据加入到一个二维数组中? 续-做软件测试有发展吗? 我的软件要打印几份文档,连在电脑上的有多个打印机,如何让多台打印机同时并行打印?提高效率。 关于ListView的一个问题 怎样获取EXCEL文件中的已用过的行数和列数? 今天又遇到了一个关于datagridview数据过滤的问题 定时跟新
我昨天看一个XNA的问题时做了一个盒子,今天想用WPF做法应该一样,但WPF可以添加各种控件,如果做什么增删改查程序可能效果更玄一些能蒙蒙客户。但我是色盲,弄完这个之后老婆说象刷油漆,太丑了呵呵。
对于开发人员来说,这个配色可以了,不过老婆要求很高的,试试采用Kuler的配色,其实运用颜色也是很有技巧的,如果你老婆喜欢日系,那么采用一些小清新的风格,确保取色时明度和饱和度一致,只需要动色调即可。
1
2
3
4
5
6
7
使用GeometryModel3D虽然也可以贴WPF控件,但控件只能显示无法在界面上操作,所以使用Viewport2DVisual3D。
这样定义十四个顶点贴纹理我感觉有点繁琐,不知道有没有更快捷的方式。
<ModelVisual3D.Content>
<Model3DGroup>
<DirectionalLight Color="#FFFFFFFF" Direction="0, 0, -1" />
<DirectionalLight Color="#FFFFFFFF" Direction="-1, 0, 0" />
<DirectionalLight Color="#FFFFFFFF" Direction="1, 0, 0" />
<DirectionalLight Color="#FFFFFFFF" Direction="0, 1, 0" />
<DirectionalLight Color="#FFFFFFFF" Direction="0, -1, 0" />
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>这十一行太拙劣,改为以下: <ModelVisual3D>
<ModelVisual3D.Content>
<AmbientLight Color="#FFFFFFFF" />
</ModelVisual3D.Content>
</ModelVisual3D>用Camera进行第一人称的变换不是想象中那么简单,旋转之后Camera的平移在WPF中比较复杂,我能想到的笨办法就是Camera的变换采用三个矩阵相乘(晚上试验),简单的办法没有找到,初学,错误和丑陋的写法很多,请高手指点。
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
RotateTransform3D rt3dud;
RotateTransform3D rt3dlr;
TranslateTransform3D tl3d;
Transform3DGroup t3dg;
double updown = 0;
double leftright = 0;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
DataGrid[] dgs = { ucontrol.dataGrid1, ucontrol.dataGrid2, ucontrol.dataGrid3,
ucontrol.dataGrid4, ucontrol.dataGrid5, ucontrol.dataGrid6 };
for (int i = 0; i < 6; i++)
{
DataTable dt = new DataTable();
for (int j = 0; j < 4; j++)
dt.Columns.Add(((char)(4 * i + j + 65)).ToString(), typeof(int));
for (int m = 0; m < 20; m++)
dt.Rows.Add(m, m, m, m);
dgs[i].ItemsSource = dt.DefaultView;
}
rt3dud = new RotateTransform3D(AxisAngleRotation3D.Identity);
rt3dlr = new RotateTransform3D(AxisAngleRotation3D.Identity);
tl3d = new TranslateTransform3D(new Vector3D(0, 0, 0));
t3dg = new Transform3DGroup();
t3dg.Children.Add(rt3dud);
t3dg.Children.Add(rt3dlr);
t3dg.Children.Add(tl3d);
//这里将变幻的对象由Viewport2DVisual3D变为Camera
camera.Transform = t3dg;
}
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
switch (e.Key)
{
case Key.Up:
updown += 5;
rt3dud.Rotation = new AxisAngleRotation3D(new Vector3D(1, 0, 0), updown);
break;
case Key.Down:
updown -= 5;
rt3dud.Rotation = new AxisAngleRotation3D(new Vector3D(1, 0, 0), updown);
break;
case Key.Left:
leftright += 5;
rt3dlr.Rotation = new AxisAngleRotation3D(new Vector3D(0, 1, 0), leftright);
break;
case Key.Right:
leftright -= 5;
rt3dlr.Rotation = new AxisAngleRotation3D(new Vector3D(0, 1, 0), leftright);
break;
default:
return;
}
e.Handled = true;
}
//这里改动较多,因为要考虑复杂的旋转之后,平易摄像机的路径不再是单纯的一个轴
protected override void OnPreviewMouseWheel(MouseWheelEventArgs e)
{
//钱进还是后退的标识
int flag = e.Delta < 0 ? -1 : 1;
//得到Camera最新的Position和LookDirection
Point3D position = Point3D.Multiply(camera.Position, t3dg.Value);
Vector3D lookat = Vector3D.Multiply(camera.LookDirection, t3dg.Value);
//设置平移的新位置,平移幅度0.02
tl3d.OffsetX = position.X + flag * lookat.X * 0.02;
tl3d.OffsetY = position.Y + flag * lookat.Y * 0.02;
tl3d.OffsetZ = position.Z + flag * lookat.Z * 0.02;
e.Handled = true;
}
}
}
{
//前进还是后退的标识
int flag = e.Delta < 0 ? -1 : 1;
//得到向量长度为单位长度的LookDirection
Vector3D lookat = Vector3D.Multiply(camera.LookDirection, rt3dud.Value * rt3dlr.Value);
//设置平移的新位置,平移幅度0.02
tl3d.OffsetX += flag * lookat.X * 0.02;
tl3d.OffsetY += flag * lookat.Y * 0.02;
tl3d.OffsetZ += flag * lookat.Z * 0.02;
e.Handled = true;
}