WPF 的 Newton 游戏动力学扩展(第 2 部分)- 使用 Blender 和 3D Xaml 编辑器基础建模






4.93/5 (12投票s)
使用 Blender 创建 WPF 场景,并导出到 3D Xaml 编辑器进行微调。
- 下载 The_WPF_Project 1.98 MB (仅源代码,无二进制文件 (包含 newton.dll))
- 下载二进制文件 - 1.14 MB (仅 Xaml 编辑器的二进制文件 (Blender 示例和 Xaml-Exporter 脚本),Moon Lander 游戏和 Simple Example App)
有了这个,你就可以… 10 秒概览
- 使用一个很棒的 3D 建模软件 Blender 为 WPF 创建 3D 场景…
- 在实时 3D 物理环境中玩转模型…
- 编写你一直秘密想要写的下一代 Amazing World Game…
- 把你的麦片和牛奶洒在键盘上,看看这有多容易…
参考文献
- Newton Game Dynamics (1.53) (http://www.newtondynamics.com/) (Newton 2 仍处于受控的 Beta 测试中)
- 我在 Code Plex 上找到的 Newton 的 C# 包装器 (但我找不到网站源了)
在我使用它的过程中,它已经被修正和测试过了。如果您想用 C# 编写原生的 Newton 应用,请随意使用它。 - Blender (2.46),一个免费的 3D 建模和动画软件。 (www.blender.org)
- Blender 到 XAML 的转换器 Python 脚本 (xaml_export.py) (http://codeplex.com/xamlexporter)
我修改了脚本,将空的 (无网格数据) 场景节点导出为 ModelVisual3D 元素。 (包含在此项目中) - Windows Presentation Foundation 的 3D 工具 (http://www.codeplex.com/3DTools)
我从那里“偷”了 MathUils 库的矩阵。 - Chris Cavanagh 以一种非常巧妙的方式使用 Newton (http://chriscavanagh.wordpress.com/2006/10/23/wpf-2d-physics)
- Josh Smith 的拖拽 Canvas 示例 (DraggingElementsInCanvas.aspx)
- 我正在使用 Sharp Develop 项目的源代码编辑器。 (http://www.icsharpcode.net/OpenSource/SD/
要求
Visual Studio 2008 (用于编译项目).Net framework 3.0 (用于查看演示)
计划发表的文章
第一部分 - 基本概念和 Moon Lander 游戏详解。第二部分 - 使用 Blender 进行建模,并使用 Xml 编辑器调整模型的 Xaml 以实现物理效果。 (本文)
*第三部分 - 更高级的导出示例,逐步构建 Moon Lander 对象。
*第四部分 - 更多关于起重机项目的内容。(仅使用 Xaml 创建机械臂。无需编码!)
* - 尚未撰写。
项目内容
项目源代码包中还有更多内容,例如更新的 Moon Lander 游戏以及 Xaml 编辑器使用的所有库,但这是与本文相关的精选内容列表。项目 | 在源代码包中的位置 |
---|---|
Xaml 编辑器 | /XamlEditor |
Blender 脚本 | /Blender |
Blender 示例 | /Examples/Blender Exporting/Basic_Export1 /Examples/Blender Exporting/Stacked_Item |
引言
在我为 Newton Dynamics Extensions 系列撰写的首篇文章中,我涵盖了 Newton 库在 Xaml 标记中的基本用法,但在进一步探索之前,您需要创建更复杂的模型。创建精美模型最简单的方法是使用专业的 3D 建模工具,例如 Blender。
现在,仅仅将 Blender 中的 3D 场景导出到 Xaml 中的 Viewport3D
场景会有一个问题,那就是您几乎总会想要在输出文件中更改或添加额外信息,以便在应用程序中使用。但是,当您回到模型进行更改然后重新导出时会发生什么?您将丢失所有更改。(厄运的毛绒兔子…对吧?) 对。
这时 Xaml 编辑器就派上用场了。它允许您有一个源文件,打开它,查看您的模型树,指定一些要更改的信息,并将这些信息与源文件分开。在这种情况下,在一个 ".xaml-project" 文件中,所以当您稍后重新加载时,您的更改将再次应用。
本文将涵盖此过程的基础知识。我不会深入讲解 Blender 建模,因为互联网上有很多教程涵盖这方面内容。我将讲解您在 Blender 中需要做些什么来创建一个用户友好的模型。
WPF 目前还不够快,无法成为一个功能齐全的游戏引擎,它甚至不支持所有那些很酷的 Direct-X 功能,但是它绝对有一个可以轻松学习和实验想法的场所,然后您就可以开始编写您一直想写的那个很棒的游戏了。这个项目可以轻松地在 Blender 中构建模型并进行玩耍。
Blender
3D 应用程序 Blender 被用作对象建模器。该项目包含“Blender 到 XAML 导出器”,经过特别修改,以便更容易地在 Blender 中构建模型,并允许通过 (Xml 编辑器) 进行修改,以包含 Newton 标记扩展。安装 Xaml 导出器
![]() |
要将 Xaml 导出器脚本安装到 Blender 中 将 (source)/Blender/xaml_export.py 文件复制到 (Program Files)/Blender/.blender/scripts 文件夹,然后重新启动 Blender。 然后,您应该会在 File > Export 菜单中看到 "Xaml (.xaml) (Empty Mesh ...)" 菜单项。 |
兴趣点
- 如果您想学习如何使用 Blender,请访问 www.blender.org - Tutorials 网站。它确实是一个非常酷的产品。它对传统的 GUI 交互有一些有趣的转折,直到您看完他们的教程,这些可能一开始并不明显。
- 我刚开始的时候非常挣扎,但是如果您喜欢 GUI 设计,看到一个不同的视角会很好。Blender 具有一些有趣的 UI 交互功能和行为。
- 嘿,它是免费的,并且值得您花时间。
Xaml 编辑器
一个 3D 编辑器。该编辑器并非真正的设计器,而是一个操纵器。它允许您探索导出的 Xaml 文件,并提供 3D Gizmo 操纵器来更改您将添加到模型的 Newton 物理属性。它接受一个源 Xaml 文件,并允许您对其进行微调(通常是添加 Newton 扩展 Xaml 标记,但任何标记的添加也可以完成)。然后您可以实时玩转模型。(这是有趣的部分 :-)) 然后您可以将结果保存到应用程序中使用,将原始源和更改分开,让您可以回到您的 3D 软件,进行更改,然后将模型重新加载到您的 WPF 应用程序中。
兴趣点
- 加载任何 Xaml 文件。
- 当源文件更改时,它会自动重新加载源文件并更新所有视图。 当您在 Blender 中更新模型时,这非常方便。您将立即看到更改。
- 您可以以树状视图的形式浏览 Xaml 场景,并在下方的 xml 编辑器中进行更改,以便合并到最终输出中。
- 可以使用鼠标查看和导航 Xaml 场景。如果对象附加了物理属性,您将能够使用覆盖在模型上的 Gizmo 来更改它们。然后,这些更改将被保存回 ".xaml-project" 文件中经过微调的信息。
- 我正在使用 SharpDevelop 项目的“Source Editor Control”用于我的语法高亮编辑器。您可以查看我的代码,了解如何在自己的项目中使用该编辑器。
- 该编辑器还使用我编写的一个新的
MouseGesture
类来处理 **鼠标移动** 和 **鼠标抬起** 按钮消息。默认的 WPF 类仅处理 鼠标按下 消息。摄像机移动通过 WPFCommandBindings
控制,因此您可以轻松更改用于导航的 UI/键盘组合,而无需重新编译应用程序。(请参见 Themes 文件夹)
Blender 和 Xaml:完美的结合
用于此示例的文件可以在 (source)/Examples/Blender Exporting/Basic_Export1 文件夹中找到。
如果您打开 BasicScene.blend.xaml-project 文件,物理夹具已经完成,场景也已修正。您可以加载它并玩转模拟模型。
如果您更大胆,可以打开源文件 BasicScene.blend.xaml 并按照接下来的示例进行操作。
一些截图
通过查看 2 张截图,您可以看到一个简单的场景,其中包含 3 个立方体。上面的两个立方体被父级化到中间的立方体,并放置在其父体的上方和后方。
前正交视图

相机视图
此视图来自场景的相机。导出时,您看到的相机视图将被导出。(请参见下一张截图)

在 Xaml 编辑器中查看的场景
如果您点击场景并拖动鼠标,您可以围绕场景导航。尝试在拖动时按住 Ctrl 或 Alt 键。

场景节点探索
树状视图已展开,显示了相机、主视觉、其子对象和光源。

初览
Xaml 导出器将整个场景导出为 Viewport3D
类,导出场景相机、灯光和模型对象及其所有变换。
导出场景对象时,它会将所有顶级/根对象导出为 ModelVisual3D
对象。几何体将被导出为 Model3DGroup
,并且默认情况下子对象将作为 Model3DGroup
对象导出到主视觉的 Model3DGroup
下。(在下一篇文章中,您将看到如何也将子对象导出为 Visuals)。
注意
您现有的任何 Viewport3D
Xaml 文件也可以在编辑器中打开,但可能会遇到一些问题。目前,该编辑器仅通过 Blender 导出的文件数据进行了测试。
Blender 中的“Outliner”视图
Outliner 视图以漂亮的树状视图给出了您所有的场景节点,类似于 Xaml 编辑器,您将主要使用此视图来选择对象,然后再操纵它们。
![]() |
|
XZY -> XYZ 变换顺序问题。

就在您认为一切都变得如此容易,并且哈哈哈哈,“3D 图形,我拥有它们”时,出现了一个障碍,嗯,也不是完全是障碍。
也许更像是一个……牙签。
如果您查看 Blender 中的“3D 视图”,您会注意到视图左下角的变换顺序图标。请注意 Z (蓝色) 和 X (红色) 表示 Blender 使用X 作为其左右变换轴,而Z 作为其上下变换轴。然而,WPF 使用X 作为左右,Y 作为上下,Z 作为前后变换轴。这会导致场景导入 Xaml 编辑器(或任何 WPF 应用程序)时,会在X 轴上旋转 +90 度。这个小小的“陷阱”将在下一节中进行探讨,当您将 Viewport3D
场景转换为 ModelVisual3D
场景时。
清理导入的场景。
好的,那么您如何导入一个原始场景并且它看起来不错。除了 3D 视图中有点奇怪的蓝色色调,似乎将场景一分为二。那是什么意思?(我的意思是蓝色是一种漂亮的颜色,但是当您编写您的“Cubes Of Death”游戏时,您可能想要一个红色调的场景。)
蓝色色调来自 Xaml 编辑器默认添加到场景的 Terrain。您正透过它,从其半透明的底部观看。然而,场景已导出并带有其奇怪的轴问题。(要移除地形,您可以选择 Dynamics > Terrain 菜单项。)
目前,您可以移动相机,一切看起来仍然正常。这是因为相机也已导出并带有奇怪的变换,因此场景的变换和相机的变换相互抵消了问题。
您 Xaml 模型的下一个演变步骤是将场景从 Viewport3D
元素转换为 ModelVisual3D
元素,然后可以将其动态加载到您应用程序的场景中。为此,请选择Edit > Remove Viewport 菜单项。如果您查看下一张截图并将其与 Blender 的相机视图进行比较,就会发现转换问题,因为视口的相机被 Xaml 编辑器添加的默认(正常 X,Y,Z 变换)场景相机所取代。请注意模型是如何被旋转的。
移除 Viewport 后的场景
截图是在缩回相机并稍微旋转以显示对象方向后拍摄的。
请注意,模型现在已旋转 90 度。您现在也可以看到 Terrain 看起来更像 Terrain 了。
注意: 默认情况下,Terrain 定位在 0,0,0 处(正好在您的模型的中心),但是一旦物理连接建立,它会自动进行调整。

Xml 视图显示您的项目现在是 ModelVisual3D
场景,而不是 Viewport3D
。请注意,相机已被移除,因为它属于viewport,但光源仍被保留。常规做法是删除 Blender 场景中的灯光,因为您的应用程序场景将拥有独立于模型的灯光设置,但是您可能希望有一个带有父级化到对象本身的灯光的模型,这也很容易做到。无论如何,Xaml 编辑器将在场景不包含任何灯光时管理默认灯光。

现在,要纠正旋转问题,编辑器项目中有一个名为 "Model Rotation" 的属性,您只需将其设置为 "1,0,0: -90",它会将根元素下的所有顶级 ModelVisual3D
元素沿 X 轴旋转 -90 度。
注意: 这本可以只应用于根元素,但我希望根元素在导出时不受任何变换影响,因为它可能会附加到程序中的某些内容,并且可以简化处理模型 Transform
需要包含 Transform3DGroup
的任务。

为您的 Glory Cubes (或者曾经的 *Death* Cubes)注入生命
模型虽然令人印象深刻,但它静止不动,“毫无生命”。就像一只死鹦鹉。(如果我的晦涩引用太晦涩,请在 YouTube 上搜索“Monty Python Dead Parrot”。)
调整 Xaml
在我之前的文章 Newton Dynamics Game Dynamics - The Moon Lander Game 中,您已经看到了用于 Newton 附加属性的 Xaml,这些属性被添加到视口场景中,以赋予 Visual 以物理属性。
<ModelVisual3D newton:World.Body="ConvexBody3D">
<ModelVisual3D.Content>
<GeometryModel3D>
...
<ModelVisual3D />
正如您将看到的,这同样的效果将在 Xaml 编辑器中实现,但不是通过进入源代码,而是通过配置对您希望合并附加属性到现有 Xaml 的 Xaml 元素的更改。
在 “Xml” 选项卡中,选择根元素下的第一个模型视觉元素,然后选择 Dynamics > Xml > Add Body Node 菜单项。查看屏幕底部的 Xaml。

请注意,它已从 <current></current>
更改为您在屏幕截图中看到的内容。<current>
元素是一个伪元素。它通过将定义在 <current>
元素内的任何元素附加到源元素,或者将定义在 <current>
元素上的任何属性合并到源元素的属性中,来修改最终输出(在“View”选项卡中查看)。
<ModelVisual3D>
<ModelVisual3D.Content>
...
<ModelVisual3D />
以下 Xaml 调整<current>
<newton:World.Body>
<newton:ConvexBody3D Mass="1" />
</newton:World.Body>
</current>
或<current newton:World.Body="ConvexBody3D">
<current />
将导致<ModelVisual3D>
<newton:World.Body>
<newton:ConvexBody3D Mass="1" />
</newton:World.Body>
<ModelVisual3D /;>
或<ModelVisual3D newton:World.Body="ConvexBody3D">
<ModelVisual3D.Content>
...
<ModelVisual3D />
被应用于最终输出。3D 视图显示最终输出,所以您所见即所得。“物理,你拥有它们”
好了!物理已经添加(很简单,对吧?对。)
如果您现在返回 “View” 选项卡,您会看到 Terrain 已向下移动,并且 Cubes 已被华丽的线框图和时髦的黄色质心 Gizmo(就在模型中心)所装饰。
所有这些 Gizmo 闪光或装饰都是物理属性被设计器拾取的结果。去模拟!!

要开始模拟,请选择Dynamics > Start/Stop Simulation 菜单项。
您可以点击模型上的任意位置,使用Pick Force Gizmo 来拖动它。

![]() |
要调整对象的“质心”,请点击对象中心的小黄色立方体,在点击时不要移动鼠标。当您松开按钮时,您会看到一个 Gizmo 允许您移动“质心”。点击箭头来移动对象。无论模拟是否打开,您都可以移动质心。看到物体对新的质量动力学做出反应非常酷。 |
要重置模型,请转到 “Xml” 选项卡,然后返回 “View” 选项卡。
结论
好吧,好吧,我们还没完成,但一篇文章的长度有限,我还需要美容觉。我年纪大了,越来越需要它。相信我,下一篇文章不会花这么长时间才能发表。嗯,你知道的……一旦我删除了所有被版主命令删除的脏话。说真的。Cubes……有时候需要脏话来形容它们。
我讨论了 Blender 导出的*基础*以及您需要注意的问题。我还简单介绍了调整的可能性。还有其他重要的场景,例如为更好的合并命名您的元素,以及导出到 <class>.xaml 文件以供您的 WPF 应用程序使用。这就是我为 Moon Lander 游戏所做的。
显然,罗马不是一天建成的,所以直到下一篇文章,它将从本文结束的地方继续。
历史
- 2008-08-25 - 初次发布。(已删除脏话)
- 2008-08-27 - 修复了许多可怕的错别字。我真是太特别了。