您的位置:首页 > 其它

Wpf 3D入门指南(Windows Presentation Foundation (WPF) 3D Tutorial)(一)

2007-05-23 22:36 555 查看
The purpose of this tutorial is to provide the simplest explanation and examples possible of how to create 3D graphics with Windows Presentation Foundation (WPF) (formerly known as "Avalon"). It is not a comprehensive guide to 3D modeling, but simply a primer for those who have no knowledge of or experience with 3D graphics. 3D or vector-based graphics is a different world from 2D GDI, and it took a long period of guessing, stumbling, and trial and error before I understood what was going on with it. Ultimately I hope that you are able to avoid some of the pains I went through by reading through this tutorial.

这篇文章的目的是为如何用WPF(也就是以前的avalon技术)建立3D图形提供一个简单的解释并提供一些示例,它并不是全面的3D建模入门教程,仅仅是为那些没有3D图形经验或知识的同行提供一个简单的入门。3D或基于矢量的图形对于2D GDI来说是一个不同的世界,大部分时间我经历了猜测,困惑,实验和错误,直到我理解了我们正在用它做什么。最后我希望你读过这篇文章後,可以避免一些我曾经经历的错误。

For your convenience, the tutorial contains inline links to the documentation of all of the .Net 3.0 classes, structures, properties, and methods used in the example code. Click away as you please.

为了您的方便,这篇指南包括了链接,这些链接链向所有在示例代码中用到的关于.NET 3.0的类,结构,属性及方法,随便你去点击。

Disclaimer

不承诺

While I make my best effort to make sure the content and examples in this tutorial are accurate and bug-free, I'm not responsible for anything bad (e.g. crashes, loss of data, any damage) that may happen if you use the information or code in this tutorial. I'll do my best to make sure bugs are fixed and that the content is as accurate as possible. In short, have some common sense and use this at your own risk.

当我尽力去保证这篇文章中的所有内容及示例都是正确且无bug的,我并不对任何不愉快的事负责 如程序崩溃,数据丢失及任何损害 ,当你用这篇文章中的信息及代码,我尽可能保证所有的bug都被调试通过并且内容都是准确的,简而言之,要有些常识并且自在自己的盘里使用它。

Mike's Version of 3D Graphics Theory

迈克关于3D图形理论的看法

When I started 3D graphics in WPF (back when it was still called Avalon), I had no idea what I was doing. I didn't have a clue what the significance was of a mesh, triangle index, or normal. This was the most painful part about learning 3D modeling, because without a minimal understanding of these things, nothing will show up correctly in WPF (or you'll just get lucky). In short, all you really need to know is what a mesh is and what it is composed of [1].

当我开始用WPF进行3D图形编程时,我不知道我正在做什么,对于网格(mesh),三角形索引(triangle index)或法线(normal)的复杂我毫无头绪。对于3D建模这是最痛苦的,因为关于这些东西没有一种简短易懂的解释,在WPF里没有什么可以突然展现出来,简而言之,所有你所需要知道的是:什么是mesh及它是由什么组成的。

What is a mesh?

什么是mesh?

A mesh is basically a representation of a surface. The mesh represents the surface through a system of points and lines. The points describe the high and low areas of the surface, and the lines connect the points to establish how you get from one point to the next.

一个网,基本上是一个代表性的表面. 网通过系统的点线代表面,点形容高与低的地区的地表, 而且线连接点,以建立你怎样从一个点到下.

At a minimum, a surface is a flat plane. A flat plane needs three points to define it. Thus, the simplest surface that can be described in a mesh is a single triangle. It turns out that meshes can only be described with triangles. That is because a triangle is the simplest, most granular way to define a surface. A large, complex surface obviously can't be accurately described by one triangle. Instead, it can be approximated by many smaller triangles. You could argue that you could use a rectangle to define a surface, but it's not as granular as a triangle. When you think about it, a rectangle can be broken into two triangles. Two triangles can much more accurately describe a surface than a single rectangle. Ok enough... the point is that a mesh represents a surface through many triangles.

A whole mesh is composed of:

Mesh Positions

Triangle indeces

Triangle normals

至少,一个表面是一个平面. 三点确定一个平面. 因此,最简单的表面上,可以说,一网是一个三角形. 这是因为一个三角形是最简单,最粒状地界定了表面. 大型复杂曲面显然不能准确地被一个三角形描述. 相反,它可通过许多较小的三角形进行组合. 你可以说你能够用一个长方形来确定一个面, 但它不是粒状作为一个三角形. 当你想想看,一个长方形,可分为两个三角形. 两个三角形可以更准确地描述一个表面比单一的长方形. ok... 问题是,网是一个通过许多三角形组成的表面.
整个网组成是:
•网位置
•三角行
•三角形法线

Mesh Positions

网格位置

A mesh position is the location of a single point on a surface. The more dense the points are, the more accurately the mesh describes the surface.

一网位置是一个表面上一个单点的位置. 点的密度越大,网越能更加准确地描述了表面.

Triangle Indeces

三角形索引

A triangle index is a mesh position that defines one of the three points of a triangle in the mesh. The mesh positions alone cannot describe the mesh triangles. After the positions have been added, you need to define what positions make up which triangles.

一个三角形指数是一个网格位置,确定了网格中一个三角形的3点中的一个点. 仅仅网位置不足以形容网格三角形. 位置加入后,你必须确定在什么位置上组成了哪些三角形.

In WPF, the order in which you add mesh positions is important. A position's index value in a mesh's position collection is used when adding triangle indeces. For example, let's say you have a surface composed of five positions {p0, p1, p2, p3, p4}. If you wanted to define a triangle from p1, p3, and p4, you would add triangle indeces with index values 1, 3, and 4. If the positions were added in a different order {p3, p4, p0, p2, p1} and you wanted a triangle made of the same positions, you would add triangle indeces with index values 4, 0, and 1.

在wpf中 , 添加网位置(mesh positions)的命令是非常重要的.当你添加三角形时需要用到网格位置集合中的一个位置索引值. 举例来说,你有一个由五个点( p0 , p1 , p2 , p3 , p4 )组成的面 . 如果你想通过p1 , p3 , p4确定一个三角形, 你会添加三角索引(triangle indeces)通过索引值1 , 3和4 . 如果这些位置通过不同的秩序( p3 , p4 , p0 , p2 , p1 ) 添加 ,你想要由一个相同位置组成的三角形, 你会放入三角索引(triangle indeces)与索引值4 , 0和1 .

The order in which you add triangle indeces is also important. When you define a triangle, you are basically defining the points in either a clockwise or counter-clockwise direction (depending on which side of the triangle you're on, of course). The reason this is important is because it affects which side of the triangle is visible. When I say "side", I don't mean which of the three triangle sides, but which side of the plane.

添加三角索引(triangle indeces)的命令也是很重要的. 当你定义一个三角形, 你基本上确定了它的点,要么以顺时针或逆时针方向(取决于你看到的三角形的哪一方) .这是很重要的,因为它影响到的三角形哪一边是可见的. 当我说"side" ,我不是指三角形的哪一边,而是指一个平面的哪一面。

Let's say you're looking straight ahead at the surface of a triangle. If you define its indeces in a clockwise direction, the side you are looking at will be invisible and the opposite side will be visible. If you define its indeces in a counter-clockwise direction, the side you are looking at will be visible and the opposite side will be invisible. You can use the "right hand rule" to remember this. Take your right hand and make a "thumbs up" sign. The direction your fingers curl is counter-clockwise and your thumb points up (or out) in the direction the surface would be visible.

话又说回来,你直接看到的是一个三角形的表面. 如果你以顺时针方向确定索引, 你正在看的那一面将要是不可见的而它的另一面是可见的. 如果你以逆时针方向确定索引, 站在你的位置将会看得见,对方将看不见. 你可以用"右手定则"记住这一点. 以右手作出一个"大拇指"的手势.手指卷曲方向是时针方向,拇指方向的表面是可见的.

Exactly why a right-hand-rule applies to index ordering is beyond me. My best guess is that WPF doesn't think it is necessary or efficient to render both sides of the triangle, so you need to pick one of them.

正是右手规则适用于指数排序令人费解. 我最好的猜测是wpf并不认为有必要或有效率,使双方的三角形 所以你需要选择其中之一.

Triangle Normals

三角形的法线

After defining positions and triangle indeces, you need to add normals to each position. While the direction in which you add triangle indeces determines which side of the triangle is visible, a normal is used by WPF to know how the surface should be lit by a light source.

在界定位置和三角索引 ,你还要为每个位置加入法线. 而方向是你放入三角索引时确定哪一侧的三角是可见的, wpf 通过使用法线知道表面是怎样被光源照射的.

A normal is a vector that is perpendicular to the surface of the triangle. The normal vector is computed as the "cross product" of two vectors that make up the side of the triangle. If you have a triangle defined by points A, B, and C, you could create the normal by multiplying AB x AC, BC x BA, or CB x CA. All three ways will result in the same normal. However, the right-hand rule still applies. AB x AC will result in a normal in the opposite direction from AC x AB.

法线是一个垂直于三角形表面的向量. 法线是三角形两边的两个差乘结果. 如果你有一个三角形,顶点为A , B和C , 你可以得到法线通过AB x AC, BC x BA, 或CB x CA. .三种方式得到在同样的法线.但是,右手定则仍然适用. AB x AC的结果与AC x AB相反 .

At this point, my lack of knowledge of 3D theory begins to show, but in general you'll want your normals to point in the same direction as the visible side of your triangle surface.

在这方面看得出来,我缺乏三维理论知识, 但一般来说,你希望你的法线和三角形可见表面方向是一致的。

Each position in the mesh should have a normal assigned to it, and a position can only have one normal. You'll add normals to the mesh in the same order that you added the positions. In other words, the index values of the normals collection in the mesh corresponds to the index values of the positions collection.

网格中的各个位置应该被分配一个法线,并且一个位置只能有一个法线. 您可以用给位置加入法线的方法去给网格加入法线. 换句话说,在网格中法线索引值集合和位置值集合是一一对应的.

The more positions you have, the more normals you have. The more normals you have, the more pleasant the lighting and shading will be. In a mesh, a single point may be the index of more than one triangle. In this case, you may want to use multiple points with the same coordinates so that you can have multiple normals at that point. Take the corner of a cube, for example. The corner of a cube is the intersection of three different triangles on the cube. If you only used one position in the mesh to define the common index of those three triangles, you could only use one normal vector for that position. As a result, two of the triangles at that position won't be shaded as well as it could be. It would be better to define that cube corner with three unique positions. Each of the three triangles would use their own unique points, and you could use three normals at that corner instead of just one.

你有愈多的位置,就有愈多的法线. 你有愈多的法线,你就更好的明暗效果. 在一个网格,单点可能是不止一个三角形的索引. 在这种情况下, 你可以使用多个具有同样座标的点,这样在那点上你可以有多条法线. 拿正方体的一个角打比方,. 一个角是立方体的三个不同的三角形相交的组成的. 如果你只用网格中的一个位置定义这三个三角形的法线, 你只能用到那个位置的一个法线向量.结果是, 三个三角形中的两个将不会想它应该的那样有阴影,用三个独立的位置去定义立方体的角会更好.三个三角形中的每个会用它自己单独的点, 并且你可以在那个角上用三个法线而不只是一个.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: