Forráskód Böngészése

Remove zh-Hans-CN folder.

jmecn 7 éve
szülő
commit
186baaf432
100 módosított fájl, 0 hozzáadás és 20419 törlés
  1. 0 112
      src/docs/asciidoc/zh-Hans-CN/documentation.adoc
  2. 0 0
      src/docs/asciidoc/zh-Hans-CN/faq.adoc
  3. 0 333
      src/docs/asciidoc/zh-Hans-CN/jme3.adoc
  4. 0 1
      src/docs/asciidoc/zh-Hans-CN/jme3/about.adoc
  5. 0 19
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/ai/ai.adoc
  6. 0 160
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/ai/building_recast.adoc
  7. 0 840
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/ai/jme3_ai.adoc
  8. 0 281
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/ai/recast.adoc
  9. 0 188
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/android.adoc
  10. 0 383
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/animation/animation.adoc
  11. 0 290
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/animation/cinematics.adoc
  12. 0 98
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/animation/motionpath.adoc
  13. 0 96
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/3d_models.adoc
  14. 0 301
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/asset_manager.adoc
  15. 0 441
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/external/3dsmax.adoc
  16. 0 254
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/external/blender-example.adoc
  17. 0 444
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/external/blender.adoc
  18. 0 67
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/external/fonts.adoc
  19. 0 49
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/external/makehuman.adoc
  20. 0 142
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/free_skymaps.adoc
  21. 0 88
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/makehuman_blender_ogrexml_toolchain.adoc
  22. 0 374
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/mixamo.adoc
  23. 0 61
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/ogrecompatibility.adoc
  24. 0 61
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/sky.adoc
  25. 0 273
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/atom_framework.adoc
  26. 0 336
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/audio/audio.adoc
  27. 0 277
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/audio/audio_environment_presets.adoc
  28. 0 7
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/audio/overview.adoc
  29. 0 575
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/capture_audio_video_to_a_file.adoc
  30. 0 193
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/collision/collision_and_intersection.adoc
  31. 0 304
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/debug_and_test/debugging.adoc
  32. 0 95
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/debug_and_test/logging.adoc
  33. 0 328
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/game_logic/application_states.adoc
  34. 0 410
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/game_logic/appstatesdemo.adoc
  35. 0 329
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/game_logic/custom_controls.adoc
  36. 0 64
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/game_logic/headless_server.adoc
  37. 0 154
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/game_logic/making_the_camera_follow_a_character.adoc
  38. 0 55
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/game_logic/remote-controlling_the_camera.adoc
  39. 0 45
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/game_logic/update_loop.adoc
  40. 0 174
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/graphics_pipeline/camera.adoc
  41. 0 361
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/graphics_pipeline/custom_meshes.adoc
  42. 0 29
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/graphics_pipeline/jme3_renderbuckets.adoc
  43. 0 213
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/graphics_pipeline/jme3_srgbpipeline.adoc
  44. 0 219
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/graphics_pipeline/multiple_camera_views.adoc
  45. 0 7
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/graphics_pipeline/overview.adoc
  46. 0 82
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/graphics_pipeline/read_graphic_card_capabilites.adoc
  47. 0 173
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/hud.adoc
  48. 0 618
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/loading_screen.adoc
  49. 0 113
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui.adoc
  50. 0 91
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui_best_practices.adoc
  51. 0 83
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui_editor.adoc
  52. 0 323
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui_java_interaction.adoc
  53. 0 572
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui_java_layout.adoc
  54. 0 82
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui_overlay.adoc
  55. 0 93
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui_popup_menu.adoc
  56. 0 79
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui_projection.adoc
  57. 0 299
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui_scenarios.adoc
  58. 0 387
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui_xml_layout.adoc
  59. 0 219
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/input/combo_moves.adoc
  60. 0 332
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/input/input_handling.adoc
  61. 0 119
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/input/mouse_picking.adoc
  62. 0 459
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/input/walking_character.adoc
  63. 0 153
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/io/save_and_load.adoc
  64. 0 293
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/light_and_shadow/light_and_shadow.adoc
  65. 0 7
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/light_and_shadow/overview.adoc
  66. 0 154
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/localization.adoc
  67. 0 346
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/material/j3m_material_files.adoc
  68. 0 158
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/material/material_definitions.adoc
  69. 0 303
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/material/material_specification.adoc
  70. 0 422
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/material/materials_overview.adoc
  71. 0 128
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/material/pbr_part1.adoc
  72. 0 172
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/material/pbr_part2.adoc
  73. 0 189
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/material/pbr_part3.adoc
  74. 0 802
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/math/math.adoc
  75. 0 25
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/math/math_for_dummies.adoc
  76. 0 24
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/math/math_video_tutorials.adoc
  77. 0 165
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/math/matrix.adoc
  78. 0 143
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/math/quaternion.adoc
  79. 0 173
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/math/rotate.adoc
  80. 0 0
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/math/vectors.adoc
  81. 0 211
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/multithread/multithreading.adoc
  82. 0 497
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/networking/networking.adoc
  83. 0 20
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/networking/networking_video_tutorials.adoc
  84. 0 63
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/networking/spidermonkey.adoc
  85. 0 57
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/physics/bullet_multithreading.adoc
  86. 0 34
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/physics/bullet_pitfalls.adoc
  87. 0 162
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/physics/hinges_and_joints.adoc
  88. 0 207
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/physics/physics_listeners.adoc
  89. 0 177
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/physics/ragdoll.adoc
  90. 0 286
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/physics/softbody.adoc
  91. 0 285
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/physics/vehicles.adoc
  92. 0 173
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/scenegraph/level_of_detail.adoc
  93. 0 166
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/scenegraph/mesh.adoc
  94. 0 190
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/scenegraph/shape.adoc
  95. 0 220
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/scenegraph/spatial.adoc
  96. 0 71
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/scenegraph/traverse_scenegraph.adoc
  97. 0 24
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/screenshots.adoc
  98. 0 82
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/script/groovy/ai.adoc
  99. 0 53
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/script/groovy_basicscripts.adoc
  100. 0 129
      src/docs/asciidoc/zh-Hans-CN/jme3/advanced/script/groovy_event.adoc

+ 0 - 112
src/docs/asciidoc/zh-Hans-CN/documentation.adoc

@@ -1,112 +0,0 @@
-= jMonkeyEngine 说明文档
-:author: yanmaoyuan
-:revnumber: 1.0
-:revdate: 2018/01/15 16:41
-:imagesdir: ../
-:keywords: documentation, sdk, install
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-本wiki页面包含jME3的安装和配置指南、jME3编程教程以及其他一些能够帮助你开发游戏项目的资料,请善用本页右上方的搜索框来检索整个wiki中的内容。
-
-TIP: This is an Admonition. You will see many of these scattered throughout the Wiki. See the <<wiki/admonitions#,Admonition Definitions>> for the meaning of this and all the other Admonitions.
-
-== 下载和安装
-
-*在安装之前,请查阅<<bsd_license#,许可证>>、<<jme3/features#,jME3功能说明>>和<<install/requirements#,开发需求>>,* 然后选择其中一个选项:
-[cols="4", options="header"]
-|===
-
-a|
-<a| 推荐
-<a| 可选
-<a| 可选
-
-a| 你打算…
-a| 使用jMonkeyEngine SDK开发
-a| 在其他的IDE中使用jMonkeyEngine
-a| 利用源码来编译自定义引擎
-
-a| 请下载…
-a| link:https://github.com/jMonkeyEngine/sdk/releases/tag/stable[jMonkeyEngine SDK]
-a| link:https://github.com/jMonkeyEngine/sdk/releases[Binaries]
-a| link:https://github.com/jMonkeyEngine/jmonkeyengine[Sources]
-
-a| 你会得到…
-a| Sources, binaries, javadoc, SDK
-a| Latest stable binary build, sources, javadoc.
-a| Sources
-
-a| 更多学习内容…
-a| * <<sdk/index#,学习使用SDK>> +
-* <<sdk/create_project#,使用SDK创建工程>> +
-
-a| 在下列环境中集成JME3: +
-
-* <<getting-start/gradle#,Gradle>> +
-* <<getting-start/maven#,Maven>> +
-* <<getting-start/netbeans#,NetBeans>> +
-* <<getting-start/eclipse#, Eclipse>> +
-* <<getting-start/android_studio#,Android Studio>> +
-* <<getting-start/intellij_idea#,Intellij IDEA>>
-a| * <<install/build_from_sources#,编译JME3源码>> +
-* <<jme3/build_jme3_sources_with_netbeans#,在NetBeans中编译JME3源码>> +
-* <<jme3/simpleapplication_from_the_commandline#,在(Linux)命令行下开发JME3>>
-
-|===
-
-(*) jME SDK创建的是基于Ant的项目,任何Java IDE都可以导入。我们建议其他IDE的用户也下载jME SDK,并选择 “File→Import Project→External Project Assets 来创建一个不包含任何代码的资源项目,用以管理项目中的资源文件(如模型、材质、贴图等)。这样您就可以在自己选择的IDE中编码,并利用jME SDK来将您的模型转换成.j3o格式。
-
-
-== 创建jME工程
-
-下载安装jME之后,请把这个<<jme3,jME教程>>加入您的书签,然后动手开发您的第一个游戏吧!
-[cols="3", options="header"]
-|===
-
-a| 教程
-a| jMonkeyEngine SDK
-a| 其他文档
-
-a| <<jme3/beginners/index#,jME3初级教程>>
-a| <<sdk/index#,jMonkeyEngine SDK 文档和视频教程>>
-a| link:http://javadoc.jmonkeyengine.org/[Full API JavaDoc]
-
-a| <<jme3/advanced/index#,jME3中级教程>>
-a| <<sdk/comic#,jMonkeyEngine SDK - 漫画 :-)>>
-a| <<jme3/external/blender#,Blender建模指南>>
-
-a| <<jme3/senior/index#,jME3进阶教程>>
-<a|
-a| <<jme3/faq#,FAQ>>
-
-|===
-
-
-== 贡献代码
-
-想给jME3贡献新的特性和功能吗?如果你是一名熟练的Java开发者,请看下列页面:
-
-*  了解已有的<<jme3/contributions#,贡献>>
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/CONTRIBUTING.md[阅读贡献者手册]
-*  link:https://github.com/jMonkeyEngine/wiki[成为维基编辑者]
-*  link:http://hub.jmonkeyengine.org/c/contribution-depot-jme3[加入官方社区的讨论]
-*  <<jme3/jme3_source_structure#,学习jME3源码架构>>
-*  <<sdk#development,开发jME SDK插件以及可视化编辑器>>
-*  <<report_bugs#,报告bug &amp; 提交补丁>>
-
-== 联系我们
-
-欢迎您的贡献和咨询:请联系 link:https://hub.jmonkeyengine.org/badges/103/core-developer[开发者],或者在 link:http://hub.jmonkeyengine.org/[官方论坛]发帖提问。
-
-* link:https://hub.jmonkeyengine.org/badges/103/core-developer[联系JME3开发团队]
-**  <<team#,[核心团队 - 我们是谁?]>>
-
-*  <<report_bugs#,报告BUG>>
-*  link:http://hub.jmonkeyengine.org/c/documentation-jme3[发现文档内容含糊或文档不存在]
-
-== 中文开发者讨论群
-
-本群不是jME的官方QQ群,而是由一群国内的jME爱好者聚集的讨论群,欢迎加入讨论,群号:423979787。
-
-中文网站: http://www.jmecn.net/

+ 0 - 0
src/docs/asciidoc/zh-Hans-CN/faq.adoc


+ 0 - 333
src/docs/asciidoc/zh-Hans-CN/jme3.adoc

@@ -1,333 +0,0 @@
-= jMonkeyEngine 教程 & 文档
-:author: (翻译 jmecn)
-:revnumber:
-:revdate: 2016/03/17 20:48
-:keywords: documentation, intro, intermediate, about
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== 初级教程
-
-初级教程将介绍一些常见的游戏开发实例,并解释一些基本概念。在正式学习前,请确认自己是否了解<<jme3/terminology#,3D游戏开发的一些基本概念>>,例如<<jme3/the_scene_graph#,场景图>>。如果你不太了解的话,建议先学习“<<jme3/math_for_dummies#,3D数学基础知识>>”以及“<<jme3/scenegraph_for_dummies#,3D场景图的基本概念>>”。
-
-link:https://github.com/jMonkeyEngine/jmonkeyengine/tree/master/jme3-examples/src/main/java/jme3test[所有示例代码]均已包含在jMonkeyEngine SDK中(yan:通过github搜索jMonkeyEngine也能找到源码),你只需要在创建工程时选择`JmeTests`模板,即可查阅这些代码。如果你要自己开发游戏的话,建议在创建工程时选择`BasicGame`模板。
-
-建议读者在学习的过程中把所有的示例代码都编写运行一遍,并且尝试着去修改这些代码,有助于加深对本教程的理解。
-
-
-[IMPORTANT]
-====
- * 使用<<sdk#,jMonkeyEngine SDK>>开发项目时,按F1键可以搜索并浏览本wiki的一份副本,帮助文档的内容与你所使用的SDK版本同步。本wiki随link:https://github.com/jMonkeyEngine/jmonkeyengine[jME3最新版本]同步更新。*
-====
-
-
-
-image::jme3/beginner/beginner-physics.png[beginner-physics.png,with="360",height="291",align="right"]
-
-
-.  <<jme3/beginner/hello_simpleapplication_zh#,第一个JME3程序>> – 实现一个简单的程序
-..  <<jme3/beginner/hello_node_zh#,节点(Node)>> – 在场景图中改变几何体和节点属性
-..  <<jme3/beginner/hello_asset_zh#,资源(Assets)>> – 加载三维模型、场景和其他的资源
-..  <<jme3/beginner/hello_main_event_loop_zh#,事件循环(Loop)>> – 在事件循环中实现事件控制功能
-..  <<jme3/beginner/hello_input_system_zh#,输入(Input)>> – 对于键盘和鼠标的输入作出响应
-..  <<jme3/beginner/hello_material_zh#,材质(Material)>> – 设置材质、纹理、透明度
-..  <<jme3/beginner/hello_animation_zh#,动画(Animation)>> – 控制动画模型
-..  <<jme3/beginner/hello_picking_zh#,拣选(Picking)>> – 射击、压下按钮、选择、捡起选项
-..  <<jme3/beginner/hello_collision_zh#,碰撞(Collision)>> – 建造墙壁和固体地板
-..  <<jme3/beginner/hello_terrain_zh#,地形(Terrain)>> – 使用贴图创建小山的风景
-..  <<jme3/beginner/hello_audio_zh#,音效(Audio)>> – 按照位置和事件来实现三维音效
-..  <<jme3/beginner/hello_effects_zh#,特效(Effects)>> – 创建粒子特效,比如:火焰、爆炸、魔法
-..  <<jme3/beginner/hello_physics_zh#,物理(Physics)>> – 撞球和坠落的砖头
-..  <<jme3/beginner/hello_vector_zh#,向量(Vector)>> – 可视化向量与向量操作
-..  <<jme3/beginner/hello_chase_camera_zh#,摄像机(Camera)>> – aka的第三人称摄像机示例代码
-
-See also: <<sdk/sample_code#,运行示例代码遇到了问题吗>>?
-
-For more help getting started, check out this tuts+ guide on “link:http://gamedevelopment.tutsplus.com/articles/how-to-learn-jmonkeyengine-3--gamedev-10479[ How to learn jMonkeyEngine 3].
-
-
-== 中级教程
-
-学初级教程后,你已经了解了所有的基本概念,是时候把它们综合起来了。下面这些文章可以帮助你理解如何在实践开发中综合应用这些知识。
-
-*jMonkeyEngine3 概念*
-
-*  <<jme3/intermediate/best_practices#,最佳实践>>
-*  <<jme3/intermediate/simpleapplication#,深入SimpleApplication类>>
-*  <<jme3/intermediate/appsettings#,jME3显示配置>>
-*  <<jme3/intermediate/file_types#,文件类型>>
-*  <<jme3/intermediate/optimization#,优化>>
-*  <<jme3/faq#,常见问题解答(FAQ)>>
-
-*数学概念*
-
-*  <<jme3/math_for_dummies#,jME3数学基础>>
-*  <<jme3/intermediate/math#,Short 3D math &quot;cheat sheet&quot;>>
-*  <<jme3/math#,jME3数学概述>>
-*  <<jme3/math_video_tutorials#,视频: jME3数学系列教程>>
-
-*3D图形学概念*
-
-*  <<jme3/intermediate/multi-media_asset_pipeline#,多媒体资源管道>>
-*  <<jme3/scenegraph_for_dummies#,3D场景图的基本概念>>
-*  <<jme3/terminology#,3D图形学术语>>
-*  <<jme3/intermediate/how_to_use_materials#,如何使用材质>>
-*  <<jme3/intermediate/transparency_sorting#,透明度排序>>
-*  <<jme3/external/blender#,使用Blender创建兼容jME3的模型>>
-*  <<jme3/external/3dsmax#,使用3dsmax创建兼容jME3的模型>>
-
-*游戏教程*
-
-*  link:http://gamedevelopment.tutsplus.com/series/cross-platform-vector-shooter-jmonkeyengine--gamedev-13757[Neon Vector Shooter tutorial on Tuts+]
-
-*视频实例教程*
-- 注意:以下视频中使用了jME 3.1 alpha 版的一些特性
-
-*  link:http://www.youtube.com/watch?v=-OzRZscLlHY[Video: jMonkeyEngine SDK Use Case Demo 1 (Quixote)]
-*  link:http://www.youtube.com/watch?v=6-YWxD3JByE[Video: jMonkeyEngine SDK Use Case Demo 2 (Models and Materials)]
-
-Learn from sample code in link:https://github.com/jMonkeyEngine/jmonkeyengine/tree/master/jme3-examples/src/main/java/jme3test[src/main/java/jme3test] (also available in the sdk by File &gt; New Project &gt; JME3 Tests) and the example games provided by the community!
-
-
-== 进阶教程
-
-现在你已经学会了所有的概念,是时候学习jMonkeyEngine的全部内容了!深入到API中去了解所有的选项,包括那些不太常用的高级方法。但是不要过度延长自己,开发游戏需要时间和奉献精神,一步一个脚印,战士! :)
-
-*控制游戏逻辑*
-
-*  <<jme3/advanced/update_loop#,主循环>>
-*  <<jme3/advanced/application_states#,AppStates>>
-*  <<jme3/advanced/custom_controls#,自定义Control>>
-**  link:http://www.youtube.com/watch?v=MNDiZ9YHIpM[Video: How to control any scene node]
-**  link:http://www.youtube.com/watch?v=-OzRZscLlHY[Video: How to remote control a character in a scene]
-
-*  <<jme3/advanced/multithreading#,多线程>>
-
-*管理3D场景图中的对象*
-
-*  <<jme3/advanced/traverse_scenegraph#,遍历场景图>>
-*  <<jme3/advanced/spatial#,Spatial: Node与Geometry的对比>>
-*  <<jme3/advanced/mesh#,网格>>
-**  <<jme3/advanced/shape#,形状>>
-**  <<jme3/advanced/3d_models#,3D模型>>
-**  <<jme3/advanced/custom_meshes#,自定义网格>>
-
-*  <<jme3/advanced/asset_manager#,资源管理器>>
-*  <<jme3/advanced/save_and_load#,读写节点数据(.J3O文件)>>
-*  <<jme3/advanced/collision_and_intersection#,碰撞与交点>>
-*  <<jme3/advanced/level_of_detail#,层次细节(LOD)>>
-
-*动画和场景*
-
-*  <<jme3/advanced/animation#,Animation>>
-*  <<jme3/advanced/cinematics#,Cinematics (cutscenes, fake destruction physics)>>
-*  <<jme3/advanced/motionpath#,MotionPaths and waypoints>>
-*  <<jme3/external/blender#,Creating jME3 compatible 3D models in Blender>>
-*  <<jme3/advanced/makehuman_blender_ogrexml_toolchain#,MakeHuman Blender OgreXML toolchain for creating and importing animated human characters>>
-*  <<sdk/blender#,Converting Blender Models to JME3 (.J3o files)>>
-**  link:https://www.youtube.com/watch?v=QiLCs4AKh28[Video: Import animated models from Blender 2.6 to JME3]
-**  link:http://www.youtube.com/watch?v=NdjC9sCRV0s[Video: Creating and Exporting OgreXML Animations from Blender 2.61 to JME3]
-**  link:https://docs.google.com/fileview?id=0B9hhZie2D-fENDBlZDU5MzgtNzlkYi00YmQzLTliNTQtNzZhYTJhYjEzNWNk&hl=en[Scene Workflow:]
-
-
-Create jme3 compatible racing tracks in blender
-* link:http://www.youtube.com/watch?v=3481ueuDJwQ&feature=youtu.be[Video: Create jme3 compatible models in blender]
-
-Exporting OgreXML scenes from Blender to JME3
-
-*  link:https://docs.google.com/leaf?id=0B9hhZie2D-fEYmRkMTYwN2YtMzQ0My00NTM4LThhOTYtZTk1MTRlYTNjYTc3&hl=en[Animation Workflow: Create Animated UV-Mapped OgreXML Models in Blender, and use them in JME3]
-**  link:http://www.youtube.com/watch?v=IDHMWsu_PqA[Video: Creating Worlds with Instances in Blender]
-**  <<jme3/advanced/ogrecompatibility#,OgreCompatibility>>
-
-*材质、光影*
-
-*  <<jme3/intermediate/how_to_use_materials#,How to Use Materials>>
-*  <<jme3/advanced/j3m_material_files#,Creating .j3m Materials>>
-*  <<jme3/advanced/material_definitions#,How to Use Material Definitions (.j3md)>>
-*  <<jme3/advanced/materials_overview#,All Material Definition Properties>>
-*  <<jme3/advanced/anisotropic_filtering#,Anisotropic Filtering for Textures>>
-*  <<jme3/advanced/light_and_shadow#,Light and Shadow>>
-*  <<jme3/advanced/jme3_shaders#,About JME3 and Shaders>>
-*  <<jme3/advanced/jme3_shadernodes#,Shader Node System>>
-*  <<jme3/advanced/jme3_srgbpipeline#,Gamma correction or sRGB pipeline>>
-*  <<jme3/shader_video_tutorials#,Videos: jME3 introduction to shaders video tutorial series>>
-*  link:http://www.youtube.com/watch?v=IuEMUFwdheE[Video: jME3 Material with Alpha Channel]
-
-*物理集成*
-
-*  <<jme3/advanced/physics#,Physics: Gravity, Collisions, Forces>>
-*  <<jme3/advanced/bullet_multithreading#,Multi-Threaded Physics>>
-*  <<jme3/advanced/physics_listeners#,Physics Listeners and Collision Detection>>
-*  <<jme3/advanced/hinges_and_joints#,Hinges and Joints>>
-*  <<jme3/advanced/walking_character#,Walking Character>>
-*  <<jme3/advanced/ragdoll#,Ragdoll>>
-*  <<jme3/advanced/vehicles#,Vehicles>>
-*  <<jme3/advanced/ray_and_sweep_tests#,Physics Rays and Sweep Tests>>
-*  link:http://www.youtube.com/watch?v=yS9a9o4WzL8[Video: Mesh Tool &amp; Physics Editor]
-
-*音频和视频*
-
-*  <<jme3/advanced/audio#,Audio: Playing Sounds>>
-*  <<jme3/advanced/audio_environment_presets#,Audio Environment Presets>>
-*  <<jme3/advanced/video#,Video: Playing Clips>>
-*  <<jme3/advanced/screenshots#,Capture Screenshots>>
-*  <<jme3/advanced/capture_audio_video_to_a_file#,Capture Audio/Video to a File>>
-
-*后置处理过滤器与特效*
-
-*  <<jme3/advanced/effects_overview#,Effects and Filters Overview>>
-*  <<jme3/advanced/bloom_and_glow#,Bloom and Glow>>
-*  <<jme3/advanced/particle_emitters#,Particle Emitters>>
-
-*地形*
-
-*  <<jme3/advanced/sky#,Sky>>
-*  <<jme3/advanced/terrain#,Terrain (TerraMonkey)>>
-*  <<jme3/advanced/endless_terraingrid#,Endless Terrain (TerrainGrid)>>
-*  <<jme3/advanced/terrain_collision#,Terrain Collision>>
-*  <<jme3/contributions/cubes#,Cubes - A Block World Framework>>
-*  <<jme3/advanced/water#,Simple Water>>
-*  <<jme3/advanced/post-processor_water#,Post-Processor Water (SeaMonkey)>>
-*  <<jme3/contributions/vegetationsystem#,Vegetation System>>
-
-*人工智能(AI)*
-
-*  <<jme3/advanced/recast#,Recast Navigation>>
-*  <<jme3/advanced/building_recast#,Updating and building Recast Native Bindings>>
-*  <<jme3/advanced/monkey_brains#,Monkey Brains>>
-*  <<jme3/advanced/steer_behaviours#,Steer Behaviours>>
-
-*多人联网游戏*
-
-*  <<jme3/advanced/networking#,Multiplayer Networking (SpiderMonkey)>>
-*  <<jme3/advanced/headless_server#,Headless Server>>
-*  <<jme3/advanced/monkey_zone#,Monkey Zone: Multi-Player Demo Code>>
-*  <<jme3/advanced/open_game_finder#,Open Game Finder>>
-*  <<jme3/advanced/networking_video_tutorials#,Videos: jME3 networking video tutorial series>>
-
-*实体系统*
-
-*  <<jme3/contributions/entitysystem#, The Zay-ES Entity System>>
-
-*摄像机*
-
-*  <<jme3/advanced/camera#,Camera>>
-*  <<jme3/advanced/making_the_camera_follow_a_character#,Making the Camera Follow a Character>>
-*  <<jme3/advanced/remote-controlling_the_camera#,Remote-Controlling the Camera>>
-*  <<jme3/advanced/multiple_camera_views#,Multiple Camera Views>>
-
-*用户交互*
-
-*  <<jme3/advanced/input_handling#,Input Handling>>
-**  link:https://github.com/jMonkeyEngine-Contributions/Lemur/wiki/Modules[Lemur Scene Graph Tools]
-***  link:http://hub.jmonkeyengine.org/t/lemur-gems-1-inputmapper-based-camera-movement/28703[Lemur Gems #1 - Input mapper based camera movement. ]
-***  link:http://hub.jmonkeyengine.org/t/lemur-gems-2-inputmapper-delegates/28710[Lemur Gems #2 - Input mapper delegates]
-***  link:http://hub.jmonkeyengine.org/t/lemur-gems-3-scene-picking/28713[Lemur Gems #3 - Scene picking]
-
-
-*  <<jme3/advanced/combo_moves#,Combo Moves>>
-*  <<jme3/advanced/mouse_picking#,Mouse Picking: Click to Select>>
-
-*图形用户界面(+++<abbr title="Graphical User Interface">GUI</abbr>+++)*
-
-*  link:https://github.com/jMonkeyEngine-Contributions/Lemur[Lemur - a native jME3 GUI library with scene graph tools]
-*  <<jme3/contributions/tonegodgui#,tonegodGUI - a native jME3 GUI library>>
-*  <<jme3/advanced/nifty_gui#,Nifty GUI - JME3 Integration Tutorial>>
-*  <<jme3/advanced/nifty_gui_best_practices#,Nifty GUI - Best Practices>>
-*  <<jme3/advanced/nifty_gui_scenarios#,Nifty GUI Scenarios (Load Screen etc)>>
-*  <<jme3/advanced/hud#,Head-Up Display (HUD)>>
-*  <<jme3/advanced/localization#,Localization>>
-*  <<jme3/advanced/swing_canvas#,Swing Canvas>>
-
-*自定义渲染*
-
-*  <<jme3/advanced/jme3_forwardrendering#,Forward Rendering process>>
-*  <<jme3/advanced/jme3_renderbuckets#,Render Buckets>>
-
-*自定义工具*
-
-*  <<jme3/tools/navigation#,Mercator Projection Tool (Marine Navigation)>>
-*  <<jme3/tools/charts#,Visualizing Maps in JME3 (Marine Charts)>>
-*  <<jme3/advanced/atom_framework#,Atom framework. Mash-up of other plugins>>
-
-*日志与调试*
-
-*  <<jme3/advanced/logging#,Logging>>
-*  <<sdk/log_files#,Log Files>>
-*  <<jme3/advanced/read_graphic_card_capabilites#,Read Graphic Card Capabilites>>
-*  <<jme3/advanced/debugging#,Debugging with Wireframes>>
-
-*Android项目开发*
-
-*  <<jme3/advanced/android#,Android Project Cheat Sheet>>
-
-*项目部署*
-
-*  <<jme3/android#,Android>>
-*  <<sdk/application_deployment#,Application Deployment (using jMonkeyEngine SDK)>>
-*  <<jme3/webstart#,WebStart Deployment (without jMonkeyEngine SDK)>>
-
-*脚本*
-
-*  <<jme3/scripting#, Groovy 脚本语言>>
-
-*虚拟现实&amp;模拟器*
-
-*  <<jme3/virtualreality#, Virtual Reality. OpenCV &amp; JavaCV>>
-
-*jMonkey User Contributions*
-
-*  <<jme3/contributions#, Contributions - User made utilities to add functionality to the engine.>>
-
-*Sample Projects*
-
-*  <<sdk/sample_code#,JmeTests>> – The “official sample project JmeTests.
-*  link:http://code.google.com/p/jmonkeyengine/source/browse/BookSamples/#BookSamples%2Fsrc[BookSamples] – Some more jME3 code samples
-
-These code examples are not supported by the core team and we cannot guarantee their correctness:
-
-*  <<jme3/user_examples_project#,User Examples Project>> – The jME3 users examples project.
-*  <<jme3/shaderblow_project#,ShaderBlow Project>> – The jME3 users shaders project.
-*  <<jme3/rise_of_mutants_project#,Rise of Mutants Project>> – Rise of Mutants Project by BigBoots Team.
-*  <<jme3/atomixtuts#,atomixtuts>> – Atomix Tutorial Series
-*  link:http://code.google.com/p/street-rally-3d/source/browse/#svn%2Ftrunk%2Fsrc%2Fsr3d[Street rally 3d source code] – A racing game programmed by rhymez.
-
-
-== SDK Documentation
-
-
-image::sdk/jmonkeyplatform-docu-2.png[jmonkeyplatform-docu-2.png,with="420",height="300",align="right"]
-
-
-The <<sdk#,jMonkeyEngine SDK>> is our recommended game development environment.
-
-*  <<sdk/comic#,jMonkeyEngine SDK - the Comic>>
-*  <<sdk#,SDK Documentation (All editors, plugins, etc)>>
-
-Here are some videos of how the jMonkeyEngine SDK makes your development team's life easier:
-
-*  link:http://www.youtube.com/watch?v=nL7woH40i5c[Video: Importing Models]
-*  link:http://www.youtube.com/watch?v=ntPAmtsQ6eM[Video: Scene Composing]
-*  link:http://www.youtube.com/watch?v=DUmgAjiNzhY[Video: Dragging&amp;Dropping Nodes]
-*  link:http://www.youtube.com/watch?v=Feu3-mrpolc[Video: Working with Materials]
-*  link:http://www.youtube.com/watch?v=oZnssg8TBWQ[Video: WebStart Deployment]
-*  link:http://www.youtube.com/watch?v=MNDiZ9YHIpM[Video: Custom Controls]
-*  Read the <<sdk#,SDK documentation>> for details.
-
-
-== 下载和安装JME3
-
-*  <<bsd_license#,Use jMonkeyEngine 3 for free under the BSD License>>
-*  <<jme3/requirements#,Software and hardware requirements>>
-*  <<jme3/features#,All Supported Features>>
-*  <</#Installation,Download jMonkeyEngine 3 SDK>>
-
-
-== Feedback
-
-jME3 is in development; if a tutorial doesn't work as expected, try using the latest daily build. If that doesn't “fix it then:
-
-*  link:http://code.google.com/p/jmonkeyengine/issues/list?can=2&q=label:Component-Docs[Report a Documentation Task]
-*  <<report_bugs#,Report a Bug>>
-*  link:http://jmonkeyengine.org/forums[Ask (and Answer!) Questions on the Forum]

+ 0 - 1
src/docs/asciidoc/zh-Hans-CN/jme3/about.adoc

@@ -1 +0,0 @@
-= 关于jMonkeyEngine3

+ 0 - 19
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/ai/ai.adoc

@@ -1,19 +0,0 @@
-= Recast Navigation
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-Building a Nav-Mesh for your JME game.
-
-
-== About
-
-
-== Setup
-
-
-== Example Code

+ 0 - 160
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/ai/building_recast.adoc

@@ -1,160 +0,0 @@
-= How to Build the jNavigation Recast Bindings
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-jNavigation is Java jME port for Recast Navigation written in C++. The project has two parts:
-
-.  link:https://github.com/QuietOne/jNavigation-native[jNavigationNative] contains Recast Navigation library and C++ wrapper for java
-.  link:https://github.com/QuietOne/jNavigation[jNavigation] is Java project that uses jNavigationNative and is the project that the end user will use
-
-If there is need for updating Recast Navigation from native side, there are two kinds of updating bindings:
-
-.  only updating methods as the Recast made more efficient or more precise
-.  adding new methods for Recast use
-
-
-== Updating methods
-
-Only updating methods are easy. The requirements needed:
-
-*  C++ compiler
-
-The jNavigationNative that has following folders and files (it has more, but these are the most important for now):
-
-*  Recast
-**  Include
-**  Source
-
-*  README.md
-*  Recast_wrap.cxx - Java - C++ wrapper
-
-Updating the methods is only the matter of putting all headers from Recast Navigation to Include folder, source to Source folders, and then building the project.
-
-As author of this project used the NetBeans 7.4 for building the project, the following instruction is included, if the building from terminal doesn't work.
-
-.  Setting link:https://netbeans.org/kb/docs/cnd/beginning-jni-linux.html[ parameters for NetBeans compiler]
-.  Remove all headers from Header Files
-.  Remove all source files *EXCEPT Recast_wrap.cxx* from Source Files
-.  Right click on Header files, select `Add Existing Item…` or `Add Existing Items from Folders…` and select needed headers
-.  Right click on Source files, select `Add Existing Item…` or `Add Existing Items from Folders…` and select needed source files
-.  Build
-.  Add built project to jNavigation project
-.  Build jNavigation project
-
-
-=== Adding new methods from native side
-
-This is more complicated process and it includes the all work done in NetBeans mentioned in previous section. After that, there are two ways to add new function:
-
-*  manually adding code to wrapper
-*  creating new wrapper with link:http://swig.org/[SWIG]
-
-
-==== Manually adding code to wrapper
-
-Example of method in wrapper:
-
-[source,java]
-----
-
-SWIGEXPORT jint JNICALL Java_com_jme3_ai_navigation_utils_RecastJNI_rcIntArray_1size(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) {
- ...
-}
-
-----
-
-The Recast_wrap.cxx uses SWIG wrapper so for declaring method in wrapper you must first use the keyword `SWIGEXPORT` then returning type (for more information on returning types see link:http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/types.html[link]), then again keyword `JNICALL` and then as the name of method `Java_com_jme3_ai_navigation_utils_RecastJNI_` + `name of class` + `name of method`, after that, there goes list of parameters needed for the function (for more information see link:http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html[link]). In body of method write how the function should be used.
-
-After adding method to wrapper, compile project and add it to jNavigation.
-In jNavigation project in class `com.jme3.ai.navigation.utils.RecastJNI.java` add native method, and after that add in class from which you would like to use this method to call this native method. It seems a little bit more complicated than it should be, but this also for support for updating native side with SWIG.
-
-
-==== Creating new wrapper with SWIG
-
-In some temporary folder add all headers. It shouldn't contain any subfolders.
-
-The following script was used for generating wrapper:
-
-[source]
-----
-
-%module Recast
-%include "carrays.i"
-%array_class(double, DoubleArray);
-%array_class(float, FloatArray);
-%array_class(int, IntArray);
-%array_class(unsigned char, UCharArray);
-%array_class(unsigned short, UShortArray);
-%array_class(unsigned int, UIntArray);
-%array_class(long, LongArray);
-%array_class(bool, BooleanArray)
-
-%{
-#include "DetourAlloc.h"
-#include "DetourAssert.h"
-#include "DetourCommon.h"
-#include "DetourCrowd.h"
-#include "DetourLocalBoundary.h"
-#include "DetourMath.h"
-#include "DetourNavMesh.h"
-#include "DetourNavMeshBuilder.h"
-#include "DetourNavMeshQuery.h"
-#include "DetourNode.h"
-#include "DetourObstacleAvoidance.h"
-#include "DetourPathCorridor.h"
-#include "DetourPathQueue.h"
-#include "DetourProximityGrid.h"
-#include "DetourStatus.h"
-#include "DetourTileCache.h"
-#include "DetourTileCacheBuilder.h"
-#include "Recast.h"
-#include "RecastAlloc.h"
-#include "RecastAssert.h"
-%}
-
-/* Let's just grab the original header file here */
-%include "DetourAlloc.h"
-%include "DetourAssert.h"
-%include "DetourCommon.h"
-%include "DetourCrowd.h"
-%include "DetourLocalBoundary.h"
-%include "DetourMath.h"
-%include "DetourNavMesh.h"
-%include "DetourNavMeshBuilder.h"
-%include "DetourNavMeshQuery.h"
-%include "DetourNode.h"
-%include "DetourObstacleAvoidance.h"
-%include "DetourPathCorridor.h"
-%include "DetourPathQueue.h"
-%include "DetourProximityGrid.h"
-%include "DetourStatus.h"
-%include "DetourTileCache.h"
-%include "DetourTileCacheBuilder.h"
-%include "Recast.h"
-%include "RecastAlloc.h"
-%include "RecastAssert.h"
-
-%pragma(java) jniclasscode=%{
-  static {
-    System.load("Recast");
-  }
-%}
-
-----
-
-If there are more headers at some moment, include them in both places.
-
-.  Save script as Recast.i into temp folder with rest of the headers
-.  Install SWIG if not already
-.  Open terminal and go to folder where the script is
-.  Execute command `swig -c++ -java Recast.i`
-.  Now SWIG will generate Java classes and new Recast_wrap.cxx
-.  Recast_wrap.cxx put in jNavigationNative with new headers and source files, as previously mentioned
-.  Build that project
-.  For jNavigation side, put only new methods in RecastJNI, and use where they are being used. For that you can see in Java class that are build with SWIG.
-.  If method uses some explicit SWIG type, try to use some method for converting it into jME type, or similar. You can probably find something in package `com.jme3.ai.navigation.utils`

+ 0 - 840
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/ai/jme3_ai.adoc

@@ -1,840 +0,0 @@
-= jMonkeyEngine Artificial Intelligence
-:author:
-:revnumber:
-:revdate: 2017/04/15 13:30
-:relfileprefix: ../../
-:imagesdir: ../..
-:experimental:
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-Most games written need some type of link:https://en.wikipedia.org/wiki/Artificial_intelligence_(video_games)[Artificial Intelligence] to deliver a feeling of realism, excitement or challenge to the player. AI can be as simple as having an NPC (Non Player Character) respond to some action taken by a player or as complicated as smoothly navigating your way through a scene full of obstacles without getting stuck. It's a time-consuming and significant challenge to develop these systems so its much easier to use an existing library to do the heavy lifting for you.
-
-Unfortunately, the jMonkeyEngine comes with no official library for dealing with AI. There is, however, the jme3 Artificial Intelligence library that is probably the closest there is to an official release. Although it never made it into any official releases, it was designed, in part, by core team members. It consists of two separate AI models, a link:https://en.wikipedia.org/wiki/Navigation_mesh[Navigation Mesh] library using link:https://en.wikipedia.org/wiki/Pathfinding[path-finding], and a simple Steering Behaviours library that uses path-following.
-
-You can read about the introduction of the library in the forum thread: link:https://hub.jmonkeyengine.org/t/ai-plugin-now-with-navmesh-pathfinding/24644[AI plugin now with NavMesh path-finding].
-
-
-== Requirements
-
-*  link:https://github.com/MeFisto94/jme3-artificial-intelligence/releases[jme3 Artificial Intelligence Library] - The library and javaDocs for jme3AI. This is also where you can report problems or help in maintaining the library.
-*  link:https://github.com/stevefsp/critterai/releases[CritterAI] - Stephen Pratt's link:http://www.critterai.org/projects/nmgen_study/[NMGen Study] project files to generate the navmesh.
-*  To get the assets (3D models) used in this example, add the <<sdk/sample_code#jme3testdata-assets#,jME3-testdata.jar>> to your classpath.
-*  Java SDK 8+.
-
-Stephen Pratt explains in detail the configuration parameters of CritterAI/Jme3AI in a easy to follow format and is suggested reading.
-
-*  link:http://www.critterai.org/projects/nmgen_study/config.html[Configuration Parameters]
-
-
-== Use Example
-
-
-The jme3 Artificial Intelligence Library contains:
-
-*  NavMesh - A Navigation Mesh path-finding AI system using the link:https://en.wikipedia.org/wiki/A*_search_algorithm[A*] algorithm.footnote:[Path-finding means computing the shortest route between two points. Usually mazes.]
-*  Steering - The foundations of an link:http://natureofcode.com/book/chapter-6-autonomous-agents/[Autonomous Agent] system that uses path-following and forces to move a character through its environment. Includes a test case as well.footnote:[Path-following is taking a path that already exists and then following that path.] 
-
-[NOTE]
-====
-This scope of this tutorial is restricted to the NavMesh part of the library and expands upon the lessons taught in the <<jme3#tutorials-for-beginners,tutorials>>. It demonstrates the use of some classes and methods found in the Medium and Advanced topics of the wiki as well. You can find the source code for this tutorial in the  link:https://github.com/jMonkeyEngine/doc-examples/tree/master/src/com/jme3/examples/jme3ai[jMonkeyEngine/docs-examples] repository.
-====
-
-Moving a character through your scene requires three things.
-
-*  A navigation mesh.
-*  A path-finding component that uses that navigation mesh to calculate a path.
-*  A way to move the character.
-
-
-== NavMesh Creation
-
-
-The first thing you need for path-finding is a navigation mesh. There are two ways to generate the NavMesh, procedural or the jMonkey link:https://github.com/jMonkeyEngine/sdk/releases[SDK].
-
-*  The SDK has a built-in command, but comes with a trade-off that no parameter exceptions are thrown. This means you are flying blind when the NavMesh fails generation.
-*  If you choose procedural, you see any generation exceptions, but you will have to do a little more work like saving, loading and/or displaying the NavMesh.
-
-Both methods produce exactly the same NavMesh and both will be covered in this tutorial.
-
-=== From the SDK
-*  Open your scene in the Terrain Editor or Scene Explorer by btn:[RMB] selecting the file in your assets folder and choosing `Edit Terrain` or `Edit in SceneComposer`.
-*  Once open, btn:[RMB] select the root node in the `SceneExplorer` and then select `menu:Spatial[NavMesh]`.
-
-This will open the `Create NavMesh` dialog with default settings. You can read in depth about each parameter by following the `Configuration Parameters` link under <<jme3/advanced/jme3_ai#requirements#,Requirements>>.
-
-.Parameter Insight
-The jme3AI system uses CritterAI, which is based off link:https://github.com/recastnavigation/recastnavigation[Recast and Detour] navigation. The author of Recast lays out a few specific rules for NavMesh creation in this link:http://digestingduck.blogspot.dk/2009/08/recast-settings-uncovered.html[blog post], which logically apply to jme3AI. Below is a translation of this post as it pertains to jme3AI.
-
-*  First you should decide the size of your character "capsule". For example, if you are using meters as units in your game world, a good size of human sized character might be (r)adius=0.4, (h)eight=2.0.
-*  Next the voxelization cell size (cs) will be derived from that. Usually good value for cs is r/2 or r/3. In outdoor environments, r/2 might be enough, indoors you sometimes want the extra precision and you might choose to use r/3 or smaller.
-*  The voxelization cell height (ch) is defined separately in order to allow greater precision in height tests. Good starting point for ch is cs/2. If you get small holes where there are discontinuities in the height (steps), you may want to decrease cell height.
-*  Next up is the character definition values. First up is `minTraversableHeight`, which defines the height of the agent.
-*  The `maxTraversableStep` defines how high steps the character can climb.
-*  The parameter `traversableAreaBorderSize` defines the agent radius. If this value is greater than zero, the navmesh will be shrunken by the `traversableAreaBorderSize`. If you want to have tight fit navmesh, use zero radius.
-*  The parameter `maxTraversableSlope` is used before voxelization to check if the slope of a triangle is too high and those polygons will be given a non-walkable flag. The parameter is in radians.
-*  In certain cases really long outer edges may decrease the triangulation results. Sometimes this can be remedied by just tessellating the long edges. The parameter `maxEdgeLength` defines the max
-edge length. A good value for `maxEdgeLength` is something like `traversableAreaBorderSize*8`. A good way to tweak this value is to first set it really high and see if your data creates long edges. If so, then try to find as big value as possible which happen to create those few extra vertices which makes the tessellation better.
-*  When the rasterized areas are converted back to vectorized representation the `edgeMaxDeviation` describes how loosely the simplification is done.  Good values are between 1.1-1.5 (1.3 usually yield good results). If the value is less, some stair-casing starts to appear at the edges and if it is more than that, the simplification starts to cut some corners.
-
-NOTE: A summary of the parameter effects is included in the comments of the link:https://github.com/jMonkeyEngine/doc-examples/blob/master/src/com/jme3/examples/jme3ai/ai/NavMeshState.java[NavMeshState.java] file and discussed in the Procedural code examples that follow this section.
-
-If there are problems with your parameter settings, you will only know if the NavMesh doesn't appear under the Node you selected and there is no task running in the status area located at the bottom right of the SDK.
-
-If the NavMesh doesn't appear, then you will have to make adjustments to the `Configuration Parameters` until it completes successfully. Minor adjustments to cell size will usually work.
-
-CAUTION: Cell size has the greatest impact on your NavMesh. The smaller the cell size, the more accurate the NavMesh, the longer it takes to generate. Generating a 1024x1024 NavMesh can take anywhere from 30 seconds to ten minutes to complete, depending on terrain complexity. Even larger NavMeshes can take many hours.
-
-TIP: Selecting the NavMesh node in the SceneExplorer will show the NavMesh in the Terrain Editor or SceneComposer view-port. If it doesn't show, with the NavMesh node selected, change the `Cull Hint` to `Never` in the `NavMesh - Properties` panel.
-
-=== Procedural Method
-There are many ways to create a NavMesh. If you look at the constructor for the link:https://github.com/jMonkeyEngine/doc-examples/blob/master/src/com/jme3/examples/jme3ai/Jme3AI.java[Jme3AI.java] file, you will see I use a <<jme3/advanced/application_states#baseappstate#,BaseAppState>> named link:https://github.com/jMonkeyEngine/doc-examples/blob/master/src/com/jme3/examples/jme3ai/ai/NavMeshState.java[NavMeshState.java] which creates a `generator` object and builds the `NavMesh` new every time the program is ran.
-
-.Jme3AI constructor
-[source, java]
-----
-public Jme3AI() {
-    super(new StatsAppState(), new DebugKeysAppState(), new TerrainState(),
-            new NavMeshState(), new PCState(), new KeyboardRunState());
-}
-----
-
-It can take from seconds to hours to build a NavMesh, depending on how complicated it is. Therefore, you would normally build the NavMesh or meshes, add them to your `Assets` folder and load them at startup. The `NavMeshState` and `NavMeshGenerator` classes are both convenience classes and are not required to create a NavMesh. If you wish to keep your game minimalist, you can set the variables for the CritterAI NavmeshGenerator (note the lower case 'm' in mesh) in the method call directly or by variable, and pass the IndexBuffer and VertexBuffer of your mesh into the CritterAI NavmeshGenerator object.
-
-[source, java]
-----
-NavmeshGenerator nmgen = new NavmeshGenerator(cellSize, cellHeight, minTraversableHeight,
-                maxTraversableStep, maxTraversableSlope,
-                clipLedges, traversableAreaBorderSize,
-                smoothingThreshold, useConservativeExpansion,
-                minUnconnectedRegionSize, mergeRegionSize,
-                maxEdgeLength, edgeMaxDeviation, maxVertsPerPoly,
-                contourSampleDistance, contourMaxDeviation);
-...
-Get mesh buffers and set IntermediateData
-...
-
-//Pass buffers and IntermediateData to build process
-TriangleMesh triMesh = nmgen.build(positions, indices, intermediateData);
-
-...
-Process trimesh
-...
-----
-
-Let's examine what it takes to create the `NavMesh` using the `NavMeshState` and `NavMeshGenerator` helper classes.
-
-.NavMeshState NavMesh generation method
-[source, java]
-----
-/**
- * creates the NavMesh
- */
-private void createNavMesh() {
-    generator = new NavMeshGenerator();
-    //The width and depth resolution used when sampling the source geometry.
-    //outdoors = agentRadius/2, indoors = agentRadius/3, cellSize =
-    //agentRadius for very small cells.
-    //Constraints > 0 , default=1
-    generator.setCellSize(.25f);
-    //The height resolution used when sampling the source geometry.
-    //minTraversableHeight, maxTraversableStep, and contourMaxDeviation
-    //will need to be greater than the value of cellHeight in order to
-    //function correctly. maxTraversableStep is especially susceptible to
-    //impact from the value of cellHeight.
-    //cellSize/2
-    //Constraints > 0, default=1.5
-    generator.setCellHeight(.125f);
-    //Represents the minimum floor to ceiling height that will still allow
-    //the floor area to be considered traversable.
-    //minTraversableHeight should be at least two times the value of
-    //cellHeight in order to get good results. Max spatial height.
-    //Constraints > 0, default=7.5
-    generator.setMinTraversableHeight(2f);
-    //Represents the maximum ledge height that is considered to still be
-    //traversable.
-    //maxTraversableStep should be greater than two times cellHeight.
-    //Constraints >= 0, default=1
-    generator.setMaxTraversableStep(0.3f);
-    //The maximum slope that is considered traversable. (In degrees.)
-    //Constraints >= 0, default=48
-    generator.setMaxTraversableSlope(50.0f);
-    //Indicates whether ledges should be considered un-walkable.
-    //Constraints None, default=false
-    generator.setClipLedges(false);
-    //Represents the closest any part of a mesh can get to an obstruction in
-    //the source geometry.
-    //traversableAreaBorderSize value must be greater than the cellSize to
-    //have an effect. Radius of the spatial.
-    //Constraints >= 0, default=1.2
-    generator.setTraversableAreaBorderSize(0.6f);
-    //The amount of smoothing to be performed when generating the distance
-    //field used for deriving regions.
-    //Constraints >= 0, default=2
-    generator.setSmoothingThreshold(0);
-    //Applies extra algorithms to help prevent malformed regions from
-    //forming.
-    //Constraints None, default=true
-    generator.setUseConservativeExpansion(true);
-    //The minimum region size for unconnected (island) regions.
-    //Constraints > 0, default=3
-    generator.setMinUnconnectedRegionSize(8);
-    //Any regions smaller than this size will, if possible, be merged with
-    //larger regions.
-    //Constraints >= 0, default=10
-    generator.setMergeRegionSize(20);
-    //The maximum length of polygon edges that represent the border of
-    //meshes.
-    //setTraversableAreaBorderSize * 8
-    //Constraints >= 0, default=0
-    generator.setMaxEdgeLength(4.0f);
-    //The maximum distance the edges of meshes may deviate from the source
-    //geometry.
-    //1.1 to 1.5 for best results.
-    //Constraints >= 0 , default=2.4
-    generator.setEdgeMaxDeviation(1.3f);
-    //The maximum number of vertices per polygon for polygons generated
-    //during the voxel to polygon conversion process.
-    //Constraints >= 3, default=6
-    generator.setMaxVertsPerPoly(6);
-    //Sets the sampling distance to use when matching the detail mesh to the
-    //surface of the original geometry.
-    //Constraints >= 0, default=25
-    generator.setContourSampleDistance(5.0f);
-    //The maximum distance the surface of the detail mesh may deviate from
-    //the surface of the original geometry.
-    //Constraints >= 0, default=25
-    generator.setContourMaxDeviation(5.0f);
-    //Time allowed before generation process times out in miliseconds.
-    //default=10000
-    generator.setTimeout(40000);
-
-    //the data object to use for storing data related to building the
-    //navigation mesh.
-    IntermediateData data = new IntermediateData();
-    generator.setIntermediateData(data);
-
-    Mesh mesh = new Mesh();
-    GeometryBatchFactory.mergeGeometries(findGeometries(app.getRootNode(),
-            new LinkedList<>(), generator), mesh);
-
-    //uncomment to show mesh
-//        Geometry meshGeom = new Geometry("MeshGeometry");
-//        meshGeom.setMesh(mesh);
-//        showGeometry(meshGeom, ColorRGBA.Yellow);
-//        saveNavMesh(meshGeom);
-
-    Mesh optiMesh = generator.optimize(mesh);
-    navMesh.loadFromMesh(optiMesh);
-
-    Geometry geom = new Geometry(DataKey.NAVMESH);
-    geom.setMesh(optiMesh);
-    //display the mesh
-    showGeometry(geom, ColorRGBA.Green);
-    //save the navmesh to Scenes/NavMesh for loading
-    exportNavMesh(geom, DataKey.NAVMESH);
-    //save geom to rootNode if you wish
-    saveNavMesh(geom);
-}
-----
-
-First, we create the link:https://github.com/jMonkeyEngine/doc-examples/blob/master/src/com/jme3/examples/jme3ai/ai/NavMeshGenerator.java[NavMeshGenerator] object and then use it to set the parameters for the NavMesh.
-
-[source, java]
-----
-generator = new NavMeshGenerator();
-...
-generator.setCellSize(.25f);
-...
-----
-
-In our next step we create an IntermediateData object.
-
-[source, java]
-----
-//the data object to use for storing data related to building the
-//navigation mesh.
-IntermediateData data = new IntermediateData();
-generator.setIntermediateData(data);
-----
-
-The IntermediateData object can be used to get information about the build process of the NavMesh such as build times. You query this object after building the NavMesh. If you don't wish to see the data, set it to null.
-
-At this point, you now have a `generator` object that you use to create the NavMesh with.
-
-Included in the link:https://github.com/jMonkeyEngine/doc-examples/blob/master/src/com/jme3/examples/jme3ai/ai/NavMeshState.java[NavMeshState.java] file is the helper method `findGeometries`.
-
-[source, java]
-----
-//Gathers all geometries in supplied node into supplied List. Uses
-//NavMeshGenerator to merge found Terrain meshes into one geometry prior to
-//adding. Scales and sets translation of merged geometry.
-private List<Geometry> findGeometries(Node node, List<Geometry> geoms,
-          NavMeshGenerator generator)
-----
-
-
-It is used to collect all geometries, attached to a node, into a List. If a child of the node is a Terrain instance (which can consist of many meshes), it will use the `generator` object to merge them into one mesh, then scale and set translation of the merged mesh prior to being added to the list. You then use GeometryBatchFactory to merge all the geometries in the list into a single `mesh` object.
-
-[source, java]
-----
-Mesh mesh = new Mesh();
-GeometryBatchFactory.mergeGeometries(findGeometries(app.getRootNode(),
-        new LinkedList<>(), generator), mesh);
-----
-
-After these methods execute, you have a single `mesh` object that is now ready to be optimized.
-
-[source, java]
-----
-Mesh optiMesh = generator.optimize(mesh);
-----
-
-This is where the parameters you set with the `generator` object are applied to the supplied `mesh`. The optimize method will return a new Mesh object that reflects your generator settings. Now is when any problems with your parameters will show themselves as either warnings or exceptions. You should keep changing the various parameters, one at a time and in small increments/decrements, until your `mesh` generates with no errors. See each parameter's notes for suggestions on how to do so.
-
-After the mesh generates, you need to link all of its cells together so it can be used as your `NavMesh` object. You do this by calling `loadFromMesh()` or `loadFromData()`, depending on your implementation, on your `optiMesh` object.
-
-[source, java]
-----
-navMesh.loadFromMesh(optiMesh);
-----
-
-If you look at the second contructor for the `NavMesh` class you will see this is all it does. You would use this constructor if you were loading a `Mesh` from a geometry that had already been optimized and saved into your `Assets` folder for example.
-
-[source, java]
-----
-public NavMesh(Mesh mesh) {
-  loadFromMesh(mesh);
-}
-----
-
-The `NavMesh` object is now ready for use in your game, but you still need to create the geometry for it if you wish to save or view it. You do this the same as you would for any newly created mesh.
-
-[source, java]
-----
-Geometry geom = new Geometry(DataKey.NAVMESH);
-geom.setMesh(navMesh);
-----
-
-Now that you have your Mesh you should save it.
-
-[source, java]
-----
-//save the navmesh to Scenes/NavMesh for loading
-exportNavMesh(geom, DataKey.NAVMESH);
-//save geom to rootNode if you wish
-saveNavMesh(geom);
-----
-
-In this instance, the object is exported to the projects `Assets` folder so it can be loaded rather than generated every time the game starts. This is the preferred method. The `saveNavMesh()` method just attaches the geometry to the `rootNode`. How and where you choose to save depends on your implementation and personal preferences.
-
-
-== Pathfinding
-
-
-There are many ways to implement the `NavMeshPathfinder` class of the jme3AI library. You can create a control, instantiate the `NavMeshPathFinder` class, and query the newly created object in a thread. You could use a single AppState to calculate all your paths. You could, as in this tutorial, extend the NavMeshPathFinder class in a custom control.
-
-You also need a way to communicate `Vector3f` changes to the `NavMeshPathfinder`. This tutorial uses an ActionListener and Interface. You could just as easily create a public method in the control, and call it from the ActionListener, or store the `Vector3f` in `UserData` and look for changes from the control itself.
-
-These are implementation decisions that are left up to you.
-
-=== Loading the NavMesh
-
-In this tutorial example, the optimized mesh was exported as a geometry using the jMonkey binary format `.j3o`. Doing so means the loading of your `NavMeshes` is done the same way you load any model, by using the `AssetManager`. Once you load the `.j3o`, you grab its `Mesh` and create the `NavMesh` object to be passed to the link:https://github.com/jMonkeyEngine/doc-examples/blob/master/src/com/jme3/examples/jme3ai/ai/NavigationControl.java[NavigationControl] constructor. This tutorial uses a <<jme3/advanced/application_states#baseappstate#,BaseAppState>> for model loading so access to the `Application` class is built in.
-
-[source, java]
-----
-//load NavMesh geometry saved to assets folder
-Geometry navGeom = (Geometry) getApplication().getAssetManager().
-        loadModel("Scenes/NavMesh/NavMesh.j3o");
-NavigationControl navControl = new NavigationControl(new NavMesh(
-        navGeom.getMesh()), getApplication(), true)
-charNode.addControl(navControl);
-//NavigationControl implements Pickable Interface
-picked = navControl;
-----
-
-[NOTE]
-
-====
-This tutorial uses a custom control, `NavigationControl`, that extends the `NavMeshPathfinder` class. As this is a tutorial, some extra variables are used for dispalying the navigation path and are not needed. The constructor for `NavMeshPathfinder` requires just the the passing of the `NavMesh` object, which makes for a cleaner control.
-
-[source, java]
-----
-public NavigationControl(NavMesh navMesh) {
-  ...
-}
-----
-
-====
-
-=== Communicating with NavigationControl
-
-This tutorial makes use of the <<jme3/beginner/hello_picking#,Hello Picking>> and <<jme3/advanced/mouse_picking#pick-a-target-using-the-mouse-pointer#,Mouse Picking>> tutorials so you should already be familiar with this method for picking and how to add the <<jme3/beginner/hello_input_system#,input mappings>> to your game. How you implement your ActionListener is up to you.
-
-.PCState ActionListener
-[source, java]
-----
-    private class ClickedListener implements ActionListener {
-
-        @Override
-        public void onAction(String name, boolean isPressed, float tpf) {
-
-            if (name.equals(ListenerKey.PICK) && !isPressed) {
-                CollisionResults results = new CollisionResults();
-                Vector2f click2d = getInputManager().getCursorPosition().clone();
-                Vector3f click3d = app.getCamera().getWorldCoordinates(click2d,
-                        0f).clone();
-                Vector3f dir = app.getCamera().getWorldCoordinates(
-                        click2d, 1f).subtractLocal(click3d).normalizeLocal();
-                Ray ray = new Ray(click3d, dir);
-                app.getRootNode().collideWith(ray, results);
-
-                for (int i = 0; i < results.size(); i++) {
-                    // For each hit, we know distance, impact point, name of geometry.
-                    float dist = results.getCollision(i).getDistance();
-                    Vector3f pt = results.getCollision(i).getContactPoint();
-                    String hit = results.getCollision(i).getGeometry().getName();
-                    System.out.println("* Collision #" + i);
-                    System.out.println(
-                            "  You shot " + hit
-                            + " at " + pt
-                            + ", " + dist + " wu away.");
-                }
-
-                if (results.size() > 0) {
-                    // The closest collision point is what was truly hit:
-                    CollisionResult closest = results.getClosestCollision();
-                    // Let's interact - we mark the hit with a red dot.
-                    mark.setLocalTranslation(closest.getContactPoint());
-                    app.getRootNode().attachChild(mark);
-                    picked.setTarget(closest.getContactPoint());
-                    System.out.println("  Closest Contact " + closest.
-                            getContactPoint());
-                } else {
-                    // No hits? Then remove the red mark.
-                    app.getRootNode().detachChild(mark);
-                }
-            }
-        }
-    }
-----
-
-The main line of interest here is,
-
-[source, java]
-----
-picked.setTarget(closest.getContactPoint());
-----
-
-where `picked` is the reference object used to communicate our `Vector3f` changes to the `NavigationControl`.
-
-[source, java]
-----
-//NavigationControl implements Pickable Interface
-picked = navControl;
-----
-
-At this point you have loaded your `NavMesh`, added the `NavigationControl` to your spatial, and instituted a method for communicating with the `NavMeshPathFinder`. Next we will delve into the details of the `NavigationControl`.
-
-
-=== NavigationControl
-
-
-The link:https://github.com/jMonkeyEngine/doc-examples/blob/master/src/com/jme3/examples/jme3ai/ai/NavigationControl.java[NavigationControl] is a <<jme3/advanced/custom_controls#,custom control>> that extends the link:https://github.com/MeFisto94/jme3-artificial-intelligence/blob/master/AI/src/com/jme3/ai/navmesh/NavMeshPathfinder.java[NavMeshPathFinder] class of the Jme3AI library and implements the `Pickable` interface.
-
-[source, java]
-----
-public class NavigationControl extends NavMeshPathfinder implements Control,
-        JmeCloneable, Pickable {
-}
-----
-
-The link:https://github.com/jMonkeyEngine/doc-examples/blob/master/src/com/jme3/examples/jme3ai/interfaces/Pickable.java[Pickable] interface is straightforward and its sole purpose in this implementation is to communicate changes made to the pick target.
-
-.Pickable Interface implementation
-[source, java]
-----
-/**
- * @param target the target to set
- */
-@Override
-public void setTarget(Vector3f target) {
-    this.target = target;
-}
-----
-
-The heartbeat of the control lies in the pathfinding thread which makes calls to the `computePath()` method. Potentially long running tasks like this should always be ran from a thread. Below, is the constructor you would normally use to instantiate your control.
-
-[source, java]
-----
-public NavigationControl(NavMesh navMesh) {
-    super(navMesh); //sets the NavMesh for this control
-    executor = Executors.newScheduledThreadPool(1);
-    startPathFinder();
-}
-----
-
-First, you call `super(navMesh)` to set the `NavMesh` for the control, then setup your `ExecutorService` and start the pathfinding thread.
-
-This is a custom thread implementation so it's up to you to handle shutting it down. This is done in the controls `setSpatial()` method.
-
-[source, java]
-----
-if (spatial == null) {
-    shutdownAndAwaitTermination(executor);
-    ...
-} else {
-    ...
-}
-----
-
-.Executor shutdown process
-[source, java]
-----
-//standard shutdown process for executor
-private void shutdownAndAwaitTermination(ExecutorService pool) {
-    pool.shutdown(); // Disable new tasks from being submitted
-    try {
-        // Wait a while for existing tasks to terminate
-        if (!pool.awaitTermination(6, TimeUnit.SECONDS)) {
-            pool.shutdownNow(); // Cancel currently executing tasks
-            // Wait a while for tasks to respond to being cancelled
-            if (!pool.awaitTermination(6, TimeUnit.SECONDS)) {
-                LOG.log(Level.SEVERE, "Pool did not terminate {0}", pool);
-            }
-        }
-    } catch (InterruptedException ie) {
-        // (Re-)Cancel if current thread also interrupted
-        pool.shutdownNow();
-        // Preserve interrupt status
-        Thread.currentThread().interrupt();
-    }
-}
-----
-
-The easiest way to move a physics character is by using the <<jme3/advanced/walking_character#bettercharactercontrol#,BetterCharacterControl>> class. In this implementation, this is done in the link:https://github.com/jMonkeyEngine/doc-examples/blob/master/src/com/jme3/examples/jme3ai/controls/PCControl.java[PCControl] class by extending `BetterCharacterControl`. Since `BetterCharacterControl` is required to be present on the spatial for pathfinding, in the `setSpatial()` method, we throw an exception to let us know if it's missing.
-
-[source, java]
-----
-if (spatial == null) {
-    ...
-} else {
-    pcControl = spatial.getControl(PCControl.class);
-    if (pcControl == null) {
-        throw new IllegalStateException(
-                "Cannot add NavigationControl to spatial without PCControl!");
-    }
-}
-----
-
-=== Pathfinding Thread
-
-.NavigationControl pathfinding thread
-[source, java]
-----
-//Computes a path using the A* algorithm. Every 1/2 second checks target
-//for processing. Path will remain untill a new path is generated.
-private void startPathFinder() {
-    executor.scheduleWithFixedDelay(() -> {
-        if (target != null) {
-            clearPath();
-            setWayPosition(null);
-            pathfinding = true;
-            //setPosition must be set before computePath is called.
-            setPosition(spatial.getWorldTranslation());
-            //warpInside(target) moves endpoint within the navMesh always.
-            warpInside(target);
-            System.out.println("Target " + target);
-            boolean success;
-            //comput the path
-            success = computePath(target);
-            System.out.println("SUCCESS = " + success);
-            if (success) {
-                //clear target if successful
-                target = null;
-                ...
-            }
-            pathfinding = false;
-        }
-    }, 0, 500, TimeUnit.MILLISECONDS);
-}
-----
-
-How you setup your pathfinding thread makes a significant difference.
-
-[source, java]
-----
-executor.scheduleWithFixedDelay(() -> {
-...
-}, 0, 500, TimeUnit.MILLISECONDS);
-----
-
-This `ExecutorService` is set to start immediately (0) with a fixed delay of (500) milliseconds. This means the task has a fixed delay of 1/2 second between the end of an execution and the start of the next execution, i.e. it doesn't take into account the actual duration of the task. If you were to use `scheduleAtFixedRate()`, you risk that the task doesn't complete in the time allocated.
-
-When you use the `BetterCharacterControl`, all that's required to move the spatial is that you `setWalkDirection()` and the spatial will continuously move in that direction. The following code breakdown explains how the `NavigationControl` takes advantage of this.
-
-It starts by having the pathfinding thread check a `target` variable for changes.
-
-[source, java]
-----
-if (target != null) {
-    ...
-}
-----
-
-If it finds a target, it will compute a new path to that `target`, and if successful, update the `NavMeshPathfinder` path variable. The `update()` loop of the control continuously checks this path variable, and if its non-null, takes an appropriate action.
-
-Before you compute the path you first clear the existing path, and set wayPosition to null.
-
-[source, java]
-----
-if (target != null) {
-    clearPath();
-    setWayPosition(null);
-    pathfinding = true;
-    ...
-}
-----
-
-Doing this allows the player to select a new `target` at any time and immediately start moving along the new path. Otherwise, the character must finish the path they are on, then backtrack to the position the character was at when the `target` change was made, before then continuing on the new path.
-
-Next, you must call `setPosition()` *before* calling the `computePath()` method.
-
-[source, java]
-----
-if (target != null) {
-  ...
-  setPosition(spatial.getWorldTranslation());
-  ...
-  //compute the path
-  success = computePath(target);
-  ...
-}
-----
-
-There are some things you need to know about how a path is computed.
-
-*  The first waypoint on any path is the one you set with `setPosition()`.
-*  The last waypoint on any path is always the `target` Vector3f.
-*  computePath() adds one waypoint to the cell *nearest* to the target only if you are not in the goalCell (the cell target is in), and if there is a cell between first and last waypoint, and if there is no direct line of sight.
-*  If inside the goalCell when a new target is selected, computePath() will do a direct line of sight placement of target. This means there will only be two waypoints set, `setPosition()` and `target`.
-*  If the `target` is outside the `NavMesh`, your endpoint will be as well.
-
-To guarantee that `target` is always inside the `NavMesh`, call
-
-[source, java]
-----
-if (target != null) {
-    ...
-    //warpInside(target) moves endpoint within the navMesh always.
-    warpInside(target);
-    ...
-    //compute the path
-    success = computePath(target);
-    ...
-}
-----
-
-before calling `computePath()` and the endpoint of the path will be moved to the closest cell to the `target` that's inside the `NavMesh`.
-
-== Character Movement
-
-.NavigationControl update() loop
-[source, java]
-----
-@Override
-public void update(float tpf) {
-    if (getWayPosition() != null) {
-        Vector3f spatialPosition = spatial.getWorldTranslation();
-        Vector2f aiPosition = new Vector2f(spatialPosition.x,
-                spatialPosition.z);
-        Vector2f waypoint2D = new Vector2f(getWayPosition().x,
-                getWayPosition().z);
-        float distance = aiPosition.distance(waypoint2D);
-        //move char between waypoints untill waypoint reached then set null
-        if (distance > .25f) {
-            Vector2f direction = waypoint2D.subtract(aiPosition);
-            direction.mult(tpf);
-            pcControl.setViewDirection(new Vector3f(direction.x, 0,
-                    direction.y).normalize());
-            pcControl.onAction(ListenerKey.MOVE_FORWARD, true, 1);
-        } else {
-            setWayPosition(null);
-        }
-    } else if (!isPathfinding() && getNextWaypoint() != null
-            && !isAtGoalWaypoint()) {
-        if (showPath) {
-            showPath();
-            showPath = false;
-        }
-        //advance to next waypoint
-        goToNextWaypoint();
-        setWayPosition(new Vector3f(getWaypointPosition()));
-
-        //set spatial physical position
-        if (getPositionType() == EnumPosition.POS_STANDING.position()) {
-            setPositionType(EnumPosition.POS_RUNNING.position());
-            stopFeetPlaying();
-            stopTorsoPlaying();
-        }
-    } else {
-        //waypoint null so stop moving and set spatials physical position
-        if (getPositionType() == EnumPosition.POS_RUNNING.position()) {
-            setPositionType(EnumPosition.POS_STANDING.position());
-            stopFeetPlaying();
-            stopTorsoPlaying();
-        }
-        pcControl.onAction(ListenerKey.MOVE_FORWARD, false, 1);
-    }
-}
-----
-
-If the `computePath()` successfully computes a new path, the path variable of the `NavMeshPathfinder` will no longer be null. The update loop of the `NavigationControl` checks this path variable, every iteration that wayPosition is null, by calling the `getNextWaypoint()` method. If the path has another waypoint, it will advance to the next position in the path and set the `wayPosition` variable of the `NavigationControl` to that position.
-
-[source, java]
-----
-} else if (!isPathfinding() && getNextWaypoint() != null
-        && !isAtGoalWaypoint()) {
-    ...
-    //advance to next waypoint
-    goToNextWaypoint();
-    setWayPosition(new Vector3f(getWaypointPosition()));
-    ...
-}
-----
-
-IMPORTANT: Remember, the first waypoint in the path is always the spatials current position. This is why you always advance the position first.
-
-On the next iteration of the controls `update()` method, it sees that `wayPosition` is no longer null and calculates the distance from the spatials current position to the `wayPosition`.
-
-[source, java]
-----
-if (getWayPosition() != null) {
-    Vector3f spatialPosition = spatial.getWorldTranslation();
-    Vector2f aiPosition = new Vector2f(spatialPosition.x,
-            spatialPosition.z);
-    Vector2f waypoint2D = new Vector2f(getWayPosition().x,
-            getWayPosition().z);
-    float distance = aiPosition.distance(waypoint2D);
-    ...
-}
-----
-
-If it's greater than the distance specified, it will `setViewDirection()` of the `PCControl` (which extends BetterCharacterControl) and then notify the `PCControl` that the spatial can move by calling the controls `onAction()` method directly.
-
-[source, java]
-----
-if (getWayPosition() != null) {
-    ...
-    //move char between waypoints untill waypoint reached then set null
-    if (distance > .25f) {
-        Vector2f direction = waypoint2D.subtract(aiPosition);
-        direction.mult(tpf);
-        pcControl.setViewDirection(new Vector3f(direction.x, 0,
-                direction.y).normalize());
-        pcControl.onAction(ListenerKey.MOVE_FORWARD, true, 1);
-    } else {
-        ...
-    }
-}
-----
-
-It's up to the `NavigationControl` to determine when the character should stop moving. Each time the spatial reaches a point that is less than the specified distance, it sets the wayPosition to null.
-
-[source, java]
-----
-if (distance > .25f) {
-    ...
-} else {
-    setWayPosition(null);
-}
-----
-
-If the path position has not yet reached the end, it will once again be advance to the next waypoint in the path and update the wayPosition.
-
-[source, java]
-----
-} else if (!isPathfinding() && getNextWaypoint() != null
-        && !isAtGoalWaypoint()) {
-    ...
-    //advance to next waypoint
-    goToNextWaypoint();
-    setWayPosition(new Vector3f(getWaypointPosition()));
-    ...
-}
-----
-
-When the last waypoint is reached, the `NavigationControl` notifies the `PCControl` that the spatial can no longer move.
-
-[source, java]
-----
-} else {
-    ...
-    pcControl.onAction(ListenerKey.MOVE_FORWARD, false, 1);
-}
-----
-
-The link:https://github.com/jMonkeyEngine/doc-examples/blob/master/src/com/jme3/examples/jme3ai/controls/PCControl.java[PCControl] class handles the actual movement of the spatial in its `update()` loop. It does this by checking the `forward` variable every iteration. This variable is set when you call the `onAction()` method from the `NavigationControl` update loop.
-
-.PCControl ActionListener
-[source, java]
-----
-@Override
-public void onAction(String name, boolean isPressed, float tpf) {
-    if (name.equals(ListenerKey.MOVE_FORWARD)) {
-        forward = isPressed;
-    }
-}
-----
-
-
-.PCControl update() loop
-[source, java]
-----
-@Override
-public void update(float tpf) {
-    super.update(tpf);
-    this.moveSpeed = 0;
-    walkDirection.set(0, 0, 0);
-    if (forward) {
-        Vector3f modelForwardDir = spatial.getWorldRotation().mult(Vector3f.UNIT_Z);
-        position = getPositionType();
-        for (EnumPosition pos : EnumPosition.values()) {
-            if (pos.position() == position) {
-                switch (pos) {
-                    case POS_RUNNING:
-                        moveSpeed = EnumPosition.POS_RUNNING.speed();
-                        break;
-                    default:
-                        moveSpeed = 0f;
-                        break;
-                }
-            }
-        }
-        walkDirection.addLocal(modelForwardDir.mult(moveSpeed));
-    }
-    setWalkDirection(walkDirection);
-}
-----
-
-The `PCControl` will then set the walk direction, based off spatials world rotation, and set the speed.
-
-
-== Conclusion
-
-
-The intent of this tutorial was to give you a general breakdown of how the Jme3AI navigation system works as well as demonstrate how flexible its implementation is. All the code in this tutorial is free for your use and can be found in the link:https://github.com/jMonkeyEngine/doc-examples[jme3 documentation repository]. The implementations design is such that you can easily change each of the parameters and then visually see how they affect the NavMesh. If you have questions or suggestions on improving this tutorial you can do so in the link:https://hub.jmonkeyengine.org/[jMonkeyEngine forum].
-
-== Other AI Options
-
-There are other jME3 specific options available you can read about in the wiki under the topic link:https://jmonkeyengine.github.io/wiki/jme3.html#artificial-intelligence-ai[Artificial Intelligence (AI)].
-
-
-== Further Reading
-
-*  link:http://www.policyalmanac.org/games/aStarTutorial.htm[A* path-finding for Beginners] by Patrick Lester
-*  link:http://natureofcode.com/book/[The Nature of Code] by Daniel Shiffman
-*  link:http://www.red3d.com/cwr/steer/gdc99/[Steering Behaviors For Autonomous Characters] by Craig W. Reynolds
-*  link:http://www.critterai.org/projects/nmgen_study/[Study: Navigation Mesh Generation Java] by Stephen Pratt

+ 0 - 281
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/ai/recast.adoc

@@ -1,281 +0,0 @@
-= Recast Navigation for JME
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== What is Recast Navigation
-
-Recast Navigation is C++ library for path-finding in 3D, continuous space. Recast has two big modules:
-
-.  Recast
-.  Detour
-
-
-=== Recast
-
-Recast is state of the art navigation mesh construction tool set for games.
-
-*  It is automatic, which means that you can throw any level geometry at it and you will get robust mesh out
-*  It is fast which means swift turnaround times for level designers
-*  It is open source so it comes with full source and you can customize it to your heart's content.
-
-
-=== Detour
-
-Recast is accompanied with Detour, path-finding and spatial reasoning toolkit. You can use any navigation mesh with Detour, but of course the data generated with Recast fits perfectly.
-
-Detour offers simple static navigation mesh which is suitable for many simple cases, as well as tiled navigation mesh which allows you to plug in and out pieces of the mesh. The tiled mesh allows you to create systems where you stream new navigation data in and out as the player progresses the level, or you may regenerate tiles as the world changes.
-
-
-== jNavigation
-
-jNavigation is port Java library for link:https://github.com/memononen/recastnavigation[Recast navigation]. jNavigation is the project in progress, and currently it enables building link:http://en.wikipedia.org/wiki/Navigation_mesh[Navigation meshes] and path-finding for one agent (bot).
-
-
-== Example
-
-In next code is described how the user should build navigation mesh, and query for it.
-
-[source,java]
-----
-
-// Step 1. Initialize build config.
-Config config = new Config();
-
-Mesh mesh = ((Geometry) scene.getChild("terrain")).getMesh();
-            
-Vector3f minBounds = RecastBuilder.calculateMinBounds(mesh);
-Vector3f maxBounds = RecastBuilder.calculateMaxBounds(mesh);
-
-config.setMaxBounds(maxBounds);
-config.setMinBounds(minBounds);
-config.setCellSize(0.3f);
-config.setCellHeight(0.2f);
-config.setWalkableSlopeAngle(45);
-config.setWalkableClimb(1);
-config.setWalkableHeight(2);
-config.setWalkableRadius(2);
-config.setMinRegionArea(8);
-config.setMergeRegionArea(20);
-config.setBorderSize(20);
-config.setMaxEdgeLength(12);
-config.setMaxVerticesPerPoly(6);
-config.setDetailSampleMaxError(1f);
-config.setDetailSampleDistance(6);
-
-RecastBuilder.calculateGridWidth(config);
-RecastBuilder.calculatesGridHeight(config);
-
-// Step 2. Rasterize input polygon soup.
-
-//context is needed for logging that is not yet fully supported in native library.
-//It must NOT be null.
-Context context = new Context();
-
-// Allocate voxel heightfield where we rasterize our input data to.
-Heightfield heightfield = new Heightfield();
-if (!RecastBuilder.createHeightfield(context, heightfield, config)) {
-    System.out.println("Could not create solid heightfield");
-    return;
-}
-
-// Allocate array that can hold triangle area types. 
-
-// In Recast terminology, triangles are what indices in jME is. I left this,
-
-// Find triangles which are walkable based on their slope and rasterize them.
-char[] areas = RecastBuilder.markWalkableTriangles(context, config.getWalkableSlopeAngle(), mesh);
-RecastBuilder.rasterizeTriangles(context, mesh, areas, heightfield, 20);
-
-
-// Step 3. Filter walkables surfaces.
-// Once all geometry is rasterized, we do initial pass of filtering to
-// remove unwanted overhangs caused by the conservative rasterization
-// as well as filter spans where the character cannot possibly stand.
-RecastBuilder.filterLowHangingWalkableObstacles(context, config.getWalkableClimb(), heightfield);
-RecastBuilder.filterLedgeSpans(context, config, heightfield);
-RecastBuilder.filterWalkableLowHeightSpans(context, config.getWalkableHeight(), heightfield);
-       
-        
-// Step 4. Partition walkable surface to simple regions.
-// Compact the heightfield so that it is faster to handle from now on.
-// This will result more cache coherent data as well as the neighbours
-// between walkable cells will be calculated.
-CompactHeightfield compactHeightfield = new CompactHeightfield();
-       
-if (!RecastBuilder.buildCompactHeightfield(context, config, heightfield, compactHeightfield)) {
-    System.out.println("Could not build compact data");
-    return;
-}
-
-if (!RecastBuilder.erodeWalkableArea(context, config.getWalkableRadius(), compactHeightfield)) {
-    System.out.println("Could not erode");
-    return;
-}
-
-// Partition the heightfield so that we can use simple algorithm later to triangulate the walkable areas.
-// There are 3 martitioning methods, each with some pros and cons:
-// 1) Watershed partitioning
-//   - the classic Recast partitioning
-//   - creates the nicest tessellation
-//   - usually slowest
-//   - partitions the heightfield into nice regions without holes or overlaps
-//   - the are some corner cases where this method creates produces holes and overlaps
-//      - holes may appear when a small obstacles is close to large open area (triangulation can handle this)
-//      - overlaps may occur if you have narrow spiral corridors (i.e stairs), this make triangulation to fail
-//   * generally the best choice if you precompute the nacmesh, use this if you have large open areas
-// 2) Monotone partioning
-//   - fastest
-//   - partitions the heightfield into regions without holes and overlaps (guaranteed)
-//   - creates long thin polygons, which sometimes causes paths with detours
-//   * use this if you want fast navmesh generation
-String partitionType = "Sample partition watershed";
-
-if (partitionType.equals("Sample partition watershed")) {
-    if (!RecastBuilder.buildDistanceField(context, compactHeightfield)) {
-        System.out.println("Could not build distance field");
-        return;
-    }
-    if (!RecastBuilder.buildRegions(context, compactHeightfield, config)) {
-        System.out.println("Could not build watershed regions");
-        return;
-    }
-}
-
-if (partitionType.equals("Sample partition monotone")) {
-    if (!RecastBuilder.buildRegionsMonotone(context, compactHeightfield, config)) {
-        System.out.println("Could not build monotone regions");
-        return;
-    }
-}
-
-// Step 5. Trace and simplify region contours.
-// Create contours.
-ContourSet contourSet = new ContourSet();
-
-if (!RecastBuilder.buildContours(context, compactHeightfield, 2f, config.getMaxEdgeLength(), contourSet)) {
-    System.out.println("Could not create contours");
-    return;
-}
-
-// Step 6. Build polygons mesh from contours.
-// Build polygon navmesh from the contours.
-PolyMesh polyMesh = new PolyMesh();
-
-if (!RecastBuilder.buildPolyMesh(context, contourSet, config.getMaxVertsPerPoly(), polyMesh)) {
-    System.out.println("Could not triangulate contours");
-    return;
-}
-
-// Step 7. Create detail mesh which allows to access approximate height on each polygon.
-PolyMeshDetail polyMeshDetail = new PolyMeshDetail();
-
-if (!RecastBuilder.buildPolyMeshDetail(context, polyMesh, compactHeightfield, config, polyMeshDetail)) {
-    System.out.println("Could not build detail mesh.");
-    return;
-}
-
-// (Optional) Step 8. Create Detour data from Recast poly mesh.
-// The GUI may allow more max points per polygon than Detour can handle.
-// Only build the detour navmesh if we do not exceed the limit.
-if (config.getMaxVertsPerPoly() > DetourBuilder.VERTS_PER_POLYGON()) {
-    return;
-}
-NavMeshCreateParams createParams = new NavMeshCreateParams();
-createParams.getData(polyMesh);
-createParams.getData(polyMeshDetail);
-//setting optional off-mesh connections (in my example there are none)
-createParams.getData(config);
-createParams.setBuildBvTree(true);
-        
-char[] navData = DetourBuilder.createNavMeshData(createParams);
-        
-if (navData == null) {
-    System.out.println("Could not build Detour navmesh.");
-    return;
-}
-        
-NavMesh navMesh = new NavMesh();
-       
-if (!navMesh.isAllocationSuccessful()) {
-    System.out.println("Could not create Detour navmesh");
-    return;
-}
-        
-Status status;
-status = navMesh.init(navData, TileFlags.DT_TILE_FREE_DATA.value());
-if (status.isFailed()) {
-    System.out.println("Could not init Detour navmesh");
-    return;
-}
-
-NavMeshQuery query = new NavMeshQuery();
-status = query.init(navMesh, 2048);
-if (status.isFailed()) {
-    System.out.println("Could not init Detour navmesh query");
-    return;
-}
-
-----
-
-After this (if everything is successful) you can use methods in `query` that was created for path-finding purposes.
-
-
-== How to get jNavigation
-
-There is 2 ways to get jNavigation:
-
-*  as plugin form
-*  as developmental project
-
-
-=== Plugin
-
-You can download “stable version from link:https://github.com/QuietOne/jNavigationPlugin/tree/master[repository]
-
-
-=== Developmental project
-
-Instructions for downloading and setting it up:
-
-*  Download C++ wrapper from link:https://github.com/QuietOne/jNavigation-native[jNavigationNative repository]
-*  Build downloaded project with C++ compiler
-*  Download java library from link:https://github.com/QuietOne/jNavigation[jNavigation repository]
-*  In Java project in class `com.jme3.ai.navigation.utils.RecastJNI.java` change +++<abbr title="Uniform Resource Locator">URL</abbr>+++ to where your build of C++ project is.
-
-[source,java]
-----
-
-static {
-    // the URL that needs to be changed
-    System.load(".../jNavigationNative.dll");
-}
-
-----
-
-If there is problem with building C++ project see <<jme3/advanced/building_recast#,link>>.
-
-
-=== Questions & Suggestions
-
-*  For suggestion and/or question on jNavigation post on link:http://hub.jmonkeyengine.org/forum/board/development/summer-of-code/[forum]
-*  For question on Recast (C++ library) ask on link:https://groups.google.com/forum/#!forum/recastnavigation[Google groups]
-
-
-=== Source
-
-*  link:https://github.com/QuietOne/jNavigationPlugin/tree/master[jNavigation plugin repository]
-*  link:https://github.com/QuietOne/jNavigation[Developmental jNavigation repository]
-*  link:https://github.com/QuietOne/jNavigation-native[Developmental jNavigationNative repository]
-
-
-==== Useful links
-
-*  <<jme3/advanced/building_recast#,How to build the native recast bindings>>
-*  link:http://www.critterai.org/projects/nmgen_study/[Study: Navigation Mesh Generation]
-*  link:http://www.stevefsp.org/projects/rcndoc/prod/index.html[Documentation of C++ Recast library] It can be useful for tracing bugs.

+ 0 - 188
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/android.adoc

@@ -1,188 +0,0 @@
-= android
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-:experimental:
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== Changing the Name of Your APK/Application:
-
-. Open your project’s properties and navigate to Application
-. Update the title
-
-This has no real effect, however it keeps continuity throughout your app. Actually, this likely renamed the window created to display your app. So, now go change the actual name of your APK:
-
-. Select `File View` in the left pane of the SDK.
-. Navigate to the `mobile/res/values` directory and open the `strings.xml` file.
-. There should be a string tag with the following key pair: name="app_name".
-. Replace `MyGame` with your app`'s name and save the file.
-. In `File view`, navigate to nbproject and open the `project.properties` file.
-. Edit the value of `application.title` to reflect your game`'s name (unless step 1/2 above altered this for you).
-
-
-== Changing the APK Icon:
-
-. Under the `File view` of your project navigate to `mobile/res` and add a `drawable` folder if one does not exist.
-. Add your icon file (png).
-. Open the Android Manifest file and add the following to your application tag:
-+
-`android:icon="@drawable/<ICON FILE NAME WITHOUT EXTENSION>"`
-
-. If you would like multiple size icons, add the following folders:
-+
-....
-drawable-hdpi (should contain the icon named the same at 72×72 pixels)\\
-drawable-ldpi (should contain the icon named the same at 36×36 pixels)\\
-drawable-mdpi (should contain the icon named the same at 48×48 pixels)\\
-drawable-xhdpi (should contain the icon named the same at 96×96 pixels)\\
-....
-
-
-== Adding a Splash Screen to your app:
-
-. Open `Android Main Activity`, either through the `Important Files` list in `Project view` or in the `File view` under `mobile/src/<package name>` directory.
-. Add the following line to the `MainActivity` method:
-+
-`splashPicID = R.drawable.<IMAGE NAME WITHOUT EXTENSION>;`
-
-. Add the image to the `mobile\res\drawable` directory.
-
-Compiling Google Play Services and Adding it to Your Project:
-
-First get the api:
-
-. Download the google play services add-on through the SDK Manager under Extras (named Google Play services).
-. Copy the directory from where you downloaded it to another location (like JME Projects Folder).
-
-
-== Compile the jar file for use with your project:
-
-. In the directory you copied, there is an android project file.
-. In JME`'s IDE, open this project
-. In the General section of the project properties, there is a list of potential Android target platforms. Select the one you are using for your project by clicking on the list (this is not intuitive at all, as the list looks like nothing more than info… not selectable items).
-. Under the Library section, click the checkbox that is labeled:
-* [*] Is Library
-. Click btn:[Ok] and then Clean & Build this project.
-
-This will compile the play services all proper like so you can add it to your project. Now, for that step:
-
-. Open your project’s properties.
-. In the Libraries section, click the btn:[Add JAR/folder] button.
-. Find and add the jar you compiled above. This can be found in:
-+
-`<COPIED DIR>\libproject\google-play-services_lib\libs\google-play-services.jar`
-
-. Modify your Android Manifest by adding the following tags under application:
-+
-`<meta-data android:name="com.google.android.gms.games.APP_ID"
-android:value="@string/app_id" />
-<meta-data android:name="com.google.android.gms.version"
-android:value="@integer/google_play_services_version"/>`
-. Add the following tag to your mobile/res/values/integers.xml file (create it if it doesn’t exist):
-+
-`<integer name="google_play_services_version">4323000</integer>`
-. Clean & Build your project
-
-
-== Adding Play Games Services to Your Project:
-
-. Download the project from:
-+
-link:https://github.com/playgameservices/android-samples[https://github.com/playgameservices/android-samples]
-. In the following directory, you find java files you will need to add to your project:
-+
-....
-<DOWNLOAD DIR>\android-samples-master\BasicSamples\libraries\BaseGameUtils\src\main\java\com\google\example\games\basegameutils\\
-Grab GameHelper.java and GameHelperUtil.java and add them to the directory you projects Main Activity is in\\
-....
-
-. In the following directory, you find a resource file you will need to add to your project:
-+
-....
-<DOWNLOAD DIR>\android-samples-master\BasicSamples\libraries\BaseGameUtils\src\main\res\values\\
-Grab the gamehelper_strings.xml into your mobile/res/values folder\\
-....
-
-. Add the following jar from the Adroid SDK folder to your project as a library:
-+
-....
-<ANDROID SDK INSTALL DIR>\adt-bundle-windows-x86_64-20131030\sdk\extras\android\support\v4\android-support-v4.jar\\
-....
-+
-And this is the basics for setting this up.
-
-
-== Adding AdMob Support to Your Project:
-
-. Open your Android Manifest and add the following tag update the application tag:
-+
-`<activity android:name="com.google.android.gms.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>`
-. After the application tag, add the following tags:
-+
-`<uses-permission android:name="android.permission.INTERNET"/> +
-<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>`
-. In the onCreate method of your Main Activity, add the following snippet (configure however you like):
-+
-....
-adView = new AdView(this);
-adView.setAdSize(AdSize.FULL_BANNER);
-adView.setAdUnitId(“<WHATEVER AD UNIT ID YOU ARE ASSIGNED THROUGH THE GOOGLE DEV CONSOLE>”);
-adView.buildLayer();
-LinearLayout ll = new LinearLayout(this);
-ll.setGravity(Gravity.BOTTOM);
-ll.addView(adView);
-addContentView(ll, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));
-....
-
-
-== Communication Between your Application & Main Activity:
-
-. Create an interface named something along the lines of `JmeToHarness.java`.
-. Open your `Android Main Activity` and implement this interface.
-. In `Main.java` of your Application, add the following:
-+
-....
- JmeToHarness harness;
- public JmeToHarness getHarness() {
-   return this.harness;
- }
- public void setHarnessListener(JmeToHarness harness) {
-    this.harness = harness;
- }
-
-....
-
-. Add the following snippet to the onCreate method of your Android Main Activity:
-+
-....
-if (app != null)
-    ((Main)app).setHarnessListener(this);
-
-....
-
-. Add error handling if you want it.
-
-This bit is ultra useful for calling AdMob changes and Play Games methods (like updating achievements, leader boards, etc, etc)
-
-EDIT: Keep this as generic as you possibly can as it should plug &amp; play with iOS &amp; Applets if you keep that in mind. Google Play Services/Play Games Services works for all of the above… soooo… anyways.
-
-
-== Changing the Package Name After Project Creation:
-
-. Open the project properties of your Application
-. Navigate to `menu:Application[Android]` and edit the package name.
-
-This does absolutely nothing, but help with consistency.
-
-So, to actually change the package name, you will want to:
-
-. Open the `Android Manifest`
-. Edit the manifest tag key pair: `package="<THE NEW PACKAGE NAME>"`
-. In `File view`, navigate to nbproject and open the `project.properties` file.
-. Edit the value of `mobile.android.package`.
-
-Take a moment or 4 to navigate through the directory structure in file view and remove any artifacts left from the previous package name build. Alternately, you can run `Clean` on the project prior to updating the package name.

+ 0 - 383
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/animation/animation.adoc

@@ -1,383 +0,0 @@
-= Animation in jME3
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-In 3D games, you do not only load static 3D models, you also want to be able to trigger animations in the model from the Java code.
-
-
-== Requirements
-
-JME3 only loads and plays animated models, it does not create them.
-
-What is required for an animated model? (<<jme3/terminology#Animation,See also: Animation terminology>>)
-
-.  For each model, you have to segment the model into a skeleton (*bone rigging*).
-.  For each motion, you have to specify how the animation distorts parts of the model (*skinning*).
-.  For each animation, you have to specify a series of snapshots of how the bones are positioned (*keyframes*).
-.  One model can contain several animations. You give every animation a name when you save it in the mesh editor.
-
-Unless you download free models, or buy them from a 3D artist, you must create your animated models in an *external mesh editor* (for example, Blender) yourself.
-
-*  <<sdk/blender#,Converting Blender Models to JME3 (.J3o files)>>
-//*  link:http://www.youtube.com/user/aramakara[Video Series: Creating models in Blender, OgreMax, 3dsMax]
-*  link:http://www.youtube.com/watch?v=NdjC9sCRV0s[Video: Creating and Exporting OgreXML Animations from Blender 2.61 to JME3 ]
-*  link:https://docs.google.com/fileview?id=0B9hhZie2D-fENDBlZDU5MzgtNzlkYi00YmQzLTliNTQtNzZhYTJhYjEzNWNk&hl=en[Scene Workflow: Exporting OgreXML scenes from Blender to JME3]
-*  link:https://docs.google.com/leaf?id=0B9hhZie2D-fEYmRkMTYwN2YtMzQ0My00NTM4LThhOTYtZTk1MTRlYTNjYTc3&hl=en[Animation Workflow: Create Animated UV-Mapped OgreXML Models in Blender, and use them in JME3]
-*  link:http://www.youtube.com/watch?v=IDHMWsu_PqA[Video: Creating Worlds with Instances in Blender]
-
-What is required in your JME3-based Java class?
-
-*  One Animation Control per animated model.
-*  As many Animation Channels per Control as you need to play your animations. In simple cases one channel is enough, sometimes you need two or more Channels per model to play gestures and motions in parallel.
-
-
-== Code Samples
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/model/anim/TestSpatialAnim.java[TestSpatialAnim.java]
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/model/anim/TestBlenderAnim.java[TestBlenderAnim.java]
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/model/anim/TestBlenderObjectAnim.java[TestBlenderObjectAnim.java]
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/model/anim/TestOgreAnim.java[TestOgreAnim.java]
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/model/anim/TestOgreComplexAnim.java[TestOgreComplexAnim.java]
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/model/anim/TestCustomAnim.java[TestCustomAnim.java]
-
-
-== Controlling Animations
-
-
-=== The Animation Control
-
-Create one `com.jme3.animation.AnimControl` object in your JME3 application for each animated model that you want to control. You have to register each animated model to one of these Animation Controls. The control object gives you access to the available animation sequences in the model.
-
-[source,java]
-----
-
-  AnimControl playerControl; // you need one Control per model
-  Node player = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml"); // load a model
-  playerControl = player.getControl(AnimControl.class); // get control over this model
-  playerControl.addListener(this); // add listener
-
-----
-
-
-=== Animation Channels
-
-An Animation Control has several Animation Channels (`com.jme3.animation.AnimChannel`). Each channel can play one animation sequence at a time.
-
-There often are situations where you want to run several animation sequences at the same time, e.g. "`shooting`" while walking or "`boxing`" while jumping. In this case, you create several channels, assign an animation to each, and play them in parallel.
-
-[source,java]
-----
-
-  AnimChannel channel_walk = playerControl.createChannel();
-  AnimChannel channel_jump = playerControl.createChannel();
-  ...
-
-----
-
-To reset a Control, call `control.clearChannels()`.
-
-
-=== Skeleton Control
-
-
-The Skeleton control deforms a model according to a skeleton. Use it to attach other geometries to your model such as clothing, weapons, accessories or a particle emitter effect. You access the control the same way as you would the AnimControl. 
-
-.Control resides in the main node of your model
-[source,java]
-----
-
-SkeletonControl skeletonControl;
-
-skeletonControl = player.getControl(SkeletonControl.class);
-
-----
-
-.Control rsides somewhere other than main node
-[source,java]
-----
-player.depthFirstTraversal(new SceneGraphVisitorAdapter() {
-    @Override
-    public void visit(Node node) {
-        if (node.getControl(SkeletonControl.class) != null) {
-            skeletonControl = node.getControl(SkeletonControl.class);
-        }
-    }
-});
-----
-
-
-== Animation Control Properties
-
-The following information is available for an AnimControl.
-[cols="2", options="header"]
-|===
-
-a|AnimControl Property
-a|Usage
-
-a|createChannel()
-a|Returns a new channel, controlling all bones by default.
-
-a|getNumChannels()
-a|The number of channels registered to this Control.
-
-a|getChannel(0)
-a|Gets individual channels by index number. At most `getNumChannels()`.
-
-a|clearChannels()
-a|Clear all channels in this control.
-
-a|addListener(animEventListener) +
-removeListener(animEventListener) +
-clearListeners()
-a|Adds or removes listeners to receive animation related events.
-
-|===
-
-[cols="2", options="header"]
-|===
-
-a|AnimControl Property
-a|Usage
-
-a|setAnimations(aniHashMap)
-a|Sets the animations that this AnimControl is capable of playing. The animations must be compatible with the skeleton given in the constructor.
-
-a|addAnim(boneAnim) +
-removeAnim(boneAnim)
-a|Adds or removes an animation from this Control.
-
-a|getAnimationNames()
-a|A String Collection of names of all animations that this Control can play for this model.
-
-a|getAnim("`anim`")
-a|Retrieve an animation from the list of animations.
-
-a|getAnimationLength("`anim`")
-a|Returns the length of the given named animation in seconds
-
-|===
-
-[cols="2", options="header"]
-|===
-
-a|AnimControl Property
-a|Usage
-
-a|getSkeleton()
-a|The Skeleton object controlled by this Control.
-
-|===
-
-== Skeleton Control Properties
-
-The following information is available for an SkeletonControl.
-
-[cols="2", options="header"]
-|===
-
-a|SkeletonControl Property
-a|Usage
-
-a|getSkeleton()
-a|The Skeleton object controlled by this Control.
-
-a|getTargets()
-a|The Skin objects controlled by this Control, as Mesh array.
-
-a|getAttachmentsNode("`bone`")
-a|Returns the attachment node of a bone. Attach models and effects to this node to make them follow this bone's motions.
-
-|===
-
-== Animation Channel Properties
-
-The following properties are set per AnimChannel.
-[cols="2", options="header"]
-|===
-
-a|AnimChannel Property
-a|Usage
-
-a|setLoopMode(LoopMode.Loop);
-a| From now on, the animation on this channel will repeat from the beginning when it ends.
-
-a|setLoopMode(LoopMode.DontLoop);
-a| From now on, the animation on this channel will play once, and the freeze at the last keyframe.
-
-a|setLoopMode(LoopMode.Cycle);
-a| From now on, the animation on this channel will play forward, then backward, then again forward, and so on.
-
-a|setSpeed(1f);
-a| From now on, play this animation slower (&lt;1f) or faster (&gt;1f), or with default speed (1f).
-
-a|setTime(1.3f);
-a| Fast-forward or rewind to a certain moment in time of this animation.
-
-|===
-
-The following information is available for a channel.
-[cols="2", options="header"]
-|===
-
-a|AnimChannel Property
-a|Usage
-
-a|getAnimationName()
-a|The name of the animation playing on this channel. Returns `null` when no animation is playing.
-
-a|getLoopMode()
-a|The current loop mode on this channel. The returned com.jme3.animation enum can be LoopMode.Loop, LoopMode.DontLoop, or LoopMode.Cycle.
-
-a|getAnimMaxTime()
-a|The total length of the animation on this channel. Or `0f` if nothing is playing.
-
-a|getTime()
-a|How long the animation on this channel has been playing. It returns `0f` if the channel has not started playing yet, or a value up to getAnimMaxTime().
-
-a|getControl()
-a|The AnimControl that belongs to this AnimChannel.
-
-|===
-
-Use the following methods to add or remove individual bones to an AnimChannel. This is useful when you play two animations in parallel on two channels, and each controls a subset of the bones (e.g. one the arms, and the other the legs).
-[cols="2", options="header"]
-|===
-
-a|AnimChannel Methods
-a|Usage
-
-a|addAllBones()
-a|Add all the bones of the model's skeleton to be influenced by this animation channel. (default)
-
-a|addBone("`bone1`") +
-addBone(bone1)
-a|Add a single bone to be influenced by this animation channel.
-
-a|addToRootBone("`bone1`") +
-addToRootBone(bone1)
-a|Add a series of bones to be influenced by this animation channel: Add all bones, starting from the given bone, to the root bone.
-
-a|addFromRootBone("`bone1`") +
-addFromRootBone(bone1)
-a|Add a series of bones to be influenced by this animation channel: Add all bones, starting from the given root bone, going towards the children bones.
-
-|===
-
-
-== Playing Animations
-
-Animations are played by channel.
-
-NOTE: Whether the animation channel plays continuously or only once, depends on the Loop properties you have set.
-
-[cols="2", options="header"]
-|===
-
-a|Channel Method
-a|Usage
-
-a|channel_walk.setAnim("`Walk`",0.50f);
-a| Start the animation named "`Walk`" on channel channel_walk. +
-The float value specifies the time how long the animation should overlap with the previous one on this channel. If set to 0f, then no blending will occur and the new animation will be applied instantly.
-
-|===
-
-[TIP]
-====
-Use the AnimEventLister below to react at the end or start of an animation cycle.
-====
-
-
-=== Usage Example
-
-In this short example, we define the space key to trigger playing the "`Walk`" animation on channel2.
-
-[source,java]
-----
-
-  public void simpleInitApp() {
-    ...
-    inputManager.addMapping("Walk", new KeyTrigger(KeyInput.KEY_SPACE));
-    inputManager.addListener(actionListener, "Walk");
-    ...
-  }
-
-  private ActionListener actionListener = new ActionListener() {
-    public void onAction(String name, boolean keyPressed, float tpf) {
-      if (name.equals("Walk") && !keyPressed) {
-        if (!channel2.getAnimationName().equals("Walk")) {
-          channel2.setLoopMode(LoopMode.Loop);
-          channel2.setAnim("Walk", 0.50f);
-        }
-      }
-    }
-  };
-
-----
-
-
-== Animation Event Listener
-
-A jME3 application that contains animations can implement the `com.jme3.animation.AnimEventListener` interface.
-
-[source,java]
-----
-public class HelloAnimation extends SimpleApplication
-                     implements AnimEventListener { ... }
-----
-
-This optional Listener enables you to respond to animation start and end events, `onAnimChange()` and `onAnimCycleDone()`.
-
-
-=== Responding to Animation End
-
-The `onAnimCycleDone()` event is invoked when an animation cycle has ended. For non-looping animations, this event is invoked when the animation is finished playing. For looping animations, this event is invoked each time the animation loop is restarted.
-
-You have access to the following objects:
-
-*  The Control to which the listener is assigned.
-*  The animation channel being played.
-*  The name of the animation that has just finished playing.
-
-[source,java]
-----
-
-  public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
-    // test for a condition you are interested in, e.g. ...
-    if (animName.equals("Walk")) {
-      // respond to the event here, e.g. ...
-      channel.setAnim("Stand", 0.50f);
-    }
-  }
-
-----
-
-
-=== Responding to Animation Start
-
-The `onAnimChange()` event is invoked every time before an animation is set by the user to be played on a given channel (`channel.setAnim()`).
-
-You have access to the following objects:
-
-*  The Control to which the listener is assigned.
-*  The animation channel being played.
-*  The name of the animation that will start playing.
-
-[source,java]
-----
-
-  public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {
-    // test for a condition you are interested in, e.g. ...
-    if (animName.equals("Walk")) {
-      // respond to the event here, e.g. ...
-      channel.setAnim("Reset", 0.50f);
-    }
-  }
-
-----

+ 0 - 290
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/animation/cinematics.adoc

@@ -1,290 +0,0 @@
-= JME3 Cinematics
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-JME3 cinematics (com.jme.cinematic) allow you to remote control nodes and cameras in a 3D game: You can script and and play cinematic scenes. You can use cinematics to create link:http://en.wikipedia.org/wiki/Cutscene[cutscenes] and movies/trailers for your game. Another good use case is efficient “destruction physics: Playing back prerecorded flying pieces of debris for demolitions is much faster than calculating them with live physics.
-
-Internally, Cinematics are implemented as <<jme3/advanced/application_states#,AppStates>>. 
-
-Short overview of the cinematic process:
-
-.  Plan the script of your movie. +
-Write down a timeline (e.g. on paper) of which character should be at which spot at which time.
-.  Attach the scene objects that you want to remote-control to one Node. +
-This Node can be the rootNode, or a Node that is attached to the rootNode. 
-.  Create a Cinematic object for this movie scene. The Cinematic will contain and manage the movie script.
-.  For each line in your script (for each keyframe in your timeline), add a CinematicEvent to the Cinematic. 
-
-
-== Sample Code
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/animation/TestCinematic.java[TestCinematic.java]
-
-
-== How to Use a Cinematic
-
-A Cinematic is like a movie script for a node. 
-
-[source,java]
-----
-Cinematic cinematic = new Cinematic(sceneNode, duration);
-cinematic.addCinematicEvent(starttime1, event1);
-cinematic.addCinematicEvent(starttime2, event2);
-cinematic.addCinematicEvent(starttime2, event3);
-...
-stateManager.attach(cinematic);
-
-----
-
-.  Create one Cinematic per scripted scene.
-**  `sceneNode` is the node containing the scene (can be the rootNode).
-**  `duration` is the duration of the whole scene in seconds.
-**  Each Cinematic is a set of CinematicEvents, that are triggered at a given moment on the timeline.
-
-.  Create one CinematicEvent for each line of your movie script.  
-**  `event` is one motion of a moving object. You can add several events. More details below.
-**  `starttime` is the time when this particular cinematic event starts on the timeline. Specify the start time in seconds since the beginning of the cinematic.
-
-.  Attach the Cinematic to the SimpleApplication's stateManager. 
-.  Play, stop and pause the Cinematic from your code.
-
-[cols="2", options="header"]
-|===
-
-a|Method
-a|Usage
-
-a|cinematic.play()
-a|Starts playing the cinematic from the start, or from where it was paused.
-
-a|cinematic.stop()
-a|Stops playing the cinematic and rewinds it.
-
-a|cinematic.pause()
-a|Pauses the cinematic.
-
-|===
-
-
-== Events(CinematicEvents)
-
-Just like a movie script consists of lines with instructions to the actors, each Cinematic consists of a series of events.
-
-Here is the list of available CinematicEvents that you use as events. Each track remote-controls scene objects in a different way:
-[cols="20,80", options="header"]
-|===
-
-a|Events(CinematicEvents)
-a|Description
-
-a|MotionEvent
-a|Use a MotionEvent to move a Spatial non-linearly over time. A MotionEvent is based on a list of waypoints in a MotionPath. The curve goes through each waypoint, and you can adjust the tension of the curve to modify the roundedness of the path. This is the motion interpolation you are going to use in most cases. 
-
-a|SoundEvent
-a|Use a SoundEvent to play a <<jme3/advanced/audio#,sound>> at a given time for the given duration.
-
-a|GuiEvent
-a|Displays a <<jme3/advanced/nifty_gui#,Nifty GUI>> at a given time for the given duration. Use it to display subtitles or HUD elements. Bind the Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ XML to the cinematic using `cinematic.bindUi(“path/to/nifty/file.xml);`
-
-a|AnimationEvent
-a|Use this to start playing a model <<jme3/advanced/animation#,animation>> at a given time (a character walking animation for example)
-
-|===
-
-You can add custom events by extending AbstractCinematicEvent.
-
-
-=== MotionEvent
-
-A MotionEvent moves a Spatial along a complex path.
-
-[source,java]
-----
-MotionEvent events= new MotionEvent (thingNode, path);
-----
-
-Details of the constructor:
-
-*  `thingNode` is the Spatial to be moved.
-*  `path` is a complex <<jme3/advanced/motionpath#,MotionPath>>.
-
-To create a MotionEvent, do the following:
-
-.  Create a MotinPath.
-.  Create a MotionEvent based on the MotionPath.
-.  Configure your MotionEvent (see below).
-.  Add the MotionEvent to a Cinematic.
-
-[cols="2", options="header"]
-|===
-
-a|MotionEvent configuration method
-a|Usage
-
-a|event.setLoopMode(LoopMode.Loop)
-a|Sets whether the animation along this path should loop (LoopMode.Loop) or play only once (LoopMode.DontLoop).
-
-a|event.setDirectionType(MotionEvent.Direction.None)
-a|Sets the direction behavior type of the controlled node. Direction.None deactivates this feature. You can choose from the following options: LookAt, Path, PathAndRotation, Rotation.
-
-a|event.setDirectionType(MotionEvent.Direction.LookAt)
-a|The spatial turns (rotates) to keep facing a certain point while moving. Specify the point with the `setLookAt()` method.
-
-a|event.setDirectionType(MotionEvent.Direction.Path)
-a|The spatial always faces in the direction of the path while moving.
-
-a|event.setDirectionType(MotionEvent.Direction.PathAndRotation)
-a|The spatial faces the direction of the path, plus an added rotation. Use together with the `setRotation()` method.
-
-a|event.setDirectionType(MotionEvent.Direction.Rotation)
-a|The spatial spins (rotates) while moving. You describe the spin by a custom quaternion. Use together with the `setRotation()` method.
-
-a|event.setLookAt(teapot.getWorldTranslation(), Vector3f.UNIT_Y)
-a|The spatial always faces towards this location. Use together with `MotionEvent.Direction.LookAt`.
-
-a|event.setRotation(quaternion)
-a|Sets the rotation. Use together with `MotionEvent.Direction.Rotation` or `MotionEvent.Direction.PathAndRotation`.
-
-|===
-
-[TIP]
-====
-Most likely you remote-control more than one object in your scene. Give the events and paths useful names such as `dragonEvent`, `dragonPath`, `heroEvent`, `heroPath`, etc.
-====
-
-
-=== SoundEvent
-
-A SoundEventplays a sound as part of the cinematic. 
-
-[source,java]
-----
-SoundEvent( audioPath, isStream, duration, loopMode )
-----
-
-Details of the constructor:
-
-*  `audioPath` is the path to an audio file as String, e.g. “Sounds/mySound.wav.
-*  `isStream` toggles between streaming and buffering. Set to true to stream long audio file, set to false to play short buffered sounds.
-*  `duration` is the time that it should take to play.
-*  `loopMode` can be LoopMode.Loop, LoopMode.DontLoop, LoopMode.Cycle.
-
-
-=== GuiEvent
-
-A GuiEventshows or hide a NiftyGUI as part of a cinematic.
-
-[source,java]
-----
-GuiEvent( screen, duration, loopMode )
-----
-
-You must use this together with bindUI() to specify the Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ XML file that you want to load:
-
-[source,java]
-----
-cinematic.bindUi("Interface/subtitle.xml");
-----
-
-Details of the constructor:
-
-*  `screen` is the name of the Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ screen to load, as String. 
-*  `duration` is the time that it should take to play.
-*  `loopMode` can be LoopMode.Loop, LoopMode.DontLoop, LoopMode.Cycle.
-
-
-=== AnimationEvent
-
-An AnimationEvent triggers an animation as part of a cinematic.
-
-[source,java]
-----
-AnimationEvent( thingNode, animationName, duration, loopMode )
-----
-
-Details of the constructor:
-
-*  `thingNode` is the Spatial whose animation you want to play.
-*  `animationName` the name of the animation stored in the animated model that you want to trigger, as a String.
-*  `duration` is the time that it should take to play.
-*  `loopMode` can be LoopMode.Loop, LoopMode.DontLoop, LoopMode.Cycle.
-
-
-=== Camera Management
-
-There is a built in system for camera switching in Cinematics. It based on CameraNode, and the cinematic just enable the given CameraNode control at a given time.
-
-First you have to bind a camera to the cinematic with a unique name. You'll be provided with a CameraNode
-
-[source,java]
-----
-
- CameraNode camNode = cinematic.bindCamera("topView", cam);
-
-----
-
-then you can do whatever you want with this camera node : place it so that you have a the camera angle you'd like, attach it to a motion event to have some camera scrolling, attach control of your own that give it whatever behavior you'd like.
-In the above example, I want it to be a top view of the scene looking at the world origin.
-
-[source,java]
-----
-
- //set its position
- camNode.setLocalTranslation(new Vector3f(0, 50, 0));
- // set it to look at the world origin
- camNode.lookAt(Vector3F.ZERO, Vector3f.UNIT_Y);
-
-----
-
-Then i just have to schedule its activation in the cinematic. I want it to get activated 3 seconds after the start of the cinematic so I just have to do 
-
-[source,java]
-----
-
- cinematic.activateCamera(3,”topView”);
-
-----
-
-
-=== Customizations
-
-You can extend individual CinematicEvents. The link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/animation/SubtitleTrack.java[SubtitleTrack.java example] shows how to extend a GuiTrack to script subtitles. See how the subtitles are used in the link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/animation/TestCinematic.java[TestCinematic.java example].
-
-You can also create new CinematicEvent by extending link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-core/src/main/java/com/jme3/cinematic/events/AbstractCinematicEvent.java[AbstractCinematicEvent]. An AbstractCinematicEvent implements the CinematicEvent interface and provides duration, time, speed, etc… management. Look at the link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/animation/TestCinematic.java[TestCinematic.java example] is to use this for a custom fadeIn/fadeOut effect in combination with a com.jme3.post.filters.FadeFilter.
-
-
-== Interacting with Cinematics
-
-
-=== CinematicEventListener
-
-[source,java]
-----
-CinematicEventListener cel = new CinematicEventListener() {
-  public void onPlay(CinematicEvent cinematic) {
-    chaseCam.setEnabled(false);
-    System.out.println("play");
-  }
-
-  public void onPause(CinematicEvent cinematic) {
-    chaseCam.setEnabled(true);
-    System.out.println("pause");
-  }
-
-  public void onStop(CinematicEvent cinematic) {
-    chaseCam.setEnabled(true);
-    System.out.println("stop");
-  }
-}
-cinematic.addListener(cel);
-----
-
-
-=== Physics Interaction
-
-Upcoming.

+ 0 - 98
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/animation/motionpath.adoc

@@ -1,98 +0,0 @@
-= MotionPath
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-A MotionPath describes the motion of a spatial between waypoints. The path can be linear or rounded. You use MotionPaths to remote-control a spatial, or the camera.
-
-[TIP]
-====
-If you want to remote-control a whole cutscene with several spatials moving at various times, then we recommened you use MotionPaths together with <<jme3/advanced/cinematics#,Cinematics>>.
-====
-
-
-== Sample Code
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/animation/TestMotionPath.java[TestMotionPath.java]
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/animation/TestCameraMotionPath.java[TestCameraMotionPath.java]
-
-
-== What Are Way Points?
-
-When shooting a movie scene, the director tells actors where to walk, for example, by drawing a series of small crosses on the floor. Cameramen often mount the camera on rails (so called dolly track) so they can follow along complex scenes more easily. 
-
-In JME3, you use MotionPaths to specify a series of positions for a character or the camera. The MotionPath automatically updates the transformation of the spatial in each frame to make it move from one point to the next.
-
-*  *A way point* is one positions on a path. 
-*  *A MotionPath* contains a list of all way points of one path. 
-
-The final shape of the path is computed using a linear interpolation or a link:http://www.mvps.org/directx/articles/catmull/[Catmull-Rom] spline interpolation on the way points. 
-
-
-== Create a MotionPath
-
-Create a Motionpath object and add way points to it.
-
-[source,java]
-----
-MotionPath path = new MotionPath();
-path.addWayPoint(new Vector3f(10, 3, 0));
-path.addWayPoint(new Vector3f(8, -2, 1));
-...
-
-----
-
-You can configure the path as follows.
-[cols="2", options="header"]
-|===
-
-a| MotionPath Method 
-a| Usage 
-
-a|path.setCycle(true)
-a|Sets whether the motion along this path should be closed (true) or open-ended (false). 
-
-a|path.addWayPoint(vector)
-a|Adds individual waypoints to this path. The order is relevant.
-
-a|path.removeWayPoint(vector) +
-removeWayPoint(index)
-a|Removes a way point from this path. You can specify the point that you want to remove as vector or as integer index.
-
-a|path.setCurveTension(0.83f)
-a|Sets the tension of the curve (Catmull-Rom Spline). A value of 0.0f results in a straight linear line, 1.0 a very round curve.
-
-a|path.getNbWayPoints()
-a|Returns the number of waypoints in this path.
-
-a|path.enableDebugShape(assetManager,rootNode)
-a|Shows a line that visualizes the path. Use this during development and for debugging so you see what you are doing.
-
-a|path.disableDebugShape()
-a|Hides the line that visualizes the path. Use this for the release build.
-
-|===
-
-
-== MotionPathListener
-
-You can hook interactions into a playing MotionPath. Register a MotionPathListener to the MotionPath to track whether way points have been reached, and then trigger a custom action. The onWayPointReach() method of the interface gives you access to the MotionEvent object `control`, and an integer value representing the current wayPointIndex.
-
-In this example, you just print the status at every way point. In a game you could trigger actions here: Transformations, animations, sounds, game actions (attack, open door, etc).
-
-[source,java]
-----
-path.addListener( new MotionPathListener() {
-  public void onWayPointReach(MotionEvent control, int wayPointIndex) {
-    if (path.getNbWayPoints() == wayPointIndex + 1) {
-      println(control.getSpatial().getName() + " has finished moving. ");
-    } else {
-      println(control.getSpatial().getName() + " has reached way point " + wayPointIndex);
-    }
-  }
-});
-----

+ 0 - 96
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/3d_models.adoc

@@ -1,96 +0,0 @@
-= Models and Scenes
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-:experimental:
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-Like <<jme3/advanced/shape#,Shape>>s, 3D models are also made up of <<jme3/advanced/mesh#,Mesh>>es, but models are more complex than Shapes. While Shapes are built into jME3, you typically create models in external 3D Mesh Editors. 
-
-
-== Using Models and Scenes with jME3
-
-To use 3D models in a jME3 application:
-
-.  Export the 3D model in Ogre XML or Wavefront OBJ format. Export Scenes as Ogre DotScene format.
-.  Save the files into a sub-directory of your jME3 `Assets` directory.
-.  In your code, you use the <<jme3/advanced/asset_manager#,Asset Manager>> to load models as <<jme3/advanced/spatial#,Spatial>>s into a jME application.
-+
-[source,java]
-----
-Spatial model = assetManager.loadModel(
-    "Models/MonkeyHead/MonkeyHead.mesh.xml" );
-----
-
-[NOTE]
-====
-(For the release build:) Use the jMonkeyEngine SDK to convert models to .j3o format. You don't need this step as long you still develop and test the application within the jMonkeyEngine SDK.
-====
-
-
-== Creating Models and Scenes
-
-To create 3D models and scenes, you need a 3D Mesh Editor such as link:http://www.blender.org/[Blender], with an <<jme3/advanced/ogrecompatibility#,OgreXML Exporter>> plugin. 
-
-[TIP]
-====
-Learn how to create link:http://en.wikibooks.org/wiki/Blender_3D:_Noob_to_Pro/UV_Map_Basics[UV textures] for more complex models, it looks more professional. 
-====
-
-3D model editors are third-party products, so please consult their documentation for instructions how to use them. Here is an example workflow for Blender users:
-
-*  <<jme3/external/blender#,Creating jME3 compatible 3D models in Blender>>
-
-To export your models as Ogre XML meshes with materials:
-
-. jMonkeyEngine requires a material file to be named the same name as the model so prior to opening the export dialog make it so. The model will export files named `ModelName.mesh.xml` with a `ModelName.material`, plus (optionally) `ModelName.skeleton.xml`, and some JPG files.
-.  Open the menu `menu:File[Export > Ogre3D]` to open the exporter dialog.
-.  In the `File Path` field: Select a target sub-directory of your `Project Assets/Textures/` directory. E.g. `Project Assets/Textures/ModelName/`. See <<jme3/intermediate/best_practices#multi-media-asset-pipeline#,Best Practices>>.
-.  In the panel at the bottom left of the export window toggle the following export settings: 
--  Swap Axis: xz-y
-- [*] Separate materials
-- [ ] Only Deformable Bones footnote:[Optional: If selected, and you have an Armature with the model, only the deform bones are exported.]
-- [ ] Export Scene footnote:[Toggle this to export your model in DotScene format]
-- [ ] Export Selected Only footnote:[Optional: If selected, you manually choose each object you want exported prior to opening the export dialog.]
-- [*] Export Meshes
-- [ ] Export Meshes Overwrite footnote:[Optional: If selected, it will overwrite the existing files in the target directory] 
-- [ ] Armature Animation footnote:[Optional: Only used if the model contains an armature.]
--  Trim Weights footnote:[Occasionally when exporting you may get a warning complaining about vertices weighted to too many bones. You are then asked to try increasing the trim weights option. Slightly increase this spinner and try exporting again. Repeat the process until the warning goes away.]
-- [*] Export Materials
-.  Click Export Ogre.
-
-You can now use the <<sdk#,jMonkeyEngine SDK>> to <<sdk/model_loader_and_viewer#,load and view models>>. You can <<sdk/scene_composer#,create scenes>> from them and write code that loads them into your application.
-
-
-== Blender Buffer Clearing
-
-
-Before exporting your Blender models, its is recommended that you clean the buffers of any unneeded `Action`, `Material`, `Texture` or `UV Image`. This is a straight forward process that only takes a few minutes. Failure to do so can lead you into a morass of problems, like having more than one AnimControl, duplicate materials and textures, wasted space from worthless images, just to mention a few potential troubles.
-
-Clearing Blender Material, Texture, UV Image Buffers::
-.  Open the `UV Image Editor`, `Material Tab` or `Texture Tab`.
-.  Select the btn:[Browse] button located next to the material, texture or UV Image name to load the item to be cleared.
-.  While holding kbd:[Shift] down, click the btn:[X] button, also known as the btn:[Unlink datablock] button, located next to the loaded item. An item that is unlinked will show a `0` before it when viewed by selecting the btn:[Browse] button and will not be saved if you exit Blender.
-.  Save your file.
-.  From the `Info` header select `menu:File[Open Recent > Your Saved File]`, to close and re-open your file.
-
-The exception to this rule is the `Linked Action` buffer, for animations, located in the `Dope Sheet Editor`. 
-
-Clearing The Linked Action Buffer::
-.  In the `Dope Sheet Editor`, change the context to `Action Editor`.
-.  Click the `Action to be linked` button and select the action you want cleared.
-.  Deselect the btn:[F] button to prevent it from saving.
-.  Change the editor type from `Dope Sheet` to `NLA Editor`. You will see the action listed.
-.  Click the btn:[Double Down Arrow] button next to the action to push it into the stack.
-.  Click the small start next to the track name.
-.  With the mouse inside the `NLA Track List`,  press kbd:[X] to delete both the track and strip.
-.  Save your file.
-.  From the `Info` header, select `menu:File[Open Recent > Your Saved File]`.
-.  Save your file again.
-.  From the `Info` header, select `menu:File[Open Recent > Your Saved File]` again.
-.  Change back to the `Dope Sheet Editor`.
-.  Click the btn:[Browse Action to be linked] button and you will see only the baked action remains and the buffer is now clear of unwanted actions. Select your action.
-.  Save your file.

+ 0 - 301
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/asset_manager.adoc

@@ -1,301 +0,0 @@
-= AssetManager
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-By assets we mean multi-media files, such as 3D models, materials, textures, scenes, custom shaders, music and sound files, and custom fonts. JME3 has an integrated asset manager that helps you keep your project assets organized. Think of the asset manager as the filesystem of your game, independent of the actual deployment platform. By default, store your assets in the `MyGame/assets/ ` directory of your project.
-
-Advantages of the AssetManager:
-
-*  The paths stay the same, no matter whether the game runs on Windows, Mac, Linux, etc!
-*  The AssetManager automatically caches and optimizes the handling of OpenGL objects. +
-For example, the same textures are not uploaded to the graphics card multiple times when multiple models use them.
-*  The <<sdk/default_build_script#,default build script>> automatically bundles the contents of the `assets` directory into the executable. 
-
-Advanced users can write a custom build and packaging script, and can register custom paths to the AssetManager, but this is up to you then. 
-
-
-== Context
-
-[source]
-----
-
-jMonkeyProjects/MyGame/assets/    # You store assets in subfolders here! <------
-jMonkeyProjects/MyGame/build/     # SDK generates built classes here (*)
-jMonkeyProjects/MyGame/build.xml  # You customize Ant build script here
-jMonkeyProjects/MyGame/nbproject/ # SDK stores default build.xml and meta data (*)
-jMonkeyProjects/MyGame/dist/      # SDK generates executable distribution here (*)
-jMonkeyProjects/MyGame/src/       # You store Java sources here
-jMonkeyProjects/MyGame/test/      # You store test classes here (optional)
-(*) Managed by jMonkeyEngine SDK -- don't edit!
-
-----
-
-See also <<jme3/intermediate/best_practices#,Best Practices>>.
-
-
-=== Usage
-
-The `assetManager` object is an com.jme3.asset.AssetManager instance that every com.jme3.app.Application can access. It maintains a root that also includes your project's classpath by default, so you can load any asset that's on the classpath, that is, the top level of your project directory. 
-
-You can use the inherited `assetManager` object directly, or use the accessor `app.getAssetManager()`.
-
-Here is an example how you load assets using the AssetManager. This lines loads a default Material from the built-in `Common/` directory:
-
-[source,java]
-----
-Material mat = (Material) assetManager.loadAsset(
-    new AssetKey("Common/Materials/RedColor.j3m"));
-----
-
-This Material is “somewhere in the jME3 JAR; the default Asset Manager is configured to handle a `Common/…` path correctly, so you don't have to specify the whole path when referring to built-in assets (such as default Materials).
-
-Additionally, you can configure the Asset Manager and add any path to its root. This means, you can load assets from any project directory you specify. The next example shows how you load assets from your project's assets directory.
-
-
-=== Asset Directory
-
-By default, jME3 searches for models in a directory named `assets`. 
-
-
-[IMPORTANT]
-====
-In Java projects created with the jMonkeyEngine SDK, an `assets` folder is created by default in your project directory. If you are using any other IDE, or the command line, you simply create an `assets` directory manually (see the Codeless Project tip below).
-====
-
-
-This is our recommended directory structure for storing assets:
-
-[source]
-----
-
-jMonkeyProjects/MyGame/src/...           # Packages, .java source code.
-jMonkeyProjects/MyGame/assets/...        # The assets directory:
-jMonkeyProjects/MyGame/assets/Interface/   # .font, .jpg, .png, .xml
-jMonkeyProjects/MyGame/assets/MatDefs/     # .j3md
-jMonkeyProjects/MyGame/assets/Materials/   # .j3m
-jMonkeyProjects/MyGame/assets/Models/      # .j3o
-jMonkeyProjects/MyGame/assets/Scenes/      # .j3o
-jMonkeyProjects/MyGame/assets/Shaders/     # .j3f, .vert, .frag
-jMonkeyProjects/MyGame/assets/Sounds/      # .ogg, .wav
-jMonkeyProjects/MyGame/assets/Textures/    # .jpg, .png; also .mesh.xml+.material, .mtl+.obj, .blend (!) 
-
-----
-
-These subdirectories are just the most common examples. 
-
-
-[IMPORTANT]
-====
-You can rename/delete/add (sub)directories inside the `assets` directory in any way you like. Note however that there is no automatic refactoring for asset paths in the SDK, so if you modify them late in the development process, you have to refactor all paths manually.
-====
-
-
-*Examples:* You can rename `assets/Sounds` to `assets/Audio`, you can delete `assets/MatDefs` if you don't use it, you can create `assets/AIscripts`, etc. You can rename/move the `assets/Textures` directory or its subdirectories, but then you have to re-export all models, and re-convert them all to .j3o, so plan ahead!
-
-
-[IMPORTANT]
-====
-Store textures in `assets/Textures/` before you work with them in a mesh editor! Export and save 3D model files (.mesh.xml+.material, .mtl+.obj, .blend) into the `assets/Textures/` (!) before you convert the model to binary format (.j3o)! This ensures that texture paths correctly point to the `assets/Textures` directory. +
-After the conversion, you move the .j3o file into the `assets/Models/` or `assets/Scenes/` directories. This way, you can reuse textures, your binaries consistently link the correct textures, and the `assets/Models` and `assets/Scenes` directories don't become cluttered.
-====
-
-
-
-=== Example Code: Loading Assets
-
-Creating a material instance with the definition “Unshaded.j3md:
-
-[source,java]
-----
-
-Material mat_brick = new Material( 
-    assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-
-----
-
-Applying a texture to the material:
-
-[source,java]
-----
-
-mat_brick.setTexture("ColorMap", 
-    assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg"));
-
-----
-
-Loading a font:
-
-[source,java]
-----
-
-guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
-
-----
-
-Loading a model:
-
-[source,java]
-----
-
-Spatial ninja = assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
-
-----
-
-Loading a scene from an Ogre3D dotScene file stored inside a zip:
-
-[source,java]
-----
-
-assetManager.registerLocator("town.zip", ZipLocator.class);
-Spatial scene = assetManager.loadModel("main.scene");
-rootNode.attachChild(scene);
-
-----
-
-Alternatively to ZipLocator, there is also a HttpZipLocator that can stream models from a zip file online:
-
-[source,java]
-----
-
-assetManager.registerLocator("https://storage.googleapis.com/"
-    + "google-code-archive-downloads/v2/code.google.com/"
-    + "jmonkeyengine/wildhouse.zip", HttpZipLocator.class);
-Spatial scene = assetManager.loadModel("main.scene");
-rootNode.attachChild(scene);
-
-----
-
-jME3 also offers a ClasspathLocator, ZipLocator, FileLocator, HttpZipLocator, and UrlLocator (see `com.jme3.asset.plugins`). 
-
-
-[IMPORTANT]
-====
-The custom build script does not automatically include all ZIP files in the executable build. See “Cannot Locate Resource solution below.
-====
-
-
-
-=== Common AssetManager Tasks
-[cols="15,85", options="header"]
-|===
-
-a| Task? 
-a| Solution! 
-
-a| Load a model with materials 
-a| Use the asset manager's `loadModel()` method and attach the Spatial to the rootNode. 
-[source,java]
-----
-Spatial elephant = assetManager.loadModel("Models/Elephant/Elephant.mesh.xml");
-rootNode.attachChild(elephant);
-----
-
-[source,java]
-----
-Spatial elephant = assetManager.loadModel("Models/Elephant/Elephant.j3o");
-rootNode.attachChild(elephant);
-----
-
-
-a| Load a model without materials 
-a| If you have a model without materials, you have to add a default material to make it visible. 
-[source,java]
-----
-Spatial teapot = assetManager.loadModel("Models/Teapot/Teapot.obj");
-Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md");
-teapot.setMaterial(mat);
-rootNode.attachChild(teapot);
-----
-
-
-a| Load a scene 
-a| You load scenes just like you load models: 
-[source,java]
-----
-Spatial scene = assetManager.loadModel("Scenes/house/main.scene");
-rootNode.attachChild(scene);
-----
-
-
-|===
-
-
-=== NullPointerException: Cannot locate resource?
-
-*Problem:*
-
-My game runs fine when I run it right from the jMonkeyEngine SDK. But when I run the stand-alone executables (.jar, .jnlp .exe, .app), a DesktopAssetManager error message occurs in the console, and it quits?
-
-[source]
-----
-com.jme3.asset.DesktopAssetManager loadAsset
-WARNING: Cannot locate resource: Scenes/town/main.scene
-com.jme3.app.Application handleError
-SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
-java.lang.NullPointerException
-
-----
-
-*Reason:*
-
-If you use the default build script, *original models and scenes (.mesh.xml, .obj, .blend, .zip), are excluded* from the distribution automatically. A stand-alone executable includes converted *.j3o files* (models and scenes) only. The default build script makes sure to bundle existing .j3o files in the distribution, but you need to remember to convert the models (from mesh.xml–&gt;.j3o, or .obj–&gt;.j3o, etc) yourself. 
-
-*Solution*
-
-Before building the executable, you must use the jMonkeyEngine SDK's context menu action to <<sdk/model_loader_and_viewer#,convert 3D models to .j3o binary format>>.
-
-.  Save your original models (.mesh.xml, .scene, .blend, or .obj files, plus textures) into `assets/Textures/`. (!)
-.  Open the jME3 project in the jMonkeyEngine SDK.
-.  Browse to the `assets` directory in the Projects window. 
-.  Right-click an original model in `assets/Textures/`, and choose “Convert to JME3 binary.
-.  The converted file appears in the same directory as the original file. It has the same name and a `.j3o` suffix. 
-.  Move the .j3o file into the `assets/Models/` or `assets/Scenes/` directory.
-.  Use the assetManager's `load()` method to load the `.j3o` file.
-
-This ensures that the model's Texture paths keep working between your 3D mesh editor and JME3.
-
-
-[IMPORTANT]
-====
-If you must load custom assets from a non-.j3o ZIP file, you must manually ammend the <<sdk/default_build_script#,default build script>> to copy ZIP files into your distribution. ZIPs are skipped by default.
-====
-
-
-
-=== Asset Handling For Other IDEs: Codeless Projects
-
-*Problem:*
-
-I use another IDE than jMonkeyEngine SDK for coding (Eclipse, IntelliJ, text editor). Where is my `asset` folder and .j3o converter?
-
-*Solution:*
-
-You can code in any IDE, but you must create a so-called codeless project in the jMonkeyEngine SDK to maintain assets. *A code-less jMonkeyEngine project does not meddle with your sources or custom build scripts.* You merely use it to convert models to .j3o binaries. 
-
-.  Create your (Eclipse or whatever) project as you like.
-.  Create a directory in your project folder and name it, for example, `assets`. +
-Store your assets there as described above.
-.  Download and install the jMonkeyEngine SDK.
-.  In the SDK, go to File → Import Projects → External Project Assets.
-.  Select your (Eclipse or whatever) project and your assets folder in the Import Wizard.
-.  You can now open this (Eclipse or whatever) project in the jMonkeyEngine SDK. +
-Convert assets as described above.
-
-
-[IMPORTANT]
-====
-If you don't use the SDK for some reason, you can still convert models to j3o format: Load any model in Ogre3D or Wavefront format with the AssetManager.loadModel() as a spatial. Then save the spatial as j3o file using <<jme3/advanced/save_and_load#,BinaryExporter>>.
-====
-
-
-
-[TIP]
-====
-Use file version control and let team members check out the project. Your developers open the project in Eclipse (etc) as they are used to. Additionally to their graphic tools, ask your graphic designers to install the jMonkeyEngine SDK, and to check out the codeless project that you just prepared. This makes it easy for non-coding team member to browse and preview game assets, to arrange scenes, and to convert files. At the same time, non-coders don't accidentally mess with code, and developers don't accidentally mess with assets. :)
-====
-

+ 0 - 441
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/external/3dsmax.adoc

@@ -1,441 +0,0 @@
-= 3ds Max Bone Animation to JME3 using OgreMax plugin
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== Asset Management
-
-For the managing of assets in general, be sure to read the <<jme3/intermediate/multi-media_asset_pipeline#,Asset Pipeline Documentation>>. It contains vital information on how to manage your asset files.
-
-
-== Creating models in 3dsMax
-
-For this tutorial I used 3D Studio Max 2012 and OgreMax 2.4.3 free edition
-
-
-=== Create Model and Bones
-
-*  Create a new file
-*  Select the “Create” tab &gt; “Geometry” &gt; “Cylinder”
-
-image:jme3/external/3dsmax-0.png[3dsmax-0.png,width="",height=""]
-
-*  Draw a cylinder, lets say with 8 height segments (must be enough for a smooth deformation)
-*  Also check “Generate Mapping Coords.”
-
-image:jme3/external/3dsmax-1.png[3dsmax-1.png,width="",height=""]
-
-*  Click “Create” tab &gt; “Systems” &gt; “Bones”
-
-image:jme3/external/3dsmax-2.png[3dsmax-2.png,width="",height=""]
-
-*  Add some bones in the center of the cylinder
-
-image:jme3/external/3dsmax-3.png[3dsmax-3.png,width="",height=""]
-
-*  Select the cylinder, right click it and click “Convert To:” &gt; “Convert to Editable Mesh” to prevent issues with OgreMax
-*  Click the “Modify” tab &gt; “Modifier List” and add the “Skin” modifier
-
-image:jme3/external/3dsmax-4.png[3dsmax-4.png,width="",height=""]
-
-*  Beneath “Bones:” click “Add” and select all of your bones
-
-image:jme3/external/3dsmax-5.png[3dsmax-5.png,width="",height=""]
-
-*  You may also edit the envelopes, but for a small test the default settings are ok
-
-
-=== Create the animation
-
-*  Select the cylinder, and click “Display” tab &gt; “Freeze Selected” so it is easier to select the bones during animation
-*  Select the two top bones and enable the “Auto Key” mode
-
-image:jme3/external/3dsmax-6.png[3dsmax-6.png,width="",height=""]
-
-*  The first key frame will be created automatically. Move the animation track slider to frame 5
-*  Move the selected bones a bit. The cylinder mesh will be deformed. Because you are in the “Auto Key” mode, a key frame will be created
-
-image:jme3/external/3dsmax-7.png[3dsmax-7.png,width="",height=""]
-
-*  Create some additional key frames. You may also select more bones and move or rotate them. I’ve created 25 frames and the last key frame equals the first, so the animation is loopable
-*  After creating the animation, disable the “Auto Key” mode
-
-
-=== OgreMax settings
-
-*  Open the “OgreMax Scene Settings” dialog from the menu
-*  In the “Meshes” tab, enable “Export XML Files” and disable “Export Binary Files” as well as “Export Vertex Colors”
-
-image:jme3/external/3dsmax-8.png[3dsmax-8.png,width="",height=""]
-
-*  Click the “Environment” tab and uncheck “Export Environment Settings”. Otherwise the JME importer will throw a NullPointerException
-
-image:jme3/external/3dsmax-9.png[3dsmax-9.png,width="",height=""]
-
-*  If you have textured your model, you may also check “Copy Bitmaps to Export Directory” in the “Bitmaps” tab
-*  Unfreeze the cylinder by clicking “Display” tab &gt; “Unfreeze All” and select it
-*  While having the cylinder selected, open the “OgreMax Object Settings” dialog from the menu
-*  Open the “Mesh Animations” tab and select type “Skeleton”, “Export Skeleton” : “Yes”
-*  Below “Mesh Animations” hit the “Add…” button
-*  Assign a name to the track, maybe “wobble”. The track type must be “Skin. Set the right “Start/End Frames” for your animation
-
-image:jme3/external/3dsmax-10.png[3dsmax-10.png,width="",height=""]
-
-*  Hit ok and you will see the animation in the table. You may add additional animations by selecting other frame ranges, if desired
-
-image:jme3/external/3dsmax-11.png[3dsmax-11.png,width="",height=""]
-
-
-=== Export and Import
-
-*  When all animations are in the list, select “OgreMax” &gt; “Export” &gt; “Export Scene” and name the file “worm.scene”
-*  Create a JME test class that imports the file, get the animation controller and start the “wobble” animation
-
-[source,java]
-----
-
-import com.jme3.animation.AnimChannel;
-import com.jme3.animation.AnimControl;
-import com.jme3.animation.Skeleton;
-import com.jme3.app.SimpleApplication;
-import com.jme3.asset.plugins.FileLocator;
-import com.jme3.light.AmbientLight;
-import com.jme3.light.PointLight;
-import com.jme3.material.Material;
-import com.jme3.math.ColorRGBA;
-import com.jme3.scene.Geometry;
-import com.jme3.scene.Node;
-import com.jme3.scene.Spatial;
-import com.jme3.scene.control.LodControl;
-import com.jme3.scene.debug.SkeletonDebugger;
-
-/**
- * This is a test class for loading a Ogre XML scene exported by OgreMax.
- * 
- * @author Stephan Dreyer
- * 
- */
-public class TestOgreMaxImport extends SimpleApplication {
-
-  @Override
-  public void simpleInitApp() {
-    assetManager.registerLocator("Assets/model/ogre/test/", FileLocator.class);
-
-    // create the geometry and attach it
-    final Node model = (Node) assetManager.loadModel("worm.scene");
-    // resize it, because of the large 3dsmax scales
-    model.setLocalScale(.001f);
-
-    // attach to root node
-    rootNode.attachChild(model);
-    addLodControl(model);
-
-    final AnimControl ac = findAnimControl(model);
-
-    try {
-      // add a skeleton debugger to make bones visible
-      final Skeleton skel = ac.getSkeleton();
-      final SkeletonDebugger skeletonDebug = new SkeletonDebugger("skeleton",
-          skel);
-      final Material mat = new Material(assetManager,
-          "Common/MatDefs/Misc/Unshaded.j3md");
-      mat.setColor("Color", ColorRGBA.Green);
-      mat.getAdditionalRenderState().setDepthTest(false);
-      skeletonDebug.setMaterial(mat);
-      ((Node) ac.getSpatial()).attachChild(skeletonDebug);
-
-      // create a channel and start the wobble animation
-      final AnimChannel channel = ac.createChannel();
-      channel.setAnim("wobble");
-    } catch (final Exception e) {
-      e.printStackTrace();
-    }
-
-    // add some lights
-    rootNode.addLight(new AmbientLight());
-    rootNode.addLight(new PointLight());
-  }
-
-  public void addLodControl(final Spatial parent) {
-    if (parent instanceof Node) {
-      for (final Spatial s : ((Node) parent).getChildren()) {
-        addLodControl(s);
-      }
-    } else if (parent instanceof Geometry) {
-      final LodControl lc = new LodControl();
-      lc.setDistTolerance(1f);
-      parent.addControl(lc);
-    }
-  }
-
-  /**
-   * Method to find the animation control, because it is not on the models root
-   * node.
-   * 
-   * @param parent
-   *          The spatial to search.
-   * @return The {@link AnimControl} or null if it does not exist.
-   */
-  public AnimControl findAnimControl(final Spatial parent) {
-    final AnimControl animControl = parent.getControl(AnimControl.class);
-    if (animControl != null) {
-      return animControl;
-    }
-
-    if (parent instanceof Node) {
-      for (final Spatial s : ((Node) parent).getChildren()) {
-        final AnimControl animControl2 = findAnimControl(s);
-        if (animControl2 != null) {
-          return animControl2;
-        }
-      }
-    }
-
-    return null;
-  }
-
-  public static void main(final String[] args) {
-    new TestOgreMaxImport().start();
-  }
-}
-
-----
-
-You will see your worms strange movements. Have fun!
-
-image:jme3/external/3dsmax-12.png[3dsmax-12.png,width="",height=""]
-
-
-==== 3ds Max Biped Animation to JME3
-
-You can also use the biped operator to animate models, but you have to consider a lot of things.
-
-
-=== Creating a character in 3dsMax
-
-I will not tell you in detail how to model a character. There I many good tutorials on the web, I used link:http://majoh.deviantart.com/art/Mandi-s-3dsmax-Biped-Tutorial-26515784[that one].
-
-*  You may create a biped before you start modeling, so it is quite easier to fit the proportions of the biped.
-*  After creating a model and a biped I got something like that:
-
-image:jme3/external/1.png[1.png,width="",height=""]
-
-*  I added the “Meshmooth modifier with 2 iterations and got this result:
-
-image:jme3/external/3dsmax_biped_2.png[3dsmax_biped_2.png,width="",height=""]
-
-*  After smoothing your mesh you could correct vertices with the “Edit Mesh modifier. Finally you add the “Physique modifier.
-*  Now you can edit your envelopes to fit your model.
-
-
-=== Creating a simple walk animation
-
-*  Select the chest of your biped, choose “Motion (1) tab &gt; “Foot Step Mode (2) &gt; “Create Multiple Footsteps (3)
-*  You need to select the “In Place Mode (4), so the character moves in place without changing its location.
-
-image:jme3/external/3dsmax_biped_3_1.png[3dsmax_biped_3_1.png,width="",height=""]
-
-*  You can now play a bit with the settings, I adjusted “Actual Stride Length and “Actual Stride Height. 
-*  For the “Number of Footsteps 6 will be sufficient because the animation is cycled later.
-*  *Note:* You can also create or edit footsteps by hand and move or rotate them.
-*  After all footsteps are created, hit the “Create Keys for Inactive Footsteps button in the “Footstep Operations panel
-*  You can now check your animation by pressing the “Play button in the timeline.
-
-
-=== Preparing the export and setting up OgreMax
-
-*  The “OgreMax Scene Settings should be the same as shown above.
-*  Because you want your animation to be looped, you've got to find two key frames where the legs are nearly in the same position. For my settings I've chosen the frames 48-78 for the walk animation.
-*  Select the character mesh and open the “OgreMax Scene Settings dialog. 
-*  Open the “Mesh Animations” tab and select type “Skeleton”, “Export Skeleton” : “Yes”
-*  Below “Mesh Animations” hit the “Add…” button
-
-image:jme3/external/3dsmax_biped_4.png[3dsmax_biped_4.png,width="",height=""]
-
-*  Enter a name for the track, e.g. “walk.
-*  Assure the track type is set to “Physique.
-*  Set the start and end frames, for me it is 48-78.
-*  Close the dialog by pushing “Ok.
-*  *Note:* It could be useful to create also a track “start_run, that blends between the stand and walk animation. I would use frame 0-47 for that.
-*  Because you have a smooth model with a lot of polygons, it may be useful to create <<jme3/advanced/mesh#,levels of detail (LOD)>>. When the camera is farther away, a low-poly mesh of your character will be rendered.
-
-image:jme3/external/3dsmax_biped_5.png[3dsmax_biped_5.png,width="",height=""]
-
-*  Open the “Mesh LOD tab in object settings.
-*  It will suffice to select the “Automatic setting, but if your animation starts to look weird, you can create them by hand.
-*  I used 4 levels of LOD with a distance of 1. Don't worry about the distance setting, you can change it later in JME.
-*  For the level reduction, I used 20 percent, which produce good results. You may adjust all the settings depending on your needs.
-*  Close the dialoque by clicking “Ok.
-
-
-=== Fixing the location
-
-*  Before you export you need to do a little fix, because your model is not really located where you see it. JME will get into a lot of trouble, if you don't change that.
-*  Assure to save the max file. Sometimes OgreMax crashes the whole application during export. If you want to change the animation after export, you should reload this file because fixing the location changes something I can't really figure out.
-
-image:jme3/external/3dsmax_biped_6.png[3dsmax_biped_6.png,width="",height=""]
-
-*  Right click the “Select and Move tool in the upper toolbar. A dialog will pop up.
-*  Set the X and Y location to 0 and close the dialog.
-*  There is another way to achieve this. If you have scaled, moved or rotated your model, just open the “Hierarchy tab and click “Transform and “Scale on the “Reset panel.
-
-
-=== Export and Import
-
-*  Now you can export your scene. Select only the mesh and use “Export selected objects. You will not need the whole scene including the biped object, but the bones are created automatically during export.
-*  Create a JME test class for the scene import.
-
-For that, I extended the first class:
-
-[source,java]
-----
-
-import com.jme3.animation.AnimChannel;
-import com.jme3.animation.AnimControl;
-import com.jme3.animation.Skeleton;
-import com.jme3.app.SimpleApplication;
-import com.jme3.asset.plugins.FileLocator;
-import com.jme3.light.AmbientLight;
-import com.jme3.light.PointLight;
-import com.jme3.material.Material;
-import com.jme3.math.ColorRGBA;
-import com.jme3.math.Vector3f;
-import com.jme3.scene.Geometry;
-import com.jme3.scene.Node;
-import com.jme3.scene.Spatial;
-import com.jme3.scene.control.LodControl;
-import com.jme3.scene.debug.SkeletonDebugger;
-import com.jme3.scene.shape.Box;
-
-/**
- * This is a test class for loading a Ogre XML scene exported by OgreMax.
- * 
- * @author Stephan Dreyer
- * 
- */
-public class TestOgreMaxImport extends SimpleApplication {
-
-  @Override
-  public void simpleInitApp() {
-    assetManager.registerLocator("Assets/model/ogre/test/", FileLocator.class);
-
-    // create the geometry and attach it
-    final Node model = (Node) assetManager.loadModel("guy.scene");
-    // resize it, because of the large 3dsmax scales
-    model.setLocalScale(.02f);
-
-    // attach to root node
-    rootNode.attachChild(model);
-    addLodControl(model);
-
-    final AnimControl ac = findAnimControl(model);
-
-    try {
-      // add a skeleton debugger to make bones visible
-      final Skeleton skel = ac.getSkeleton();
-      final SkeletonDebugger skeletonDebug = new SkeletonDebugger("skeleton",
-          skel);
-      final Material mat = new Material(assetManager,
-          "Common/MatDefs/Misc/Unshaded.j3md");
-      mat.setColor("Color", ColorRGBA.Green);
-      mat.getAdditionalRenderState().setDepthTest(false);
-      skeletonDebug.setMaterial(mat);
-      ((Node) ac.getSpatial()).attachChild(skeletonDebug);
-
-      // create a channel and start the walk animation
-      final AnimChannel channel = ac.createChannel();
-      channel.setAnim("walk");
-    } catch (final Exception e) {
-      e.printStackTrace();
-    }
-
-    flyCam.setMoveSpeed(40f);
-    cam.setLocation(new Vector3f(15, 10, 15));
-    cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
-    cam.setFrustumNear(1f);
-
-    // add some lights
-    rootNode.addLight(new AmbientLight());
-
-    final PointLight pl = new PointLight();
-    pl.setPosition(new Vector3f(-3f, 3f, 1f));
-    rootNode.addLight(pl);
-
-    // add a box as floor
-    final Box b = new Box(100f, 0.1f, 100f);
-    final Geometry geo = new Geometry("floor", b);
-
-    final Material mat = new Material(assetManager,
-        "Common/MatDefs/Misc/Unshaded.j3md");
-    mat.setColor("Color", ColorRGBA.LightGray);
-    geo.setMaterial(mat);
-
-    rootNode.attachChild(geo);
-  }
-
-  /**
-   * Method to traverse through the scene graph and add a {@link LodControl} to
-   * the mesh.
-   * 
-   * @param parent
-   *          The Node to add the control to.
-   */
-  public void addLodControl(final Spatial parent) {
-    if (parent instanceof Node) {
-      for (final Spatial s : ((Node) parent).getChildren()) {
-        addLodControl(s);
-      }
-    } else if (parent instanceof Geometry) {
-      final LodControl lc = new LodControl();
-
-      // the distance for LOD changes is set here, you may adjust this
-      lc.setDistTolerance(1f);
-      parent.addControl(lc);
-    }
-  }
-
-  /**
-   * Method to find the animation control, because it is not on the models root
-   * node.
-   * 
-   * @param parent
-   *          The spatial to search.
-   * @return The {@link AnimControl} or null if it does not exist.
-   */
-  public AnimControl findAnimControl(final Spatial parent) {
-    final AnimControl animControl = parent.getControl(AnimControl.class);
-    if (animControl != null) {
-      return animControl;
-    }
-
-    if (parent instanceof Node) {
-      for (final Spatial s : ((Node) parent).getChildren()) {
-        final AnimControl animControl2 = findAnimControl(s);
-        if (animControl2 != null) {
-          return animControl2;
-        }
-      }
-    }
-
-    return null;
-  }
-
-  public static void main(final String[] args) {
-    new TestOgreMaxImport().start();
-  }
-}
-
-----
-
-After starting the class, you can see a nice smooth walk animation (if it's not smooth, you need to adjust your track frames):
-
-image:jme3/external/3dsmax_biped_7.png[3dsmax_biped_7.png,width="",height=""]
-
-As you can see, the LOD is working:
-
-image:jme3/external/3dsmax_biped_8.png[3dsmax_biped_8.png,width="",height=""]

+ 0 - 254
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/external/blender-example.adoc

@@ -1,254 +0,0 @@
-= Warg - from cube to animated and textured game model Example
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-[IMPORTANT]
-====
-to make this example you need to know basic of modeling like extending faces / merge vertexes / (move vertex / edge / face) / etc.
-====
-
-
-
-== Preview
-
-image:jme3/external/preview.jpg[preview.jpg,width="",height=""]
-
-
-== Step 1 - Prepare
-
-- Open Blender with new Scene
-- Add a simple Cube. To make it press shift-a and select Cube
-
-image:jme3/external/2.jpg[2.jpg,width="",height=""]
-
-- “t” key open tool window. let’s open it and set x-mirror ON
-
-image:jme3/external/4.jpg[4.jpg,width="",height=""]
-
-- Subdivide this cube to get more faces
-* this can be also done via modifiers → subdivision surface (it will be later)
-
-image:jme3/external/5.jpg[5.jpg,width="",height=""]
-
-- “n” key open second toolbar with useable options. let's load an example image to help us build Warg.
-I found a nice warg image on devian art.
-
-image:jme3/external/example.jpg[example.jpg,width="",height=""]
-
-- make simple Warg Shape like on images
-
-image:jme3/external/6.jpg[6.jpg,width="",height=""]
-image:jme3/external/7.jpg[7.jpg,width="",height=""]
-image:jme3/external/9.jpg[9.jpg,width="",height=""]
-
-
-== Step 2 - Modeling
-
-- in tool window(“t”) is a smooth tool that can help model the warg.
-
-image:jme3/external/10.jpg[10.jpg,width="",height=""]
-
-- to easly add edge loop use “loop cut and slide” tool that work that way:
-
-image:jme3/external/12.jpg[12.jpg,width="",height=""]
-image:jme3/external/13.jpg[13.jpg,width="",height=""]
-
-- Go to modifiers and add Mirror surface
-
-image:jme3/external/14.jpg[14.jpg,width="",height=""]
-
-- add some details like eyes / etc.
-
-
-[IMPORTANT]
-====
-need to know how to use extend faces(key “e) and merge extended face.
-====
-
-
-image:jme3/external/15.jpg[15.jpg,width="",height=""]
-image:jme3/external/16.jpg[16.jpg,width="",height=""]
-
-- to use smooth shading just set it in tool window.
-
-image:jme3/external/17.jpg[17.jpg,width="",height=""]
-
-- Apply modifier. just press “Apply” button in Mirror modifier.
-- Remove doubles (it removes vertexes that are too close each other).
-
-image:jme3/external/18.jpg[18.jpg,width="",height=""]
-
-
-== Step 2 - Armature
-
-- Shift-a and add armature in Object Mode.
-
-
-[NOTE]
-====
-shift-a to add a bone in Edit Mode
-====
-
-image:jme3/external/19.jpg[19.jpg,width="",height=""]
-
-[NOTE]
-====
-tail should be done in other way. Start to build skeleton from start of the tail (not end)
-====
-
-image:jme3/external/21.jpg[21.jpg,width="",height=""]
-
-- Show names and change armature view (if you like)
-
-image:jme3/external/22.jpg[22.jpg,width="",height=""]
-
-- set Names for bones (via properties window or “n” option window)
-
-image:jme3/external/23.jpg[23.jpg,width="",height=""]
-
-- Select left side bones only, press shift-d to copy them, and make mirror.
-Remember to have cursor in 0,0,0 and have settings like on image (if not then you will need just to move copied bones manually)
-
-image:jme3/external/25.jpg[25.jpg,width="",height=""]
-
-- Press “w” and select “flip names”
-
-image:jme3/external/26.jpg[26.jpg,width="",height=""]
-image:jme3/external/27.jpg[27.jpg,width="",height=""]
-
-- In Object Mode:
-* Select Model
-* With SHIFT select armature
-* Press “p” and select “with automatic weights”
-
-image:jme3/external/28.jpg[28.jpg,width="",height=""]
-
-- Try move a leg in Pose Mode
-
-[NOTE]
-====
-Pose Mode work like Edit mode, use “r to rotate a bone. using “x/“y/“z after “g/“r/“s will also work here like everything else.
-====
-
-image:jme3/external/29.jpg[29.jpg,width="",height=""]
-
-- Go to Animation View
-
-image:jme3/external/30.jpg[30.jpg,width="",height=""]
-
-- Add a new action
-
-image:jme3/external/31.jpg[31.jpg,width="",height=""]
-
-- Select all bones in Pose Mode and apply location / rottion / scale.
-To do it press “i” and select it like on image:
-
-image:jme3/external/32.jpg[32.jpg,width="",height=""]
-
-
-[TIP]
-====
-alt-r / alt-g / alt-s – clear rotation / location / scale
-====
-
-- there is possibility to copy poses
-
-image:jme3/external/33.jpg[33.jpg,width="",height=""]
-
-- and also to copy them in mirrored pose
-
-image:jme3/external/35.jpg[35.jpg,width="",height=""]
-
-- in action editor you can easly remove / move / scale frames
-
-image:jme3/external/34.jpg[34.jpg,width="",height=""]
-
-- If animation work not linear (and you don't like it), then you can change it in Curve editor window
-
-image:jme3/external/36.jpg[36.jpg,width="",height=""]
-
-- Thats all for Animations, for more just Read JME wiki / documentation.
-
-
-== Step 2 - Texturing
-
-- Move armature to second layer.
-press “m” to make it.
-
-image:jme3/external/37.jpg[37.jpg,width="",height=""]
-
-- In edit mode, need to mark seam on Edges to prepare model for texturing.
-press ctrl-e to make it.
-
-image:jme3/external/38.jpg[38.jpg,width="",height=""]
-
-- do it similar to this (or you can make it better):
-
-image:jme3/external/40.jpg[40.jpg,width="",height=""]
-image:jme3/external/41.jpg[41.jpg,width="",height=""]
-image:jme3/external/43.jpg[43.jpg,width="",height=""]
-
-- Press “u” and select first option “unwrap”
-- In UV window you can minimize stretch
-(minimize stretch change with mouse wheele).
-
-image:jme3/external/44.jpg[44.jpg,width="",height=""]
-
-- make a 2 geometries for model:
-* body (contains faces for body)
-* eyes (containes faces for eyes)
-
-image:jme3/external/45.jpg[45.jpg,width="",height=""]
-
-image:jme3/external/48.jpg[48.jpg,width="",height=""]
-
-- for eyes you can use “Sphere projection for unwrap”
-
-image:jme3/external/49.jpg[49.jpg,width="",height=""]
-
-- Select texture image
-
-image:jme3/external/50.jpg[50.jpg,width="",height=""]
-
-- under “n” option window, set like on image to see texture.
-(ViewPort need to be set as solid, ViewPort is near Object/Edit select)
-
-image:jme3/external/52.jpg[52.jpg,width="",height=""]
-
-- Just make texture of model (using Texture Mode – where Object / edit mode is)
-
-
-[NOTE]
-====
-under “t tools you can change color / size / etc of brush
-====
-
-
-image:jme3/external/55.jpg[55.jpg,width="",height=""]
-
-- Using 2d tool like Gimp / Photoshop, use filter/modifier to get nice looking skin
-
-image:jme3/external/56.jpg[56.jpg,width="",height=""]
-
-- Now only need to export via Ogre Mesh or just via Blend file (using SDK).
-
-- For eyes and body, use separated j3m files, then set them in SceneComposer.
-
-
-[IMPORTANT]
-====
-also don’t forget about NLA editor and set off envelopes to make animations work!
-====
-
-
-here are docs:
-
-<<jme3/external/blender#,jme3:external:blender>>
-
-- Done!

+ 0 - 444
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/external/blender.adoc

@@ -1,444 +0,0 @@
-= Creating assets in Blender3D
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-:experimental:
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-This section discusses how to create and import models from Blender3D (2.78+, see bottom of page for Blender 2.49 and before) to jME3. Furthermore, it explains how you can create various typical game-related assets like "`Normal`" maps of high-poly models and "`Baked Lighting`" maps.
-
-
-== Asset Management
-
-For the managing of assets in general, be sure to read the <<jme3/intermediate/multi-media_asset_pipeline#,Asset Pipeline Documentation>>. It contains vital information on how to manage your asset files.
-
-
-== Creating Models
-
-Game-compatible models are models that basically only consist of a mesh and UV-mapped textures, in some cases animations. All other material parameters or effects (like particles, etc.) cannot be expected to be transferred properly and probably would not translate to live rendering very well anyway.
-
-
-=== UV Mapped Textures
-
-To successfully import a texture, the texture *has to* be UV-mapped to the model. Heres how to assign "`Diffuse`", "`Normal`" and "`Specular`" maps:
-
-image::jme3/external/blender-material-4.png[blender-material-4.png,width="",height=""]
-image::jme3/external/blender-material-3.png[blender-material-3.png,width="",height=""]
-image::jme3/external/blender-material-2.png[blender-material-2.png,width="",height=""]
-image::jme3/external/blender-material-1.png[blender-material-1.png,width="",height=""]
-
-It's important to note that each used texture will create one separate geometry. So it's best to either combine the UV maps or use a pre-made atlas with different texture types from the start and then map the uv coords of the models to the atlas instead of painting on the texture. This works best for large models like cities and space ships.
-
-
-=== Animations
-
-Animations for jME3 have to be bone animations, simple object movement is supported by the blender importer, mesh deformation or other forms of animation are not supported.
-
-To create an animation from scratch do the following:
-
-.  Create the model.
-..  Make sure your models location, rotation and scale is applied and zero / one (see "`Model Checklist`" below).
-+
-TIP: Did you know? You can make any model from a box by only using extrusion, this creates very clean meshes.
-
-.  Create the armature bones, don't forget to have one root bone!
-..  Start by placing the cursor at zero.
-..  Go to the `menu:Add[Armature > Single Bone]` menu and create the root bone.
-+
-image::jme3/external/blender-add-bone.png[blender-add-bone.png,width="",height=""]
-
-..  Select the bone and go to edit mode (press kbd:[Tab]).
-..  Select the root bone end and press kbd:[E] to extrude the bone, then start rigging your model this way.
-+
-IMPORTANT: Make sure your armature's location, rotation and scale is applied (see "`Model Checklist`" below) before continuing.
-
-.  Make the armature the parent of the model.
-..  Make sure you are back in object mode (press kbd:[Tab] again).
-..  First select the model object then select the armature object with kbd:[Shift] pressed, then press kbd:[Ctrl] + kbd:[P].
-..  When you do this, you can select how the bone groups will be mapped to the model vertices initially. Select btn:[With Automatic Weights].
-+
-[NOTE]
-====
-When you parent your mesh to the armature, Blender automatically adds the `Armature` modifier to the mesh.
-
-image:jme3/external/blender-make-armature.png[blender-make-armature.png,width="",height=""]
-====
-+
-Voila, your model should move when you move the bones in pose mode.
-
-.  From the `Info` header, press the btn:[Choose Screen Layout] button and select the `Animation` layout.
-.  In the `Dope Sheet Editor` window, press the btn:[Context] button and select `Action Editor`.
-+
-image::jme3/external/blender-action-editor.png[blender-action-editor.png,width="",height=""]
-
-.  Add an action by pressing the btn:[+] button.
-.  Set the "`Rotation Mode`" of the bone to `Quaternion` or switch later from your "`Rotation Mode`" to `Quaternion` and make a `Keyframe`.
-+
-image::jme3/external/blender-switch-rotationmode.png[blender-switch-rotationmode.png,width="",height=""]
-.  Create the ``Keyframe``s (select the model armature and press kbd:[I]) along the timeline.
-+
---
-image::jme3/external/blender-add-keyframes.png[blender-add-keyframes.png,width="",height=""]
-
-Each action will be an animation available via the animation control in jME after the import.
-
-IMPORTANT: Press the btn:[F] button next to the action so it will be saved even if there's no references. The animation would else be deleted if its not the active animation on the armature and the file is saved.
---
-
-
-=== Model Checklist
-
-Sometimes you do not create the model yourself and often models from the web are not really made for OpenGL live rendering or not completely compatible with the bone system in jME.
-
-To export an animated model in Blender make sure the following conditions are met:
-
-TIP: This checklist is interactive for your convenience.
-
-[%interactive]
-* [ ] The animation has to be a *bone animation*.
-* [ ] Apply Location, Rotation and Scale to the mesh in Blender: In the `3D Viewport` in Blender, select the mesh in `Object Mode`, from the `3D View Editor` header, click `menu:Object[Apply > Location / Rotation / Scale]`.
-+
-image::jme3/external/blender_apply_mesh.png[blender_apply_mesh.png,width="300",height=""]
-
-* [ ] Apply Location, Rotation and Scale to the armature in Blender: In the `3D Viewport` in Blender, select the armature in `Object Mode`, from the `3D View Editor` header, click `menu:Object[Apply > Location / Rotation / Scale]`.
-+
-image::jme3/external/blender_apply_bones.png[blender_apply_bones.png,width="300",height=""]
-
-* [ ] Set the mesh’s origin point in the bottom of the mesh (see the image below).
-* [ ] Set the armature’s origin point in the bottom of the armature (see the image below).
-* [ ] Armature’s origin point and mesh’s origin point must be in the same location (see the image below).
-* [ ] Use a root bone located in the armature’s origin. This root bone must be in vertical position (see the image below) and it is the root bone of the armature. If you rotate the root bone, the entire armature might be rotated when you import the model into jMonkey.
-* [ ] Uncheck:
-** [ ] Bone Envelopes
-+
---
-on the Armature modifier for the mesh (see the image below).
-
-image::jme3/external/blender_envelopes.png[blender_envelopes.png,width="300",height=""]
---
-* [ ] Under the armature data tab, make sure the bone type is `Octahedral` (see image below).
-//*  Uncheck "`Envelopes`" checkbox on the armature (see the image below).
-+
-image::jme3/external/blender_rootbone2.png[blender_rootbone2.png,width="",height=""]
-
-
-You can use `SkeletonDebugger` to show the skeleton on your game in order to check if the mesh and the skeleton are loaded correctly:
-
-[source,java]
-----
-final Material soldier2Mat = assetManager.loadMaterial("Materials/soldier2/soldier2.j3m");
-final Spatial soldier2 = assetManager.loadModel("Models/soldier2/soldier2.j3o");
-TangentBinormalGenerator.generate(soldier2);
-soldier2.setMaterial(soldier2Mat);
-
-final Node soldier2Node = new Node("Soldier2 Node");
-
-soldier2Node.attachChild(soldier2);
-rootNode.attachChild(soldier2Node);
-
-final AnimControl animControl = soldier2.getControl(AnimControl.class);
-animControl.addListener(this);
-final AnimChannel animChannel = animControl.createChannel();
-
-final SkeletonDebugger skeletonDebug = new SkeletonDebugger("skeleton", animControl.getSkeleton());
-final Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-mat.setColor("Color", ColorRGBA.Green);
-mat.getAdditionalRenderState().setDepthTest(false);
-skeletonDebug.setMaterial(mat);
-soldier2Node.attachChild(skeletonDebug);
-----
-
-image::jme3/external/blender_finished.png[blender_finished.png,width="500",height=""]
-
-Also check out these videos and resources:
-
-*  link:https://hub.jmonkeyengine.org/t/importing-animations-from-blender-2-62-using-ogre-xml-things-to-check-if-you-are-getting-problems/22234[Forum: How to import animated models from Blender 2.6 correctly] (link:https://www.youtube.com/watch?v=QiLCs4AKh28[Video])
-*  link:http://www.youtube.com/watch?v=NdjC9sCRV0s[Video tutorial for animated models from Blender 2.6]
-*  link:https://docs.google.com/fileview?id=0B9hhZie2D-fENDBlZDU5MzgtNzlkYi00YmQzLTliNTQtNzZhYTJhYjEzNWNk&hl=en[Exporting OgreXML scenes from Blender 2.49 to jME]
-
-
-== Normal Map baking
-
-Models for live rendering should have a low polygon count. To increase the perceived detail of a model, Normal maps are commonly used in games. This tutorial will show how to create a Normal map from a "`HighPoly`" version of your model that you can apply to a "`LowPoly`" version of the model in your game.
-
-
-=== Blender Modeling LowPoly & HighPoly
-
-.Method 1
-If you use the `Multiresolution` modifier you only need one object. Let's look at this example, the Blender object Monkey, with an applied `Triangulate` modifier:
-
-image::jme3/external/monkey.png[monkey.png,width="50%",height=""]
-
-.  Add a "`Monkey`" object by selecting the btn:[Monkey] button located on the "`Create Tab`".
-.. While in `Object Mode`, in the `Properties` panel under the `Modifiers` tab, add a `Triangulate` modifier and apply it:
-..  While in `Object Mode`, in the `Properties` panel under the `Modifiers` tab, add a `Multiresolution` modifier:
-+
---
-image::jme3/external/3.1.gif[3.1.gif,width="300",height=""]
-
-There are two types of modifiers: Catmull-Clark and Simple.
-
-*  Simple is better for things like walls or floors.
-*  Catmull-Clark is better for objects like spheres.
-
-When using Catmull-Clark with a higher "`subdivide`" value (more than 3), it's good to have the "`Preview`" value above 0 and less than the subdivide level. This is because Catmull-Clark smooths the vertices, so the Normal map is not so precise.
-
-Regardless of the choice, the larger the difference is between "`Render`" and "`Preview`", the deeper the detail is on the Normal map.
-
-*  Here is an example of `Preview 1`, it's more smooth than the original mesh:
-
-image::jme3/external/monkeyprev1.png[monkkeyprev1.png,width="50%",height=""]
---
-.  From the `File` header at the top of the 3d View, click the btn:[Choose Screen layout] button and select "`UV Editing`".
-.  In the `3d View`, select the Monkey and kbd:[Tab] into "`Edit Mode`".
-.  If the Monkey vertices are not already highlighted, press the kbd:[A] key until all vertices are highlighted.
-.  From the `3d View` header, select `menu:Mesh[UV Unwrap>Smart UV Project]`.
-..  Click the btn:[Island Margin] button once to advance the value to .03.
-..  Click btn:[OK] when ready.
-.  In the `UV Image Editor`, click the btn:[New]  button.
-..  Change the name to something like "`monkey_bump`".
-..  Optionally, change the `Generated Type` to "`UV Grid`".
-..  Uncheck:
-** [ ] 32 Bit
-..  Click btn:[OK] when ready.
-.  From the `File` header at the top of the `UV Image Editor`, click the btn:[Choose Screen layout] button and select "`Default`".
-.  With your mouse inside the `3D View`, tab into `Object Mode`.
-.  Now go into the `Render` tab, and bake a `Normal` map using the same configuration as here:
-+
---
-image::jme3/external/4.gif[4.gif,width="300",height=""]
-
-IMPORTANT: Remember! The actual preview affects the baking output and mesh export!
---
-
-.  Navigate back to the `UV Editing` layout and save your image by selecting `menu:Image*[Save As]` from the `UV Image Editor` header.
-
-TIP: The asterisk kbd:[*] next to the `Image` menu item means the image has not yet been saved.
-
-.Normal map from Method 1
-image::jme3/external/monkey_bump.png[monkey_bump.png,width="50%",height=""]
-
-This second method produces the best results by far:
-
-.Method 2
-.  Follow the steps for "`Method 1`" but before baking, uncheck:
-** [ ] Bake from Multires
-.  Make a copy of your mesh (kbd:[SHIFT]+kbd:[D]).
-.  Remove the Multires modifier from the copied model.
-.  Remove any materials from the copied model.
-.  Remove the armature modifier from the copied model.
-.  Select the original (HighPoly) model.
-.  Go into pose mode, clear any pose transformations.
-.  The "`HighPoly`" and "`LowPoly`" models should be on top of each other now.
-.  Select the original (HighPoly) model.
-.  Hold kbd:[SHIFT] and select the copied (LowPoly) model.
-.  In the `Properties` panel, in the `Render` tab:
-..  Bake Mode: `Normal`
-..  check:
-** [x] Selected to Active
-..  Use a reasonably high value for "`Margin`" (4+ pixels at least for 1024x1024 maps).
-.  Bake and don't forget to save the Normal map image.
-
-[IMPORTANT]
-====
-Keep in mind that when you duplicate the model, you are also duplicating its UV mapping. What this means is your "HiPoly" model and "`LowPoly`" model are both assigned to an image.
-
-If you ever see this error:
-
-"No objects or images found to bake to"
-
-You are either missing the image for the "`LowPoly`" model, or in the Outliner, the camera symbol (Restrict Render) is off (grayed out).
-====
-
-.Normal map from Method 2
-image::jme3/external/monkey_bump2.png[monkey_bump2.png,width="50%",height=""]
-
-=== Fixing the Normal colors in Blender
-
-There are two "`standards`" for Normal maps:
-
-*  DirectX
-*  OpenGL
-
-The difference between them is that the green channel is inverted. One would expect that JME supports the OpenGL way, but actually JME supports the DirectX way because it’s what Blender supports and the developers of JME thought it would be easier in the Blender to JME workflow.
-
-Because of this, you need to fix the colors to prepare the Normal map for using it with the JME Lighting Material. You should only have to invert the green channel, the red and blue channels should stay unchanged. The curve for the red and blue channels should go from bottom left to top right, the green from top left to bottom right.
-
-To do this after baking and saving the original Normal map image:
-
-. In the "`UV Editing`" layout, from the "`UV Image Editor`" header select `menu:Image[Invert>Invert Green Channel]`.
-.  Save the inverted image to a destination you want and use it with the JME Lighting Material and the "`LowPoly`" version of the model.
-
-.Normal map invert results (Method 2 example)
-image::jme3/external/monkey_bump2_invert.png[monkey_bump2_invert.png,width="50%",height=""]
-
-[TIP]
-.Inverting Tips
-====
-If you build the engine from source, the master branch link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md#L39[PBR material] has a NormalType parameter that allows one to handle this in the shader instead of having to edit the Normal map.
-
-You can also use the SDK to invert the channel:
-
-.  In the SDK, btn:[RMB] select the image and choose "`Edit Texture`".
-.  In the window header, press the btn:[Filters] button and choose `menu:Invert[Green]`.
-.  When satisfied, save the change in the same format as the original image using `menu:File[Save]`.
-====
-
-This is what the final outcome of Normal map baking should produce for you. A "`LowPoly`" model that looks like it's a "`HighPoly`" model.
-
-.Final results (Method 2 example)
-image::jme3/external/monkey_final.gif[monkey_final.gif,width="",height=""]
-
-
-== LightMap baking
-
-The goal of this tutorial is to explain briefly how to bake light map in blender with a separate set of texture coordinates and then export a model using this map in jME3.
-
-
-=== Blender modeling + texturing
-
-*  create a mesh in blender and unwrap it to create uvs
-**  image:jme3/advanced/1.jpg[1.jpg,width="600",height=""]
-
-
-*  In the mesh tab you can see the sets of Uvs, it will create the first one.
-**  You can assign w/e texture on it, i used the built in checker of blender for the example.
-
-*  In this list, create a new one and click on the camera icon so that baking is made with this set. Name it LightUvMap.
-*  In the 3D view in edit mode select all your mesh vertice and hit 'U'/LightMap pack then ok it will unfold the mesh for light map.
-*  Create a new image, go to the render tab an all at the end check the “Bake section and select shadows. Then click bake.
-*  If all went ok it will create a light map like this.
-**  image:jme3/advanced/2.jpg[2.jpg,width="600",height=""]
-
-*  Go to the material tab, create a new one for your model and go to the Texture Tab.
-*  Create 2 textures one for the color map, and one for the light map.
-*  In the Mapping section be sure to select coordinates : UV and select the good set of coordinates.
-**  image:jme3/advanced/3.jpg[3.jpg,width="600",height=""]
-
-*  Then the light map
-**  image:jme3/advanced/4.jpg[4.jpg,width="600",height=""]
-
-
-
-== Importing the model in the SDK and creating the appropriate material
-
-Once this is done, export your model with the ogre exporter (or import it directly via the blend importer), and turn it into J3o with the SDK.
-
-*  Create material for it using the lighting definition.
-*  Add the colorMap in the diffuse map slot and the lightMap in the light map slot.
-*  Make sure you check “SeparateTexCoords
-**  image:jme3/advanced/5.jpg[5.jpg,width="600",height=""]
-
-*  It should roughly result in something like that :
-**  image:jme3/advanced/6.jpg[6.jpg,width="600",height=""]
-
-
-The blend file, the ogre xml files and the textures can be found in the download section of the google code repo
-
-link:http://code.google.com/p/jmonkeyengine/downloads/detail?name=LightMap.zip&can=2&q=#makechanges[http://code.google.com/p/jmonkeyengine/downloads/detail?name=LightMap.zip&amp;can=2&amp;q=#makechanges]
-
-
-== Modelling racing tracks and cars
-
-Follow the link below to a pdf tutorial by rhymez where I guide you to modelling a car and importing it to the jMonkeyengine correctly and edit it in the vehicle editor.Plus how to model a simple racing track.
-link:http://www.indiedb.com/games/street-rally-3d/downloads/modelling-in-blender-to-the-jmonkeyengine[http://www.indiedb.com/games/street-rally-3d/downloads/modelling-in-blender-to-the-jmonkeyengine]
-
-
-== Optimizing Models for 3D games
-
-Follow the link below to a pdf tutorial by rhymez where I guide you on how you can optimize your models for faster rendering.
-link:http://www.indiedb.com/games/street-rally-3d/downloads/optimizing-3d-models-for-games[http://www.indiedb.com/games/street-rally-3d/downloads/optimizing-3d-models-for-games]
-
-
-== SkyBox baking
-
-There are several ways to create static images to use for a sky in your game. This will describe the concepts used in blender and create an ugly sky emoji:smiley Check the links below for other ways and prettier skies.
-
-A sky box is a texture mapped cube, it can also, loosely, be called en EnvMap or a CubeMap. The camera is inside the cube and the clever thing that jME does is to draw the sky so it is always behind whatever else is in your scene. Imagine the monkey is the camera in the picture.
-
-*  image:jme3/external/skybox-concept.png[skybox-concept.png,width="",height=""]
-
-But a real sky is not a box around our heads, it is more like a sphere. So if we put any old image in the sky it will look strange and might even look like a box. This is not what we want. The trick is to distort the image so that it will _look_ like a sphere even if it in fact is a picture pasted on a box. Luckily blender can do that tricky distortion for us.
-
-The screenshots are from Blender 2.63 but the equivalent operations have been in blender for years so with minor tweaks should work for almost any version.
-
-So let's get started
-
-*  Fire up blender and you'll see something like this.
-**  image:jme3/external/start-screen2.png[start-screen2.png,width="",height=""]
-
-*  The cube in the start scene is perfect for us. What we'll do is have Blender render the scene onto that cube. The resulting image is what we'll use for our sky box. So our jME sky will look like we stood inside the blender box and looked out on the scene in blender.
-*  Start by selecting the box and set its material to shadeless.
-**  image:jme3/external/shadeless.png[shadeless.png,width="",height=""]
-
-*  Now we will create a texture for the box. Make sure the texture is an `Environment Map`, that the `Viewpoint Object` is set to the cube. The resolution is how large the resulting image will be. More pixels makes the sky look better but comes at the cost of texture memory. You'll have to trim the resolution to what works in your application.
-**  image:jme3/external/texture.png[texture.png,width="",height=""]
-
-*  Next up is the fun part, create the sky scene in blender. You can do whatever fits your application, include models for a city landscape, set up a texture mapped sphere in blender with a nice photographed sky, whatever you can think will make a good sky. I am not so creative so I created this scene:
-**  image:jme3/external/scene.png[scene.png,width="",height=""]
-
-*  Now render the scene (press F12). It doesn't actually matter where the camera is in blender but you might see something similar to this:
-**  image:jme3/external/render.png[render.png,width="",height=""]
-
-*  You can see that Blender has actually drawn the scene onto the cube. This is exactly what we want. Now to save the image.
-*  Select the texture of the cube and select save environment map.
-**  image:jme3/external/saveenvmap.png[saveenvmap.png,width="",height=""]
-
-*  That is it for Blender. Open the saved image in some image editor (I use the Gimp from link:http://www.gimp.org[http://www.gimp.org] here).
-
-
-[TIP]
-====
-The SDK also contains an image editor, right-click the image and select “edit image to open it.
-====
-
-
-*  You will notice that Blender has taken the 6 sides of the cube and pasted together into one image (3x2). So now we need to cut it up again into 6 separate images. In gimp I usually set the guides to where I want to cut and then go into Filters→Web→Slice and let gimp cut it up for me.
-**  image:jme3/external/post-slice.png[post-slice.png,width="",height=""]
-
-*  Next up is to move the image files into your assets directory and create the sky in jME. You can do that in the Scene Composer by right clicking the scene node, select `Add Spatial` and then select `Skybox`.
-
-If you want to do it from code, here is an example:
-
-[source,java]
-----
-
-public void simpleInitApp() {
-
-    Texture westTex = assetManager.loadTexture("Textures/west.png");
-    Texture eastTex = assetManager.loadTexture("Textures/east.png");
-    Texture northTex = assetManager.loadTexture("Textures/north.png");
-    Texture southTex = assetManager.loadTexture("Textures/south.png");
-    Texture upTex = assetManager.loadTexture("Textures/top.png");
-    Texture downTex = assetManager.loadTexture("Textures/bottom.png");
-
-    final Vector3f normalScale = new Vector3f(-1, 1, 1);
-    Spatial skySpatial = SkyFactory.createSky(
-                        assetManager,
-                        westTex,
-                        eastTex,
-                        northTex,
-                        southTex,
-                        upTex,
-                        downTex,
-                        normalScale);
-    rootNode.attachChild(skySpatial);
-}
-----
-
-
-[TIP]
-====
-This example uses a strange normalScale, this is to flip the image on the X-axis and might not be needed in your case. Hint: the texture is applied on the outside of the cube but we are inside so what do we see?
-====
-
-
-
-== Further reading
-
-*  <<jme3/external/blender-example#,Warg - from cube to animated and textured game model Example>>
-*  <<jme3/advanced/sky#,How to add a Sky to your Scene>>
-*  link:http://hub.jmonkeyengine.org/t/jmonkeyengine-tutorial-how-to-create-skymaps-using-blender/19313[http://hub.jmonkeyengine.org/t/jmonkeyengine-tutorial-how-to-create-skymaps-using-blender/19313]

+ 0 - 67
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/external/fonts.adoc

@@ -1,67 +0,0 @@
-= Font Creator
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:keywords: gui, documentation, hud
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-This SDK plugin provides font support for jMonkeyEngine games. It creates AngelFont files from system fonts. Make sure you have the rights/license to use this font! You can link:https://www.google.com/search?q=free+fonts[search for and download free fonts] from many sites.
-
-
-== Installation
-
-If the plugin is installed, you see it under `Plugins → Installed`
-
-
-image::jme3/external/install-font-plugin.png[install-font-plugin.png,width="450",height="275",align="center"]
-
-
-(If you don't see it, go to `Tools → Plugins → Available Plugins` to install Font Creator.)
-
-
-== Create Font
-
-The following example creates the custom font `Orbitron.fnt` in the `assets/Interface/Fonts` directory.
-
-
-image::jme3/external/font-1.png[font-1.png,width="",height="",align="center"]
-
-
-
-image::jme3/external/font-2.png[font-2.png,width="",height="",align="center"]
-
-
-
-image::jme3/external/font-3.png[font-3.png,width="",height="",align="center"]
-
-
-
-image::jme3/external/font-4.png[font-4.png,width="",height="",align="center"]
-
-
-
-image::jme3/external/font-5.png[font-5.png,width="",height="",align="center"]
-
-
-
-== Use Font
-
-The following example loads text in the custom font `Orbitron.fnt` from the `assets/Interface/Fonts` directory. You use `com.jme3.font.*` package to handle text on the screen. `guiNode` is a preconfigured node in any `SimpleApplication`-based game.
-
-[source,java]
-----
-
-BitmapFont myFont = assetManager.loadFont("Interface/Fonts/Orbitron.fnt");
-BitmapText hudText = new BitmapText(myFont, false);
-hudText.setText("You can write any string here");
-guiNode.attachChild(hudText);
-
-----
-
-== create font for RTL languages like persian and arabic
-
-to create and use persian bitmap fonts use this tool.
- link:https://github.com/younes-noori/bitMapFontCreator[bitMapFontCreator for RTL languages]

+ 0 - 49
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/external/makehuman.adoc

@@ -1,49 +0,0 @@
-= Creating a Character using MakeHuman
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-Here's the procedure:
-
-.  If you haven't already, install the jMonkeyEngine3 SDK, launch the IDE, and create a JME3 project.
-.  Install the MakeHuman application, the Blender application, and the MakeHuman Blender tools.
-**  Download the latest stable version of the MakeHuman application from link:http://www.makehuman.org/[http://www.makehuman.org/]
-**  Download the latest stable MakeHuman Blender tools from link:http://www.makehuman.org/[http://www.makehuman.org/]
-**  Download the corresponding (not necessarily the latest) version of the Blender application from link:http://www.blender.org/[http://www.blender.org/]
-**  Install the MakeHuman application as directed by link:http://www.makehuman.org/doc/node/install_makehuman.html[http://www.makehuman.org/doc/node/install_makehuman.html]
-**  Install the Blender application.
-**  Install the MakeHuman tool scripts to Blender's scripts directory.  On Windows 7 machines, this involves unzipping the archive to `C:\Users\&lt;username&gt;\AppData\Roaming\Blender Foundation\Blender\&lt;version&gt;\scripts\addons`
-**  Launch the Blender application, open a `User Preferences` editor, activate the `Addons` tab, and check the box labelled `Import-Export:Import:MakeHuman(.mhx)`.
-**  Click the `Save User Preferences` button.
-
-.  Generate an .mhx file containing a human figure.
-**  Launch the MakeHuman application.
-**  Configure a human figure using the `Modelling`, `Geometries`, and `Materials` tabs.
-**  On the `Pose/Animate` tab, select a rig for animation if desired.
-**  Under the `Files` tab, select the `Save` sub-tab.
-**  Save to a file (in case you need to make changes later).  Note that there are two `Save` buttons: one in the `Save As` window which merely sets a pathname and another in the main window.  The .mhm file isn't written until you click the second `Save` button.
-**  Under the `Files` tab, select the `Export` sub-tab.
-**  Select `Blender exchange (mhx)` as the export format.
-**  Export to a file.  Again, there's a `Save` button in the Save As window which merely sets a pathname.  The .mhx file isn't written until you click the `Export` button in the main window.
-**  You may now close the MakeHuman application.
-
-.  Convert the .mhx file to a .blend file:
-**  Launch the Blender application and delete the initial cube.
-**  From the `Info` editor's toolbar, select `File` &gt; `Import` &gt; `MakeHuman(.mhx)…`
-**  In the `File Browser`, select your .mhx file and click the `Import MHX` button.
-**  After the import completes, you can view and edit the model using a `3D View` editor.
-**  From the `Info` editor's toolbar, select `File` &gt; `Save As…`
-**  Select a pathname in the assets/Models folder of your JME3 project.
-**  Clicking the `Save As Blender File` button in the `File Browser` writes the file.
-**  You may now close the Blender application.
-
-.  Convert the .blend file to a .j3o file:
-**  Launch the jMonkeyEngine3 IDE.
-**  Open your JME3 project.
-**  Under the `Project Assets` node of your project, open the `Models` folder.
-**  Right-click on your .blend file and select `Convert to j3o binary`
-

+ 0 - 142
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/free_skymaps.adoc

@@ -1,142 +0,0 @@
-= How to create free SkyMaps
-:author: 
-:revnumber: 
-:revdate: 2017/04/4 10:23
-:relfileprefix: ../../
-:imagesdir: ../..
-:experimental: 
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-There are a plethora of ways to create skymaps with varying levels of difficulty and expense. The link:http://planetside.co.uk/[Terragen] program has been mentioned as one way to do so but it is now limited in its use and for commercial purposes is not free. Another program, link:https://www.daz3d.com/bryce-7-pro[Bryce], is also not free and seems to of stalled in development based off there only being a 32bit version available. Maybe they are doing things behind the scenes but its still not a free program. This articles intent is to give the JME3 user other options for the creation of skymaps using the free programs Blender and Gimp. It is not the be all, end all of skymap creation. If you know of better methods or tools please feel free to share your wisdom on the link:https://hub.jmonkeyengine.org/[forums].
-
-
-== Blender
-
-
-Using Blender you can create your skymaps for free. Once link:https://www.blender.org/[Blender] is setup, your skymaps creation can be done easily. For this article I will go into detail on how to setup Blender to create Angular maps based off a video produced by jMonkey contributor glaucomardano and mentioned in this link:https://hub.jmonkeyengine.org/t/jmonkeyengine-tutorial-how-to-create-skymaps-using-blender/19313[forum post]. Contributor glaucomardano did a good job on the video but it requires previous knowledge of Blender to be able to easily follow along. As such, I will translate it to paper for you. You can view his video by following this link: link:https://youtu.be/z38Aikz5nE8[jMonkeyEngine Tutorial - How to create skymaps using blender].
-
-[NOTE]
-====
-This tutorial is an adaptation of contributor glaucomardanos production, not an exact duplicate. +
-These steps assume you're using the default blender setup and apply to vers 2.78c+. +
-The tutorial is in checklist format so you can mark items as you go to keep your place.
-====
-
-[%interactive]
-.Blender Skybox Checklist
-- [ ] Start with a new file in blender.
-- [ ] Select the lamp and the default cube in the 3d view or in the Outliner panel (top-right panel) and delete them: kbd:[X]. They are not needed for this procedure.
-- [ ] Select the camera object in the 3d view or in the Outliner panel then clear its location and rotation by using keyboard shortcuts kbd:[Alt]+kbd:[G] and kbd:[Alt]+kbd:[R].
-- [ ] In the properties panel (lower-right panel) select the Object tab (orange box). This will give you a visual perspective of the camera changes you are about to make.
-- [ ] Rename the Camera to Camera-north.
-- [ ] With your cursor inside the 3d view, change to top-ortho view by pressing kbd:[NumPad 7] followed by kbd:[NumPad 5].
-- [ ] With the camera still selected, press kbd:[R] immediately followed by kbd:[X] immediately followed by 90 immediately followed by kbd:[Enter] to rotate the camera 90 degrees around the X axis.
-- [ ] With the camera still selected, press kbd:[Shift]+kbd:[D]. This will duplicate the camera. Next press kbd:[Enter] to set the selection.
-- [ ] Press kbd:[R] immediately followed by 180 immediately followed by kbd:[Enter]. This will rotate the camera 180 degrees around the Z axis. Rename this camera to Camera-south.
-- [ ] With the camera still selected, press kbd:[Shift]+kbd:[D]. This will duplicate the camera. Next press kbd:[Enter] to set the selection.
-- [ ] With the camera still selected, press kbd:[R] immediately followed by 90 immediately followed by kbd:[Enter]. This will rotate the camera another 90 degrees around the Z axis. Rename this camera to Camera-west.
-- [ ] With the camera still selected, press kbd:[Shift]+kbd:[D]. This will duplicate the camera. Next press kbd:[Enter] to set the selection.   
-- [ ] With the camera still selected, press kbd:[R] immediately followed by -180 immediately followed by kbd:[Enter]. This will rotate the camera -180 degrees around the Z axis. Rename this camera to Camera-east.
-- [ ] With your mouse inside the 3d view change your view to right-ortho by entering kbd:[NumPad 3].
-- [ ] Select Camera-south in 3d view or in the Outliner panel (top-right panel) and press kbd:[Shift]+kbd:[D]. This will duplicate the camera. Next press kbd:[Enter] to set the selection.
-- [ ] With the camera still selected, press kbd:[R] immediately followed by 90 immediately followed by kbd:[Enter]. This will rotate the camera 90 degrees around the X axis. The camera should now be pointing up. Rename this camera to Camera-up.
-- [ ] With the camera still selected, press kbd:[Shift]+kbd:[D]. This will duplicate the camera. Next press kbd:[Enter] to set the selection.
-- [ ] With the camera still selected, press kbd:[R] immediately followed by 180 immediately followed by kbd:[Enter]. This will rotate the camera 180 degrees along the X axis. The camera should now be facing down. Rename this camera to Camera-down.
-- [ ] Save your file.
-
-[%interactive]
-.Angular Map
-- [ ] Open up a web browser and search for "free high res skymap" and select a Angular map of your choice or you can find some here at link:https://blenderartists.org/forum/showthread.php?24038-Free-high-res-skymaps-%2528Massive-07-update!%2529[https://blenderartists.org/forum/showthread.php?24038-Free-high-res-skymaps-%2528Massive-07-update!%2529] instead. Remember to select an *ANGULAR* map.
-- [ ] Save a map to your pc in a place you can easily locate it from later in blender.
-
-[%interactive]
-.Textures Tab
-- [ ] From the properties panel (bottom-right panel) select the Textures tab (red-white checkerboard) then press the new button to create a new texture. Rename this texture to AngMap.
-- [ ] Under the Image panel select open and navigate to the file you saved earlier.
-- [ ] In the Mapping panel select AngMap from the drop down box.
-- [ ] In the Influence panel de-select blend (ble) and select horizon (hor).
-
-[%interactive]
-.Data Tab
-- [ ] From the properties panel select the Data tab (reel to reel camera).
-- [ ] In the lens panel change the Focal Lens value from 35 to 16. Do this for every camera.
-
-[%interactive]
-.Render Tab
-- [ ] From the properties panel select the Render tab (normal looking camera).
-- [ ] In the Dimensions panel set the resolution to any number that is a power of 2. For this example 1024 x 1024. 
-- [ ] Slide the resolution scale to 100%.
-- [ ] In the Output panel change the image type to JPEG. I have found out by trial and error that using a JPEG file has the same image quality as a PNG or DDS file but with a huge difference in image size. A single PNG image will clock in at over 8mb to the JPEG size of 325kb. Even converting to a DDS file comes in at over 3mb for comparison (using RGB888 as is recommended by Momoko_Fan/Core Developer in this link:https://hub.jmonkeyengine.org/t/best-dds-format-for-skyfactory/17668/2[forum post]) with no gain in image quality that I could see. Your welcome to experiment on your own if you wish.
-- [ ] Set the image format to RGB.
-- [ ] Setting the quality slider has the effect of reducing the image size where 0 is maximum compression and 100 is no compression. In this example, setting it to 0 reduced the image sizes to less than 125kb, once again with no discernable image degradation that I could see.
-
-[%interactive]
-.World Tab
-- [ ] In the properties panel select the World tab.
-- [ ] Check the Real Sky toggle.
-
-[%interactive]
-.Map Generator Setup 
-- [ ] From the header at the top of the 3d view click the btn:[Choose Screen Layout] button next to the word `Default` and select `Split Verticle F/R`. 
-- [ ] Click the `+` sign to create a new layout. 
-- [ ] Rename this new layout Angular Map Generator or a name of your choosing.
-- [ ] In the left side 3d view, at the bottom, next to the word view, is the btn:[Current Editor Type] button. Click it and change it to `UV/Image Editor`.
-- [ ] Place your mouse inside the right side 3d view and press kbd:[NumPad 5] to toggle ortho view. You're now setup to render your Angular map.
-- [ ] Save your file.
-
-[%interactive]
-.Rendering And Saving
-- [ ] With your first camera selected (in this case Camera-down) and your mouse inside the right side 3d view, press kbd:[Ctrl]+kbd:[NumPad 0] to set your selected camera to be the active camera. 
-- [ ] Press kbd:[F12] to render the scene. A image will appear in the left side UV/Image Editor.
-- [ ] With your mouse inside the left side UV/Image Editor you can scroll in or out to center the view.
-- [ ] With your mouse inside the left side UV/Image Editor press kbd:[F3] to save your image. Rename the image (down.jpg in this case). 
-
-Follow this same procedure for the remaining cameras. Rendering, renaming and saving each. After you have rendered all your images you can copy and paste them into your asset folder for JME3. Usually under the `Assets/Texture` directory. 
-
-To use your images in your code, in simpleInitApp(), load the Textures and use the SkyFactory to create your sky.
-
-[source,java]
-----
-Texture west = getAssetManager().loadTexture("Textures/Sky/west.jpg");
-Texture east = getAssetManager().loadTexture("Textures/Sky/east.jpg");
-Texture north = getAssetManager().loadTexture("Textures/Sky/north.jpg");
-Texture south = getAssetManager().loadTexture("Textures/Sky/south.jpg");
-Texture up = getAssetManager().loadTexture("Textures/Sky/up.jpg");
-Texture down = getAssetManager().loadTexture("Textures/Sky/down.jpg");
-getRootNode().attachChild(SkyFactory.createSky(getAssetManager(), west, east, north, south, up, down));
-----
-
-Many thanks go out to contributor glaucomardano for his video. He has excellent taste in music.
-
-Listed below are other Blender tutorials JME3 users may find valuable. 
-
-*  link:https://www.katsbits.com/tutorials/blender/cycles-skybox.php[Render a Skybox using Cycles]
-*  link:https://www.katsbits.com/tutorials/blender/render-skybox.php[Render a Skybox Environment Map]
-
-
-== Gimp
-
-
-You can use link:https://www.gimp.org/[Gimp] to create SkyMaps from a single image with the addition of 2 scripts.
-
-*  link:https://code.google.com/archive/p/gimp-dds/[Gimp-dds]
-*  link:http://registry.gimp.org/node/25532[Cubemap Layers Generator]
-
-After installing the scripts you open a image in gimp. This script works by slicing up the image into 6 layers of equal size, each by the power of 2. 
-
-.  After you open the image you select `menu:Filters[Generic > Cubemap Layers Generator]`.
-.  Fill in the details as follows. 
-**  Source: navigate to the image you are slicing.
-**  Cubemap layout: `Cross Horizontal`
-**  2 to the power of: `10` (for 1024 sized Layers) 
-.  Press btn:[OK] to slice up the image.
-.  Select `menu:File[Export As]` and change the `Name` and `File Type` to `.dds`. Choose your save location, typically `Assets/Textures`.
-.  Press btn:[Export].
-. A DDS panel will open. Apply the following settings:
-* Compression: `None`
-* Format: `RGB8`
-* Save: `As cube map`
-* MipMaps: `No mipmaps`
-. Press btn:[OK] to export.
-
-You attach the exported image to your scene as is explained in the <<jme3/advanced/sky#,How to add a Sky to your Scene>> tutorial.

+ 0 - 88
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/makehuman_blender_ogrexml_toolchain.adoc

@@ -1,88 +0,0 @@
-= MakeHuman Blender OgreXML toolchain for creating and importing animated human characters
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-This guide describes how to use MakeHuman Blender OgreXML toolchain.
-
-
-== Tools
-
-The latest versions at time of writing are:
-
-*  MakeHuman: 1.0.2
-*  Blender: 2.72
-*  OgreXML exporter for Blender: 0.6.0
-
-The tools can be downloaded from the following URLs:
-
-*  MakeHuman: [link:http://www.makehuman.org/][http://www.makehuman.org/]]
-*  Blender: [link:http://www.blender.org/][http://www.blender.org/]]
-*  OgreXML exporter for Blender: <<jme3/advanced/ogrecompatibility#,Working Blender and OgreXML Versions>>
-
-
-== Seed Project
-
-Public domain seed project with some preset characters and animations:
-
-*  JME3 Open Asset Pack: [link:https://github.com/bubblecloud/jme3-open-asset-pack][https://github.com/bubblecloud/jme3-open-asset-pack]]
-
-
-== Preparation
-
-.  Install MakeHuman and Blender.
-.  Install MakeHuman Blender importer from MakeHuman installation to Blender scripts folder and enable the script from Blender File → User Preferences → Addons.
-.  Install OgreXML exporter to Blender scripts folder and enable the script from Blender File → User Preferences → Addons.
-.  Clone the seed project or create your own project.
-.  Locate or create character model folder (src/main/resources/character/human/female)
-
-
-== Creating Character Model with MakeHuman
-
-.  Create character model with MakeHuman. ([link:http://www.makehuman.org/documentation][http://www.makehuman.org/documentation]])
-**  NOTE: If you want to use JME3 Open Asset Pack animations without tweaking then use either male.mhm or female.mhm as preset and do not change the body proportions.
-
-.  Choose basic skeleton from Pose/Animate tab if you are not already using either of the presets.
-.  Export to blender exchange format from Files → Export tab.
-**  Choose Mesh Format → Blender exchange.
-**  Tick only Options → Feet on Ground and Scale Units → Meter 
-
-
-
-== Animating Character Model with Blender
-
-.  Import the character model in blender exchange format (MHX) to Blender or open preset blender file female.blend.
-.  If you use your own character you can append animations from male.blend or female.blend preset files with Blender File → Append  function. Animations are in the animation folder.
-.  Tune the character model / materials and animate the character. ([link:http://www.blender.org/support/tutorials/][http://www.blender.org/support/tutorials/]])
-
-
-== Exporting Character Model from Blender to Ogre XML
-
-.  Make sure that your scene objects in Blender do not have any spaces or special characters in their names. Rename them if they do.
-.  Arrange all your animations in single NLA track after each other without overlaps or touching in the timeline.
-.  Unlink any animations linked directly to your character armature or mesh.
-.  Export using Blender → File → Export Ogre3D (scene and mesh) and tick the following options:
-**  copy shader programs
-**  Export Scen
-**  Export Meshes
-**  Export Meshes (overwrite)
-**  Armature Animation
-**  Optimize Arrays
-**  Export Materials
-**  Tangents
-**  Reorganize Buffers
-**  Optimize Animations
-
-
-
-== Importing Ogre XML to JME3
-
-You can load the ogre XML with asset manager or import them to SDK and hence convert them to JME3 asset format.
-
-You can test the animations by making your own version of AnimationPreviewer:
-
-link:https://github.com/bubblecloud/jme3-open-asset-pack/blob/master/src/main/java/com/jme3/asset/AnimationPreview.java[https://github.com/bubblecloud/jme3-open-asset-pack/blob/master/src/main/java/com/jme3/asset/AnimationPreview.java]

+ 0 - 374
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/mixamo.adoc

@@ -1,374 +0,0 @@
-= Animating Blender Models With Mixamo
-:author:
-:revnumber:
-:revdate: 2017/05/25 13:04
-:relfileprefix: ../../
-:imagesdir: ../..
-:experimental:
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== Using Mixamo For Model Animation
-
-With very little effort, you can use Adobes Mixamo to fully animate your Blender models. Once you understand the process that is.
-
-This guide requires:
-
-*  link:https://www.blender.org/download/[Blender version 2.78c] with its default settings. The exception being `Select With:`, under `menu:File[User Preferences >  Input]` is set to `Left Click`.
-*  Blender Ogre exporter 0.6.0, found <<jme3/advanced/ogrecompatibility#,here>>, enabled.
-*  Blender FBX file Importing and Exporting, enabled.
-*  A Modest amount of Blender knowledge.
-*  A link:https://www.mixamo.com/#/[Mixamo] account.
-
-
-== Prepare to Export
-
-To properly animate your models there are a few rules you must follow.
-
-*  Read the link:https://community.mixamo.com/hc/en-us/articles/210310918-Auto-Rigger-Troubleshooting[Auto-Rig Error Troubleshooting] guide before you do anything else.
-*  Clean up your Blender file prior to exporting. This means you have a game ready model that will become the base for all your animations. The following checklist is provided for your convenience.
-[%interactive]
-- [ ] You have no Animations.
-- [ ] You have UV Mapped your model.
-- [ ] Your models origin is at the base of the mesh.
-- [ ] You have one Material named the same as your mesh.
-- [ ] You have baked and packed your Texture. For this tutorial we use a diffuse texture (i.e. your using a texture atlas), no normal or specular maps.
-- [ ] You have cleared the UV, Material and Texture buffers of unused images, materials and textures.
-- [ ] There are no `Actions` stored in the `Dope Sheet Editor` buffer.  Open the `Action Editor` context, select the btn:[Browse Action to be linked] button to check there are no stored actions.
-- [ ] You have applied the Location, Rotation, and Scale to your model.
-- [ ] *MOST IMPORTANT OF ALL*, in the `menu:Properties Panel[Scene Tab > Units Panel]` set the btn:[Unit of Measure] to Meters and the Length to Metric. Adobe uses centimeters for the FBX exporter and if this is not set the models scale will be unusual to say the least. Besides that, JME3 uses 1 WU = 1 Meter so this will keep things consistent. If you are doing this now, you may have to re-scale your model before proceeding.
-
-[TIP]
-====
-See <<jme3/advanced/3d_models#blender-buffer-clearing#,Blender Buffer Clearing>> if you don't already know how to clear your buffers.
-
-See <<jme3/external/blender#,Creating assets in Blender3D>> for help on creating jME3 compatible models.
-====
-
-== Blender FBX Export
-
-
-.  In the `3d Viewport`, select your model, it will be high-lighted in orange.
-.  In the `Info` header, select `menu:File[Export > FBX]`.
-.  Enter a file path to export to, usually the same folder as your `.blend` file for simplicity.
-.  Enter a file name.
-.  In the `Export FBX` panel, located in the bottom left of the export dialog:
-Main Tab::
-- [x] Selected Objects
-- Scale = 1
-+
-[IMPORTANT]
-====
-Click the button next to scale to deselect btn:[Scale all data]. Failure to do so will destroy the scale of your model. If the button is selected, it will be dark in color.
-====
-
--  Forward = -Z Forward
--  Up = Y Up
--  Which kind of object to export = Mesh
-Geometries Tab::
-- [x] Apply Modifiers
-.  When you are done, click the btn:[Export FBX] button to export the file.
-
-[TIP]
-====
-You can save these FBX export settings by clicking the btn:[+] button next to btn:[Operator Presets].
-====
-
-
-== Mixamo FBX Import
-
-
-.  Create an link:https://www.mixamo.com/#/[Mixamo] account and login.
-.  From the `Default Character` panel, select `Upload Character`.
-.  Navigate to the file to be uploaded or drag and drop it onto the file up-loader.
-.  Select `Open`.
-
-[NOTE]
-====
-Generally, if at any time during the import and rigging process the model does not appear within the time specified in the dialog that is showing, something has gone wrong and you will have to restart the process over.
-====
-
-== Mixamo Auto-Rigger
-
-
-If everything went well the `Auto-Rigger` will open and your model will be facing you.  If not, fix your model in Blender before proceeding.
-
-.  If the model is facing you, click btn:[Next].
-.  In this panel you will rig your model. Place the markers as shown in the Auto-Rigger dialog image.
-+
-[NOTE]
-====
-Remember that the model is facing you so its right is on your left.
-====
-
-.  Select the LOD you are after. This is based off how many bones you want the hand of the model to have. Feel free to cycle through the options to see what each one does.
-.  When you are through click the btn:[Next] button to rig your model.
-.  When the model appears, if satisfied with the results, click `Finish`.
-
-
-== Mixamo Animations
-
-
-.  In the far right panel select btn:[Find Animations].
-.  After deciding on an animation, click the animation to have it applied to your model.
-.  After the animation is applied to your model, toggle the btn:[In Place] checkbox if it's a moving animation.
-+
-[TIP]
-====
-You can make small adjustments to the animation by using the sliders. The most common adjustment you will make is the  `Character Arm-Space`. If you find the models hands are clipping through the model then use this slider to remedy the situation.
-====
-
-.  When satisfied with the animation, select the btn:[Download] button and follow the `Mixamo Download` instructions below.
-
-If you wish to add more animations, after the download, remove the animation by clicking on the btn:[X] button located next to the animations name. Add your new animation and when satisfied, download the new animation. Repeat as often as is neccessary.
-
-
-
-== Mixamo Download
-
-
-When downloading `*Animations*` from Mixamo:
-
-.  Make sure the btn:[In Place] checkbox is selected if it's a moving animation.
-.  In the `Download Settings` dialog use the default settings.
-*  Format = FBX
-*  Skin = With Skin
-* Frames per second = 30
-*  Keyframe Reduction = none
-.  Click btn:[Download] and save it to your computer.
-
-When downloading `*Characters*` from Mixamo:
-
-.  In the `Download Settings` dialog the `Format` is FBX and `Pose` is TPose.
-.  Click btn:[Download] and save it to your computer.
-
-
-== Creating Blender Animations
-
-Download your TPose model using the instructions for downloading `*Characters*` given above. We will use it as our newly rigged model for Blender. To keep things organized we will create a `.blend` file for every animation and later use a separate `.blend` file to combine all animations into one jME3 compatible animation.
-
-The following steps apply to any animation you want to add in the future.
-
-.  Start Blender if it is not already open.
-.  In the `Info` header, at the top of the program, select `menu:File[New > Reload Startup]`.
-.  Select the default cube and delete it.
-Scene Tab::
-*  In the `Properties` panel, located at the bottom right, select the `Scene` tab.
-*  In the `Units` panel, change the `Units of measure` to `Meters` and `Length` to `Metric`. You must *always* have these settings when importing from or exporting to Mixamo.
-+
-[TIP]
-====
-You should create and save a default startup file in Blender. `menu:File[Save Startup File]`. This way you will not have to constantly redo things. Setting your `Units of measure` is the least you should do. You can always restore the default startup file by selecting `menu:File[Load Factory Settings]` at any time.
-====
-
-.  In the `Info` header, select `menu:File[Import > FBX]`.
-.  Select the FBX file you downloaded earlier.
-.  In the `Import Fbx` panel located at the bottom left of the import dialog, leave all settings at their defaults.
-Main::
--  Scale = 1
-- [x] Import Normals
-- [x] Import Animations
-- Armature offset = 1
-- [x] Image Search
-- Decal offset = 0
-- [x] Use pre/post rotation
-Armatures::
--  Nothing checked
-.  When ready click btn:[Import FBX].
-.  After Blender imports the file, both the armature and model are selected, in this order, select `menu:Object[Apply > Rotation]`. Repeat this for the `Location` and `Scale`. Alternatively, select the armature and model individually and repeat the process.
-.  Select the Armature.
-.  In the `Timeline`, determine the Length of the animation by btn:[RMB] selecting the last keyframe in the timeline. +
- Set `End:` to this value.
-.  Click the btn:[|<<] button to reset timeline back to the first frame.
-.  In the `Info` header, change the `Default` screen layout to `Animation`.
-.  In the `Dope Sheet Editor`, change the `Dope Sheet` mode/context to `Action Editor`. The `Linked Action` will now show the action name of the animation you imported.
-.  Rename this to the name of the imported animation. In this instance it was TPose.
-.  Select the btn:[F] button to save the action.
-.  Save your file with the same name as the action.
-
-[NOTE]
-====
-Mixamo sets the rotation mode of bones to `Quaternion` as is appropriate for preventing link:https://en.wikipedia.org/wiki/Gimbal_lock[`Gimbal Lock`]. Keep this in mind if you decide to modify your animation. Blender defaults to `XYZ Euler` so you will need to change this setting prior to inserting new keyframes.
-====
-
-
-== Action Baking
-
-
-There are many ways to export or import files for jMonkeyEngine. If you plan to use a method other than `Ogre Exporter`, you may need to bake your actions. Baking is a destructive process so it is recommended that *after* completion of <<jme3/advanced/mixamo#creating-blender-animations#, Creating Blender Animations>>, test the animation in-game.
-
-If you find yourself in need of baking, the process is as follows.
-
-.  Using the animation file you created in the previous section, from the `Info` header, select `menu:File[Save Copy]`.
-.  Save the file somewhere other than the current folder. This will save you the effort of re-creating the animation file if you need it at some other time.
-.  In the `Info` header, change the `Default` screen layout to `Animation`.
-.  In the `Dope Sheet Editor`, change the `Dope Sheet` mode/context to `Action Editor`.
-.  Click the btn:[Action to be linked] button and select your action.
-.  In the `3d Viewport` header, select the armature.
-*  Depending on the mode selected choose:
-.. Object Mode: `menu:Object[Animation > Bake Action]`.
-.. Pose Mode: `menu:Pose[Animation > Bake Action]`.
-.  In the `Bake Action` dialog, deselect and set the settings as follows:
-Bake Action::
-- [ ] Selected Only
-- [x] Visual Keying
-- [x] Clear Constraints
-- [ ] Clear Parents
-- [ ] Overwrite Current
--  Bake Data = Pose
-.  When ready click btn:[OK].
-.  The `Linked Action` in the `Dope Sheet Editor` will change to the newly baked action and is named `Action`. Rename this to the name of the imported animation.
-.  Select the btn:[F] button to save the action.
-.  Save your file.
-.  Clear the old action from the `Linked Action` buffer. See <<jme3/advanced/3d_models#blender-buffer-clearing#,Blender Buffer Clearing>> for more information.
-
-
-== Creating The Rigged Animation File
-
-
-It's good practice to have a separate file for combining animations. Things can go wrong, animations may change, and you don't want to destroy your original model file by accident. Our plan of attack has been we create a .blend file for every animation and then use this separate rigged file to combine them into one. To keep it simple we will use a copy of the first animation we downloaded and created a `.blend` file for.
-
-You create a rigged animation file only one time per model.
-
-.  If you have closed the TPose.blend file, open it. In the `Info` header select `menu:File[Save As]` and save the file using the models name with the word `Rigged` added. This will be the only file we add animations to, for this model, from now on. It has our default TPose action which will allow us to start our animation track for `Ogre` animation exporting.
-.  Select your `Armature`.
-Object Tab::
-..  In the `Properties` panel, navigate to the `Object` tab. In the `Display` panel toggle `X-Ray` on.
-.  With your mouse inside the `3d Viewport`, press kbd:[Num Pad 1] followed by kbd:[Numpad 5].
-.  kbd:[Tab] into `Edit Mode`.
-.  Set the `3d Cursor` to the models origin.
-.  Select `menu:Add[Single Bone]`.
-+
-[IMPORTANT]
-====
-The models origin and the `Root` bone origin must be at the same location.
-====
-
-. Scale the bone down or up as needed by selecting the `Tip` (ball at the narrowest part of the bone) and dragging the `Z` arrow (blue arrow) of the manipulator up or down until you are satisfied with its scale. *DO NOT CHANGE THE ANGLE OR MOVE THE BASE OF THE BONE FROM CENTER*.
-.  When satisfied with the scale, select the body of the bone to select the entire bone.
-Bone Tab::
-..  In the `Properties` panel, navigate to the `Bone` tab.
-..  Rename the bone to `Root`.
-..  Deselect the `Deform` panel checkbox.
-.  In the `3d Viewport`, select the body of the armatures `Hip` bone, the lowest bone in the center of the armature, to select the entire bone.
-.  While holding kbd:[Shift] down, btn:[LMB] select the `Root` bone.
-.  Press kbd:[Ctrl] + kbd:[P].
-. In the `Make Parent` dialog choose `Keep Offset`.
-.  With the mouse inside the 3d Viewport, kbd:[Tab] out of `Edit Mode`.
-. Select your model.
-Data Tab::
-..  In the `Properties` panel, navigate to the `Data` tab and make sure the `Mesh` has the same name as your model.
-Material Tab::
-..  In the `Properties` panel, navigate to the `Material` tab and make sure there is one `Material` in the `Material List` and it is the same name as your model.
-..  In the `Transparency` panel, move the `Alpha` slider to 1.
-+
-[IMPORTANT]
-====
-There appears to be a bug where the FBX importer adds an `Alpha` map texture to your model. If the `Alpha` slider is not at one, and you use the Blender importer of the SDK, or convert a .blend file, it will be transparent. `Ogre` export is unaffected.
-====
-
-..  Deselect the checkbox of the `Transparency` panel.
-Texture Tab::
-..  In the `Properties` panel, navigate to the `Texture` tab, you will note that your texture has duplicate names in the `Texture List`. The bottom texture is actually a transparent `Alpha` texture and appears to be a bug. Select the *second* texture in the `*Texture List*` to highlight it.
-..  While holding down the kbd:[Shift] key, press the btn:[X] button next to the `*Texture Data Block*` to delete it.
-..  Select your remaining texture in the `Texture List` to highlight it. You will note the `Texture Data Block` is now red due to no texture being assigned.
-..  Click on the btn:[Browse Texture to be linked] button next to the `Texture Data Block` and select your texture.
-..  In the `Image` panel, click the btn:[Small Box] button located next to your texture's path to pack the image file.
-.  In the `Info` header, change the layout from `Animation` to `UV Editing`.
-.  With your mouse inside the `3d Viewport` and the model still selected, kbd:[Tab] into edit mode. If your model is not completely orange press kbd:[A] untill all vertices are selected. You will see your UV Mapped mesh appear in the `UV Image Editor` window.
-.  In the `UV Image Editor`, click the btn:[Browse Image to be linked] button and select your UV image.
-.  kbd:[Tab] out of `Edit Mode`.
-.  In the `Info` header, change the layout from `UV Editing` to `Default` and then click the btn:[+] button to create a new layout.
-.  Rename this new layout `NLA Editing`.
-.  Click the `Current Editor Type` button, located at the bottom left (small box) of the `3d Viewport`, and change it from `3d View` to `NLA Editor`. Our TPose action is now visible.
-+
-NOTE: If the action is not visible, navigate to the `Dope Sheet Editor` and from the `Action Editor` context, select the `Action`.
-
-.  Click the btn:[Double Down Arrow] button to push the action down into the stack.
-.  Beneath the TPose strip you will see a slider. Drag this slider to the right until your strip is nested up against the left margin of the window.
-. Save your file.
-
-
-== Ogre Export
-
-
-Your rigged file is now `Ogre` export ready. Before we go any further, we will test our export to verify it's error free.
-
-.  In the `Info` header, change the layout to `Default`.
-.  kbd:[Shift] + btn:[LMB] select your armature and your model.
-.  From the `Info` header, select `menu:File[Export > Ogre3d]`.
-.  Select a destination path in your games `Assets` folder, usually the `Textures` folder.
-.  Make sure `Selected Only` is checked and `Only Deformable Bones` is unchecked.
-.  When you're happy with your export settings click btn:[Export Ogre].
-
-If your file exports clean, proceed with the next steps. If not, fix any errors before continuing.
-
-[TIP]
-====
-More on the `Ogre` settings can be found in <<jme3/advanced/3d_models#creating-models-and-scenes#,creating models and scenes>>.
-====
-
-
-== Appending Blender Animations
-
-Follow the directions for <<jme3/advanced/mixamo#mixamo-animations#,Mixamo Animations>>, <<jme3/advanced/mixamo#mixamo-download#,Mixamo Download>>, <<jme3/advanced/mixamo#creating-blender-animations#,Creating Blender Animations>> and <<jme3/advanced/mixamo#clearing-the-linked-action-buffer#,Clearing The Linked Action Buffer>> for all animations you wish to append to your *rigged* animation file.
-
-.  If your `Rigged` file is closed, open it.
-.  From the `Info` header, change the Layout to `Default`.
-.  In the `3d Viewport`, select the armature of the model.
-.  From the `Info` header, select `menu:File[Append]`.
-.  Navigate to, and select the `.blend` animation file you want to append.
-.  From the folders list select the `Action` folder, followed by your action.
-.  When ready, select the btn:[Append From Library] button to finalize your selection.
-.  From the `Info` header, change your layout to `Animation`.
-.  In the `Dope Sheet Editor`, change the context to `Action Editor` if not already selected.
-.  Click the btn:[Action to be linked] button and select your append action from the list.
-.  Select the btn:[F] button to save the action.
-.  From the `Info` header, change the layout from `Animation` to the `NLA Editing` layout we created in the <<jme3/advanced/mixamo#creating-the-rigged-animation-file#,Creating The Rigged Animation File>> section of this tutorial. You will see your append `Action` at the top of the list.
-.  From the `NLA Editor` header, select `menu:Add[Add Tracks]`. A new track has now been added to the top of the list.
-.  Click the btn:[Double Down Arrow] button next to the `Action` to push it down into the stack.
-.  btn:[LMB] select the strip to make it the only strip selected.
-.  btn:[LMB] drag the selected strip to the right until there is at least a 4 keyframe gap between the furthest strip to the right in the list and the append strip you are dragging.
-+
-[TIP]
-====
-When the strip is in drag mode it will be purple. While in drag mode you do not need to keep the btn:[LMB] pressed.
-====
-
-.  When you are satisfied with the position, btn:[LMB] click the strip to finalize your selection. Your append strip should now be the furthest strip to the right in the list.
-+
-[TIP]
-====
-You can use the mouse scroll wheel to shrink or expand the strip window to bring all strips into the view.
-
-You can drag the slider, at the bottom of the strip window, to the right or left to position the strips against the side of the window.
-====
-
-.  With the mouse inside the strip window, press the kbd:[N] key to open the properties window.
-.  In the `Active Strip` panel, under `Strip Extents`, you will see the `End Frame` number. In the `Timeline`, set `End:` to this number. Every time you append an `Action` you must increase this number to equal the total length off all strips combined, including the gaps between strips.
-.  Save your file.
-
-Your file is now ready to <<jme3/advanced/mixamo#ogre-export#,export>>.
-
-[IMPORTANT]
-====
-Prior to export:
-
-In the `NLA Editor` make sure no `Actions` are waiting to be pushed down into the stack. If there are, it must be removed or made into a strip prior to export.
-
-In the `Dope Sheet Editor` make sure no `Actions` are selected in the `Action Editor` context. If one is selected, it will be sitting at the top of the `NLA Editor` stack.
-
-An `Action` that has not been pushed down into the `NLA Stack` will block your `NLA Strip` from playing.
-====
-
-Your NLA strip should look something like this:
-
-image::jme3/advanced/MixamoNLA.png[MixamoNLA.png,width="",height=""]
-
-
-== Notes
-
-
-*  You can see a similar video demonstration of this entire process in <<jme3#animations-and-scenes#,Animations And Scenes>> under the CadNav → Mixamo → JME Workflow heading.
-*  See <<jme3/beginner/hello_animation#,Hello Animation>> and <<jme3/advanced/animation#,Animation in JME3>> to learn how to use your animated model.

+ 0 - 61
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/ogrecompatibility.adoc

@@ -1,61 +0,0 @@
-= Working Blender and OgreXML Versions
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-Here you can find working combinations of Blender and the OgreXML exporter, with any tips or bugs associated with each.
-[cols="3", options="header"]
-|===
-
-a| Blender Version
-a| OgreXML Exporter Version
-a| Notes
-
-a|2.78
-a| link:http://code.google.com/p/blender2ogre/downloads/list[0.6.0]
-a|Root bone, no transforms on object, no envelopes
-
-a| 2.6.3
-a| link:http://code.google.com/p/blender2ogre/downloads/list[0.5.8]
-a| Root bone, no transforms on object, no envelopes
-
-a| 2.6.2
-a| link:http://code.google.com/p/blender2ogre/downloads/list[0.5.5]
-a| Root bone, no transforms on object, no envelopes
-
-a| 2.6.1
-a| ?
-<a|
-
-a| 2.6.0
-a| ?
-<a|
-
-|===
-
-
-== Tips
-
-Tips for exporting animations through OgreXML correctly:
-
-*  apply all transformations
-*  armature should have 0,0,0 transformation (loc,rot,scale)
-*  model object should have 0,0,0 transformation (loc,rot,scale)
-*  root bone should have 0,0,0 transformation (loc,rot,scale)
-*  no envelopes
-
-Test Character - link:http://dl.dropbox.com/u/26887202/123/jme_blender/characterOgre26.zip[http://dl.dropbox.com/u/26887202/123/jme_blender/characterOgre26.zip]
-
-image:jme3/advanced/ogre_solved.jpg[ogre_solved.jpg,width="",height=""]
-image:jme3/advanced/ogre_solved2.png[ogre_solved2.png,width="",height=""]
-
-
-== Troubleshooting
-
-*Q:* _My animation is stretched._
-
-*A:* Use the exporting tips provided above

+ 0 - 61
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/asset_pipeline/sky.adoc

@@ -1,61 +0,0 @@
-= How to add a Sky to your Scene
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-Here is an example for how you add a static horizon (a background landscape and a sky) to a scene.
-Having a discernable horizon with a suitable landscape (or space, or ocean, or whatever) in the background makes scenes look more realistic than just a single-colored “sky background.
-
-
-== Adding the Sky
-
-Adding a sky is extremely easy using the `com.jme3.util.SkyFactory`.
-
-[source,java]
-----
-getRootNode().attachChild(SkyFactory.createSky(getAssetManager(), "Textures/Sky/Bright/BrightSky.dds", SkyFactory.EnvMapType.CubeMap));
-----
-
-To add a sky you need to supply:
-
-.  The assetManager object to use
-.  A cube or sphere map texture of the sky
-.  Set the map type: link:http://javadoc.jmonkeyengine.org/com/jme3/util/SkyFactory.EnvMapType.html[SkyFactory.EnvMapType]. In this instance, CubeMap. 
-
-Internally, the SkyFactory calls the following methods:
-
-.  `sky.setQueueBucket(Bucket.Sky);` makes certain the sky is rendered in the right order, behind everything else.
-.  `sky.setCullHint(Spatial.CullHint.Never);` makes certain that the sky is never culled.
-.  The SkyFactory uses the internal jME3 material definition `Sky.j3md`. This Material definition works with sphere and cube maps. 
-
-
-== Creating the Textures
-
-As the sky texture we use the sample BrightSky.dds file from jme3test-test-data. 
-
-How to create a sky textures?
-
-*  There are many tools out there that generate cube and sphere maps. +
-Examples for landscape texture generators are Terragen or Bryce.
-*  The actual texture size does not matter, as long as you add the Sky Geometry to the Sky bucket: Everything in the sky bucket will always be infinitely far away behind everything else, and never intersect with your scene. +
-Of course the higher the resolution, the better it will look. On the other hand, if the graphic is too big, it will slow the game down. 
-*  A box or sphere map is the simplest solution. But you can use any Node as sky, even complex sets of geometries and quads with animated clouds, blinking stars, city skylines, etc.
-*  JME3 supports cube maps in PNG, JPG, or (compressed) DDS format.
-
-Box or Sphere?
-
-*  If you have access to cube map textures, then use a SkyBox
-**  link:http://1.bp.blogspot.com/_uVsWqMqIGQU/SN0IZEE117I/AAAAAAAAAPs/4lfHx1Erdqg/s1600/skybox[SkyBox examples]
-
-*  If you have access to sphere map textures – specially projected sky images that fit inside a sphere – then you use a SkySphere or SkyDome. 
-**  link:http://wiki.delphigl.com/index.php/Datei:Skysphere.jpg[SkySphere example]
-
-For more information on Skymap creation see: 
-
-*  <<jme3/advanced/free_skymaps#,How to create free skymaps>>
-*  <<jme3/external/blender.html#skybox-baking#,SkyBox baking>>

+ 0 - 273
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/atom_framework.adoc

@@ -1,273 +0,0 @@
-= atom_framework
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== Atom framework Introduction
-
-*Hi Monkeys,*
-
-*Atom framework for game developing in Java. Powered by JME3.*
-
-*Atom* framework which on top of JME3 and have some features like AI, Scripting, Database, VirtualReallity, Trigger, Multiplayer…(more below)  to make developing game process in JME3 much more easier!
-
-
-[TIP]
-====
-
-Go to the Atomix Game making tutorials. <<jme3/atomixtuts#,atomixtuts>>
-====
-
-
-
-=== Open Source
-
-Atom Core : The AtomCore source code is hosted in Googlecode
-
-Googlecode: link:https://code.google.com/p/atom-game-framework/[https://code.google.com/p/atom-game-framework/]
-
-Github: link:https://github.com/atomixnmc/atom-game-framework[https://github.com/atomixnmc/atom-game-framework]
-
-Wiki: link:https://code.google.com/p/atom-game-framework/wiki/[https://code.google.com/p/atom-game-framework/wiki/]
-
-
-=== Documentations:
-
-<<jme3/advanced/atom_framework/design#, Detailed architecture designs >>
-
-<<jme3/advanced/atom_framework/docs#, Detailed documentation >>
-
-<<jme3/advanced/atom_framework/comparison#, Detailed comparison>>
-
-
-=== Idea & Buzz
-
-*Better, more freedom, more fun!*
-
-From +++<strike>UDK and Unity</strike>+++ 's battle field, I've dreamt about making even better game engine with the help of my 2 fav technologies - *Java* and *opensource*.
-
-JME3 and Netbean combination are the most brighten idea I 've seen in years. I think it deserve a better reputation worldwide.
-
-
-==== Initial Ideas:
-
-*  Ease the learning curve
-*  Fun play/create game like kids in a sandbox
-*  Framework for games and apps(3D) 
-*  Nextgen techs
-
-
-==== Why call it Atom?
-
-link:https://en.wikipedia.org/wiki/Atom[https://en.wikipedia.org/wiki/Atom]
-
-Yes, this is for game developing. But in its heart is future's technologies. 
-
-....
- Atom Etymology: Devive the thing as small as you can, than compose it into a thing again.
-....
-[quote]
-____
- The same in programming, after all, modulize is to be integrated again! That really is the core idea of Atom framework, use the most simple primitives to compose the bigger, bigger matter! Every where, small tiny, fastest, embed inside others, stick together well…Take a look in Atom Ex <<jme3/advanced/atom_framework/atomex#,atomex>>, you will see the picture more clearly.
-____
-
-The most conceptual inspiration for Atom framework is project link:http://ptolemy.eecs.berkeley.edu/index.htm[http://ptolemy.eecs.berkeley.edu/index.htm] . Unfortunately Ptolemy is in “for research only area and its direction toward the much large scale than game developing. That's why Atom framework was born with the learnt architecture from Ptolemy. 
-[quote]
-____
- The Ptolemy project studies modeling, simulation, and design of concurrent, real-time, embedded systems. The focus is on assembly of concurrent components. The key underlying principle in the project is the use of well-defined models of computation that govern the interaction between components. A major problem area being addressed is the use of heterogeneous mixtures of models of computation
-____
-[quote]
-____
- Atom is designed to MAKE concurrent, real-time, embedded systems and GAMES. So it focus more in code generation, profile, monitoring; focus more in graphics, physics, player experience…etc. Underlying, it borrow quite a bunch of concept that built in Ptolemy.
-____
-
-
-=== Features
-
-* Atom framework Highlights*
-
-*  Flexible: Game | simulations centric but not forced!
-*  Modular: Dependency injection along with Component injection
-*  Parallel: Embrace parallel computing
-*  Next gen: Come with Bleeding edge technologies and powers of Java languages
-*  Cloud ready: Scale to web and distributed computing
-*  With ease: +++<abbr title="Graphical User Interface">GUI</abbr>+++ Tools everywhere, almost zero config need
-
-Full Features list
-
-*  Cross game genre framework for JME3
-**  <<jme3/advanced/atom_framework/atomcore#,General stage - world ; game play and cycle>>
-**  <<jme3/advanced/atom_framework/atomcore/entitysystem#,General Entity framework>>
-**  <<jme3/advanced/atom_framework/atomcore/event#,General Event framework>>
-**  <<jme3/advanced/atom_framework/atomcore/config#,Intuitive config framework  >>- toward zero-config approach
-**  <<jme3/advanced/atom_framework/atomcore/actor#,Actor and interactive agents, workers>>
-**  <<jme3/advanced/atom_framework/atomcore/execution#,Execution and monitor>>
-
-*  Network | Web ready
-**  Web scale support 
-**  <<jme3/advanced/atom_framework/atomcore/net#, Network &amp; Messaging framework>>
-**  <<jme3/advanced/atom_framework/atomcore/league#, Social foundation framework>>
-
-*  Additional to JME3 features (as libraries or toolkits)
-**  <<jme3/advanced/atom_framework/atomcore/fx#, UltimateEffects >>
-***  <<jme3/advanced/atom_framework/atomcore/particles#, UltimateParticles>>
-***  <<jme3/advanced/atom_framework/atomcore/sprite#, Cross dimension model >>
-***  <<jme3/advanced/atom_framework/atomcore/filters#, Filters >>
-
-**  <<jme3/advanced/atom_framework/atomcore/cinematic#, Cinematic >>
-**  <<jme3/advanced/atom_framework/atomcore/gui#, General extensible GUI with CSS>>
-**  <<jme3/advanced/atom_framework/atomexasset#, Ultimate asset pipeline>>
-**  <<jme3/advanced/atom_framework/atomanim#, Ultimate animation framework>>
-**  <<jme3/advanced/atom_framework/atomelight#, Extra rendering methods>>
-
-
-
-=== Architecture and components
-
-Here are its architecture and components.
-
-iframe::http://bubbl.us/view/1860d6/2fd77c/15vOUTXerN5GQ/[width="800px", height="400px", alt="", scroll="true",border="true",align="false"]
-
-
-
-==== Atom Core Libraries
-
-*  *<<jme3/advanced/atom_framework/atomcore#, AtomCore>>* : addition to JME3 core packages. 
-**  Cross game-genre elements: stage, cycle, entity, logic, trigger, event, config; 
-**  Managers: Advanced assets manager, dependecy injection, factory, scripting, basic DB..; 
-**  Common case: Common state, common scenerio, common UIs… 
-**  More Buzz? <<jme3/advanced/atom_framework/atomcore#, AtomCore documentation >>
-
-*  *<<jme3/advanced/atom_framework/atomscripting#, Atom Scripting>>* Base technology for use Groovy (potentional Scala, Jython..) as JME game scripting language… 
-**  Provide Test bed enviroment, thread-safe and intelligent Groovy swing component to extend the SDK in seconds
-**  More Buzz? <<jme3/advanced/atom_framework/atomscripting#, Atom Scripting>>
-
-*  *<<jme3/advanced/atom_framework/ai#, Atom AI>>* : a “framework to bring AI to jME3 game (also means real-time application)! But it's awesome in its own way. 
-**  Focus in AI coding, creating, testing, simulating, profiling in 3d enviroments.
-**  Come with tools as SDK plugins!
-**  Check <<jme3/advanced/atom_framework/ai#, Atom AI wiki>> for more buzz
-
-
-
-==== Ingame editor facilities and kits
-
-*  <<jme3/advanced/atom_framework/atomeditor#,Atom Editor>>: sotiphicated in-game editor application and +++<abbr title="Application Programming Interface">API</abbr>+++ for 3D games modelled toward netbean platform architecture. [In constrast with SimpleGameEditor project].
-*  <<jme3/advanced/atom_framework/atom2deditor#,Atom 2D Editor>>: for 2D games.
-*  *<<jme3/advanced/atom_framework/codegen#,Code Gen>>*: a “framework that intend to become the base technologies for all generation related techs in the Atom framework. <<jme3/advanced/atom_framework/codegen#,codegen>>
-**  Focus in provide general and abstract way to modeling|design game|real-time app concept and object, source codes. 
-**  Its first attempt to become a GLSL, Groovy generator, then become a Logic, source code generator… 
-**  Come with tools as SDK plugins!
-
-*  *<<jme3/advanced/atom_framework/citygen#,City Gen>>*: a “framework at first try to be a city generator, then grow up to be fullfill every geometric generating operations in 3D.
-**  Focus in “Level generator with 3d models, blueprint and geometric shapes, such as dugeon, city, rivers, mountain, trees…
-**  Can corporate with Code gen and other geometric libs to become a generative 3D editor…
-**  Come with tools as SDK plugins!
-
-
-
-==== Atom SDK
-
-*  *Atom SDK* : Expansion for current functions and features of the jME SDK on top of Netbean platform for desktop Swing based editing, more intuitive more user friendly and suchs.
-**  Full List? <<jme3/advanced/atom_framework/atomsdk#,atomsdk>>
-
-*  *TeeheeComposer* : Act as the base editor for video, cinematic, audio, effects, facial composer… anything require time-base keyframed or unlinear editing like sequences.
-**  An almighty composer, think about 3DSMax or Adobe After Effect in 3D
-**  Come with a lot of tools for the SDK : <<jme3/advanced/atom_framework/teehee#,teehee>>
-***  Cinematic composer
-***  Dialogue composer
-***  Effect composer
-***  Particle composer
-***  Animation composer
-
-
-*  *RPGCreator* : Despite of its name, its not just for Role playing game! 
-**  Provide functions to create| test| config basic game with these key elements : characters| stories| skills| items| modes| regions… almost every game genre has them embeded partly ( cross game genre)
-**  Come with tools as SDK plugins! <<jme3/advanced/atom_framework/rpgcreator#,rpgcreator>>
-
-*  *Nextgen Tools*
-**  Facial tools : Think FaceFX for JME :p <<jme3/advanced/atom_framework/facial#,facial>>
-**  Character customization management tools : Smart way to organize and corporate your assets, config, database and code for CC <<jme3/advanced/atom_framework/cc#,cc>>
-**  Vitural reality tools : Toolset for corporate vitural reality artifact in your app <<jme3/advanced/atom_framework/vr#,vr>>
-**  MMORPG tools : Toolset for creating of a MMORPG game's component and all its management structure. Epic! <<jme3/advanced/atom_framework/mmorpgtools#,mmorpgtools>>
-**  Human Simulation tools: Think advanced locomotion and AI (like Mechanim of Unity) multiply 10. In fact, it's quite similar with tool from Autodesk that simulations social beheviours of human characters. Epic! <<jme3/advanced/atom_framework/humansim#,humansim>>
-
-
-
-==== AtomEx Libraries and platform
-
-*  *Atom Ex* : addition to Atom framework which make its much more modulizable, extensible and enterprise ready. Distributed computing, web based, database… much more.
-**  More Buzz? <<jme3/advanced/atom_framework/atomex#, AtomEx documentation >>
-
-
-
-=== Vision
-
-
-==== Java,... again??!
-
-Yeah, it was long time ago, you quit learning java because java gaming is a dead end.
-
-But Android come to play, and the the market are open so freaking big that even companies live with their C++ code base want to take advantage of the new wave…
-
-Recently Java has so much improvements and then JME3 enchant the talents all around the world to develop the master peices of software!
-
-
-==== But did we chasing after them?
-
-No, we are not. We are going ahead of them with all the techniques from the almightly open-source.
-
-Java communities are much more open and helpful than any of those Microsoft, Apple, UDK, Unity,… evils… Let's make a fairplay at last!
-
-
-==== Can we win?
-
-The time will tell… but at least, we once gain give the power to the hands of the people, not just some rich and intelligent people, that's the most critical point!
-
-
-=== Project status
-
-If you interest in contribute to Atom framework open-sourced project, here is the status of the project in 2014 and some mile stones it want to reach in the future.
-
-<<jme3/advanced/atom_framework/status#,Atom framework open-sourced project Status - 2014>>
-
-
-=== Other open-source dependencies
-
-Actually it use directly/indirectly various projects of JME3 great contributors and open source projects:
-
-*  AI from @Sploreg,@shirkit and mine
-*  VirtualReallity integrated with OpenCV, JavaCV : @noncom + mine
-*  ShaderBlow from @mifth
-*  SpriteEngine @dansion
-*  Forestor from @androlo
-*  Multiplayer on top of MirrorMonkey, Kryonet, Arianne, ThreeRings, …
-*  MonkeyZone code which I believe written by @normen @nehon and core guys :p
-*  Database using Cayenne, Depot
-*  … other contributors 
-
-( I will add them later :p please forgive if I can't remember your name immediately )
-
-[WARNING]
-====
-Hundred of opensource projects…Nail it
-====
-
-
-
-[TIP]
-====
-_I want to thank all of you for you great great great contributions, help me and my friends here to start learning game programming and doing our own game. Salute! My job is to glue the those great gems together, (pretty time consuming job) :_
-
-====
-
-
-As the spliting above, then I will make two different topic to keep them separate, the Atom framework and the Series of game making.
-
-<<jme3/atomixtuts#, Atomix Series of game making>>
-
-GOTO <<jme3/advanced/atom_framework/docs#,Detailed Atom framework Documentation>>

+ 0 - 336
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/audio/audio.adoc

@@ -1,336 +0,0 @@
-= Audio in jME3
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: sound, documentation, environment
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-Place audio files in the `assets/Sound/` directory of your project. jME3 supports Ogg Vorbis audio compression (.ogg) and uncompressed PCM Wave (.wav) formats. You can use for example link:http://audacity.sourceforge.net/[Audacity] to convert from other formats.
-
-
-== Audio Terminology
-
-*  *Streaming:* There are two ways to load audio data: Short audio files are to be stored entirely in memory (prebuffered), while long audio files, such as music, are streamed from the hard drive as it is played.
-*  *Looping:* You can play a sound either once and then stop, or repeatedly (continuously) in a loop. +
-You cannot loop streamed sounds.
-*  *Instance:* If you play the same audio twice, the playing is queued up and jME plays one after the other. If you play instances of sounds, several instances of the same sound can play at the same time.
-
-
-== Creating Audio Nodes: Streamed or Buffered
-
-The main jME audio class to look at is `com.jme3.audio.AudioNode`. When creating a new audio node you need to declare whether how you want to load this sound:
-
-*  *Buffered:* By default, a new audio node is buffered. This means jME3 loads the whole file into memory before playing. Use this for short sounds. You create a buffered sound  by setting DataType.Buffer, or using no DataType at all: 
-[source,java]
-----
-AudioNode boom = new AudioNode(assetManager, "Sound/boom.wav");
-AudioNode boom = new AudioNode(assetManager, "Sound/boom.wav", DataType.Buffer);
-----
-
-*  *Streamed:* If it is a long file such as music or a dialog, you stream the audio. Streaming means, you load and play in parallel until the sound is done. You cannot loop streams. You create a streamed sound by setting the boolean to true:
-[source,java]
-----
-AudioNode music = new AudioNode(assetManager, "Sound/music.wav", DataType.Stream);
-----
-
-
-
-== Getting AudioNode Properties
-
-[cols="2", options="header"]
-|===
-
-a|AudioNode Method
-a|Usage
-
-a|getStatus()
-a|Returns either AudioSource.Status.Playing, AudioSource.Status.Stopped, or AudioSource.Status.Paused. 
-
-a|getVolume()
-a|Returns the volume. 
-
-a|getPitch()
-a|Returns the pitch. 
-
-|===
-
-[NOTE]
-====
-There are other obvious getters to poll the status of all corresponding setters listed here.
-====
-
-
-== Setting AudioNode Properties
-
-[cols="2", options="header"]
-|===
-
-a|AudioNode Method
-a|Usage
-
-a|setTimeOffset(0.5f)
-a|Play the sound starting at a 0.5 second offset from the beginning. Default is 0.
-
-a|setPitch(1)
-a|Makes the sound play in a higher or lower pitch. Default is 1. 2 is twice as high, .5f is half as high. 
-
-a|setVolume(1)
-a|Sets the volume gain. 1 is the default volume, 2 is twice as loud, etc. 0 is silent/mute. 
-
-a|setRefDistance(50f)
-a|The reference distance controls how far a sound can still be heard at 50% of its original volume (_this is assuming an exponential fall-off!_). A sound with a high RefDist can be heard loud over wide distances; a sound with a low refDist can only be heard when the listener is close by. Default is 10 world units.
-
-a|setMaxDistance(100f)
-a| The 'maximum attenuation distance' specifies how far from the source the sound stops growing more quiet (sounds in nature don't do that). Set this to a smaller value to keep the sound loud even at a distance; set this to higher value to let the sound fade out quickly. Default is 20 world units.
-
-a|setLooping(false)
-a|Configures the sound so that, if it is played, it plays once and stops. No looping is the default.
-
-|===
-
-
-=== Looping & Ambient Sounds
-
-[cols="2", options="header"]
-|===
-
-a|AudioNode Method
-a|Usage
-
-a|setPositional(false) +
-setDirectional(false)
-a|All 3D effects switched off. This sound is global and plays in headspace (it appears to come from everywhere). Good for environmental ambient sounds and background music.
-
-a|setLooping(true)
-a|Configures the sound to be a loop: After the sound plays, it repeats from the beginning, until you call stop() or pause(). Good for music and ambient background noises. +
-*Before 3.1-alpha2, Looping does not work on streamed sounds.* 
-
-|===
-
-
-=== Positional 3D Sounds
-
-[cols="2", options="header"]
-|===
-
-a|AudioNode Method
-a|Usage
-
-a|setPositional(true) +
-setLocalTranslation(…)
-a|Activates 3D audio: The sound appears to come from a certain position, where it is loudest. Position the AudioNode in the 3D scene, or move it with mobile players or NPCs.
-
-a|setReverbEnabled(true)
-a|Reverb is a 3D echo effect that only makes sense with positional AudioNodes. Use Audio Environments to make scenes sound as if they were “outdoors, or “indoors in a large or small room, etc. The reverb effect is defined by the `com.jme3.audio.Environment` that the `audioRenderer` is in. See “Setting Audio Environment Properties below. 
-
-|===
-
-
-[IMPORTANT]
-====
-Positional 3D sounds require an `AudioListener` object in the scene (representing the player's ears).
-====
-
-
-
-=== Directional 3D Sounds
-
-[cols="2", options="header"]
-|===
-
-a|AudioNode Method
-a|Usage
-
-a|setDirectional(true) +
-setDirection(…) 
-a|Activates 3D audio: This sound can only be heard from a certain direction. Specify the direction and angle in the 3D scene if you have setDirectional() true. Use this to restrict noises that should not be heard, for example, through a wall.
-
-a|setInnerAngle() +
-setOuterAngle()
-a|Set the angle in degrees for the directional audio. The angle is relative to the direction. Note: By default, both angles are 360° and the sound can be heard from all directions!
-
-|===
-
-
-[IMPORTANT]
-====
-Directional 3D sounds require an AudioListener object in the scene (representing the player's ears). 
-====
-
-
-
-== Play, Pause, Stop
-
-You play, pause, and stop a node called myAudioNode by using the respective of the following three methods:
-
-[source,java]
-----
-myAudioNode.play();
-----
-
-[source,java]
-----
-myAudioNode.pause();
-----
-
-[source,java]
-----
-myAudioNode.stop();
-----
-
-[NOTE]
-====
-Whether an Audio Node plays continuously or only once, depends on the Loop properties you have set above!
-====
-
-You can also start playing instances of an AudioNode. Use the `playInstance()` method if you need to play the same AudioNode multiple times, possibly simulatenously. Note that changes to the parameters of the original AudioNode do not affect the instances that are already playing!
-
-[source,java]
-----
-myAudioNode.playInstance();
-----
-
-
-== The Audio Listener
-
-The default AudioListener object `listener` in `SimpleApplication` is the user's ear in the scene. If you use 3D audio (positional or directional sounds), you must move the AudioListener with the player: For example, for a first-person player, you move the listener with the camera. For a third-person player, you move the listener with the player avatar Geometry.
-
-[source,java]
-----
-
-  @Override
-  public void simpleUpdate(float tpf) {
-    // first-person: keep the audio listener moving with the camera
-    listener.setLocation(cam.getLocation());
-    listener.setRotation(cam.getRotation());
-  }
-
-----
-
-
-== Setting Audio Environment Properties
-
-Optionally, You can choose from the following environmental presets from `com.jme3.audio.Environment`. This presets influence subtle echo effects (reverb) that evoke associations of different environments in your users. That is, it makes you scene sound “indoors or “outdoors etc. You use Audio Environments together with `setReverbEnabled(true)` on positional AudioNodes (see above).
-
-[cols="11", options="header"]
-|===
-
-a|Environment
-a|density
-a|diffusion
-a|gain
-a|gainHf
-a|decayTime
-a|decayHf
-a|reflGain
-a|reflDelay
-a|lateGain
-a|lateDelay
-
-<a|Garage      
-a|1.00f
-a|1.0f
-a|1.0f
-a|1.00f
-a|0.90f
-a|0.5f
-a|0.751f
-a|0.0039f
-a|0.661f
-a|0.0137f
-
-<a|Dungeon     
-a|0.75f
-a|1.0f
-a|1.0f
-a|0.75f
-a|1.60f
-a|1.0f
-a|0.950f
-a|0.0026f
-a|0.930f
-a|0.0103f
-
-<a|Cavern      
-a|0.50f
-a|1.0f
-a|1.0f
-a|0.50f
-a|2.25f
-a|1.0f
-a|0.908f
-a|0.0103f
-a|0.930f
-a|0.0410f
-
-a|AcousticLab 
-a|0.50f
-a|1.0f
-a|1.0f
-a|1.00f
-a|0.28f
-a|1.0f
-a|0.870f
-a|0.0020f
-a|0.810f
-a|0.0080f
-
-<a|Closet      
-a|1.00f
-a|1.0f
-a|1.0f
-a|1.00f
-a|0.15f
-a|1.0f
-a|0.600f
-a|0.0025f
-a|0.500f
-a|0.0006f
-
-|===
-
-.  Activate a Environment preset
-**  Either use a default, e.g. make you scene sounds like a dungeon environment: 
-+
-[source,java]
-----
-audioRenderer.setEnvironment(new Environment(Environment.Dungeon));
-----
-
-**  Or activate <<jme3/advanced/audio_environment_presets#,custom environment settings>> in the Environment constructor:
-+
-[source,java]
-----
-audioRenderer.setEnvironment(
-        new Environment( density, diffusion, gain, gainHf, decayTime, decayHf,
-                reflGain, reflDelay, lateGain, lateDelay ) );
-----
-
-
-.  Activate 3D audio for certain sounds: 
-+
-[source,java]
-----
-footstepsAudio.setPositional(true);
-footstepsAudio.setReverbEnabled(true);
-----
-
-
-
-[TIP]
-====
-A sound engineer can create a custom `com.​jme3.​audio.Environment` object and specify custom environment values such as density, diffusion, gain, decay, delay… You can find many <<jme3/advanced/audio_environment_presets#,examples of custom audio environment presets>> here.
-====
-
-
-Advanced users find more info about OpenAL and its features here: link:http://web.archive.org/web/20130327063429/http://connect.creativelabs.com/openal/Documentation/OpenAL_Programmers_Guide.pdf[OpenAL 1.1 Specification]. 
-
-
-[IMPORTANT]
-====
-It depends on the hardware whether audio effects are supported (if not, you get the message `OpenAL EFX not available! Audio effects won't work.`)
-====
-

+ 0 - 277
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/audio/audio_environment_presets.adoc

@@ -1,277 +0,0 @@
-= Audio Environment Presets
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-Use these presets together with <<jme3/advanced/audio#,Audio>> Nodes to create different “moods for sounds. Environment effects make your audio sound as if the listener were in various places that have different types of echoes. 
-
-Usage:
-
-[source,java]
-----
-
-Environment Generic = new Environment(
-    new float[]{ 0, 7.5f, 1f, -1000, -100, 0, 1.49f, 0.83f, 1f, -2602,
-                 0.007f, 0f, 0f, 0f, 200, 0.011f, 0f, 0f, 0f, 0.250f,
-                 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-audioRenderer.setEnvironment(myEnvironment);
-
-----
-
-
-== Castle
-
-[source,java]
-----
-
-CastleSmallRoom    = new Environment ( new float[]{ 26, 8.3f, 0.890f, -1000, -800, -2000, 1.22f, 0.83f, 0.31f, -100, 0.022f, 0f, 0f, 0f, 600, 0.011f, 0f, 0f, 0f, 0.138f, 0.080f, 0.250f, 0f, -5f, 5168.6f, 139.5f, 0f, 0x20} );
-CastleShortPassage = new Environment ( new float[]{ 26, 8.3f, 0.890f, -1000, -1000, -2000, 2.32f, 0.83f, 0.31f, -100, 0.007f, 0f, 0f, 0f, 200, 0.023f, 0f, 0f, 0f, 0.138f, 0.080f, 0.250f, 0f, -5f, 5168.6f, 139.5f, 0f, 0x20} );
-CastleMediumroom   = new Environment ( new float[]{ 26, 8.3f, 0.930f, -1000, -1100, -2000, 2.04f, 0.83f, 0.46f, -400, 0.022f, 0f, 0f, 0f, 400, 0.011f, 0f, 0f, 0f, 0.155f, 0.030f, 0.250f, 0f, -5f, 5168.6f, 139.5f, 0f, 0x20} );
-CastleLongpassage  = new Environment ( new float[]{ 26, 8.3f, 0.890f, -1000, -800, -2000, 3.42f, 0.83f, 0.31f, -100, 0.007f, 0f, 0f, 0f, 300, 0.023f, 0f, 0f, 0f, 0.138f, 0.080f, 0.250f, 0f, -5f, 5168.6f, 139.5f, 0f, 0x20} );
-CastleLargeroom    = new Environment ( new float[]{ 26, 8.3f, 0.820f, -1000, -1100, -1800, 2.53f, 0.83f, 0.50f, -700, 0.034f, 0f, 0f, 0f, 200, 0.016f, 0f, 0f, 0f, 0.185f, 0.070f, 0.250f, 0f, -5f, 5168.6f, 139.5f, 0f, 0x20} );
-CastleHall         = new Environment ( new float[]{ 26, 8.3f, 0.810f, -1000, -1100, -1500, 3.14f, 0.79f, 0.62f, -1500, 0.056f, 0f, 0f, 0f, 100, 0.024f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5168.6f, 139.5f, 0f, 0x20} );
-CastleCupboard     = new Environment ( new float[]{ 26, 8.3f, 0.890f, -1000, -1100, -2000, 0.67f, 0.87f, 0.31f, 300, 0.010f, 0f, 0f, 0f, 1100, 0.007f, 0f, 0f, 0f, 0.138f, 0.080f, 0.250f, 0f, -5f, 5168.6f, 139.5f, 0f, 0x20} );
-CastleCourtyard    = new Environment ( new float[]{ 26, 8.3f, 0.420f, -1000, -700, -1400, 2.13f, 0.61f, 0.23f, -1300, 0.160f, 0f, 0f, 0f, -300, 0.036f, 0f, 0f, 0f, 0.250f, 0.370f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x1f} );
-CastleAlcove       = new Environment ( new float[]{ 26, 8.3f, 0.890f, -1000, -600, -2000, 1.64f, 0.87f, 0.31f, 00, 0.007f, 0f, 0f, 0f, 300, 0.034f, 0f, 0f, 0f, 0.138f, 0.080f, 0.250f, 0f, -5f, 5168.6f, 139.5f, 0f, 0x20} );
-
-----
-
-
-== Warehouse, Factory
-
-[source,java]
-----
-
-FactoryAlcove       = new Environment ( new float[]{ 26, 1.8f, 0.590f, -1200, -200, -600, 3.14f, 0.65f, 1.31f, 300, 0.010f, 0f, 0f, 0f, 000, 0.038f, 0f, 0f, 0f, 0.114f, 0.100f, 0.250f, 0f, -5f, 3762.6f, 362.5f, 0f, 0x20} );
-FactoryShortpassage = new Environment ( new float[]{ 26, 1.8f, 0.640f, -1200, -200, -600, 2.53f, 0.65f, 1.31f, 0, 0.010f, 0f, 0f, 0f, 200, 0.038f, 0f, 0f, 0f, 0.135f, 0.230f, 0.250f, 0f, -5f, 3762.6f, 362.5f, 0f, 0x20} ) );
-FactoryMediumroom   = new Environment ( new float[]{ 26, 1.9f, 0.820f, -1200, -200, -600, 2.76f, 0.65f, 1.31f, -1100, 0.022f, 0f, 0f, 0f, 300, 0.023f, 0f, 0f, 0f, 0.174f, 0.070f, 0.250f, 0f, -5f, 3762.6f, 362.5f, 0f, 0x20} );
-FactoryLongpassage  = new Environment ( new float[]{ 26, 1.8f, 0.640f, -1200, -200, -600, 4.06f, 0.65f, 1.31f, 0, 0.020f, 0f, 0f, 0f, 200, 0.037f, 0f, 0f, 0f, 0.135f, 0.230f, 0.250f, 0f, -5f, 3762.6f, 362.5f, 0f, 0x20} );
-FactoryLargeroom    = new Environment ( new float[]{ 26, 1.9f, 0.750f, -1200, -300, -400, 4.24f, 0.51f, 1.31f, -1500, 0.039f, 0f, 0f, 0f, 100, 0.023f, 0f, 0f, 0f, 0.231f, 0.070f, 0.250f, 0f, -5f, 3762.6f, 362.5f, 0f, 0x20} );
-FactoryHall         = new Environment ( new float[]{ 26, 1.9f, 0.750f, -1000, -300, -400, 7.43f, 0.51f, 1.31f, -2400, 0.073f, 0f, 0f, 0f, -100, 0.027f, 0f, 0f, 0f, 0.250f, 0.070f, 0.250f, 0f, -5f, 3762.6f, 362.5f, 0f, 0x20} );
-FactoryCupboard     = new Environment ( new float[]{ 26, 1.7f, 0.630f, -1200, -200, -600, 0.49f, 0.65f, 1.31f, 200, 0.010f, 0f, 0f, 0f, 600, 0.032f, 0f, 0f, 0f, 0.107f, 0.070f, 0.250f, 0f, -5f, 3762.6f, 362.5f, 0f, 0x20} );
-FactoryCourtyard    = new Environment ( new float[]{ 26, 1.7f, 0.570f, -1000, -1000, -400, 2.32f, 0.29f, 0.56f, -1300, 0.140f, 0f, 0f, 0f, -800, 0.039f, 0f, 0f, 0f, 0.250f, 0.290f, 0.250f, 0f, -5f, 3762.6f, 362.5f, 0f, 0x20} );
-FactorySmallroom    = new Environment ( new float[]{ 26, 1.8f, 0.820f, -1000, -200, -600, 1.72f, 0.65f, 1.31f, -300, 0.010f, 0f, 0f, 0f, 500, 0.024f, 0f, 0f, 0f, 0.119f, 0.070f, 0.250f, 0f, -5f, 3762.6f, 362.5f, 0f, 0x20} );
-
-----
-
-
-== Ice Palace
-
-[source,java]
-----
-
-IcepalaceAlcove       = new Environment ( new float[]{ 26, 2.7f, 0.840f, -1000, -500, -1100, 2.76f, 1.46f, 0.28f, 100, 0.010f, 0f, 0f, 0f, -100, 0.030f, 0f, 0f, 0f, 0.161f, 0.090f, 0.250f, 0f, -5f, 12428.5f, 99.6f, 0f, 0x20} );
-IcepalaceShortpassage = new Environment ( new float[]{ 26, 2.7f, 0.750f, -1000, -500, -1100, 1.79f, 1.46f, 0.28f, -600, 0.010f, 0f, 0f, 0f, 100, 0.019f, 0f, 0f, 0f, 0.177f, 0.090f, 0.250f, 0f, -5f, 12428.5f, 99.6f, 0f, 0x20} ) );
-IcepalaceMediumroom   = new Environment ( new float[]{ 26, 2.7f, 0.870f, -1000, -500, -700, 2.22f, 1.53f, 0.32f, -800, 0.039f, 0f, 0f, 0f, 100, 0.027f, 0f, 0f, 0f, 0.186f, 0.120f, 0.250f, 0f, -5f, 12428.5f, 99.6f, 0f, 0x20} );
-IcepalaceLongpassage  = new Environment ( new float[]{ 26, 2.7f, 0.770f, -1000, -500, -800, 3.01f, 1.46f, 0.28f, -200, 0.012f, 0f, 0f, 0f, 200, 0.025f, 0f, 0f, 0f, 0.186f, 0.040f, 0.250f, 0f, -5f, 12428.5f, 99.6f, 0f, 0x20} );
-IcepalaceLargeroom    = new Environment ( new float[]{ 26, 2.9f, 0.810f, -1000, -500, -700, 3.14f, 1.53f, 0.32f, -1200, 0.039f, 0f, 0f, 0f, 000, 0.027f, 0f, 0f, 0f, 0.214f, 0.110f, 0.250f, 0f, -5f, 12428.5f, 99.6f, 0f, 0x20} );
-IcepalaceHall         = new Environment ( new float[]{ 26, 2.9f, 0.760f, -1000, -700, -500, 5.49f, 1.53f, 0.38f, -1900, 0.054f, 0f, 0f, 0f, -400, 0.052f, 0f, 0f, 0f, 0.226f, 0.110f, 0.250f, 0f, -5f, 12428.5f, 99.6f, 0f, 0x20} );
-IcepalaceCupboard     = new Environment ( new float[]{ 26, 2.7f, 0.830f, -1000, -600, -1300, 0.76f, 1.53f, 0.26f, 100, 0.012f, 0f, 0f, 0f, 600, 0.016f, 0f, 0f, 0f, 0.143f, 0.080f, 0.250f, 0f, -5f, 12428.5f, 99.6f, 0f, 0x20} );
-IcepalaceCourtyard    = new Environment ( new float[]{ 26, 2.9f, 0.590f, -1000, -1100, -1000, 2.04f, 1.20f, 0.38f, -1000, 0.173f, 0f, 0f, 0f, -1000, 0.043f, 0f, 0f, 0f, 0.235f, 0.480f, 0.250f, 0f, -5f, 12428.5f, 99.6f, 0f, 0x20} );
-IcepalaceSmallroom    = new Environment ( new float[]{ 26, 2.7f, 0.840f, -1000, -500, -1100, 1.51f, 1.53f, 0.27f, -100, 0.010f, 0f, 0f, 0f, 300, 0.011f, 0f, 0f, 0f, 0.164f, 0.140f, 0.250f, 0f, -5f, 12428.5f, 99.6f, 0f, 0x20} );
-
-----
-
-
-== Space Station
-
-[source,java]
-----
-
-SpacestationAlcove       = new Environment ( new float[]{ 26, 1.5f, 0.780f, -1000, -300, -100, 1.16f, 0.81f, 0.55f, 300, 0.007f, 0f, 0f, 0f, 000, 0.018f, 0f, 0f, 0f, 0.192f, 0.210f, 0.250f, 0f, -5f, 3316.1f, 458.2f, 0f, 0x20} );
-SpacestationMediumroom   = new Environment ( new float[]{ 26, 1.5f, 0.750f, -1000, -400, -100, 3.01f, 0.50f, 0.55f, -800, 0.034f, 0f, 0f, 0f, 100, 0.035f, 0f, 0f, 0f, 0.209f, 0.310f, 0.250f, 0f, -5f, 3316.1f, 458.2f, 0f, 0x20} );
-SpacestationShortpassage = new Environment ( new float[]{ 26, 1.5f, 0.870f, -1000, -400, -100, 3.57f, 0.50f, 0.55f, 0, 0.012f, 0f, 0f, 0f, 100, 0.016f, 0f, 0f, 0f, 0.172f, 0.200f, 0.250f, 0f, -5f, 3316.1f, 458.2f, 0f, 0x20} );
-SpacestationLongpassage  = new Environment ( new float[]{ 26, 1.9f, 0.820f, -1000, -400, -100, 4.62f, 0.62f, 0.55f, 0, 0.012f, 0f, 0f, 0f, 200, 0.031f, 0f, 0f, 0f, 0.250f, 0.230f, 0.250f, 0f, -5f, 3316.1f, 458.2f, 0f, 0x20} );
-SpacestationLargeroom    = new Environment ( new float[]{ 26, 1.8f, 0.810f, -1000, -400, -100, 3.89f, 0.38f, 0.61f, -1000, 0.056f, 0f, 0f, 0f, -100, 0.035f, 0f, 0f, 0f, 0.233f, 0.280f, 0.250f, 0f, -5f, 3316.1f, 458.2f, 0f, 0x20} );
-SpacestationHall         = new Environment ( new float[]{ 26, 1.9f, 0.870f, -1000, -400, -100, 7.11f, 0.38f, 0.61f, -1500, 0.100f, 0f, 0f, 0f, -400, 0.047f, 0f, 0f, 0f, 0.250f, 0.250f, 0.250f, 0f, -5f, 3316.1f, 458.2f, 0f, 0x20} );
-SpacestationCupboard     = new Environment ( new float[]{ 26, 1.4f, 0.560f, -1000, -300, -100, 0.79f, 0.81f, 0.55f, 300, 0.007f, 0f, 0f, 0f, 500, 0.018f, 0f, 0f, 0f, 0.181f, 0.310f, 0.250f, 0f, -5f, 3316.1f, 458.2f, 0f, 0x20} );
-SpacestationSmallroom    = new Environment ( new float[]{ 26, 1.5f, 0.700f, -1000, -300, -100, 1.72f, 0.82f, 0.55f, -200, 0.007f, 0f, 0f, 0f, 300, 0.013f, 0f, 0f, 0f, 0.188f, 0.260f, 0.250f, 0f, -5f, 3316.1f, 458.2f, 0f, 0x20} );
-
-----
-
-
-== Wooden Hut or Ship
-
-[source,java]
-----
-
-WoodenAlcove           = new Environment ( new float[]{ 26, 7.5f, 1f, -1000, -1800, -1000, 1.22f, 0.62f, 0.91f, 100, 0.012f, 0f, 0f, 0f, -300, 0.024f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 4705f, 99.6f, 0f, 0x3f} );
-WoodenShortpassage     = new Environment ( new float[]{ 26, 7.5f, 1f, -1000, -1800, -1000, 1.75f, 0.50f, 0.87f, -100, 0.012f, 0f, 0f, 0f, -400, 0.024f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 4705f, 99.6f, 0f, 0x3f} );
-WoodenMediumroom       = new Environment ( new float[]{ 26, 7.5f, 1f, -1000, -2000, -1100, 1.47f, 0.42f, 0.82f, -100, 0.049f, 0f, 0f, 0f, -100, 0.029f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 4705f, 99.6f, 0f, 0x3f} );
-WoodenLongpassage      = new Environment ( new float[]{ 26, 7.5f, 1f, -1000, -2000, -1000, 1.99f, 0.40f, 0.79f, 000, 0.020f, 0f, 0f, 0f, -700, 0.036f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 4705f, 99.6f, 0f, 0x3f} );
-WoodenLargeroom        = new Environment ( new float[]{ 26, 7.5f, 1f, -1000, -2100, -1100, 2.65f, 0.33f, 0.82f, -100, 0.066f, 0f, 0f, 0f, -200, 0.049f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 4705f, 99.6f, 0f, 0x3f} );
-WoodenHall             = new Environment ( new float[]{ 26, 7.5f, 1f, -1000, -2200, -1100, 3.45f, 0.30f, 0.82f, -100, 0.088f, 0f, 0f, 0f, -200, 0.063f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 4705f, 99.6f, 0f, 0x3f} );
-WoodenCupboard         = new Environment ( new float[]{ 26, 7.5f, 1f, -1000, -1700, -1000, 0.56f, 0.46f, 0.91f, 100, 0.012f, 0f, 0f, 0f, 100, 0.028f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 4705f, 99.6f, 0f, 0x3f} );
-WoodenSmallroom        = new Environment ( new float[]{ 26, 7.5f, 1f, -1000, -1900, -1000, 0.79f, 0.32f, 0.87f, 00, 0.032f, 0f, 0f, 0f, -100, 0.029f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 4705f, 99.6f, 0f, 0x3f} );
-WoodenCourtyard        = new Environment ( new float[]{ 26, 7.5f, 0.650f, -1000, -2200, -1000, 1.79f, 0.35f, 0.79f, -500, 0.123f, 0f, 0f, 0f, -2000, 0.032f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 4705f, 99.6f, 0f, 0x3f} );
-
-----
-
-
-== Sport
-
-[source,java]
-----
-
-SportEmptystadium      = new Environment ( new float[]{ 26, 7.2f, 1f, -1000, -700, -200, 6.26f, 0.51f, 1.10f, -2400, 0.183f, 0f, 0f, 0f, -800, 0.038f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x20} );
-SportSquashcourt       = new Environment ( new float[]{ 26, 7.5f, 0.750f, -1000, -1000, -200, 2.22f, 0.91f, 1.16f, -700, 0.007f, 0f, 0f, 0f, -200, 0.011f, 0f, 0f, 0f, 0.126f, 0.190f, 0.250f, 0f, -5f, 7176.9f, 211.2f, 0f, 0x20} );
-SportSmallswimmingpool = new Environment ( new float[]{ 26, 36.2f, 0.700f, -1000, -200, -100, 2.76f, 1.25f, 1.14f, -400, 0.020f, 0f, 0f, 0f, -200, 0.030f, 0f, 0f, 0f, 0.179f, 0.150f, 0.895f, 0.190f, -5f, 5000f, 250f, 0f, 0x0} );
-SportLargeswimmingpool = new Environment ( new float[]{ 26, 36.2f, 0.820f, -1000, -200, 0, 5.49f, 1.31f, 1.14f, -700, 0.039f, 0f, 0f, 0f, -600, 0.049f, 0f, 0f, 0f, 0.222f, 0.550f, 1.159f, 0.210f, -5f, 5000f, 250f, 0f, 0x0} );
-SportGymnasium         = new Environment ( new float[]{ 26, 7.5f, 0.810f, -1000, -700, -100, 3.14f, 1.06f, 1.35f, -800, 0.029f, 0f, 0f, 0f, -500, 0.045f, 0f, 0f, 0f, 0.146f, 0.140f, 0.250f, 0f, -5f, 7176.9f, 211.2f, 0f, 0x20} );
-SportFullstadium       = new Environment ( new float[]{ 26, 7.2f, 1f, -1000, -2300, -200, 5.25f, 0.17f, 0.80f, -2000, 0.188f, 0f, 0f, 0f, -1100, 0.038f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x20} );
-
-----
-
-
-== Pipes
-
-[source,java]
-----
-
-Sewerpipe    = new Environment ( new float[]{ 21, 1.7f, 0.800f, -1000, -1000, 0, 2.81f, 0.14f, 1f, 429, 0.014f, 0f, 0f, 0f, 1023, 0.021f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-PipeSmall    = new Environment ( new float[]{ 26, 50.3f, 1f, -1000, -900, -1300, 5.04f, 0.10f, 0.10f, -600, 0.032f, 0f, 0f, 0f, 800, 0.015f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 2854.4f, 20f, 0f, 0x3f} );
-PipeLongthin = new Environment ( new float[]{ 26, 1.6f, 0.910f, -1000, -700, -1100, 9.21f, 0.18f, 0.10f, -300, 0.010f, 0f, 0f, 0f, -300, 0.022f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 2854.4f, 20f, 0f, 0x0} );
-PipeLarge    = new Environment ( new float[]{ 26, 50.3f, 1f, -1000, -900, -1300, 8.45f, 0.10f, 0.10f, -800, 0.046f, 0f, 0f, 0f, 400, 0.032f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 2854.4f, 20f, 0f, 0x3f} );
-PipeResonant = new Environment ( new float[]{ 26, 1.3f, 0.910f, -1000, -700, -1100, 6.81f, 0.18f, 0.10f, -300, 0.010f, 0f, 0f, 0f, 00, 0.022f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 2854.4f, 20f, 0f, 0x0} );
-
-----
-
-
-== Moods
-
-[source,java]
-----
-
-Heaven    = new Environment ( new float[]{ 26, 19.6f, 0.940f, -1000, -200, -700, 5.04f, 1.12f, 0.56f, -1230, 0.020f, 0f, 0f, 0f, 200, 0.029f, 0f, 0f, 0f, 0.250f, 0.080f, 2.742f, 0.050f, -2f, 5000f, 250f, 0f, 0x3f} );
-Hell      = new Environment ( new float[]{ 26, 100f, 0.570f, -1000, -900, -700, 3.57f, 0.49f, 2f, -10000, 0.020f, 0f, 0f, 0f, 300, 0.030f, 0f, 0f, 0f, 0.110f, 0.040f, 2.109f, 0.520f, -5f, 5000f, 139.5f, 0f, 0x40} );
-Memory    = new Environment ( new float[]{ 26, 8f, 0.850f, -1000, -400, -900, 4.06f, 0.82f, 0.56f, -2800, 0f, 0f, 0f, 0f, 100, 0f, 0f, 0f, 0f, 0.250f, 0f, 0.474f, 0.450f, -10f, 5000f, 250f, 0f, 0x0} );
-Drugged   = new Environment ( new float[]{ 23, 1.9f, 0.500f, -1000, 0, 0, 8.39f, 1.39f, 1f, -115, 0.002f, 0f, 0f, 0f, 985, 0.030f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 1f, -5f, 5000f, 250f, 0f, 0x1f} );
-Dizzy     = new Environment ( new float[]{ 24, 1.8f, 0.600f, -1000, -400, 0, 17.23f, 0.56f, 1f, -1713, 0.020f, 0f, 0f, 0f, -613, 0.030f, 0f, 0f, 0f, 0.250f, 1f, 0.810f, 0.310f, -5f, 5000f, 250f, 0f, 0x1f} );
-Psychotic = new Environment ( new float[]{ 25, 1f, 0.500f, -1000, -151, 0, 7.56f, 0.91f, 1f, -626, 0.020f, 0f, 0f, 0f, 774, 0.030f, 0f, 0f, 0f, 0.250f, 0f, 4f, 1f, -5f, 5000f, 250f, 0f, 0x1f} );
-
-----
-
-
-== Car Racing
-
-[source,java]
-----
-
-DrivingCommentator    = new Environment ( new float[]{ 26, 3f, 0f, 1000, -500, -600, 2.42f, 0.88f, 0.68f, -1400, 0.093f, 0f, 0f, 0f, -1200, 0.017f, 0f, 0f, 0f, 0.250f, 1f, 0.250f, 0f, -10f, 5000f, 250f, 0f, 0x20} );
-DrivingPitgarage       = new Environment ( new float[]{ 26, 1.9f, 0.590f, -1000, -300, -500, 1.72f, 0.93f, 0.87f, -500, 0f, 0f, 0f, 0f, 200, 0.016f, 0f, 0f, 0f, 0.250f, 0.110f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x0} );
-DrivingIncarRacer      = new Environment ( new float[]{ 26, 1.1f, 0.800f, -1000, 0, -200, 0.17f, 2f, 0.41f, 500, 0.007f, 0f, 0f, 0f, -300, 0.015f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 10268.2f, 251f, 0f, 0x20} );
-DrivingIncarSports     = new Environment ( new float[]{ 26, 1.1f, 0.800f, -1000, -400, 0, 0.17f, 0.75f, 0.41f, 0, 0.010f, 0f, 0f, 0f, -500, 0f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 10268.2f, 251f, 0f, 0x20} );
-DrivingIncarLuxury     = new Environment ( new float[]{ 26, 1.6f, 1f, -1000, -2000, -600, 0.13f, 0.41f, 0.46f, -200, 0.010f, 0f, 0f, 0f, 400, 0.010f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 10268.2f, 251f, 0f, 0x20} );
-DrivingFullgrandstand  = new Environment ( new float[]{ 26, 8.3f, 1f, -1000, -1100, -400, 3.01f, 1.37f, 1.28f, -900, 0.090f, 0f, 0f, 0f, -1500, 0.049f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 10420.2f, 250f, 0f, 0x1f} );
-DrivingEmptygrandstand = new Environment ( new float[]{ 26, 8.3f, 1f, -1000, 0, -200, 4.62f, 1.75f, 1.40f, -1363, 0.090f, 0f, 0f, 0f, -1200, 0.049f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 10420.2f, 250f, 0f, 0x1f} );
-DrivingTunnel          = new Environment ( new float[]{ 26, 3.1f, 0.810f, -1000, -800, -100, 3.42f, 0.94f, 1.31f, -300, 0.051f, 0f, 0f, 0f, -300, 0.047f, 0f, 0f, 0f, 0.214f, 0.050f, 0.250f, 0f, -5f, 5000f, 155.3f, 0f, 0x20} );
-
-----
-
-
-== City
-
-[source,java]
-----
-
-CityIndoors   = new Environment ( new float[]{ 16, 7.5f, 0.500f, -1000, -800, 0, 1.49f, 0.67f, 1f, -2273, 0.007f, 0f, 0f, 0f, -1691, 0.011f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-CityStreets   = new Environment ( new float[]{ 26, 3f, 0.780f, -1000, -300, -100, 1.79f, 1.12f, 0.91f, -1100, 0.046f, 0f, 0f, 0f, -1400, 0.028f, 0f, 0f, 0f, 0.250f, 0.200f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x20} );
-CitySubway    = new Environment ( new float[]{ 26, 3f, 0.740f, -1000, -300, -100, 3.01f, 1.23f, 0.91f, -300, 0.046f, 0f, 0f, 0f, 200, 0.028f, 0f, 0f, 0f, 0.125f, 0.210f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x20} );
-CityMuseum    = new Environment ( new float[]{ 26, 80.3f, 0.820f, -1000, -1500, -1500, 3.28f, 1.40f, 0.57f, -1200, 0.039f, 0f, 0f, -0f, -100, 0.034f, 0f, 0f, 0f, 0.130f, 0.170f, 0.250f, 0f, -5f, 2854.4f, 107.5f, 0f, 0x0} );
-CityLibrary   = new Environment ( new float[]{ 26, 80.3f, 0.820f, -1000, -1100, -2100, 2.76f, 0.89f, 0.41f, -900, 0.029f, 0f, 0f, -0f, -100, 0.020f, 0f, 0f, 0f, 0.130f, 0.170f, 0.250f, 0f, -5f, 2854.4f, 107.5f, 0f, 0x0} );
-CityUnderpass = new Environment ( new float[]{ 26, 3f, 0.820f, -1000, -700, -100, 3.57f, 1.12f, 0.91f, -800, 0.059f, 0f, 0f, 0f, -100, 0.037f, 0f, 0f, 0f, 0.250f, 0.140f, 0.250f, 0f, -7f, 5000f, 250f, 0f, 0x20} );
-CityAbandoned = new Environment ( new float[]{ 26, 3f, 0.690f, -1000, -200, -100, 3.28f, 1.17f, 0.91f, -700, 0.044f, 0f, 0f, 0f, -1100, 0.024f, 0f, 0f, 0f, 0.250f, 0.200f, 0.250f, 0f, -3f, 5000f, 250f, 0f, 0x20} );
-
-----
-
-
-== Small Indoor Rooms
-
-[source,java]
-----
-
-Room         = new Environment ( new float[]{ 2, 1.9f, 1f, -1000, -454, 0, 0.40f, 0.83f, 1f, -1646, 0.002f, 0f, 0f, 0f, 53, 0.003f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-Bathroom     = new Environment ( new float[]{ 3, 1.4f, 1f, -1000, -1200, 0, 1.49f, 0.54f, 1f, -370, 0.007f, 0f, 0f, 0f, 1030, 0.011f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-Livingroom   = new Environment ( new float[]{ 4, 2.5f, 1f, -1000, -6000, 0, 0.50f, 0.10f, 1f, -1376, 0.003f, 0f, 0f, 0f, -1104, 0.004f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-Paddedcell   = new Environment ( new float[]{ 1, 1.4f, 1f, -1000, -6000, 0, 0.17f, 0.10f, 1f, -1204, 0.001f, 0f, 0f, 0f, 207, 0.002f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-Stoneroom    = new Environment ( new float[]{ 5, 11.6f, 1f, -1000, -300, 0, 2.31f, 0.64f, 1f, -711, 0.012f, 0f, 0f, 0f, 83, 0.017f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-----
-
-
-== Medium-Sized Indoor Rooms
-
-[source,java]
-----
-
-Workshop     = new Environment ( new float[]{ 26, 1.9f, 1f, -1000, -1700, -800, 0.76f, 1f, 1f, 0, 0.012f, 0f, 0f, 0f, 100, 0.012f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x0} );
-Schoolroom   = new Environment ( new float[]{ 26, 1.86f, 0.690f, -1000, -400, -600, 0.98f, 0.45f, 0.18f, 300, 0.017f, 0f, 0f, 0f, 300, 0.015f, 0f, 0f, 0f, 0.095f, 0.140f, 0.250f, 0f, -5f, 7176.9f, 211.2f, 0f, 0x20} );
-Practiseroom = new Environment ( new float[]{ 26, 1.86f, 0.870f, -1000, -800, -600, 1.12f, 0.56f, 0.18f, 200, 0.010f, 0f, 0f, 0f, 300, 0.011f, 0f, 0f, 0f, 0.095f, 0.140f, 0.250f, 0f, -5f, 7176.9f, 211.2f, 0f, 0x20} );
-Outhouse     = new Environment ( new float[]{ 26, 80.3f, 0.820f, -1000, -1900, -1600, 1.38f, 0.38f, 0.35f, -100, 0.024f, 0f, 0f, -0f, -400, 0.044f, 0f, 0f, 0f, 0.121f, 0.170f, 0.250f, 0f, -5f, 2854.4f, 107.5f, 0f, 0x0} );
-Caravan      = new Environment ( new float[]{ 26, 8.3f, 1f, -1000, -2100, -1800, 0.43f, 1.50f, 1f, 0, 0.012f, 0f, 0f, 0f, 600, 0.012f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x1f} );
-Dustyroom    = new Environment ( new float[]{ 26, 1.8f, 0.560f, -1000, -200, -300, 1.79f, 0.38f, 0.21f, -600, 0.002f, 0f, 0f, 0f, 200, 0.006f, 0f, 0f, 0f, 0.202f, 0.050f, 0.250f, 0f, -10f, 13046f, 163.3f, 0f, 0x20} );
-Chapel       = new Environment ( new float[]{ 26, 19.6f, 0.840f, -1000, -500, 0, 4.62f, 0.64f, 1.23f, -700, 0.032f, 0f, 0f, 0f, -200, 0.049f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0.110f, -5f, 5000f, 250f, 0f, 0x3f} );
-
-----
-
-
-== Large Indoor Rooms
-
-[source,java]
-----
-
-Auditorium     = new Environment ( new float[]{ 6, 21.6f, 1f, -1000, -476, 0, 4.32f, 0.59f, 1f, -789, 0.020f, 0f, 0f, 0f, -289, 0.030f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-Concerthall    = new Environment ( new float[]{ 7, 19.6f, 1f, -1000, -500, 0, 3.92f, 0.70f, 1f, -1230, 0.020f, 0f, 0f, 0f, -02, 0.029f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-Cave           = new Environment ( new float[]{ 8, 14.6f, 1f, -1000, 0, 0, 2.91f, 1.30f, 1f, -602, 0.015f, 0f, 0f, 0f, -302, 0.022f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x1f} );
-Arena          = new Environment ( new float[]{ 9, 36.2f, 1f, -1000, -698, 0, 7.24f, 0.33f, 1f, -1166, 0.020f, 0f, 0f, 0f, 16, 0.030f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-Hangar         = new Environment ( new float[]{ 10, 50.3f, 1f, -1000, -1000, 0, 10.05f, 0.23f, 1f, -602, 0.020f, 0f, 0f, 0f, 198, 0.030f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-DomeTomb       = new Environment ( new float[]{ 26, 51.8f, 0.790f, -1000, -900, -1300, 4.18f, 0.21f, 0.10f, -825, 0.030f, 0f, 0f, 0f, 450, 0.022f, 0f, 0f, 0f, 0.177f, 0.190f, 0.250f, 0f, -5f, 2854.4f, 20f, 0f, 0x0} );
-DomeSaintPauls = new Environment ( new float[]{ 26, 50.3f, 0.870f, -1000, -900, -1300, 10.48f, 0.19f, 0.10f, -1500, 0.090f, 0f, 0f, 0f, 200, 0.042f, 0f, 0f, 0f, 0.250f, 0.120f, 0.250f, 0f, -5f, 2854.4f, 20f, 0f, 0x3f} );
-
-----
-
-
-== Hallways, Alleys
-
-[source,java]
-----
-
-Carpettedhallway = new Environment ( new float[]{ 11, 1.9f, 1f, -1000, -4000, 0, 0.30f, 0.10f, 1f, -1831, 0.002f, 0f, 0f, 0f, -1630, 0.030f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-Hallway          = new Environment ( new float[]{ 12, 1.8f, 1f, -1000, -300, 0, 1.49f, 0.59f, 1f, -1219, 0.007f, 0f, 0f, 0f, 441, 0.011f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-Stonecorridor    = new Environment ( new float[]{ 13, 13.5f, 1f, -1000, -237, 0, 2.70f, 0.79f, 1f, -1214, 0.013f, 0f, 0f, 0f, 395, 0.020f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-Alley            = new Environment ( new float[]{ 14, 7.5f, 0.300f, -1000, -270, 0, 1.49f, 0.86f, 1f, -1204, 0.007f, 0f, 0f, 0f, -4, 0.011f, 0f, 0f, 0f, 0.125f, 0.950f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-
-----
-
-
-== Outdoors
-
-[source,java]
-----
-
-Backyard      = new Environment ( new float[]{ 26, 80.3f, 0.450f, -1000, -1200, -600, 1.12f, 0.34f, 0.46f, -700, 0.069f, 0f, 0f, -0f, -300, 0.023f, 0f, 0f, 0f, 0.218f, 0.340f, 0.250f, 0f, -5f, 4399.1f, 242.9f, 0f, 0x0} );
-Plain         = new Environment ( new float[]{ 19, 42.5f, 0.210f, -1000, -2000, 0, 1.49f, 0.50f, 1f, -2466, 0.179f, 0f, 0f, 0f, -1926, 0.100f, 0f, 0f, 0f, 0.250f, 1f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-Rollingplains = new Environment ( new float[]{ 26, 80.3f, 0f, -1000, -3900, -400, 2.13f, 0.21f, 0.46f, -1500, 0.300f, 0f, 0f, -0f, -700, 0.019f, 0f, 0f, 0f, 0.250f, 1f, 0.250f, 0f, -5f, 4399.1f, 242.9f, 0f, 0x0} );
-Deepcanyon    = new Environment ( new float[]{ 26, 80.3f, 0.740f, -1000, -1500, -400, 3.89f, 0.21f, 0.46f, -1000, 0.223f, 0f, 0f, -0f, -900, 0.019f, 0f, 0f, 0f, 0.250f, 1f, 0.250f, 0f, -5f, 4399.1f, 242.9f, 0f, 0x0} );
-Creek         = new Environment ( new float[]{ 26, 80.3f, 0.350f, -1000, -1500, -600, 2.13f, 0.21f, 0.46f, -800, 0.115f, 0f, 0f, -0f, -1400, 0.031f, 0f, 0f, 0f, 0.218f, 0.340f, 0.250f, 0f, -5f, 4399.1f, 242.9f, 0f, 0x0} );
-Valley        = new Environment ( new float[]{ 26, 80.3f, 0.280f, -1000, -3100, -1600, 2.88f, 0.26f, 0.35f, -1700, 0.263f, 0f, 0f, -0f, -800, 0.100f, 0f, 0f, 0f, 0.250f, 0.340f, 0.250f, 0f, -5f, 2854.4f, 107.5f, 0f, 0x0} );
-Forest        = new Environment ( new float[]{ 15, 38f, 0.300f, -1000, -3300, 0, 1.49f, 0.54f, 1f, -2560, 0.162f, 0f, 0f, 0f, -229, 0.088f, 0f, 0f, 0f, 0.125f, 1f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-Mountains     = new Environment ( new float[]{ 17, 100f, 0.270f, -1000, -2500, 0, 1.49f, 0.21f, 1f, -2780, 0.300f, 0f, 0f, 0f, -1434, 0.100f, 0f, 0f, 0f, 0.250f, 1f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x1f} );
-Quarry        = new Environment ( new float[]{ 18, 17.5f, 1f, -1000, -1000, 0, 1.49f, 0.83f, 1f, -10000, 0.061f, 0f, 0f, 0f, 500, 0.025f, 0f, 0f, 0f, 0.125f, 0.700f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x3f} );
-Parkinglot    = new Environment ( new float[]{ 20, 8.3f, 1f, -1000, 0, 0, 1.65f, 1.50f, 1f, -1363, 0.008f, 0f, 0f, 0f, -1153, 0.012f, 0f, 0f, 0f, 0.250f, 0f, 0.250f, 0f, -5f, 5000f, 250f, 0f, 0x1f} );
-
-----
-
-
-== Water
-
-[source,java]
-----
-
-Underwater     = new Environment ( new float[]{ 22, 1.8f, 1f, -1000, -4000, 0, 1.49f, 0.10f, 1f, -449, 0.007f, 0f, 0f, 0f, 1700, 0.011f, 0f, 0f, 0f, 0.250f, 0f, 1.180f, 0.348f, -5f, 5000f, 250f, 0f, 0x3f} );
-Smallwaterroom = new Environment ( new float[]{ 26, 36.2f, 0.700f, -1000, -698, 0, 1.51f, 1.25f, 1.14f, -100, 0.020f, 0f, 0f, 0f, 300, 0.030f, 0f, 0f, 0f, 0.179f, 0.150f, 0.895f, 0.190f, -7f, 5000f, 250f, 0f, 0x0} );
-
-----

+ 0 - 7
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/audio/overview.adoc

@@ -1,7 +0,0 @@
-= OVERVIEW
-:author: yanmaoyuan
-:revnumber:
-:revdate: 2018/01/15 16:29
-:experimental:
-:keywords:
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]

+ 0 - 575
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/capture_audio_video_to_a_file.adoc

@@ -1,575 +0,0 @@
-= Capture Audio/Video to a File
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-So you've made your cool new JMonkeyEngine3 game and you want to
-create a demo video to show off your hard work. Or maybe you want to
-make a cutscene for your game using the physics and characters in the
-game itself.  Screen capturing is the most straightforward way to do
-this, but it can slow down your game and produce low-quality video and
-audio as a result. A better way is to record video and audio directly
-from the game while it is running using VideoRecorderAppState.
-
-
-[TIP]
-====
-Combine this method with jMonkeyEngine's
-<<jme3/advanced/cinematics#,Cinematics>>
-feature to record high-quality game trailers!
-====
-
-
-
-== Simple Way
-
-First off, if all you need is to record video at 30fps with no sound, then look
-no further than jMonkeyEngine 3's built in `VideoRecorderAppState`
-class.
-
-Add the following code to your `simpleInitApp()` method.
-
-[source,java]
-----
-
-stateManager.attach(new VideoRecorderAppState()); //start recording
-
-----
-
-The game will run slow, but the recording will be in high-quality and
-normal speed. Recording starts when the state is
-attached, and ends when the application quits or the state is detached.
-
-The video files will be stored in your *user home directory*.
-If you want to save to another path, specify a File object in the
-VideoRecorderAppState constructor.
-
-That's all!
-
-
-== Advanced Way
-
-
-[NOTE]
-====
-This way of A/V recording is still in development.
-It works for all of jMonkeyEngine's test cases.
-If you experience any problems or
-if something isn't clear, please link:http://jmonkeyengine.org/members/bortreb/[let me know]. – bortreb
-====
-
-
-If you want to record audio as well, record at different framerates,
-or record from multiple viewpoints at once, then there's a full
-solution for doing this already made for you here:
-
-link:http://www.aurellem.com/releases/jmeCapture-latest.zip[http://www.aurellem.com/releases/jmeCapture-latest.zip]
-
-link:http://www.aurellem.com/releases/jmeCapture-latest.tar.bz2[http://www.aurellem.com/releases/jmeCapture-latest.tar.bz2]
-
-Download the archive in your preferred format, extract,
-add the jars to your project, and you are ready to go.
-
-The javadoc is here:
-link:http://www.aurellem.com/jmeCapture/docs/[http://www.aurellem.com/jmeCapture/docs/]
-
-To capture video and audio you use the
-`com.aurellem.capture.Capture` class, which has two methods,
-`captureAudio()` and `captureVideo()`, and the
-`com.aurellem.capture.IsoTimer` class, which sets the audio and
-video framerate.
-
-The steps are:
-
-[source,java]
-----
-
-yourApp.setTimer(new IsoTimer(desiredFramesPerSecond));
-
-----
-
-This causes jMonkeyEngine to take as much time as it needs to fully
-calculate every frame of the video and audio.  You will see your game
-speed up and slow down depending on how computationally demanding your
-game is, but the final recorded audio and video will be perfectly
-sychronized and will run at exactly the fps which you specified.
-
-[source,java]
-----
-
-captureVideo(yourApp, targetVideoFile);
-captureAudio(yourApp, targetAudioFile);
-
-----
-
-These will cause the app to record audio and video when it is run.
-Audio and video will stop being recorded when the app stops. Your
-audio will be recorded as a 44,100 Hz linear PCM wav file, while the
-video will be recorded according to the following rules:
-
-1.) (Preferred) If you supply an empty directory as the file, then
-the video will be saved as a sequence of .png files, one file per
-frame.  The files start at 0000000.png and increment from there.
-You can then combine the frames into your preferred
-container/codec. If the directory is not empty, then writing
-video frames to it will fail, and nothing will be written.
-
-2.) If the filename ends in “.avi then the frames will be encoded as
-a RAW stream inside an AVI 1.0 container.  The resulting file
-will be quite large and you will probably want to re-encode it to
-your preferred container/codec format.  Be advised that some
-video payers cannot process AVI with a RAW stream, and that AVI
-1.0 files generated by this method that exceed 2.0GB are invalid
-according to the AVI 1.0 +++<abbr title="specification">spec</abbr>+++ (but many programs can still deal
-with them.)  Thanks to
-link:http://www.randelshofer.ch/blog/2008/08/writing-avi-videos-in-pure-java/[Werner Randelshofer]
-for his excellent work which made the AVI file writer option possible.
-
-3.) Any non-directory file ending in anything other than “.avi will
-be processed through Xuggle.  Xuggle provides the option to use
-many codecs/containers, but you will have to install it on your
-system yourself in order to use this option. Please visit
-link:http://www.xuggle.com/[http://www.xuggle.com/] to learn how to do this.
-
-Note that you will not hear any sound if you choose to record sound to
-a file.
-
-
-=== Basic Example
-
-Here is a complete example showing how to capture both audio and video
-from one of jMonkeyEngine3's advanced demo applications.
-
-[source,java]
-----
-
-import java.io.File;
-import java.io.IOException;
-
-import jme3test.water.TestPostWater;
-
-import com.aurellem.capture.Capture;
-import com.aurellem.capture.IsoTimer;
-import com.jme3.app.SimpleApplication;
-
-
-/**
- * Demonstrates how to use basic Audio/Video capture with a
- * jMonkeyEngine application. You can use these techniques to make
- * high quality cutscenes or demo videos, even on very slow laptops.
- *
- * @author Robert McIntyre
- */
-
-public class Basic {
-
-    public static void main(String[] ignore) throws IOException{
-	File video = File.createTempFile("JME-water-video", ".avi");
-	File audio = File.createTempFile("JME-water-audio", ".wav");
-
-	SimpleApplication app = new TestPostWater();
-	app.setTimer(new IsoTimer(60));
-	app.setShowSettings(false);
-
-	Capture.captureVideo(app, video);
-	Capture.captureAudio(app, audio);
-
-	app.start();
-
-	System.out.println(video.getCanonicalPath());
-	System.out.println(audio.getCanonicalPath());
-    }
-}
-
-----
-
-
-=== How it works
-
-A standard JME3 application that extends `SimpleApplication` or
-`Application` tries as hard as it can to keep in sync with
-_user-time_.  If a ball is rolling at 1 game-mile per game-hour in the
-game, and you wait for one user-hour as measured by the clock on your
-wall, then the ball should have traveled exactly one game-mile. In
-order to keep sync with the real world, the game throttles its physics
-engine and graphics display.  If the computations involved in running
-the game are too intense, then the game will first skip frames, then
-sacrifice physics accuracy.  If there are particuraly demanding
-computations, then you may only get 1 fps, and the ball may tunnel
-through the floor or obstacles due to inaccurate physics simulation,
-but after the end of one user-hour, that ball will have traveled one
-game-mile.
-
-When we're recording video, we don't care if the game-time syncs with
-user-time, but instead whether the time in the recorded video
-(video-time) syncs with user-time. To continue the analogy, if we
-recorded the ball rolling at 1 game-mile per game-hour and watched the
-video later, we would want to see 30 fps video of the ball rolling at
-1 video-mile per _user-hour_. It doesn't matter how much user-time it
-took to simulate that hour of game-time to make the high-quality
-recording.
-
-The IsoTimer ignores real-time and always reports that the same amount
-of time has passed every time it is called. That way, one can put code
-to write each video/audio frame to a file without worrying about that
-code itself slowing down the game to the point where the recording
-would be useless.
-
-
-=== Advanced Example
-
-The package from aurellem.com was made for AI research and can do more
-than just record a single stream of audio and video. You can use it
-to:
-
-1.) Create multiple independent listeners that each hear the world
-from their own perspective.
-
-2.) Process the sound data in any way you wish.
-
-3.) Do the same for visual data.
-
-Here is a more advanced example, which can also be found along with
-other examples in the jmeCapture.jar file included in the
-distribution.
-
-[source,java]
-----
-
-package com.aurellem.capture.examples;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.nio.ByteBuffer;
-
-import javax.sound.sampled.AudioFormat;
-
-import org.tritonus.share.sampled.FloatSampleTools;
-
-import com.aurellem.capture.AurellemSystemDelegate;
-import com.aurellem.capture.Capture;
-import com.aurellem.capture.IsoTimer;
-import com.aurellem.capture.audio.CompositeSoundProcessor;
-import com.aurellem.capture.audio.MultiListener;
-import com.aurellem.capture.audio.SoundProcessor;
-import com.aurellem.capture.audio.WaveFileWriter;
-import com.jme3.app.SimpleApplication;
-import com.jme3.audio.AudioNode;
-import com.jme3.audio.Listener;
-import com.jme3.cinematic.MotionPath;
-import com.jme3.cinematic.events.AbstractCinematicEvent;
-import com.jme3.cinematic.events.MotionTrack;
-import com.jme3.material.Material;
-import com.jme3.math.ColorRGBA;
-import com.jme3.math.FastMath;
-import com.jme3.math.Quaternion;
-import com.jme3.math.Vector3f;
-import com.jme3.scene.Geometry;
-import com.jme3.scene.Node;
-import com.jme3.scene.shape.Box;
-import com.jme3.scene.shape.Sphere;
-import com.jme3.system.AppSettings;
-import com.jme3.system.JmeSystem;
-
-/**
- *
- * Demonstrates advanced use of the audio capture and recording
- * features.  Multiple perspectives of the same scene are
- * simultaneously rendered to different sound files.
- *
- * A key limitation of the way multiple listeners are implemented is
- * that only 3D positioning effects are realized for listeners other
- * than the main LWJGL listener.  This means that audio effects such
- * as environment settings will *not* be heard on any auxiliary
- * listeners, though sound attenuation will work correctly.
- *
- * Multiple listeners as realized here might be used to make AI
- * entities that can each hear the world from their own perspective.
- *
- * @author Robert McIntyre
- */
-
-public class Advanced extends SimpleApplication {
-
-	/**
-	 * You will see three grey cubes, a blue sphere, and a path which
-	 * circles each cube.  The blue sphere is generating a constant
-	 * monotone sound as it moves along the track.  Each cube is
-	 * listening for sound; when a cube hears sound whose intensity is
-	 * greater than a certain threshold, it changes its color from
-	 * grey to green.
-	 *
-	 *  Each cube is also saving whatever it hears to a file.  The
-	 *  scene from the perspective of the viewer is also saved to a
-	 *  video file.  When you listen to each of the sound files
-	 *  alongside the video, the sound will get louder when the sphere
-	 *  approaches the cube that generated that sound file.  This
-	 *  shows that each listener is hearing the world from its own
-	 *  perspective.
-	 *
-	 */
-	public static void main(String[] args) {
-		Advanced app = new Advanced();
-		AppSettings settings = new AppSettings(true);
-		settings.setAudioRenderer(AurellemSystemDelegate.SEND);
-		JmeSystem.setSystemDelegate(new AurellemSystemDelegate());
-		app.setSettings(settings);
-		app.setShowSettings(false);
-		app.setPauseOnLostFocus(false);
-
-
-		try {
-			Capture.captureVideo(app, File.createTempFile("advanced",".avi"));
-			Capture.captureAudio(app, File.createTempFile("advanced", ".wav"));
-		}
-		catch (IOException e) {e.printStackTrace();}
-
-		app.start();
-	}
-
-
-	private Geometry bell;
-	private Geometry ear1;
-	private Geometry ear2;
-	private Geometry ear3;
-	private AudioNode music;
-	private MotionTrack motionControl;
-	private IsoTimer motionTimer = new IsoTimer(60);
-
-	private Geometry makeEar(Node root, Vector3f position){
-		Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-		Geometry ear = new Geometry("ear", new Box(1.0f, 1.0f, 1.0f));
-		ear.setLocalTranslation(position);
-		mat.setColor("Color", ColorRGBA.Green);
-		ear.setMaterial(mat);
-		root.attachChild(ear);
-		return ear;
-	}
-
-	private Vector3f[] path = new Vector3f[]{
-			// loop 1
-			new Vector3f(0, 0, 0),
-			new Vector3f(0, 0, -10),
-			new Vector3f(-2, 0, -14),
-			new Vector3f(-6, 0, -20),
-			new Vector3f(0, 0, -26),
-			new Vector3f(6, 0, -20),
-			new Vector3f(0, 0, -14),
-			new Vector3f(-6, 0, -20),
-			new Vector3f(0, 0, -26),
-			new Vector3f(6, 0, -20),
-			// loop 2
-			new Vector3f(5, 0, -5),
-			new Vector3f(7, 0, 1.5f),
-			new Vector3f(14, 0, 2),
-			new Vector3f(20, 0, 6),
-			new Vector3f(26, 0, 0),
-			new Vector3f(20, 0, -6),
-			new Vector3f(14, 0, 0),
-			new Vector3f(20, 0, 6),
-			new Vector3f(26, 0, 0),
-			new Vector3f(20, 0, -6),
-			new Vector3f(14, 0, 0),
-			// loop 3
-			new Vector3f(8, 0, 7.5f),
-			new Vector3f(7, 0, 10.5f),
-			new Vector3f(6, 0, 20),
-			new Vector3f(0, 0, 26),
-			new Vector3f(-6, 0, 20),
-			new Vector3f(0, 0, 14),
-			new Vector3f(6, 0, 20),
-			new Vector3f(0, 0, 26),
-			new Vector3f(-6, 0, 20),
-			new Vector3f(0, 0, 14),
-			// begin ellipse
-			new Vector3f(16, 5, 20),
-			new Vector3f(0, 0, 26),
-			new Vector3f(-16, -10, 20),
-			new Vector3f(0, 0, 14),
-			new Vector3f(16, 20, 20),
-			new Vector3f(0, 0, 26),
-			new Vector3f(-10, -25, 10),
-			new Vector3f(-10, 0, 0),
-			// come at me!
-			new Vector3f(-28.00242f, 48.005623f, -34.648228f),
-			new Vector3f(0, 0 , -20),
-	};
-
-	private void createScene() {
-		Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-		bell = new Geometry( "sound-emitter" , new Sphere(15,15,1));
-		mat.setColor("Color", ColorRGBA.Blue);
-		bell.setMaterial(mat);
-		rootNode.attachChild(bell);
-
-		ear1 = makeEar(rootNode, new Vector3f(0, 0 ,-20));
-		ear2 = makeEar(rootNode, new Vector3f(0, 0 ,20));
-		ear3 = makeEar(rootNode, new Vector3f(20, 0 ,0));
-
-		MotionPath track = new MotionPath();
-
-		for (Vector3f v : path){
-			track.addWayPoint(v);
-		}
-		track.setCurveTension(0.80f);
-
-		motionControl = new MotionTrack(bell,track);
-		// for now, use reflection to change the timer...
-		// motionControl.setTimer(new IsoTimer(60));
-
-		try {
-			Field timerField;
-			timerField = AbstractCinematicEvent.class.getDeclaredField("timer");
-			timerField.setAccessible(true);
-			try {timerField.set(motionControl, motionTimer);}
-			catch (IllegalArgumentException e) {e.printStackTrace();}
-			catch (IllegalAccessException e) {e.printStackTrace();}
-		}
-		catch (SecurityException e) {e.printStackTrace();}
-		catch (NoSuchFieldException e) {e.printStackTrace();}
-
-
-		motionControl.setDirectionType(MotionTrack.Direction.PathAndRotation);
-		motionControl.setRotation(new Quaternion().fromAngleNormalAxis(-FastMath.HALF_PI, Vector3f.UNIT_Y));
-		motionControl.setInitialDuration(20f);
-		motionControl.setSpeed(1f);
-
-		track.enableDebugShape(assetManager, rootNode);
-		positionCamera();
-	}
-
-
-	private void positionCamera(){
-		this.cam.setLocation(new Vector3f(-28.00242f, 48.005623f, -34.648228f));
-		this.cam.setRotation(new Quaternion(0.3359635f, 0.34280345f, -0.13281013f, 0.8671653f));
-	}
-
-	private void initAudio() {
-		org.lwjgl.input.Mouse.setGrabbed(false);
-		music = new AudioNode(assetManager, "Sound/Effects/Beep.ogg", false);
-
-		rootNode.attachChild(music);
-		audioRenderer.playSource(music);
-		music.setPositional(true);
-		music.setVolume(1f);
-		music.setReverbEnabled(false);
-		music.setDirectional(false);
-		music.setMaxDistance(200.0f);
-		music.setRefDistance(1f);
-		//music.setRolloffFactor(1f);
-		music.setLooping(false);
-		audioRenderer.pauseSource(music);
-	}
-
-	public class Dancer implements SoundProcessor {
-		Geometry entity;
-		float scale = 2;
-		public Dancer(Geometry entity){
-			this.entity = entity;
-		}
-
-		/**
-		 * this method is irrelevant since there is no state to cleanup.
-		 */
-		public void cleanup() {}
-
-
-		/**
-		 * Respond to sound!  This is the brain of an AI entity that
-		 * hears its surroundings and reacts to them.
-		 */
-		public void process(ByteBuffer audioSamples, int numSamples, AudioFormat format) {
-			audioSamples.clear();
-			byte[] data = new byte[numSamples];
-			float[] out = new float[numSamples];
-			audioSamples.get(data);
-			FloatSampleTools.byte2floatInterleaved(data, 0, out, 0,
-					numSamples/format.getFrameSize(), format);
-
-			float max = Float.NEGATIVE_INFINITY;
-			for (float f : out){if (f > max) max = f;}
-			audioSamples.clear();
-
-			if (max > 0.1){entity.getMaterial().setColor("Color", ColorRGBA.Green);}
-			else {entity.getMaterial().setColor("Color", ColorRGBA.Gray);}
-		}
-	}
-
-	private void prepareEar(Geometry ear, int n){
-		if (this.audioRenderer instanceof MultiListener){
-			MultiListener rf = (MultiListener)this.audioRenderer;
-
-			Listener auxListener = new Listener();
-			auxListener.setLocation(ear.getLocalTranslation());
-
-			rf.addListener(auxListener);
-			WaveFileWriter aux = null;
-
-			try {aux = new WaveFileWriter(File.createTempFile("advanced-audio-" + n, ".wav"));}
-			catch (IOException e) {e.printStackTrace();}
-
-			rf.registerSoundProcessor(auxListener,
-					new CompositeSoundProcessor(new Dancer(ear), aux));
-
-		}
-	}
-
-
-	public void simpleInitApp() {
-		this.setTimer(new IsoTimer(60));
-		initAudio();
-
-		createScene();
-
-		prepareEar(ear1, 1);
-		prepareEar(ear2, 1);
-		prepareEar(ear3, 1);
-
-		motionControl.play();
-
-	}
-
-	public void simpleUpdate(float tpf) {
-		motionTimer.update();
-		if (music.getStatus() != AudioSource.Status.Playing){
-			music.play();
-		}
-		Vector3f loc = cam.getLocation();
-		Quaternion rot = cam.getRotation();
-		listener.setLocation(loc);
-		listener.setRotation(rot);
-		music.setLocalTranslation(bell.getLocalTranslation());
-	}
-
-}
-
-----
-
-image:http://www.youtube.com/v/oCEfK0yhDrY?.swf[oCEfK0yhDrY?.swf,width="400",height=""]
-
-
-=== Using Advanced features to Record from more than one perspective at once
-
-image:http://www.youtube.com/v/WIJt9aRGusc?.swf[WIJt9aRGusc?.swf,width="400",height=""]
-
-
-== More Information
-
-This is the old page showing the first version of this idea
-link:http://aurellem.org/cortex/html/capture-video.html[http://aurellem.org/cortex/html/capture-video.html]
-
-All source code can be found here:
-
-link:http://hg.bortreb.com/audio-send[http://hg.bortreb.com/audio-send]
-
-link:http://hg.bortreb.com/jmeCapture[http://hg.bortreb.com/jmeCapture]
-
-More information on the modifications to OpenAL to support multiple
-listeners can be found here.
-
-link:http://aurellem.org/audio-send/html/ear.html[http://aurellem.org/audio-send/html/ear.html]

+ 0 - 193
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/collision/collision_and_intersection.adoc

@@ -1,193 +0,0 @@
-= Collision and Intersection
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-The term collision can be used to refer to <<jme3/advanced/physics_listeners#,physical interactions>> (where <<jme3/advanced/physics#,physical objects>> collide, push and bump off one another), and also to non-physical _intersections_ in 3D space. This article is about the non-physical (mathematical) collisions.
-
-Non-physical collision detection is interesting because it uses less computing resources than physical collision detection. The non-physical calculations are faster because they do not have any side effects such as pushing other objects or bumping off of them. Tasks such as <<jme3/advanced/mouse_picking#,mouse picking>> are easily implemented using mathematical techniques such as ray casting and intersections.  Experienced developers optimize their games by finding ways to simulate certain (otherwise expensive physical) interactions in a non-physical way.
-
-*Example:* One example for an optimization is a physical vehicle's wheels. You could make the wheels fully physical disks, and have jME calculate every tiny force – sounds very accurate? It's total overkill and too slow for a racing game. A more performant solution is to cast four invisible rays down from the vehicle and calculate the intersections with the floor. These non-physical wheels require (in the simplest case) only four calculations per tick to achieve an effect that players can hardly distinguish from the real thing.
-
-
-== Collidable
-
-The interface com.jme3.collision.Collidable declares one method that returns how many collisions were found between two Collidables: `collideWith(Collidable other, CollisionResults results)`.
-
-*  A `com.jme3.collision.CollisionResults` object is an ArrayList of comparable `com.jme3.collision.CollisionResult` objects.
-*  You can iterate over the CollisionResults to identify the other parties involved in the collision. +
-Note that jME counts _all_ collisions, this means a ray intersecting a box will be counted as two hits, one on the front where the ray enters, and one on the back where the ray exits.
-
-[cols="2", options="header"]
-|===
-
-a|CollisionResults Method
-a|Usage
-
-<a|size()
-a|Returns the number of CollisionResult objects.
-
-a|getClosestCollision()
-a|Returns the CollisionResult with the lowest distance.
-
-a|getFarthestCollision()
-a|Returns the CollisionResult with the farthest distance.
-
-<a|getCollision(i)
-a|Returns the CollisionResult at index i.
-
-|===
-
-A CollisionResult object contains information about the second party of the collision event.
-[cols="2", options="header"]
-|===
-
-a|CollisionResult Method
-a|Usage
-
-a|getContactPoint()
-a|Returns the contact point coordinate on the second party, as Vector3f.
-
-a|getContactNormal()
-a|Returns the Normal vector at the contact point, as Vector3f.
-
-a|getDistance()
-a|Returns the distance between the Collidable and the second party, as float.
-
-a|getGeometry()
-a|Returns the Geometry of the second party.
-
-a|getTriangle(t)
-a|Binds t to the triangle t on the second party's mesh that was hit.
-
-a|getTriangleIndex()
-a|Returns the index of the triangle on the second party's mesh that was hit.
-
-|===
-
-
-=== Code Sample
-
-Assume you have two collidables a and b and want to detect collisions between them. The collision parties can be Geometries, Nodes with Geometries attached (including the rootNode), Planes, Quads, Lines, or Rays. An important restriction is that you can only collide geometry vs bounding volumes or rays. (This means for example that a must be of Type Node or Geometry and b respectively of Type BoundingBox, BoundingSphere or Ray.)
-
-The following code snippet can be triggered by listeners (e.g. after an input action such as a click), or timed in the update loop.
-
-[source,java]
-----
-
-  // Calculate detection results
-  CollisionResults results = new CollisionResults();
-  a.collideWith(b, results);
-  System.out.println("Number of Collisions between" +
-      a.getName()+ " and " + b.getName() + ": " + results.size());
-  // Use the results
-  if (results.size() > 0) {
-    // how to react when a collision was detected
-    CollisionResult closest  = results.getClosestCollision();
-    System.out.println("What was hit? " + closest.getGeometry().getName() );
-    System.out.println("Where was it hit? " + closest.getContactPoint() );
-    System.out.println("Distance? " + closest.getDistance() );
-  } else {
-    // how to react when no collision occured
-  }
-}
-----
-
-You can also loop over all results and trigger different reactions depending on what was hit and where it was hit. In this example, we simply print info about them.
-
-[source,java]
-----
-
-  // Calculate Results
-  CollisionResults results = new CollisionResults();
-  a.collideWith(b, results);
-  System.out.println("Number of Collisions between" + a.getName()+ " and "
-   + b.getName() " : " + results.size());
-  // Use the results
-  for (int i = 0; i < results.size(); i++) {
-    // For each hit, we know distance, impact point, name of geometry.
-    float     dist = results.getCollision(i).getDistance();
-    Vector3f    pt = results.getCollision(i).getContactPoint();
-    String   party = results.getCollision(i).getGeometry().getName();
-    int        tri = results.getCollision(i).getTriangleIndex();
-    Vector3f  norm = results.getCollision(i).getTriangle(new Triangle()).getNormal();
-    System.out.println("Details of Collision #" + i + ":");
-    System.out.println("  Party " + party + " was hit at " + pt + ", " + dist + " wu away.");
-    System.out.println("  The hit triangle #" + tri + " has a normal vector of " + norm);
-  }
-
-----
-
-Knowing the distance of the collisions is useful for example when you intersect Lines and Rays with other objects.
-
-
-== Bounding Volumes
-
-A `com.jme3.bounding.BoundingVolume` is an interface for dealing with containment of a collection of points. All BoundingVolumes are `Collidable` and are used as optimization to calculate non-physical collisions more quickly: It's always faster to calculate an intersection between simple shapes like spheres and boxes than between complex shapes like models.
-
-jME3 computes bounding volumes for all objects. These bounding volumes are later used for frustum culling, which is making sure only objects visible on-screen are actually sent for rendering.
-
-All fast-paced action and shooter games use BoundingVolumes as an optimization. Wrap all complex models into simpler shapes – in the end, you get equally useful collision detection results, but faster. link:http://en.wikipedia.org/wiki/Bounding_volume[More about bounding volumes...]
-
-Supported types:
-
-// image::http://www.jmonkeyengine.com/jme/wiki-data/userref/capsule.png[Capsule,width="150",height="110",align="right"]
-
-
-*  Type.AABB = Axis-aligned bounding box, that means it doesn't rotate, which makes it less precise. A `com.jme3.bounding.BoundingBox` is an axis-aligned cuboid used as a container for a group of vertices of a piece of geometry. A BoundingBox has a center and extents from that center along the x, y and z axis. This is the default bounding volume, since it is fairly fast to generate and gives better accuracy than the bounding sphere.
-*  Type.Sphere: `com.jme3.bounding.BoundingSphere` is a sphere used as a container for a group of vertices of a piece of geometry. A BoundingSphere has a center and a radius.
-*  Type.OBB = Oriented bounding box. This bounding box is more precise because it can rotate with its content, but is computationally more expensive. (Currently not supported.)
-*  Type.Capsule = Cylinder with rounded ends, also called “swept sphere. Typically used for mobile characters. (Currently not supported.)
-
-
-[NOTE]
-====
-Note: If you are looking for bounding volumes for physical objects, use <<jme3/advanced/physics#,CollisionShapes>>.
-====
-
-
-
-=== Usage
-
-For example you can use Bounding Volumes on custom meshes, or complex non-physical shapes.
-
-[source,java]
-----
-mesh.setBound(new BoundingSphere());
-mesh.updateBound();
-----
-
-
-== Mesh and Scene Graph Collision
-
-One of the supported ``Collidable``s are meshes and scene graph objects. To execute a collision detection query against a scene graph, use `Spatial.collideWith()`. This will traverse the scene graph and return any mesh collisions that were detected. Note that the first collision against a particular scene graph may take a long time, this is because a special data structure called link:http://en.wikipedia.org/wiki/Bounding_interval_hierarchy[Bounding Interval Hierarchy (BIH)] needs to be generated for the meshes. At a later point, the mesh could change and the BIH tree would become out of date, in that case, call link:http://javadoc.jmonkeyengine.org/com/jme3/scene/Mesh.html#createCollisionData--[Mesh.createCollisionData()] on the changed mesh to update the BIH tree.
-
-
-== Intersection
-
-A `com.jme3.math.Ray` is an infinite line with a beginning, a direction, and no end; whereas a `com.jme3.math.Line` is an infinite line with only a direction (no beginning, no end).
-
-Rays are used to perform line-of-sight calculations. This means you can detect what users were “aiming at when they clicked or pressed a key. You can also use this to detect whether game characters can see something (or someone) or not.
-
-*  *Click to select:* You can determine what a user has clicked by casting a ray from the camera forward in the direction of the camera. Now identify the closest collision of the ray with the rootNode, and you have the clicked object.
-*  *Line of sight:* Cast a ray from a player in the direction of another player. Then you detect all collisions of this ray with other entities (walls versus foliage versus window panes) and use this to calculate how likely it is that one can see the other.
-
-
-[TIP]
-====
-These simple but powerful ray-surface intersection tests are called Ray Casting. As opposed to the more advanced Ray Tracing technique, Ray Casting does not follow the ray's reflection after the first hit – the ray just goes straight on.
-====
-
-
-Learn the details of how to implement <<jme3/advanced/mouse_picking#,Mouse Picking>> here.
-
-'''
-
-TODO:
-
-*  Bounding Interval Hierarchy (`com.jme3.collision.bih.BIHNode`)
-*  com.jme3.scene.CollisionData

+ 0 - 304
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/debug_and_test/debugging.adoc

@@ -1,304 +0,0 @@
-= Debugging
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-When you deal with complex game engine features like animations or physics it is handy to get feedback from the engine how it interpreted the current state. Is the physical object's collision shape really where you think it is? Is the skeleton of the animated character moving like you think it should? This document shows you how to activate visual debug aides.
-
-What if you just want to quickly write code that loads models and brings them in their start position? You may not want to hunt for a sample model, convert it, add lights, and load materials. Instead you use "`hasslefree`" simple shapes, and a "`hasslefree`" unshaded material or wireframe: No model, no light source, no materials are needed to see them in your test scene.
-
-If you ever have problems with objects appearing in the wrong spot, with the wrong scale, or wrong orientation, simply attach debug shapes to your scene to have a point of reference in 3D space – just like a giant ruler. If your code positions the debug shapes correctly, but models remain invisible when you apply the same code to them, you know that the problem must be either the model (where is its origin coordinate?), or the light (too dark? too bright? missing?), or the model's material (missing?) – and not the positioning code.
-
-Here are some different debug shapes:
-
-
-image::jme3/advanced/debug-shapes.png[debug-shapes.png,width="600",height="220",align="center"]
-
-
-
-== Debug Shapes
-
-
-=== Coordinate Axes
-
-The coordinate axes (com.jme3.scene.debug.Arrow) help you see the cardinal directions (X,Y,Z) from their center point. Scale the arrows to use them as a "`ruler`" for a certain length.
-
-[source,java]
-----
-
-private void attachCoordinateAxes(Vector3f pos) {
-    Arrow arrow = new Arrow(Vector3f.UNIT_X);
-    putShape(arrow, ColorRGBA.Red).setLocalTranslation(pos);
-
-    arrow = new Arrow(Vector3f.UNIT_Y);
-    putShape(arrow, ColorRGBA.Green).setLocalTranslation(pos);
-
-    arrow = new Arrow(Vector3f.UNIT_Z);
-    putShape(arrow, ColorRGBA.Blue).setLocalTranslation(pos);
-}
-
-private Geometry putShape(Mesh shape, ColorRGBA color) {
-    Geometry g = new Geometry("coordinate axis", shape);
-    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-    mat.getAdditionalRenderState().setWireframe(true);
-    mat.getAdditionalRenderState().setLineWidth(4);
-    mat.setColor("Color", color);
-    g.setMaterial(mat);
-    rootNode.attachChild(g);
-    return g;
-}
-----
-
-
-=== Wireframe Grid
-
-Use a wireframe grid (com.jme3.scene.debug.Grid) as a ruler or simple floor.
-
-[source,java]
-----
-
-private Geometry attachGrid(Vector3f pos, int size, ColorRGBA color) {
-    Geometry g = new Geometry("wireframe grid", new Grid(size, size, 0.2f));
-    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-    mat.getAdditionalRenderState().setWireframe(true);
-    mat.setColor("Color", color);
-    g.setMaterial(mat);
-    g.center().move(pos);
-    rootNode.attachChild(g);
-    return g;
-}
-----
-
-
-=== Wireframe Cube
-
-Use a wireframe cube (com.jme3.scene.debug.WireBox) as a stand-in object to see whether your code scales, positions, or orients, loaded models right.
-
-[source,java]
-----
-
-public Geometry attachWireBox(Vector3f pos, float size, ColorRGBA color) {
-    Geometry g = new Geometry("wireframe cube", new WireBox(size, size, size));
-    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-    mat.getAdditionalRenderState().setWireframe(true);
-    mat.setColor("Color", color);
-    g.setMaterial(mat);
-    g.setLocalTranslation(pos);
-    rootNode.attachChild(g);
-    return g;
-}
-----
-
-
-=== Wireframe Sphere
-
-Use a wireframe sphere (com.jme3.scene.debug.WireSphere) as a stand-in object to see whether your code scales, positions, or orients, loaded models right.
-
-[source,java]
-----
-
-private Geometry attachWireSphere(Vector3f pos, float size, ColorRGBA color) {
-    Geometry g = new Geometry("wireframe sphere", new WireSphere(size));
-    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-    mat.getAdditionalRenderState().setWireframe(true);
-    mat.setColor("Color", color);
-    g.setMaterial(mat);
-    g.setLocalTranslation(pos);
-    rootNode.attachChild(g);
-    return g;
-}
-----
-
-
-== Wireframe for Physics
-
-You can display a wireframe of the (usually invisible) collision shape around all physical objects. Use this for debugging when analyzing unexpected behaviour. Does not work with DETACHED physics, please switch to PARALLEL or SEQUENTIAL for debugging.
-
-[source,java]
-----
-//Create the physics space.
-bulletAppState = new BulletAppState();
-bulletAppState.setDebugEnabled(true);
-getStateManager().attach(bulletAppState);
-----
-
-With debugging enabled, colors are used to indicate various types of physical objects:
-
-*  A magenta wire mesh indicates an active rigid body.
-*  A blue wire mesh indicates a rigid body which is either new or inactive.
-*  A yellow wire mesh indicates a ghost.
-*  Two green arrows indicate a joint.
-*  A pink wire mesh indicates a character.
-
-
-== Wireframe for Animations
-
-Making the skeleton visible inside animated models can be handy for debugging animations. The `control` object is an AnimControl, `player` is the loaded model.
-
-.AnimControl is known to be in the main node
-[source,java]
-----
-
-SkeletonDebugger skeletonDebug = new SkeletonDebugger("skeleton", control.getSkeleton());
-Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-mat.setColor("Color", ColorRGBA.Green);
-mat.getAdditionalRenderState().setDepthTest(false);
-skeletonDebug.setMaterial(mat);
-player.attachChild(skeletonDebug);
-----
-
-.AnimControl is nested somewhere
-[source,java]
-----
-private void debugSkeleton(Node player) {
-    player.depthFirstTraversal(new SceneGraphVisitorAdapter() {
-        @Override
-        public void visit(Node node) {
-            if (node.getControl(AnimControl.class) != null) {
-                AnimControl control = node.getControl(AnimControl.class);
-                SkeletonDebugger skeletonDebug = new SkeletonDebugger("skeleton",
-                        control.getSkeleton());
-                Material mat = new Material(getApplication().getAssetManager(),
-                        "Common/MatDefs/Misc/Unshaded.j3md");
-                mat.setColor("Color", ColorRGBA.Green);
-                mat.getAdditionalRenderState().setDepthTest(false);
-                skeletonDebug.setMaterial(mat);
-                player.attachChild(skeletonDebug);
-            }
-        }
-    });
-}
-----
-
-== Example: Toggle Wireframe on Model
-
-We assume that you have loaded a model with a material `mat`.
-
-Then you can add a switch to toggle the model's wireframe on and off, like this:
-
-.  Create a key input trigger that switches between the two materials: E.g. we toggle when the T key is pressed.
-+
-[source,java]
-----
-inputManager.addMapping("toggle wireframe", new KeyTrigger(KeyInput.KEY_T));
-inputManager.addListener(actionListener, "toggle wireframe");
-----
-
-.  Now add the toggle action to the action listener.
-+
-[source,java]
-----
-
-private ActionListener actionListener = new ActionListener() {
-    @Override
-    public void onAction(String name, boolean pressed, float tpf) {
-        // toggle wireframe
-        if (name.equals("toggle wireframe") && !pressed) {
-            wireframe = !wireframe; // toggle boolean
-            mat.getAdditionalRenderState().setWireframe(wireframe);
-        }
-        // else ... other input tests.
-    }
-};
-----
-
-.  Alternatively, you could traverse over the whole scene and toggle for all Geometry objects in there if you don't want to create a new SceneProcessor.
-+
-[source,java]
-----
-
-private ActionListener actionListener = new ActionListener() {
-    boolean wireframe = false;
-
-    @Override
-    public void onAction(String name, boolean pressed, float tpf) {
-        // toggle wireframe
-        if (name.equals("toggle wireframe") && !pressed) {
-            wireframe = !wireframe; // toggle boolean
-            rootNode.depthFirstTraversal(new SceneGraphVisitor() {
-                @Override
-                public void visit(Spatial spatial) {
-                    if (spatial instanceof Geometry) {
-                        ((Geometry) spatial).getMaterial()
-                                .getAdditionalRenderState().setWireframe(wireframe);
-                    }
-                }
-            });
-        }
-        // else ... other input tests.
-    }
-};
-----
-
-
-TIP: To set the line width of wireframe display, use mesh.setLineWidth(lineWidth). Default line width is 1.
-
-
-== Example: Toggle Wireframe on the scene
-
-To display the wireframe of the entire scene instead on one material at a time, first create the following Scene Processor.
-
-[source,java]
-----
-public class WireProcessor implements SceneProcessor {
-
-    RenderManager renderManager;
-    Material wireMaterial;
-
-    public WireProcessor(AssetManager assetManager) {
-        wireMaterial = new Material(assetManager, "/Common/MatDefs/Misc/Unshaded.j3md");
-        wireMaterial.setColor("Color", ColorRGBA.Blue);
-        wireMaterial.getAdditionalRenderState().setWireframe(true);
-    }
-
-    @Override
-    public void initialize(RenderManager rm, ViewPort vp) {
-        renderManager = rm;
-    }
-
-    @Override
-    public void reshape(ViewPort vp, int w, int h) {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    @Override
-    public boolean isInitialized() {
-        return renderManager != null;
-    }
-
-    @Override
-    public void preFrame(float tpf) {
-    }
-
-    @Override
-    public void postQueue(RenderQueue rq) {
-        renderManager.setForcedMaterial(wireMaterial);
-    }
-
-    @Override
-    public void postFrame(FrameBuffer out) {
-        renderManager.setForcedMaterial(null);
-    }
-
-    @Override
-    public void cleanup() {
-        renderManager.setForcedMaterial(null);
-    }
-}
-----
-
-Then attach the scene processor to the +++<abbr title="Graphical User Interface">GUI</abbr>+++ Viewport.
-
-[source,java]
-----
-getViewPort().addProcessor(new WireProcessor());
-----
-
-
-== See also
-
-*  <<jme3/advanced/spatial#,Spatial>> – if you can't see certain spatials, you can modify the culling behaviour to identify problems (such as inside-out custom meshes)

+ 0 - 95
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/debug_and_test/logging.adoc

@@ -1,95 +0,0 @@
-= Logging and Monitoring
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== Logging Like a Newbie
-
-Many developers just use `System.out.println()` to print diagnostic strings to the terminal. The problem with that is that before the release, you have to go through all your code and make certain you removed all these `println()` calls. You do not want your customers to see them, and needlessly worry about ominous outdated debugging diagnostics. 
-
-
-== Logging Like a Pro
-
-Instead of `println()`, use the standard Java logger from `java.util.logging`. It has many advantages for professional game development:
-
-*  You tag each message with its *log level*: Severe error, informative warning, etc.
-*  You can *switch off or on printing of log messages* up to certain log level with just one line of code.
-**  During development, you would set the log level to `fine`, because you want all warnings printed.
-**  For the release, you set the log level to only report `severe` errors, and never print informative diagnostics.
-
-*  The logger message string is *localizable* and can use variables. Optimally, you localize all error messages.
-
-To print comments like a pro, you use the following logger syntax.
-
-.  Declare the logger object once per file. In the following code, replace `HelloWorld` by the name of the class where you are using this line.
-+
-[source,java]
-----
-private static final Logger LOGGER = Logger.getLogger(HelloWorld.class.getName());
-----
-
-.  Declare the info that you want to include in the message. The variables (here `a, b, c`) can be any printable Java object. +
-Example: `Vector3f a = cam.getLocation();` 
-.  Put the variables in a new `Object` array. Refer to the variables as `{0},{1},{2}` etc in the message string. Variables are numbered in the order you put them into the `Object` array. 
-.  Add the logger line and specify the log level:
-**  Usecase 1: During debugging, a developer uses a warning to remind himself of a bug:
-+
-[source,java]
-----
-LOGGER.log(Level.WARNING, "why is {0} set to {1} again?!", 
-                      new Object[]{a , b});
-----
-
-**  Usecase 2: For the release, you inform the customer of a problem and how to solve it. 
-+
-[source,java]
-----
-LOGGER.log(Level.SEVERE, "MyGame error: {0} must not be {1} after {2}! Adjust flux generator settings.", 
-                      new Object[]{a , b , c});
-----
-
-[IMPORTANT]
-====
-As you see in the examples, you should phrase potentially “customer facing errors in a neutral way and offer _a reason and a solution_ for the error (if you don't, it has no value to your customer). If your deveopment team uses WARNINGs as replacement for casual printlns, make sure you deactivate them for the release.
-====
-
-
-More details about link:http://docs.oracle.com/javase/8/docs/api/java/util/logging/Level.html[Java log levels] here.
-
-
-== Switching the Logger on and off
-
-In the release version you will deactivate the logging output to the terminal.
-
-To deactivate the default logger for a release, you set the log level to only report `severe` messages:
-
-[source,java]
-----
-Logger.getLogger(””).setLevel(Level.SEVERE);
-----
-
-During development or a beta test, you can tune down the default logger, and set the log level to only report ``warning``s:
-
-[source,java]
-----
-Logger.getLogger(””).setLevel(Level.WARNING);
-----
-
-To activate full logging, e.g. for debugging and testing, use the `fine` level: 
-
-[source,java]
-----
-Logger.getLogger(””).setLevel(Level.FINE);
-----
-
-
-== Advanced Error Handling
-
-When an uncaught exception reaches certain parts of the jME3 system then the default response is to log the error and then exit the application. This is because an error happening every frame will rapidly fill logs with repeated failings and potentially mask or over-write the original cause of the problem or even the application may continue for a while and then suffer other errors caused by the first and make the root cause hard to determine.
-
-This behaviour can be partially modified by overriding the method handleError in SimpleApplication, for example to display a custom message to users, or to provide users with information on how to report a bug or even to change the way that the error is logged. 

+ 0 - 328
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/game_logic/application_states.adoc

@@ -1,328 +0,0 @@
-= Application States
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-:experimental:
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-The `com.jme3.app.state.AppState` class is a customizable jME3 interface that allows you to control the global game logic, the overall game mechanics. (To control the behaviour of a Spatial, see <<jme3/advanced/custom_controls#,Custom Controls>> instead. Controls and AppStates can be used together.)
-
-
-== Overview
-
-
-=== Use Case Examples
-
-There are situations during your game development where you think:
-
-*  Mouse and key inputs are handled differently in-game versus in the main menu. Can I group a set of input handler settings, and activate and deactivate them all in one step?  
-*  I have the in-game scene, and a character editor, and a Captain's Quarters screen. Can I group a set of nodes and behaviours, and swap them in and out in one step?
-*  When I pause the game, I want the character's “idle animation to continue, but all other loops and game events should stop. How do I define what happens when the game is paused/unpaused? 
-*  I have a conditional block that takes up a lot of space in my simpleUpdate() loop. Can I wrap up this block of code, and switch it on and off in one step?
-*  Can I package everything that belongs in-game, and everything that belongs to the menu screen, and switch between these two “big states in one step? 
-
-You can! This is what AppStates are there for. An AppState class is subset of (or an extension to) your application. Every AppState class has access to all fields in your main application (AssetManager, ViewPort, StateManager, InputManager, RootNode, GuiNode, etc) and hooks into the main update loop. An AppState can contain:
-
-*  a subset of class fields, functions, methods (game state data and accessors), 
-*  a subset of +++<abbr title="Graphical User Interface">GUI</abbr>+++ elements and their listeners, 
-*  a subset of input handlers and mappings, 
-*  a subset of nodes that you load and attach to the rootNode, 
-*  a subset of conditional actions that you branch to in the simpleUpdate() loop, 
-*  a subset of other AppStates and Controls
-*  … or combinations thereof. 
-
-
-=== Supported Features
-
-Each AppState lets you define what happens to it in the following situations:
-
-*  *The AppState is initialized:* You load and initialize game data, InputHandlers, AppStates and Controls and attach nodes. +
-The AppState executes its own simpleInitApp() method when it is attached, so to speak.
-*  *The AppState has been enabled (unpaused):* This toggles a boolean isEnabled() to true. Here you attach nodes and listeners that should become active while it's running. 
-*  *While the AppState is running/paused:* You can poll isEnabled() to define paused and unpaused game behaviour in the update() loop. In update(), you poll and modify the game state, modify the scene graph, and trigger events. Test if `!isEnabled()`, and write code that skips the running sections of this AppState's `update()` loop. +
-Each AppState has its own update loop, which hooks into the main simpleUpdate() loop (callback). 
-*  *The AppState has been disabled (paused):* This toggles a boolean isEnabled() to false. Here you switch all objects to their specific “paused behaviour. 
-*  *The AppState is cleaned up:* Here you decide what happens when the AppState is detached. Save this AppState's game state, unregister Controls and InputHandlers, detach related AppStates, detach nodes from the rootNode, etc.
-
-
-[TIP]
-====
-AppStates are extremely handy to swap out, or pause/unpause whole sets of other AppStates. For example, an InGameState (loads in-game +++<abbr title="Graphical User Interface">GUI</abbr>+++, activates click-to-shoot input mappings, inits game content, starts game loop) versus MainScreenState (stops game loop, saves and detaches game content, switches to menu screen +++<abbr title="Graphical User Interface">GUI</abbr>+++, switches to click-to-select input mappings).
-====
-
-
-
-=== Usage
-
-To implement game logic:
-
-.  Create one AbstractAppState instance for each set of game mechanics. 
-.  Implement game behaviour in the AppState's update() method.
-**  You can pass custom data as arguments in the constructor.
-**  The AppState has access to everything inside the app's scope via the Application `app` object.
-
-.  Create and attach the AppState to the AppStateManager (`stateManager.attach(myAppState);`) and initialize it.
-.  Enable and disable (unpause and pause) the AppStates that you need during the game.
-.  Detach the AppState from the AppStateManager (`stateManager.detach(myAppState);`) and clean it up.
-
-When you add several AppStates to one Application and activate them, their initialize() methods and update() loops are executed in the order in which the AppStates were added to the AppStateManager.
-
-
-=== Code Samples
-
-JME3 comes with a BulletAppState that implements Physical behaviour (using the jBullet library). You, for example, could write an Artificial Intelligence AppState to control all your enemy units. Existing examples in the code base include:
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-bullet/src/common/java/com/jme3/bullet/BulletAppState.java[BulletAppState] controls physical behaviour in PhysicsControl'ed Spatials.
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/app/state/TestAppStates.java[TestAppStates.java] an example of a custom AppState
-**  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/app/state/RootNodeState.java[RootNodeState.java]
-
-
-
-== AppState
-
-The AppState interface lets you initialize sets of objects, and hook a set of continuously executing code into the main loop.
-[cols="25,75", options="header"]
-|===
-
-a|AppState Method
-a|Usage
-
-a|initialize(asm,app)
-a|When this AppState is added to the game, the RenderThread initializes the AppState and then calls this method. You can modify the scene graph from here (e.g. attach nodes). To get access to the main app, call: 
-[source,java]
-----
-super.initialize(stateManager, app);
-this.app = (SimpleApplication) app;
-----
-
-
-a|cleanup()
-a|This method is executed after you remove the AppState from the game. Here you implement clean-up code for when this state is detached. You can modify the scene graph from here (e.g. detach nodes).
-
-a|update(float tpf)
-a|Here you implement the behaviour that you want to hook into the simpleUpdate() loop while this state is attached to the game. You can modify the scene graph from here.
-
-a|isInitialized()
-a|Your implementations of this interface should return the correct respective boolean value. (See AbstractAppState)
-
-a|setEnabled(true) +
-setEnabled(false)
-a|Temporarily enables or disables an AppState. (See AbstractAppState) 
-
-a|isEnabled()
-a|Test whether AppState is enabled or disabled. Your implementation should consider the boolean. (See AbstractAppState)
-
-a|stateAttached(asm) +
-stateDetached(asm)
-a|The AppState knows when it is attached to, or detached from, the AppStateManager, and triggers these two methods. Don't modify the scene graph from here! (Typically not used.) 
-
-a|render(RenderManager rm)
-a|Renders the state, plus your optional customizations. (Typically not used.)
-
-a|postRender()
-a|Called after all rendering commands are flushed, including your optional customizations. (Typically not used.)
-
-|===
-
-
-== AbstractAppState
-
-The link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-core/src/main/java/com/jme3/app/state/AbstractAppState.java[AbstractAppState] class already implements some common methods (`isInitialized(), setEnabled(), isEnabled()`) and makes creation of custom AppStates a bit easier. We recommend you extend AbstractAppState and override the remaining AppState methods: `initialize(), setEnabled(), cleanup()`.
-
-Definition:
-
-[source,java]
-----
-public class MyAppState extends AbstractAppState {
-
-    private SimpleApplication app;
-
-    private Node x = new Node("x");  // some custom class fields...    
-    public Node getX(){ return x; }  // some custom methods... 
-    
-    @Override
-    public void initialize(AppStateManager stateManager, Application app) {
-      super.initialize(stateManager, app); 
-      this.app = (SimpleApplication)app;          // cast to a more specific class
-      
-      // init stuff that is independent of whether state is PAUSED or RUNNING
-      this.app.getRootNode().attachChild(getX()); // modify scene graph...
-      this.app.doSomething();                     // call custom methods...
-   }
-    
-   @Override
-    public void cleanup() {
-      super.cleanup();
-      // unregister all my listeners, detach all my nodes, etc...
-      this.app.getRootNode().detachChild(getX()); // modify scene graph...
-      this.app.doSomethingElse();                 // call custom methods...
-    }
-
-    @Override
-    public void setEnabled(boolean enabled) {
-      // Pause and unpause
-      super.setEnabled(enabled);
-      if(enabled){
-        // init stuff that is in use while this state is RUNNING
-        this.app.getRootNode().attachChild(getX()); // modify scene graph...
-        this.app.doSomethingElse();                 // call custom methods...
-      } else {
-        // take away everything not needed while this state is PAUSED
-        ...
-      }
-    }
-    
-    // Note that update is only called while the state is both attached and enabled.
-    @Override
-    public void update(float tpf) {
-      // do the following while game is RUNNING
-      this.app.getRootNode().getChild("blah").scale(tpf); // modify scene graph...
-      x.setUserData(...);                                 // call some methods...
-    }
-    
-}
-----
-
-
-== BaseAppState
-
-
-A new link:http://javadoc.jmonkeyengine.org/com/jme3/app/state/BaseAppState.html[BaseAppState] class was introduced as part of the link:https://hub.jmonkeyengine.org/t/jmonkeyengine-3-1-alpha-4-released/35478[updates] being made to the AppState interface. AbstractAppState is the most minimal of the minimal implementations of the AppState interface. You essentially still need to do everything yourself, including getting the funky enable/disable/initialized/terminate logic right. Now you just extend BaseAppState and you get onEnable() and onDisable() already worked out for you.
-
-Definition:
-
-[source,java]
-----
-public class MyBaseAppState extends BaseAppState {        
-    @Override    
-    protected void initialize(Application app) {        
-        //It is technically safe to do all initialization and cleanup in the         
-        //onEnable()/onDisable() methods. Choosing to use initialize() and         
-        //cleanup() for this is a matter of performance specifics for the         
-        //implementor.        
-        //TODO: initialize your AppState, e.g. attach spatials to rootNode    
-    }
-
-    @Override    
-    protected void cleanup(Application app) {        
-        //TODO: clean up what you initialized in the initialize method,        
-        //e.g. remove all spatials from rootNode    
-    }
-    
-    //onEnable()/onDisable() can be used for managing things that should     
-    //only exist while the state is enabled. Prime examples would be scene     
-    //graph attachment or input listener attachment.    
-    @Override    
-    protected void onEnable() {        
-        //Called when the state is fully enabled, ie: is attached and         
-        //isEnabled() is true or when the setEnabled() status changes after the         
-        //state is attached.    
-    }
-    
-    @Override    
-    protected void onDisable() {        
-        //Called when the state was previously enabled but is now disabled         
-        //either because setEnabled(false) was called or the state is being         
-        //cleaned up.    
-    }        
-    
-    @Override    
-    public void update(float tpf) {        
-        //TODO: implement behavior during runtime    
-    }
-    
-}
-----
-
-Notable BaseAppState changes are as follows:
-
-
-*  You no longer need to call super.initialize(stateManager, app) because it is now called by BaseAppState upon initialization for you.
-*  You no longer have to cast SimpleApplication to have access to AssetManager, AppStateManager, and you can even get a State directly. The getters getApplication(), getAssetManager(), getState(type) and their methods are available to you immediately. However, you still have to cast SimpleApplication to get rootNode.
-*  You no longer call super during cleanup, its done for you now.
-*  It's now safe to do all initialization and cleanup in the onEnable()/onDisable() methods.
-*  Cleanup and setEnabled now have logging built in.
-
-You use BaseAppState as you would AbstractAppState, other than mentioned above, and which one you use is entirely up to you. However, BaseAppState makes your life easier and is the recommended one to use now.
-
-See link:http://javadoc.jmonkeyengine.org/com/jme3/app/state/BaseAppState.html[BaseAppState] for more information.
-
-== Pausing and Unpausing
-
-You define what an AppState does when Paused or Unpaused, in the `setEnabled()` and `update()` methods. Call `myState.setEnabled(false)` on all states that you want to pause. Call `myState.setEnabled(true)` on all states that you want to unpause.
-
-
-== AppStateManager
-
-The com.jme3.app.state.AppStateManager holds the list of AppStates for an application. AppStateManager ensures that active AppStates can modify the scene graph, and that the update() loops of active AppStates is executed. There is one AppStateManager per application. You typically attach several AppStates to one AppStateManager, but the same state can only be attached once.
-[cols="2", options="header"]
-|===
-
-a|AppStateManager Method
-a|Usage
-
-a|hasState(myState)
-a|Is AppState object 'myState' attached?
-
-a|getState(MyAppState.class)
-a|Returns the first attached state that is an instance of a subclass of `MyAppState.class`.
-
-|===
-
-The AppStateManager's `render(), postRender(), cleanup()` methods are internal, ignore them, users never call them directly.
-
-*  If a detached AppState is attached then initialize() will be called on the following render pass.
-*  If an attached AppState is detached then cleanup() will be called on the following render pass.
-*  If you attach an already-attached AppState then the second attach is a no-op and will return false.
-*  If you both attach and detach an AppState within one frame then neither initialize() or cleanup() will be called, although if either is called both will be.
-*  If you both detach and then re-attach an AppState within one frame then on the next update pass its cleanup() and initialize() methods will be called in that order.
-
-
-== Best Practices
-
-
-=== Communication Among AppStates
-
-You can only access other AppStates (read from and write to them) from certain places: From a Control's update() method, from an AppState's update() method, and from the SimpleApplication's simpleUpdate() loop. Don't mess with the AppState from other places, because from other methods you have no control over the order of modifications; the game can go out of sync because you can't know when (during which half-finished step of another state change) your modification will be performed.
-
-You can use custom accessors to get data from AppStates, to set data in AppStates, or to trigger methods in AppStates.
-
-[source,java]
-----
-this.app.getStateManager().getState(MyAppState.class).doSomeCustomStuffInThisState();
-----
-
-
-=== Initialize Familiar Class Fields
-
-To access class fields of the SimpleApplication the way you are used to, initialize them to local variables, as shown in the following AppState template:
-
-[source,java]
-----
-
-private SimpleApplication app;
-private Node              rootNode;
-private AssetManager      assetManager;
-private AppStateManager   stateManager;
-private InputManager      inputManager;
-private ViewPort          viewPort;
-private BulletAppState    physics;
-
-public class MyAppState extends AbstractAppState {
-  @Override
-  public void initialize(AppStateManager stateManager, Application app) {
-    super.initialize(stateManager, app);
-    this.app = (SimpleApplication) app; // can cast Application to something more specific
-    this.rootNode     = this.app.getRootNode();
-    this.assetManager = this.app.getAssetManager();
-    this.stateManager = this.app.getStateManager();
-    this.inputManager = this.app.getInputManager();
-    this.viewPort     = this.app.getViewPort();
-    this.physics      = this.stateManager.getState(BulletAppState.class);
-  }
-}
-
-----

+ 0 - 410
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/game_logic/appstatesdemo.adoc

@@ -1,410 +0,0 @@
-= Simple AppStates Demo
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-[IMPORTANT]
-====
-
-THIS DEMO IS OUT OF DATE AND NEEDS CORRECTING
-
-====
-
-
-
-== THIS DEMO IS OUT OF DATE AND NEEDS CORRECTING FOR NOW PLEASE SEE
-
- <<jme3/advanced/application_states#,jme3:advanced:application_states>>
-
-Note: this tutorial needs to be fixed and is currently not correct.  One should almost never override stateDetached and stateAttached… and should certainly never do anything scene related in them.
-
-This demo is a simple example of how you use AppStates to toggle between a StartScreen and a SettingsScreen (press RETURN) while the game is paused, and start the game by switching to a GameRunning state (press BACKSPACE). 
-
-There are four files, Main.java, GameRunningState.java, StartScreenState.java, SettingsScreenState.java. 
-
-
-=== Main.java
-
-[source,java]
-----
-
-package chapter04.appstatedemo;
-
-import com.jme3.app.SimpleApplication;
-import com.jme3.input.KeyInput;
-import com.jme3.input.controls.ActionListener;
-import com.jme3.input.controls.KeyTrigger;
-import com.jme3.input.controls.Trigger;
-
-/**
- * This demo shows a simple "game" with three AppStates. Instead of game content, 
- * it just displays three cubes on different backgrounds.
- * <ul>
- * <li>StartScreenState: This state is enabled 
- *     when the user starts the application, or the the game is paused. 
- *     Press BACKSPACE to return to the game, press RETURN to go to Settings.</li>
- * <li>GameRunningState: This state shows the game content and is enabled while the game is running. 
- *     Press BACKSPACE to pause and return to the start screen.</li>
- * <li>SettingsScreenState: This Settings screen state can be reached from the start screen
- *     Press RETURN to toggle it on and off.</li>
- * </ul>
- */
-public class Main extends SimpleApplication {
-
-  private Trigger pause_trigger = new KeyTrigger(KeyInput.KEY_BACK);
-  private Trigger save_trigger = new KeyTrigger(KeyInput.KEY_RETURN);
-  private boolean isRunning = false; // starts at startscreen
-  private GameRunningState gameRunningState;
-  private StartScreenState startScreenState;
-  private SettingsScreenState settingsScreenState;
-
-  
-  /** Start the jMonkeyEngine application */
-  public static void main(String[] args) {
-    Main app = new Main();
-    app.start();
-  }
-
-  /**
-   * initialize the scene here
-   */
-  @Override
-  public void simpleInitApp() {
-    setDisplayFps(false);
-    setDisplayStatView(false);
-
-    gameRunningState    = new GameRunningState(this);
-    startScreenState    = new StartScreenState(this);
-    settingsScreenState = new SettingsScreenState(this);
-
-    stateManager.attach(startScreenState);
-
-    inputManager.addMapping("Game Pause Unpause", pause_trigger);
-    inputManager.addListener(actionListener, new String[]{"Game Pause Unpause"});
-    inputManager.addMapping("Toggle Settings", save_trigger);
-    inputManager.addListener(actionListener, new String[]{"Toggle Settings"});
-  }
-  
-  private ActionListener actionListener = new ActionListener() {
-    public void onAction(String name, boolean isPressed, float tpf) {
-      System.out.println("key" + name);
-      if (name.equals("Game Pause Unpause") && !isPressed) {
-        if (isRunning) {
-          stateManager.detach(gameRunningState);
-          stateManager.attach(startScreenState);
-          System.out.println("switching to startscreen...");
-
-        } else {
-          stateManager.detach(startScreenState);
-          stateManager.attach(gameRunningState);
-          System.out.println("switching to game...");
-        }
-        isRunning = !isRunning;
-      } else if (name.equals("Toggle Settings") && !isPressed && !isRunning) {
-        if (!isRunning && stateManager.hasState(startScreenState)) {
-          stateManager.detach(startScreenState);
-          stateManager.attach(settingsScreenState);
-          System.out.println("switching to settings...");
-        } else if (!isRunning && stateManager.hasState(settingsScreenState)) {
-          stateManager.detach(settingsScreenState);
-          stateManager.attach(startScreenState);
-          System.out.println("switching to startscreen...");
-        }
-      }
-    }
-  };
-
-  @Override
-  public void simpleUpdate(float tpf) {}
-
-}
- 
-
-----
-
-
-=== GameRunningState.java
-
-[source,java]
-----
-
-package chapter04.appstatedemo;
-
-import com.jme3.app.Application;
-import com.jme3.app.SimpleApplication;
-import com.jme3.app.state.AbstractAppState;
-import com.jme3.app.state.AppStateManager;
-import com.jme3.asset.AssetManager;
-import com.jme3.font.BitmapFont;
-import com.jme3.font.BitmapText;
-import com.jme3.material.Material;
-import com.jme3.math.ColorRGBA;
-import com.jme3.math.Vector3f;
-import com.jme3.renderer.ViewPort;
-import com.jme3.scene.Geometry;
-import com.jme3.scene.Node;
-import com.jme3.scene.shape.Box;
-
-/**
- * A template how to create an Application State. This example state simply
- * changes the background color depending on the camera position.
- */
-public class GameRunningState extends AbstractAppState {
-
-  private ViewPort viewPort;
-  private Node rootNode;
-  private Node guiNode;
-  private AssetManager assetManager;
-  private Node localRootNode = new Node("Game Screen RootNode");
-  private Node localGuiNode = new Node("Game Screen GuiNode");
-  private final ColorRGBA backgroundColor = ColorRGBA.Blue;
-
-  public GameRunningState(SimpleApplication app){
-    this.rootNode     = app.getRootNode();
-    this.viewPort      = app.getViewPort();
-    this.guiNode       = app.getGuiNode();
-    this.assetManager  = app.getAssetManager();  
-  }
-
-  @Override
-  public void initialize(AppStateManager stateManager, Application app) {
-    super.initialize(stateManager, app);
-
-    /** Load this scene */
-    viewPort.setBackgroundColor(backgroundColor);
-
-    Box mesh = new Box(Vector3f.ZERO, 1, 1, 1);
-    Geometry geom = new Geometry("Box", mesh);
-    Material mat = new Material(assetManager,
-            "Common/MatDefs/Misc/Unshaded.j3md");
-    mat.setColor("Color", ColorRGBA.Green);
-    geom.setMaterial(mat);
-    geom.setLocalTranslation(1, 0, 0);
-    localRootNode.attachChild(geom);
-
-    /** Load the HUD*/
-    BitmapFont guiFont = assetManager.loadFont(
-            "Interface/Fonts/Default.fnt");
-    BitmapText displaytext = new BitmapText(guiFont);
-    displaytext.setSize(guiFont.getCharSet().getRenderedSize());
-    displaytext.move(10, displaytext.getLineHeight() + 20, 0);
-    displaytext.setText("Game running. Press BACKSPACE to pause and return to the start screen.");
-    localGuiNode.attachChild(displaytext);
-  }
-
-  @Override
-  public void update(float tpf) {
-    /** the action happens here */
-    Vector3f v = viewPort.getCamera().getLocation();
-    viewPort.setBackgroundColor(new ColorRGBA(v.getX() / 10, v.getY() / 10, v.getZ() / 10, 1));
-    rootNode.getChild("Box").rotate(tpf, tpf, tpf);
-  }
-  
-  @Override
-  public void stateAttached(AppStateManager stateManager) {
-    rootNode.attachChild(localRootNode);
-    guiNode.attachChild(localGuiNode);
-    viewPort.setBackgroundColor(backgroundColor);
-  }
-
-  @Override
-  public void stateDetached(AppStateManager stateManager) {
-    rootNode.detachChild(localRootNode);
-    guiNode.detachChild(localGuiNode);
-
-  }
-
-}
-
-----
-
-
-=== SettingsScreenState.java
-
-[source,java]
-----
-
-package chapter04.appstatedemo;
-
-import com.jme3.app.Application;
-import com.jme3.app.SimpleApplication;
-import com.jme3.app.state.AbstractAppState;
-import com.jme3.app.state.AppStateManager;
-import com.jme3.asset.AssetManager;
-import com.jme3.font.BitmapFont;
-import com.jme3.font.BitmapText;
-import com.jme3.material.Material;
-import com.jme3.math.ColorRGBA;
-import com.jme3.math.Vector3f;
-import com.jme3.renderer.ViewPort;
-import com.jme3.scene.Geometry;
-import com.jme3.scene.Node;
-import com.jme3.scene.shape.Box;
-
-/**
- * A template how to create an Application State. This example state simply
- * changes the background color depending on the camera position.
- */
-public class SettingsScreenState extends AbstractAppState {
-
-  private ViewPort viewPort;
-  private Node rootNode;
-  private Node guiNode;
-  private AssetManager assetManager;
-  private Node localRootNode = new Node("Settings Screen RootNode");
-  private Node localGuiNode = new Node("Settings Screen GuiNode");
-  private final ColorRGBA backgroundColor = ColorRGBA.DarkGray;
-
-  public SettingsScreenState(SimpleApplication app) {
-    this.rootNode     = app.getRootNode();
-    this.viewPort      = app.getViewPort();
-    this.guiNode       = app.getGuiNode();
-    this.assetManager  = app.getAssetManager();
-  }
-
-  @Override
-  public void initialize(AppStateManager stateManager, Application app) {
-    super.initialize(stateManager, app);
-
-    /** Load this scene */
-    viewPort.setBackgroundColor(backgroundColor);
-
-    Box mesh = new Box(new Vector3f(-1, -1, 0), .5f, .5f, .5f);
-    Geometry geom = new Geometry("Box", mesh);
-    Material mat = new Material(assetManager,
-            "Common/MatDefs/Misc/Unshaded.j3md");
-    mat.setColor("Color", ColorRGBA.Red);
-    geom.setMaterial(mat);
-    geom.setLocalTranslation(1, 0, 0);
-    localRootNode.attachChild(geom);
-
-    /** Load the HUD */
-    BitmapFont guiFont = assetManager.loadFont(
-            "Interface/Fonts/Default.fnt");
-    BitmapText displaytext = new BitmapText(guiFont);
-    displaytext.setSize(guiFont.getCharSet().getRenderedSize());
-    displaytext.move(10, displaytext.getLineHeight() + 20, 0);
-    displaytext.setText("Settings screen. Press RETURN to save "
-            + "and return to start screen.");
-    localGuiNode.attachChild(displaytext);
-  }
-
-  @Override
-  public void update(float tpf) {
-     /** the action happens here */
-  }
-
-  @Override
-  public void stateAttached(AppStateManager stateManager) {
-    rootNode.attachChild(localRootNode);
-    guiNode.attachChild(localGuiNode);
-    viewPort.setBackgroundColor(backgroundColor);
-  }
-
-  @Override
-  public void stateDetached(AppStateManager stateManager) {
-    rootNode.detachChild(localRootNode);
-    guiNode.detachChild(localGuiNode);
-  }
-  
-}
-
-----
-
-
-=== StartScreenState.java
-
-[source,java]
-----
-
-package chapter04.appstatedemo;
-
-import com.jme3.app.Application;
-import com.jme3.app.SimpleApplication;
-import com.jme3.app.state.AbstractAppState;
-import com.jme3.app.state.AppStateManager;
-import com.jme3.asset.AssetManager;
-import com.jme3.font.BitmapFont;
-import com.jme3.font.BitmapText;
-import com.jme3.material.Material;
-import com.jme3.math.ColorRGBA;
-import com.jme3.math.Vector3f;
-import com.jme3.renderer.ViewPort;
-import com.jme3.scene.Geometry;
-import com.jme3.scene.Node;
-import com.jme3.scene.shape.Box;
-
-/**
- * A template how to create an Application State. This example state simply
- * changes the background color depending on the camera position.
- */
-public class StartScreenState extends AbstractAppState {
-
-  private ViewPort viewPort;
-  private Node rootNode;
-  private Node guiNode;
-  private AssetManager assetManager;
-  private Node localRootNode = new Node("Start Screen RootNode");
-  private Node localGuiNode = new Node("Start Screen GuiNode");
-  private final ColorRGBA backgroundColor = ColorRGBA.Gray;  
-
-public StartScreenState(SimpleApplication app){
-    this.rootNode     = app.getRootNode();
-    this.viewPort     = app.getViewPort();
-    this.guiNode      = app.getGuiNode();
-    this.assetManager = app.getAssetManager();  
-  }
-
-  @Override
-  public void initialize(AppStateManager stateManager, Application app) {
-    super.initialize(stateManager, app);
-    
-    /** Init this scene */
-    viewPort.setBackgroundColor(backgroundColor);
-
-    Box mesh = new Box(new Vector3f(-1,1,0), .5f,.5f,.5f);
-    Geometry geom = new Geometry("Box", mesh);
-    Material mat = new Material(assetManager,
-            "Common/MatDefs/Misc/Unshaded.j3md");
-    mat.setColor("Color", ColorRGBA.Yellow);
-    geom.setMaterial(mat);
-    geom.setLocalTranslation(1, 0, 0);
-    localRootNode.attachChild(geom);
-
-    /** Load a HUD */
-    BitmapFont guiFont = assetManager.loadFont(
-            "Interface/Fonts/Default.fnt");
-    BitmapText displaytext = new BitmapText(guiFont);
-    displaytext.setSize(guiFont.getCharSet().getRenderedSize());
-    displaytext.move( 10, displaytext.getLineHeight() + 20,  0);
-    displaytext.setText("Start screen. Press BACKSPACE to resume the game, "
-            + "press RETURN to edit Settings.");
-    localGuiNode.attachChild(displaytext);
-  }
-
-  @Override
-  public void update(float tpf) {
-    /** the action happens here */
-  }
-
-  @Override
-  public void stateAttached(AppStateManager stateManager) {
-    rootNode.attachChild(localRootNode);
-    guiNode.attachChild(localGuiNode);
-    viewPort.setBackgroundColor(backgroundColor);
-  }
-
-  @Override
-  public void stateDetached(AppStateManager stateManager) {
-    rootNode.detachChild(localRootNode);
-    guiNode.detachChild(localGuiNode);
-  }
-  
-}
-
-----

+ 0 - 329
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/game_logic/custom_controls.adoc

@@ -1,329 +0,0 @@
-= Custom Controls
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-A `com.jme3.scene.control.Control` is a customizable jME3 interface that allows you to cleanly steer the behaviour of game entities (Spatials), such as artificially intelligent behaviour in NPCs, traps, automatic alarms and doors, animals and pets, self-steering vehicles or platforms – anything that moves and interacts. Several instances of custom Controls together implement the behaviours of a type of Spatial. 
-
-To control global game behaviour see <<jme3/advanced/application_states#,Application States>> – you often use AppStates and Control together.
-
-*  link:http://www.youtube.com/watch?v=MNDiZ9YHIpM[Quick video introduction to Custom Controls]
-
-To control the behaviour of spatials:
-
-.  Create one control for each _type of behavior_. When you add several controls to one spatial, they will be executed in the order they were added. +
-For example, one NPC can be controlled by a PhysicsControl instance and an AIControl instance.
-.  Define the custom control and implement its behaviour in the Control's update method:
-**  You can pass arguments into your custom control.
-**  In the control class, the object `spatial` gives you access to the spatial and subspatials that the control is attached to.
-**  Here you modify the `spatial`'s transformation (move, scale, rotate), play animations, check its environement, define how it acts and reacts. 
-
-.  Add an instance of the Control to a spatial to give it this behavior. The spatial's game state is updated automatically from now on. +
-[source,java]
-----
-spatial.addControl(myControl);
-----
-
-
-To implement game logic for a type of spatial, you will either extend AbstractControl (most common case), or implement the Control interface, as explained in this article.
-
-
-== Usage
-
-Use <<jme3/advanced/custom_controls#,Controls>> to implement the _behaviour of types of game entities_.
-
-*  Use Controls to add a type of behaviour (that is, methods and fields) to individual Spatials. 
-*  Each Control has its own `update()` loop that hooks into `simpleUpdate()`. Use Controls to move blocks of code out of the `simpleUpdate()` loop.
-*  One Spatial can be influenced by several Controls. (Very powerful and modular!) 
-*  Each Spatial needs its own instance of the Control. 
-*  A Control only has access to and control over the Spatial it is attached to.
-*  Controls can be saved as .j3o file together with a Spatial. 
-
-Examples: You can write
-
-*  A WalkerNavControl, SwimmerNavControl, FlyerNavControl… that defines how a type of NPC finds their way around. All NPCs can walk, some can fly, others can swim, and some can all three, etc.
-*  A PlayerNavControl that is steered by user-configurable keyboard and mouse input.
-*  A generic animation control that acts as a common interface that triggers animations (walk, stand, attack, defend) for various entities.
-*  A DefensiveBehaviourControl that remote-controls NPC behaviour in fight situations. 
-*  An IdleBehaviourControl that remote-controls NPC behaviour in neutral situations. 
-*  A DestructionControl that automatically replaces a structure with an appropriate piece of debris after collision with a projectile… 
-
-The possibilities are endless. emoji:smiley
-
-
-== Example Code
-
-Other examples include the built-in RigidBodyControl in JME's physics integration, the built-in TerrainLODControl that updates the terrain's level of detail depending on the viewer's perspective, etc.
-
-Existing examples in the code base include:
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-core/src/main/java/com/jme3/animation/AnimControl.java[AnimControl.java] allows manipulation of skeletal animation, including blending and multiple channels.
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-core/src/main/java/com/jme3/scene/control/CameraControl.java[CameraControl.java] allows you to sync the camera position with the position of a given spatial.
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-core/src/main/java/com/jme3/scene/control/BillboardControl.java[BillboardControl.java] displays a flat picture orthogonally, e.g. a speech bubble or informational dialog.
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/tree/master/jme3-bullet/src/common/java/com/jme3/bullet/control[PhysicsControl] subclasses (such as CharacterControl, RigidBodyControl, VehicleControl) allow you to add physical properties to any spatial. PhysicsControls tie into capabilities provided by the BulletAppState.
-
-
-== AbstractControl Class
-
-
-[TIP]
-====
-The most common way to create a Control is to create a class that extends AbstractControl.
-====
-
-
-The AbstractControl can be found under `com.jme3.scene.control.AbstractControl`. This is a default abstract class that implements the Control interface.
-
-*  You have access to a boolean `isEnabled()`.
-*  You have access to the Spatial object `spatial`. 
-*  You override the `controlUpdate()` method to implement the Spatial's behaviour. 
-*  You have access to a `setEnabled(boolean)` method. This activates or deactivates this Control's behaviour in this spatial temporarily. While the AbstractControl is toggled to be disabled, the `controlUpdate()` loop is no longer executed. +
-For example, you disable your IdleBehaviourControl when you enable your DefensiveBehaviourControl in a spatial.
-
-Usage: Your custom subclass implements the three methods `controlUpdate()`, `controlRender()`, `setSpatial()`, and `cloneForSpatial()` as shown here:
-
-[source,java]
-----
-public class MyControl extends AbstractControl implements Savable, Cloneable {  
-    private int index; // can have custom fields -- example     
-    
-    public MyControl(){} // empty serialization constructor    
-    
-    /** Optional custom constructor with arguments that can init custom fields.    
-      * Note: you cannot modify the spatial here yet! */  
-    public MyControl(int i){     
-        // index=i; // example   
-    }     
-    
-    /** This method is called when the control is added to the spatial,    
-      * and when the control is removed from the spatial (setting a null value).    
-      * It can be used for both initialization and cleanup. */      
-    @Override  
-    public void setSpatial(Spatial spatial) {    
-        super.setSpatial(spatial);    
-        /* Example:    
-        if (spatial != null){        
-            // initialize    
-        }else{        
-            // cleanup    
-        }    
-        */  
-    }
-    /** Implement your spatial's behaviour here.    
-      * From here you can modify the scene graph and the spatial    
-      * (transform them, get and set userdata, etc).    
-      * This loop controls the spatial while the Control is enabled. */  
-    @Override  
-    protected void controlUpdate(float tpf){    
-        if(spatial != null) {      
-            // spatial.rotate(tpf,tpf,tpf); // example behaviour    
-        }  
-    }    
-    
-    @Override  
-    public Control cloneForSpatial(Spatial spatial){    
-        final MyControl control = new MyControl();    
-        /* Optional: use setters to copy userdata into the cloned control */    
-        // control.setIndex(i); // example    
-        control.setSpatial(spatial);    
-        return control;  
-    }    
-    
-    @Override  
-    protected void controlRender(RenderManager rm, ViewPort vp){     
-        /* Optional: rendering manipulation (for advanced users) */  
-    }    
-    
-    @Override  
-    public void read(JmeImporter im) throws IOException {      
-        super.read(im);      
-        // im.getCapsule(this).read(...);  
-    }    
-    
-    @Override  
-    public void write(JmeExporter ex) throws IOException {      
-        super.write(ex);      
-        // ex.getCapsule(this).write(...);  
-    }  
-}
-----
-
-See also:
-
-*  To learn more about `write()` and `read()`, see <<jme3/advanced/save_and_load#,Save and Load>>
-*  To learn more about `setUserData()`, see <<jme3/advanced/spatial#,Spatial>>.
-
-
-== The Control Interface
-
-
-[TIP]
-====
-In the less common case that you want to create a Control that also extends another class, create a custom interface that  extends jME3's Control interface. Your class can become a Control by implementing the Control interface, and at the same time extending another class.
-====
-
-
-The Control interface can be found under `com.jme3.scene.control.Control`. It has the following method signatures:
-
-*  `cloneForSpatial(Spatial)`: Clones the Control and attaches it to a clone of the given Spatial. +
-Implement this method to be able to <<jme3/advanced/save_and_load#,save() and load()>> Spatials carrying this Control. +
-The AssetManager also uses this method if the same spatial is loaded twice. You can specify which fields you want your object to reuse (e.g. collisionshapes) in this case. 
-*  `setEnabled(boolean)`: Toggles a boolean that enables or disables the Control. Goes with accessor `isEnabled();`. You test for it in the `update(float tpf)` loop before you execute anything.
-*  There are also some internal methods that you do not call from user code: `setSpatial(Spatial s)`, `update(float tpf);`, `render(RenderManager rm, ViewPort vp)`.
-
-Usage example:
-
-. Create a custom control interface.
-+
-[source,java]
-----
-public interface MyControlInterface extends Control {    
-    public void setSomething(int x); // optionally, add custom methods
-}
-----
-
-. Create custom Controls implementing your Control interface.
-+
-[source,java]
-----
-public class MyControl extends MyCustomClass implements MyControlInterface {
-    protected Spatial spatial;
-    
-    protected boolean enabled = true;
-    
-    public MyControl() { } // empty serialization constructor
-    
-    public MyControl(int x) { // custom constructor        
-        super(x);    
-    }
-    
-    @Override    
-    public void update(float tpf) {        
-        if (enabled && spatial != null) {            
-            // Write custom code to control the spatial here!        
-        }    
-    }        
-    
-    @Override    
-    public void render(RenderManager rm, ViewPort vp) {        
-        // optional for advanced users, e.g. to display a debug shape    
-    }        
-    
-    @Override    
-    public Control cloneForSpatial(Spatial spatial) {        
-        MyControl control = new MyControl();        
-        // set custom properties        
-        control.setSpatial(spatial);        
-        control.setEnabled(isEnabled());         
-        // set some more properties here...        
-        return control;    
-    }        
-    
-    @Override    
-    public void setEnabled(boolean enabled) {        
-        this.enabled = enabled;    
-    }        
-    
-    @Override    
-    public boolean isEnabled() {        
-        return enabled;    
-    }        
-    
-    @Override    
-    public void setSomething(int z) {        
-        // You can add custom methods ...    
-    }        
-    
-    @Override    
-    public void write(JmeExporter ex) throws IOException {        
-        super.write(ex);        
-        OutputCapsule oc = ex.getCapsule(this);        
-        oc.write(enabled, "enabled", true);        
-        oc.write(spatial, "spatial", null);        
-        // write custom variables ....    
-    }    
-    
-    @Override    
-    public void read(JmeImporter im) throws IOException {        
-        super.read(im);        
-        InputCapsule ic = im.getCapsule(this);        
-        enabled = ic.readBoolean("enabled", true);        
-        spatial = (Spatial) ic.readSavable("spatial", null);        
-        // read custom variables ....    
-    }
-}
-----
-
-
-== Best Practices
-
-
-Use the getControl() accessor to get Control objects from Spatials. No need to pass around lots of object references. Here's an example from the link:http://code.google.com/p/monkeyzone/[MonkeyZone] code:
-
-[source,java]
-----
-public class CharacterAnimControl implements Control {  
-    ...  
-    public void setSpatial(Spatial spatial) {    
-        ...    
-        animControl      = spatial.getControl(AnimControl.class);    
-        characterControl = spatial.getControl(CharacterControl.class);    
-        ...  
-    }
-}
-----
-
-You can create custom Control interfaces so a set of different Controls provide the same methods and can be accessed with the interface class type.
-
-[source,java]
-----
-public interface ManualControl extends Control {    
-    public void steerX(float value);    
-    public void steerY(float value);    
-    public void moveX(float value);    
-    public void moveY(float value);    
-    public void moveZ(float value);   
-    ...
-}
-----
-
-Then you create custom sub-Controls and implement the methods accordingly to the context:
-
-[source,java]
-----
-public class ManualVehicleControl   extends ManualControl {...}
-----
-
-and
-
-[source,java]
-----
-public class ManualCharacterControl extends ManualControl {...}
-----
-
-Then add the appropriate controls to spatials:
-
-[source,java]
-----
-
-characterSpatial.addControl(new ManualCharacterControl());
-...
-vehicleSpatial.addControl(new ManualVehicleControl());
-...
-----
-
-[TIP]
-====
-Use the getControl() method on a Spatial to get a specific Control object, and activate its behaviour!
-
-[source,java]
-----
-ManualControl c = mySpatial.getControl(ManualControl.class);
-c.steerX(steerX);
-----
-====

+ 0 - 64
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/game_logic/headless_server.adoc

@@ -1,64 +0,0 @@
-= jME3 Headless Server
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: server, spidermonkey, headless, network, documentation
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-When adding multiplayer to your game, you may find that your server needs to know about game state (e.g. where are players, objects? Was that a direct hit? etc.) You can code all this up yourself, but there's an easier way. 
-
-It's very easy to change your current (client) game to function as a server as well.
-
-
-== What Does Headless Mean?
-
-A headless server…
-
-*  does not display any output – no window opens, no audio plays, no graphics are rendered.
-*  ignores all input – no input handling.
-*  keeps game state – you can attach to, transform, and save the rootNode, although the scene is not displayed.
-*  calls the `simpleUpdate()` loop – you can run tests and trigger events as usual.
-
-
-== Client Code
-
-First, let's take a look at the default way of creating a new game (in its simplest form):
-
-[source,java]
-----
-
-public static void main(String[] args) {
-  Application app = new Main();
-  app.start();
-}
-----
-
-
-== Headless Server Code
-
-Now, with a simple change you can start your game in Headless mode. This means that all input and audio/visual output will be ignored. That's a good thing for a server.
-
-[source,java]
-----
-
-import com.jme3.system.JmeContext;
-import com.jme3.system.JmeContext.Type;
-
-public static void main(String[] args) {
-  Application app = new Main();
-  app.start(JmeContext.Type.Headless);
-}
-----
-
-
-== Next steps
-
-Okay, so you can now start your game in a headless 'server mode', where to go from here?
-
-*  Parse `String[] args` from the `main`-method to enable server mode on demand (e.g. start your server like `java -jar mygame.jar –server`.
-*  Integrate <<jme3/advanced/networking#,SpiderMonkey>>, to provide game updates to the server over a network.
-*  Only execute code that's needed. (E.g. place all rendering code inside an `if (servermode)`-block) (or `if (!servermode)` for the client).
-*  Add decent <<jme3/advanced/logging#,logging>> so your server actually makes sense.

+ 0 - 154
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/game_logic/making_the_camera_follow_a_character.adoc

@@ -1,154 +0,0 @@
-= Making the Camera Follow a 3rd-Person Character
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-When players steer a game character with 1st-person view, they directly steer the camera (`flyCam.setEnabled(true);`), and they never see the walking character itself. In a game with 3rd-person view, however, the players see the character walk, and you (the game developer) want to make the camera follow the character around when it walks.
-
-There are two ways how the camera can do that:
-
-*  Registering a chase camera to the player and the input manager.
-*  Attaching the camera to the character using a camera node.
-
-*Important:* Using third-person view requires you to deactivate the default flyCam (first-person view). This means that you have to configure your own navigation (<<jme3/advanced/input_handling#,key inputs and analogListener>>) that make your player character walk. For moving a physical player character, use `player.setWalkDirection()`, for a non-physical character you can use `player.move()`.
-
-
-== Code Samples
-
-Press the WASD or arrow keys to move. Drag with the left mouse button to rotate.
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/input/TestChaseCamera.java[TestChaseCamera.java]
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/input/TestCameraNode.java[TestCameraNode.java]
-
-
-== Camera Node
-
-To make the camera follow a target node, add this camera node code to your init method (e.g. `simpleInitApp()`). The `target` spatial is typically the player node.
-
-[source,java]
-----
-
-// Disable the default flyby cam
-flyCam.setEnabled(false);
-//create the camera Node
-camNode = new CameraNode("Camera Node", cam);
-//This mode means that camera copies the movements of the target:
-camNode.setControlDir(ControlDirection.SpatialToCamera);
-//Attach the camNode to the target:
-target.attachChild(camNode);
-//Move camNode, e.g. behind and above the target:
-camNode.setLocalTranslation(new Vector3f(0, 5, -5));
-//Rotate the camNode to look at the target:
-camNode.lookAt(target.getLocalTranslation(), Vector3f.UNIT_Y);
-
-----
-
-[IMPORTANT]
-====
-Where the example says `camNode.setLocalTranslation(new Vector3f(0, 5, -5));`, you have to supply your own start position for the camera. This depends on the size of your target (the player character) and its position in your particular scene. Optimally, you set this to a spot a bit behind and above the target.
-====
-
-[cols="2", options="header"]
-|===
-
-a|Methods
-a|Description
-
-a|setControlDir(ControlDirection.SpatialToCamera)
-a|User input steers the target spatial, and the camera follows the spatial. +
-The spatial's transformation is copied over the camera's transformation. +
-Example: Use with <<jme3/advanced/physics#,CharacterControl>>led spatial.
-
-a|setControlDir(ControlDirection.CameraToSpatial)
-a|User input steers the camera, and the target spatial follows the camera. +
-The camera's transformation is copied over the spatial's transformation. Use with first-person flyCam.
-
-|===
-
-*Code sample:*
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/input/TestCameraNode.java[TestCameraNode.java] – Press the WASD or arrow keys to move. Drag with the left mouse button to rotate.
-
-
-== Chase Camera
-
-To activate the chase camera, add the following code to your init method (e.g. `simpleInitApp()`). The `target` spatial is typically the player node. You will be able to rotate the target by dragging (keeping the left mouse button pressed and moving the mouse).
-
-[source,java]
-----
-
-// Disable the default flyby cam
-flyCam.setEnabled(false);
-// Enable a chase cam for this target (typically the player).
-ChaseCamera chaseCam = new ChaseCamera(cam, target, inputManager);
-chaseCam.setSmoothMotion(true);
-
-----
-[cols="2", options="header"]
-|===
-
-a|Method
-a|Description
-
-a|setInvertVerticalAxis(true)
-a|Invert the camera's vertical rotation Axis 
-
-a|setInvertHorizontalAxis(true)
-a|Invert the camera's horizontal rotation Axis
-
-a|setTrailingEnabled(true)
-a|Camera follows the target and flies around and behind when the target moves towards the camera. Trailing only works with smooth motion enabled. (Default)
-
-a|setTrailingEnabled(false)
-a|Camera follows the target, but does not rotate around the target when the target changes direction.
-
-a|setSmoothMotion(true)
-a|Activate SmoothMotion when trailing. This means the camera seems to accelerate and fly after the character, when it has caught up, it slows down again.
-
-a|setSmoothMotion(false)
-a|Disable smooth camera motion. Disabling SmoothMotion also disables trailing.
-
-a|setLookAtOffset(Vector3f.UNIT_Y.mult(3))
-a|Camera looks at a point 3 world units above the target.
-
-a|setToggleRotationTrigger(new MouseButtonTrigger(MouseInput.BUTTON_MIDDLE))
-a|Enable rotation by keeping the middle mouse button pressed (like in Blender). This disables the rotation on right and left mouse button click.
-
-a|setToggleRotationTrigger(new MouseButtonTrigger( +
-MouseInput.BUTTON_MIDDLE), +
-new KeyTrigger(KeyInput.KEY_SPACE))
-a|Activate mutiple triggers for the rotation of the camera, e.g. spacebar and middle mouse button, etc.
-
-a|setRotationSensitivity(5f)
-a|How fast the camera rotates. Use values around &lt;1.0f (all bigger values are ignored).
-
-|===
-
-*Code sample:*
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/input/TestChaseCamera.java[TestChaseCamera.java] – Press the WASD or arrow keys to move. Drag with the left mouse button to rotate.
-
-
-== Which to Choose?
-
-What is the difference of the two code samples above?
-[cols="2", options="header"]
-|===
-
-a|CameraNode
-a|ChaseCam
-
-a|Camera follows immediately, flies at same speed as target.
-a|Camera moves smoothly and accelerates and decelerates, flies more slowly than the target and catches up.
-
-a|Camera stays attached to the target at a constant distance.
-a|Camera orbits the target and approaches slowly.
-
-a|Drag-to-Rotate rotates the target and the camera. You always see the target from behind.
-a|Drag-to-Rotate rotates only the camera. You can see the target from various sides.
-
-|===

+ 0 - 55
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/game_logic/remote-controlling_the_camera.adoc

@@ -1,55 +0,0 @@
-= Remote-Controlling the Camera
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: camera, documentation, cinematics
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== Positioning the Camera
-
-You can steer the camera using <<jme3/advanced/cinematics#,Cinematics>>:
-
-.  Create a Cinematic.
-.  Create a CameraNode and bind the camera object to the Cinematic. Note that we also give the camera node a name in this step. 
-+
-[source,java]
-----
-CameraNode camNode = cinematic.bindCamera("topView", cam);
-----
-
-.  Position the camera node in its start location.
-.  Use activateCamera() to give the control of the camera to this node. You now see the scene from this camera's point of view. For example to see through the camera node named “topView, 6 seconds after the start of the cinematic, you'd write 
-+
-[source,java]
-----
-cinematic.activateCamera(6, "topView");
-----
-
-
-
-=== Code Sample
-
-[source,java]
-----
-
-flyCam.setEnabled(false);
-Cinematic cinematic = new Cinematic(rootNode, 20);
-
-CameraNode camNodeTop = cinematic.bindCamera("topView", cam);
-camNodeTop.setControlDir(ControlDirection.SpatialToCamera);
-camNodeTop.getControl(0).setEnabled(false);
-
-CameraNode camNodeSide = cinematic.bindCamera("sideView", cam);
-camNodeSide.setControlDir(ControlDirection.CameraToSpatial);
-camNodeSide.getControl(0).setEnabled(false);
-
-----
-
-
-== Moving the Camera
-
-If desired, attach the camNode to a MotionEvent to let it travel along waypoints. This is demonstrated in the link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/animation/TestCameraMotionPath.java[TestCameraMotionPath.java] example.

+ 0 - 45
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/game_logic/update_loop.adoc

@@ -1,45 +0,0 @@
-= Main Update Loop
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: basegame, control, input, init, keyinput, loop, states, state
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-Extending your application from com.jme3.app.<<jme3/intermediate/simpleapplication#,SimpleApplication>> provides you with an update loop. This is where you implement your game logic (game mechanics).
-
-Some usage examples: Here you remote-control NPCs (computer controlled characters), generate game events, and respond to user input.
-
-To let you see the main update loop in context, understand that the SimpleApplication does the following:
-
-*  *Initialization* – Execute `simpleInitApp()` method once.
-*  *Main Update Loop*
-..  Input listeners respond to mouse clicks and keyboard presses – <<jme3/advanced/input_handling#,Input handling>> 
-..  Update game state:
-...  Update overall game state – Execute <<jme3/advanced/application_states#,Application States>>
-...  User code update – Execute `simpleUpdate()` method
-...  Logical update of entities – Execute <<jme3/advanced/custom_controls#,Custom Controls>>
-
-..  Render audio and video
-...  <<jme3/advanced/application_states#,Application States>> rendering.
-...  Scene rendering.
-...  User code rendering – Execute `simpleRender()` method.
-
-..  Repeat loop.
-
-*  *Quit* – If user requests `exit()`, execute `cleanup()` and `destroy()`. +
-The jME window closes and the loop ends.
-
-
-== Usage
-
-In a trivial <<jme3/intermediate/simpleapplication#,SimpleApplication>> (such as a <<jme3/beginner#,Hello World tutorial>>), all code is either in the `simpleInitApp()` (initialization) or `simpleUpdate()` (behaviour) method – or in a helper method/class that is called from one of these two. This trivial approach will make your main class very long, hard to read, and hard to maintain. You don't need to load the whole scene at once, and you don't need to run all conditionals tests all the time.
-
-It's a best practice to modularize your game mechanics and spread out initialization and update loop code over several Java objects:
-
-*  Move modular code blocks from the `simpleInitApp()` method into <<jme3/advanced/application_states#,AppStates>>. Attach AppStates to initialize custom subsets of “one dungeon, and detach it when the player exits this “dungeon. +
-Examples: Weather/sky audio and visuals, physics collision shapes, sub-rootnodes of individual dungeons including dungeon NPCs, etc.
-*  Move modular code blocks from the `simpleUpdate()` method into the update loops of <<jme3/advanced/custom_controls#,Custom Controls>> to control individual entity behavior (NPCs), and into the update method of <<jme3/advanced/application_states#,AppStates>> to control world events. +
-Examples: Weather behaviour, light behaviour, physics behaviour, individual NPC behaviour, trap behaviour, etc.

+ 0 - 174
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/graphics_pipeline/camera.adoc

@@ -1,174 +0,0 @@
-= The jME3 Camera
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: camera, documentation
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-[NOTE]
-====
-By default, the mouse pointer is invisible, and the mouse is set up to control the camera rotation.
-====
-
-
-== Default Camera
-
-The default com.jme3.renderer.Camera object is `cam` in com.jme3.app.Application.
-
-The camera object is created with the following defaults:
-
-*  Width and height are set to the current Application's settings.getWidth() and settings.getHeight() values. 
-*  Frustum Perspective:
-**  Frame of view angle of 45° along the Y axis
-**  Aspect ratio of width divided by height
-**  Near view plane of 1 wu
-**  Far view plane of 1000 wu
-
-*  Start location at (0f, 0f, 10f).
-*  Start direction is looking at the origin.
-
-[cols="2", options="header"]
-|===
-
-a|Method
-a|Usage
-
-a|cam.getLocation(), setLocation()
-a|The camera position
-
-a|cam.getRotation(), setRotation()
-a|The camera rotation
-
-a|cam.getLeft(), setLeft()
-a|The left axis of the camera
-
-a|cam.getUp(), setUp()
-a|The up axis of the camera, usually Vector3f(0,1,0)
-
-a|cam.getDirection()
-a|The vector the camera is facing
-
-a|cam.getAxes(), setAxes(left,up,dir)
-a|One accessor for the three properties left/up/direction.
-
-a|cam.getFrame(), setFrame(loc,left,up,dir)
-a|One accessor for the four properties location/left/up/direction.
-
-a|cam.resize(width, height, fixAspect)
-a|Resize an existing camera object while keeping all other settings. Set fixAspect to true to adjust the aspect ratio (?)
-
-a|cam.setFrustum( near, far, left, right, top, bottom )
-a|The frustum is defined by the near/far plane, left/right plane, top/bottom plane (all distances as float values)
-
-a|cam.setFrustumPerspective( fovY, aspect ratio, near, far)
-a|The frustum is defined by view angle along the Y axis (in degrees), aspect ratio, and the near/far plane.
-
-a|cam.lookAt(target,up)
-a|Turn the camera to look at Coordinate target, and rotate it around the up axis.
-
-a|cam.setParallelProjection(false)
-a|Normal perspective
-
-a|cam.setParallelProjection(true)
-a|Parallel projection perspective
-
-a|cam.getScreenCoordinates()
-a|?
-
-|===
-
-[TIP]
-====
-After you change view port, frustum, or frame, call `cam.update();`
-====
-
-
-== FlyBy Camera
-
-The `flyCam` class field gives you access to an AppState that extends the default camera in `com.jme3.app.SimpleApplication` with more features. The input manager of the `com.jme3.input.FlyByCamera` AppState is preconfigured to respond to the WASD keys for walking forwards and backwards, and strafing to the sides; move the mouse to rotate the camera (“Mouse Look), scroll the mouse wheel for zooming in or out. The QZ keys raise or lower the camera vertically.
-
-[source]
-----
-
-Q  W             up   forw
-A  S  D    -->  left  back  right 
-Z               down  
-
-----
-[cols="2", options="header"]
-|===
-
-a|Method
-a|Usage
-
-a|flyCam.setEnabled(true);
-a|Activate the flyby cam
-
-a|flyCam.setMoveSpeed(10);
-a|Control the move speed
-
-a|flyCam.setRotationSpeed(10);
-a|Control the rotation speed
-
-a|flyCam.setDragToRotate(true)
-a|Forces the player to keep mouse button pressed to rotate camera, typically used for Applets. If false (default), all mouse movement will be captured and interpreted as rotations.
-
-|===
-
-The FlyByCamera is active by default, but you can change all these defaults for your game.
-
-
-== Chase Camera
-
-jME3 also supports an optional Chase Cam that can follow a moving target Spatial (`com.jme3.input.ChaseCamera`). When you use the chase cam, the player clicks and hold the mouse button to rotate the camera around the camera target. You can use a chase cam if you need the mouse pointer visible in your game.
-
-[source,java]
-----
-
-flyCam.setEnabled(false);
-ChaseCamera chaseCam = new ChaseCamera(cam, target, inputManager);
-
-----
-[cols="2", options="header"]
-|===
-
-a|Method
-a|Usage
-
-a|chaseCam.setSmoothMotion(true);
-a|Interpolates a smoother acceleration/deceleration when the camera moves.
-
-a|chaseCam.setChasingSensitivity(5f)
-a|The lower the chasing sensitivity, the slower the camera will follow the target when it moves.
-
-a|chaseCam.setTrailingSensitivity(0.5f)
-a|The lower the traling sensitivity, the slower the camera will begin to go after the target when it moves. Default is 0.5;
-
-a|chaseCam.setRotationSensitivity(5f)
-a|The lower the sensitivity, the slower the camera will rotate around the target when the mosue is dragged. Default is 5.
-
-a|chaseCam.setTrailingRotationInertia(0.1f)
-a|This prevents the camera to stop too abruptly when the target stops rotating before the camera has reached the target's trailing position. Default is 0.1f.
-
-a|chaseCam.setDefaultDistance(40);
-a|The default distance to the target at the start of the application.
-
-a|chaseCam.setMaxDistance(40);
-a|The maximum zoom distance. Default is 40f.
-
-a|chaseCam.setMinDistance(1);
-a|The minimum zoom distance. Default is 1f.
-
-a|chaseCam.setMinVerticalRotation(-FastMath.PI/2);
-a|The minimal vertical rotation angle of the camera around the target. Default is 0.
-
-a|chaseCam.setDefaultVerticalRotation(-FastMath.PI/2);
-a|The default vertical rotation angle of the camera around the target at the start of the application.
-
-a|chaseCam.setDefaultHorizontalRotation(-FastMath.PI/2);
-a|The default horizontal rotation angle of the camera around the target at the start of the application.
-
-|===

+ 0 - 361
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/graphics_pipeline/custom_meshes.adoc

@@ -1,361 +0,0 @@
-= Custom Mesh Shapes
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:keywords: spatial, node, mesh, geometry, scenegraph
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-image::jme3/advanced/custom_mesh.png[custom_mesh.png,width="150",height="150",align="left"]
-
-Use the Mesh class to create custom shapes that go beyond Quad, Box, Cylinder, and Sphere, even procedural shapes are possible. Thank you to KayTrance for providing the sample code!
-
-[NOTE]
-====
-In this tutorial, we (re)create a very simple rectangular mesh (a quad), and we have a look at different ways of coloring it. Coding a custom quad may not be very useful because it's exactly the same as the built-in `com.jme3.scene.shape.Quad`. We chose a simple quad to teach you how to build any shape out of triangles, without the distractions of more complex shapes.
-====
-
-*  Full code sample: link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/model/shape/TestCustomMesh.java[TestCustomMesh.java]
-
-
-== Polygon Meshes
-
-Polygon <<jme3/advanced/mesh#,mesh>>es are made up of triangles. The corners of the triangles are called vertices. When ever you create any new shape, you break it down into triangles.
-
-*Example:* Let's look at a cube. A cube is made up of 6 rectangles. Each rectangle can be broken down into two triangles. This means you need 12 triangles to describe a cube mesh. Therefor you must provide the coordinates of the triangles' 8 corners (called vertices).
-
-The important thing is that you have to specify the vertices of each triangle in the right order: Each triangle separately, counter-clockwise.
-
-Sounds harder than it is – let's create a simple custom mesh, a quad.
-
-
-== Creating a Quad Mesh
-
-In this tutorial we want to create a 3x3 Quad. The quad has four vertices, and is made up of two triangles. In our example, we decide that the bottom left corner is at 0/0/0 and the top right is at 3/3/0.
-
-[source]
-----
-0,3,0--3,3,0
-| \        |
-|   \      |
-|     \    |
-|       \  |
-|         \|
-0,0,0--3,0,0
-----
-
-
-=== The Mesh Object
-
-The base class for creating meshes is `com.jme3.scene.Mesh`.
-
-[source,java]
-----
-Mesh mesh = new Mesh();
-----
-
-[TIP]
-====
-If you create your own Mesh-based class (`public class MyMesh extends Mesh {  }`), replace the variable `mesh` by `this` in the following examples.
-====
-
-
-=== Vertex Coordinates
-
-To define your own shape, determine the shape's *vertex coordinates* in 3D space. Store the list of corner positions in an `com.jme3.math.Vector3f` array. For a Quad, we need four vertices: Bottom left, bottom right, top left, top right. We name the array `vertices[]`.
-
-[source,java]
-----
-
-Vector3f [] vertices = new Vector3f[4];
-vertices[0] = new Vector3f(0,0,0);
-vertices[1] = new Vector3f(3,0,0);
-vertices[2] = new Vector3f(0,3,0);
-vertices[3] = new Vector3f(3,3,0);
-
-----
-
-
-=== Texture Coordinates
-
-Next, we define the Quad's 2D *texture coordinates* for each vertex, in the same order as the vertices: Bottom left, bottom right, top left, top right. We name this Vector2f array `texCoord[]`
-
-[source,java]
-----
-
-Vector2f[] texCoord = new Vector2f[4];
-texCoord[0] = new Vector2f(0,0);
-texCoord[1] = new Vector2f(1,0);
-texCoord[2] = new Vector2f(0,1);
-texCoord[3] = new Vector2f(1,1);
-
-----
-
-This syntax means, when you apply a texture to this mesh, the texture will fill the quad from corner to corner at 100% percent size. Especially when you stitch together a larger mesh, you use this to tell the renderer whether, and how exactly, you want to cover the whole mesh. E.g. if you use .5f or 2f as texture coordinates instead of 1f, textures will be stretched or shrunk accordingly.
-
-
-=== Connecting the Dots
-
-Next we turn these unrelated coordinates into *triangles*: We define the order in which each triangle is constructed. Think of these indexes as coming in groups of three. Each group of indexes describes one triangle. If the corners are identical, you can (and should!) reuse an index for several triangles.
-
-Remember that you must specify the vertices counter-clockwise.
-
-[source,java]
-----
-
-int [] indexes = { 2,0,1, 1,3,2 };
-
-----
-
-This syntax means:
-
-*  The indices 0,1,2,3 stand for the four vertices that you specified for the quad in `vertices[]`.
-*  The 2,0,1 triangle starts at top left, continues bottom left, and ends at bottom right.
-*  The 1,3,2 triangle start at bottom right, continues top right, and ends at top left.
-
-[source]
-----
-
-2\2--3
-| \  | Counter-clockwise
-|  \ |
-0--1\1
-
-----
-
-If the shape is more complex, it has more triangles, and therefor also more vertices/indices. Just continue expanding the list by adding groups of three indices for each triangle. (For example a three-triangle “house shape has 5 vertices/indices and you'd specify three groups: `int [] indexes = { 2,0,1, 1,3,2, 2,3,4 };`.)
-
-
-[TIP]
-====
-If you get the order wrong (clockwise) for some of the triangles, then these triangles face backwards. If the <<jme3/advanced/spatial#,Spatial>>'s material uses the default `FaceCullMode.Back` (see “face culling), the broken triangles appear as holes in the rendered mesh. You need to identify and fix them in your code.
-====
-
-
-
-=== Setting the Mesh Buffer
-
-You store the Mesh data in a buffer.
-
-.  Using `com.jme3.util.BufferUtils`, we create three buffers for the three types of information we have:
-**  vertex coordinates,
-**  texture coordinates,
-**  indices.
-
-.  We assign the data to the appropriate type of buffer inside the `Mesh` object. The three buffer types (`Position`, `TextCoord`, `Index`) are taken from an enum in `com.jme3.scene.VertexBuffer.Type`.
-.  The integer parameter describes the number of components of the values. Vertex postions are 3 float values, texture coordinates are 2 float values, and the indices are 3 ints representing 3 vertices in a triangle.
-.  To render the mesh in the scene, we need to pre-calculate the bounding volume of our new mesh: Call the `updateBound()` method on it.
-
-[source,java]
-----
-
-mesh.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
-mesh.setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoord));
-mesh.setBuffer(Type.Index,    3, BufferUtils.createIntBuffer(indexes));
-mesh.updateBound();
-
-----
-
-Our Mesh is ready! Now we want to see it.
-
-
-== Using the Mesh in a Scene
-
-We create a `com.jme3.scene.Geometry` and `com.jme3.material.Material` from our `mesh`, apply a simple color material to it, and attach it to the rootNode to make it appear in the scene.
-
-[source,java]
-----
-
-Geometry geo = new Geometry("OurMesh", mesh); // using our custom mesh object
-Material mat = new Material(assetManager,
-    "Common/MatDefs/Misc/Unshaded.j3md");
-mat.setColor("Color", ColorRGBA.Blue);
-geo.setMaterial(mat);
-rootNode.attachChild(geo);
-
-----
-
-Library for assetManager?
-Ta-daa!
-
-
-== Using a Quad instead
-
-We created a quad Mesh it can be replace by a Quad such as :
-
-[source,java]
-----
-
-Quad quad = new Quad(1,1); // replace the definition of Vertex and Textures Coordinates plus indexes
-Geometry geo = new Geometry("OurQuad", quad); // using Quad object
-Material mat = new Material(assetManager,
-    "Common/MatDefs/Misc/Unshaded.j3md");
-mat.setColor("Color", ColorRGBA.Blue);
-geo.setMaterial(mat);
-rootNode.attachChild(geo);
-
-----
-
-If you want to change the Textures Coordinates, in order to change the scale of the texture, use :
-
-[source,java]
-----
-
-Quad quad = new Quad(1,1);
-quad.scaleTextureCoordinates(new Vector2f(width , height));
-
-----
-
-
-== Dynamic Meshes
-
-If you are modifying a mesh dynamically in a way which changes the model's bounds, you need to update it:
-
-.  Call `updateBound()` on the mesh object, or
-.  Call `updateModelBound()` on the Geometry object containing the mesh - which in turns calls `updateBound()` on the mesh.
-
-The updateModelBound() method warns you about not usually needing to use it, but that can be ignored in this special case.
-
-__N.B.: This does not work on TerrainQuad.  Please use the TerrainQuad.adjustHeight() function to edit the TerrainQuad mesh instead.  Additionally, if you want to use collisions on them afterwards, you need to call TerrainPatch.getMesh().createCollisionData(); to update the collision data, else it will collide with what seems to be the old mesh.__
-
-
-== Optional Mesh Features
-
-There are more vertex buffers in a Mesh than the three shown above. For an overview, see also <<jme3/advanced/mesh#,mesh>>.
-
-
-=== Example: Vertex Colors
-
-Vertex coloring is a simple way of coloring meshes. Instead of just assigning one solid color, each vertex (corner) has a color assigned. The faces between the vertices are then colored with a gradient. For this demo, you can use the same mesh `mesh` object that you defined above.
-
-[source,java]
-----
-Geometry geo = new Geometry ("ColoredMesh", mesh); // using the custom mesh
-Material matVC = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-matVC.setBoolean("VertexColor", true);
-----
-
-You create a float array color buffer:
-
-*  Assign 4 color values, RGBA, to each vertex.
-**  To loop over the 4 color values, use a color index
-[source,java]
-----
-int colorIndex = 0;
-----
-
-
-*  The color buffer contains four color values for each vertex.
-**  The Quad in this example has 4 vertices.
-[source,java]
-----
-float[] colorArray = new float[4*4];
-
-----
-
-**  Tip: If your mesh has a different number of vertices, you would write:
-[source,java]
-----
-float[] colorArray = new float[yourVertexCount * 4]
-----
-
-
-
-Loop over the colorArray buffer to quickly set some RGBA value for each vertex. As usual, RGBA color values range from 0.0f to 1.0f. *Note that the color values in this example are arbitrarily chosen.* It's just a quick loop to give every vertex a different RGBA value (a purplish gray, purple, a greenish gray, green, see screenshot), without writing too much code. For your own mesh, you'd assign meaningful values for the color buffer depending on which color you want your mesh to have.
-
-[source,java]
-----
-
-// note: the red and green values are arbitray in this example
-for(int i = 0; i < 4; i++){
-   // Red value (is increased by .2 on each next vertex here)
-   colorArray[colorIndex++]= 0.1f+(.2f*i);
-   // Green value (is reduced by .2 on each next vertex)
-   colorArray[colorIndex++]= 0.9f-(0.2f*i);
-   // Blue value (remains the same in our case)
-   colorArray[colorIndex++]= 0.5f;
-   // Alpha value (no transparency set here)
-   colorArray[colorIndex++]= 1.0f;
-}
-----
-
-Next, set the color buffer. An RGBA color value contains four float components, thus the parameter `4`.
-
-[source,java]
-----
-mesh.setBuffer(Type.Color, 4, colorArray);
-geo.setMaterial(matVC);
-
-----
-
-When you run this code, you see a gradient color extending from each vertex.
-
-
-=== Example: Using Meshes With Lighting.j3md
-
-The previous examples used the mesh together with the `Unshaded.j3md` material. If you want to use the mesh with a Phong illuminated material (such as `Lighting.j3md`), the mesh must include information about its Normals. (Normal Vectors encode in which direction a mesh polygon is facing, which is important for calculating light and shadow!)
-
-[source,java]
-----
-
-float[] normals = new float[12];
-normals = new float[]{0,0,1, 0,0,1, 0,0,1, 0,0,1};
-mesh.setBuffer(Type.Normal, 3, BufferUtils.createFloatBuffer(normals));
-
-----
-
-You need to specify as many normals as the polygon has vertices. For a flat quad, the four normals point in the same direction. In this case, the direction is the Z unit vector (0,0,1), this means our quad is facing the camera.
-
-If the mesh is more complex or rounded, calculate cross products of neighbouring vertices to identify normal vectors!
-
-
-=== Example: Point Mode
-
-Additionally to coloring the faces as just described, you can hide the faces and show only the vertices as colored corner points.
-
-[source,java]
-----
-Geometry coloredMesh = new Geometry ("ColoredMesh", cMesh);
-...
-mesh.setMode(Mesh.Mode.Points);
-mesh.updateBound();
-mesh.setStatic();
-Geometry points = new Geometry("Points", mesh);
-points.setMaterial(mat);
-rootNode.attachChild(points);
-rootNode.attachChild(geo);
-
-----
-
-This will result in a 10 px dot being rendered for each of the four vertices. The dot has the vertex color you specified above. The Quad's faces are not rendered at all in this mode. You can use this to visualize a special debugging or editing mode in your game.
-
-
-== Debugging Tip: Culling
-
-By default, jME3 optimizes a mesh by “backface culling, this means not drawing the inside. It determines the side of a triangle by the order of the vertices: The frontface is the face where the vertices are specified counter-clockwise.
-
-This means for you that, by default, your custom mesh is invisible when seen from “behind or from the inside. This may not be a problem, typically this is even intended, because it's faster. The player will not look at the inside of most things anyway. For example, if your custom mesh is a closed polyhedron, or a flat wallpaper-like object, then rendering the backfaces (the inside of the pillar, the back of the painting, etc) would indeed be a waste of resources.
-
-In case however that your usecase requires the backfaces be visible, you have two options:
-
-*  If you have a very simple scene, you can simply deactivate backface culling for this one mesh's material.
-[source]
-----
-mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);
-----
-
-*  Another solution for truly double-sided meshes is to specify each triangle twice, the second time with the opposite order of vertices. The second (reversed) triangle is a second frontface that covers up the culled backface.
-[source]
-----
-int[] indexes = { 2,0,1, 1,3,2, 2,3,1, 1,0,2 };
-----
-
-'''
-
-See also:
-
-*  <<jme3/advanced/spatial#,Spatial>> – contains more info about how to debug custom meshes (that do not render as expected) by changing the default culling behaviour.
-*  <<jme3/advanced/mesh#,Mesh>> – more details about advanced Mesh properties

+ 0 - 29
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/graphics_pipeline/jme3_renderbuckets.adoc

@@ -1,29 +0,0 @@
-= Render Buckets
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-For each viewport the rendering happens as follows:
-
-*  For each processor call preFrame
-*  Dispatch each geometry in a corresponding renderQueue (one for each Bucket) and build shadow queues
-*  For each processor call postQueues
-*  Rendering OpaqueBucket with object sorted front to back. (In order to minimize overdraw)
-*  Rendering SkyBucket with depth forced to 1.0. this means every object of this bucket will be far away and behind everything
-*  Rendering TransparentBucket with object sorted back to front. (So transparent objects can be seen correctly through each other)
-*  For each processor call postFrame
-*  Rendering TranslucentBucket with objects sorted back to front
-
-The translucent bucket is rendered at the end. That’s where you put transparent object that you don’t want to be affected by post processing ( shadows or what ever). Self-light-emitting particle emitters (such as a fire) are a good example.
-
-Post processors are not applied to this bucket with one exception : the FilterPostProcessor.
-
-The filter post processor hijacks the rendering process and renders a full screen quad with the texture of the scene applied on it.
-
-Once it’s done the depth buffer is 0, so it’s impossible to render a queue over it with proper depth test so if you use a FilterPostProcessor you have to add at the end of your filter stack the TranslucentBucketFilter. It will handle the translucent bucket rendering instead of the RenderManager. (Of course the correct depth information is passed to the filter).
-
-The nice side effect of this is that if you want to apply a post filter to your translucent bucket (like bloom for example) you can just push up the translucent bucket filter in the filter stack.

+ 0 - 213
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/graphics_pipeline/jme3_srgbpipeline.adoc

@@ -1,213 +0,0 @@
-= Gamma Correction or sRGB pipeline
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== Overview
-
-Here is a quick overview of what lies under the “Gamma Correction term. +
-More in depth rundowns on the matter can be found here : link:http://http.developer.nvidia.com/GPUGems3/gpugems3_ch24.html[http://http.developer.nvidia.com/GPUGems3/gpugems3_ch24.html] and here link:http://www.arcsynthesis.org/gltut/Texturing/Tutorial%2016.html[http://www.arcsynthesis.org/gltut/Texturing/Tutorial%2016.html]
-
-We consider color values to be linear when computing lighting. What does that means? That means that we assume that the color 0.5,0.5,0.5 is half way between black and white. +
-The problem is that it’s not the case, or at least not when you look at the color through a monitor. +
-CRT monitors had physical limitations that prevented them to have a linear way of representing colors. that means that 0.5,0.5,0.5 through a monitor is not half way between black and white (it’s darker). Note that black and white remains the same though. +
-If we do not take that into account, the rendered images are overly darken and feels dull. +
-LCD monitors still mimic this physical limitation (I guess for backward compatibility). +
-*Output correct colors* +
-Gamma Correction is the technique that tends to correct the issue. Gamma is an power factor applied to the color by the monitor when lighting a pixel on screen (or at least a simplification of the function applied). So when we output the color, we have to apply the inverse power of this factor to nullify the effect : finalColor = pow(computedColor, 1/gamma); +
-
-*Knowing what colors we have as input* +
-The other aspect of gamma correction is the colors we get as input in the rendering process that are stored in textures or in ColorRGBA material params. Almost all image editors are storing color data in images already gamma corrected (so that colors are correct when you display the picture in a viewer of in a browser). Also most hand picked colors (in a color picker) can be assumed as gamma corrected as you most probably chose this color through a monitor display.
-Such images or color are said to be in sRGB color space, meaning “standard RGB” (which is not the standard one would guess).
-That means that textures and colors that we use as input in our shaders are not in a linear space. The issue is that we need them in linear space when we compute the lighting, else the lighting is wrong.
-To avoid this we need to apply some gamma correction to the colors : (pow(color, gamma);
-This only apply to textures that will render colors on screen (basically diffuse map, specular, light maps). Normal maps, height maps don’t need the correction.
-
-This is the kind of difference you can have : +
-left is non corrected output, right is gamma corrected output. +
-image:http://i.imgur.com/uNL7vw8.png[uNL7vw8.png,width="",height=""]
-
-
-
-=== Implementation
-
-*  To handle proper gamma corrected ouput colors, Opengl expose an ARB extension that allows you to output a color in linear space and have the GPU automatically correct it : link:https://www.opengl.org/registry/specs/ARB/framebuffer_sRGB.txt[https://www.opengl.org/registry/specs/ARB/framebuffer_sRGB.txt]
-*  To handle the input, instead of classic RGBA8 image format, one can use SRGB8_ALPHA8_EXT which is basically RGBA in sRGB. Using this you specify the GPU that the texture is in sRGB space and when fetching  a color from it, the GPU will linearize the color value for you (for free). There are sRGB equivalent to all 8 bits formats (even compressed format like DXT).
-*  But all textures don't need this. For example, normal maps, height maps colors are most probably generated and not hand picked by an artist looking through a monitor. The implementation needs to account for it and expose a way to exclude some textures from the sRGB pipeline.
-
-Gamma Correction in jME 3.0 is based on those three statements.
-
-[IMPORTANT]
-====
-Note that Gamma Correction is only available on desktop with LWJGL or JOGL renderer. They are not yet supported on Android or iOS renderers.
-====
-
-
-
-==== Turning Gamma Correction on/off
-
-You can turn Gamma Correction on and off using the AppSettings. There is a method setGammaCorrection(boolean) that changes the setting.
-use this in the main() method of your application :
-
-[source,java]
-----
-
-AppSettings settings = new AppSettings(true);
-settings.setGammaCorrection(true);
-app.setSettings(settings);
-
-----
-
-This setting is also exposed in the Settings dialog displayed when you launch a jME application. +
-image:http://i.imgur.com/Lya1ldH.png[Lya1ldH.png,width="400",height=""]
-
-
-[IMPORTANT]
-====
-This is a short hand to enable both linearization of input textures and Gamma correction of the rendered output on screen. +
-*Both can be enabled separately*.
-
-====
-
-
-
-===== Enabling output Gamma Correction
-
-You can enable or disable the Gamma correction of the rendered output by using:
-
-[source,java]
-----
-renderer.setMainFrameBufferSrgb(boolean srgb)
-----
-
-This will be ignored if the hardware doesn't have the GL_ARB_framebuffer_sRGB or the GL_EXT_texture_sRGB.
-This can be toggled at run time.
-
-This uses Opengl hardware gamma correction that uses an approximated Gamma value of 2.2 and uses the following formula : color = pow(color,1/gamma) 
-
-[NOTE]
-====
-This will not yield exact results, as the real gamma can vary depending on the monitor. +
-If this is a problem, please refer to the “handling gamma correction in a post process section.
-====
-
-
-===== Enabling texture linearization
-
-You can enable or disable texture linearization by using
-
-[source,java]
-----
-renderer.setLinearizeSrgbImages(boolean linearize)
-----
-
-This will be ignored if the hardware doesn't have the GL_ARB_framebuffer_sRGB or the GL_EXT_texture_sRGB.
-
-[IMPORTANT]
-====
-Toggling this setting at runtime will produce unexpected behavior for now. A change in this setting would need a proper reload of the context to work.
-====
-
-
-All images marked as in sRGB color space will be uploaded to the GPU using a sRGB image format.
-Opengl hardware texture linearization also uses an approximated Gamma value of 2.2 and linearize the fetched texel color using the following formula : color = pow(color, gamma) +
-As with output gamma correction this will not give exact result, but the error is less important since most image editor uses the same approximation to correct images and save them in sRGB color space.
-
-Not all image format have their sRGB equivalent, and only 8bit formats.
-Here is an exhaustive list of the supported format and there equivalent :
-
-*  RGB8 : GL_SRGB8
-*  RGBA8 : GL_SRGB8_ALPHA8
-*  BGR8 : GL_SRGB8
-*  ABGR8 : GL_SRGB8_ALPHA8
-*  Luminance8 : GL_SLUMINANCE8
-*  Luminance8Alpha8 : GL_SLUMINANCE8_ALPHA8
-*  DXT1 : GL_COMPRESSED_SRGB_S3TC_DXT1
-*  DXT1A : GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1
-*  DXT3 : GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3
-*  DXT5 : GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5
-
-
-[IMPORTANT]
-====
-Conventionally only the rgb channels are gamma corrected, as the alpha channel does not a represent a color value
-====
-
-
-
-==== Excluding images from the sRGB pipeline
-
-
-[IMPORTANT]
-====
-Only loaded images will be marked as in sRGB color space, when using assetManager.loadTexture or loadAsset. +
-The color space of an image created by code will have to be specified in the constructor or will be assumed as Linear if not specified.
-====
-
-
-Not all images need to be linearized. Some images don't represent color information that will be displayed on screen, but more different sort of data packed in a texture. +
-The best example is a Normal map that will contains normal vectors for each pixel. Height maps will contain elevation values. These textures must not be linearized.
-
-There is no way to determine the real color space of an image when loading it, so we must deduce the color space from the usage it's loaded for. The usage is dictated by the material, those textures are used for, and by the material parameter they are assigned to.
-One can now specify in a material definition file (j3md) if a texture parameter must be assumed as in linear color space, and thus, must not be linearized, by using the keyword -LINEAR next to the parameter (case does not matter).
-
-For example here is how the NormalMap parameter is declared in the lighting material definition.
-
-[source]
-----
-
- // Normal map
- Texture2D NormalMap -LINEAR
-
-----
-
-When a texture is assigned to this material param by using material.setTexture(“NormalMap, myNormalTexture), the color space of this texture's image will be forced to linear. So if you make your own material and want to use Gamma Correction, make sure you properly mark your textures as in the proper color space.
-
-This can sound complicated, but you just have to answer this question :  Does my image represent color data? if the answer is no, then you have to set the -Linear flag.
-
-
-==== ColorRGBA as sRGB
-
-
-[IMPORTANT]
-====
-The r, g, b attributes of a ColorRGBA object are *ALWAYS* assumed in Linear color space.
-
-====
-
-
-If you want to set a color that you hand picked in a color picker, you should use the setAsSRGB method of ColorRGBA. This will convert the given values to linear color space by using the same formula as before : color = pow (color, gamma) where gamma = 2.2;
-
-If you want to retrieve those values from a ColorRGBA, you can call the getAsSRGB method. The values will be converted back to sRGB color Space.
-
-[NOTE]
-====
-The return type of that method is a Vector4f and not a ColorRGBA, because as stated before, all ColorRGBA objects r,g,b attributes are assumed in Linear color space.
-====
-
-
-==== Handling rendered output Gamma Correction with a post process filter
-
-As stated before, the hardware gamma correction uses and approximated gamma value of 2.2.
-Some may not be satisfied with that approximations and may want to pick a more appropriate gamma value.
-You can see in some games some Gamma calibration screens, that are here to help the player pick a correct gamma value for the monitor he's using.
-
-For this particular case, you can do as follow :
-
-.  Enable Gamma Correction global app setting.
-.  Disable rendered output correction : renderer.setMainFrameBufferSrgb(false); (for example in the simpleInit method of your SimpleApplication).
-.  Use the GammaCorrectionFilter in a FilterPostProcessor, and set the proper gamma value on it (default is 2.2).
-
-
-=== Should you use this?
-
-Yes. Mostly because it's the only way to have proper lighting.
-If you're starting a new project it's a no brainer…use it, period. And don't allow the player to turn it off.
-
-Now if you already spent time to adjust lighting in your scenes, without gamma correction, turning it on will make everything too bright, and you'll have to adjust all your lighting and colors again.
-That's why we kept a way to turn it off, for backward compatibility.

+ 0 - 219
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/graphics_pipeline/multiple_camera_views.adoc

@@ -1,219 +0,0 @@
-= Multiple Camera Views
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: camera, documentation
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-You can split the screen and look into the 3D scene from different camera angles at the same time. E.g. you can have two rootnodes with different scene graphs, and two viewPorts, each of which can only see its own subset of the scene with its own subset of port-processing filters, so you get two very different views of the scene.
-
-The packages used in this example are `com.jme3.renderer.Camera` and `com.jme3.renderer.ViewPort`. You can get the full sample code here: link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/renderer/TestMultiViews.java[TestMultiViews.java]
-
-
-== How to resize and Position ViewPorts
-
-The default viewPort is as big as the window. If you have several, they must be of different sizes, either overlapping or adjacent to one another. How do you tell jME which of the ViewPorts should appear where on the screen, and how big they should be?
-
-Imagine the window as a 1.0f x 1.0f rectangle. The default cam's viewPort is set to 
-
-[source,java]
-----
-cam.setViewPort(0f, 1f, 0f, 1f);
-----
-
-This setting makes the ViewPort take up the whole rectangle. 
-
-The four values are read in the following order: 
-
-[source,java]
-----
-cam.setViewPort(x1,x2 , y1,y2);
-----
-
-*  *X-axis* from left to right
-*  *Y-axis* upwards from bottom to top
-
-Here are a few examples:
-
-[source,java]
-----
-
-cam1.setViewPort( 0.0f , 1.0f   ,   0.0f , 1.0f );
-cam2.setViewPort( 0.5f , 1.0f   ,   0.0f , 0.5f );
-
-----
-
-These viewport parameters are, (in this order) the left-right extend, and the bottom-top extend of a views's rectangle on the screen. 
-
-[source]
-----
-
-0.0 , 1.0       1.0 , 1.0
-       +-----+-----+
-       |cam1       |
-       |           |
-       |     +-----+
-       |     |     |
-       |     |cam2 |
-       +-----+-----+
-0.0 , 0.0       1.0 , 0.0
-----
-
-Example: Cam2's rectangle is in the bottom right: It extends from mid (x1=0.5f) bottom (y1=0.0f), to right (x2=1.0f) mid (y2=0.5f)
-
-
-[IMPORTANT]
-====
-If you scale the views in a way so that the aspect ratio of a ViewPort is different than the window's aspect ratio, then the ViewPort appears distorted. In these cases, you must recreate (not clone) the ViewPort's cam object with the right aspect ratio. For example: `Camera cam5 = new Camera(100,100);` 
-====
-
-
-
-== Four-Time Split Screen
-
-In this example, you create four views (2x2) with the same aspect ratio as the window, but each is only half the width and height. 
-
-
-=== Set up the First View
-
-You use the preconfigured Camera `cam` and `viewPort` from `SimpleApplication` for the first view. It's in the bottom right.
-
-[source,java]
-----
-
-cam.setViewPort(.5f, 1f, 0f, 0.5f); // Resize the viewPort to half its size, bottom right.
-
-----
-
-Optionally, place the main camera in the scene and rotate it in its start position. 
-
-[source,java]
-----
-cam.setLocation(new Vector3f(3.32f, 4.48f, 4.28f));
-cam.setRotation(new Quaternion (-0.07f, 0.92f, -0.25f, -0.27f));
-
-----
-
-
-=== Set Up Three More Views
-
-Here is the outline for how you create the three other cams and viewPorts (link:http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/renderer/TestMultiViews.java[Full code sample is here].) In the code snippet, `cam_n` stand for `cam_2` - `cam_4`, respectively, same for `view_n`.
-
-.  Clone the first cam to reuse its settings
-.  Resize and position the cam's viewPort with setViewPort().
-.  (Optionally) Move the cameras in the scene and rotate them so they face what you want to see.
-.  Create a ViewPort for each camera
-.  Reset the camera's enabled statuses
-.  Attach the Node to be displayed to this ViewPort. +The camera doesn't have to look at the rootNode, but that is the most common use case.
-
-Here is the abstract code sample for camera `n`:
-
-[source,java]
-----
-
-Camera cam_n    = cam.clone();
-cam_n.setViewPort(...); // resize the viewPort
-cam_n.setLocation(new Vector3f(...));
-cam_n.setRotation(new Quaternion(...));
-        
-ViewPort view_n = renderManager.createMainView("View of camera #n", cam_n);
-view_n.setClearEnabled(true);
-view_n.attachScene(rootNode);
-view_n.setBackgroundColor(ColorRGBA.Black);
-
-----
-
-To visualize what you do, use the following drawing of the viewport positions:
-
-[source]
-----
-
-0.0 , 1.0       1.0 , 1.0
-       +-----+-----+
-       |     |     |
-       |cam3 |cam4 |
-       +-----------+
-       |     |     |
-       |cam2 |cam1 |
-       +-----+-----+
-0.0 , 0.0       1.0 , 0.0
-----
-
-This are the lines of code that set the four cameras to create a four-times split screen.
-
-[source,java]
-----
-
-cam1.setViewPort( 0.5f , 1.0f  ,  0.0f , 0.5f);
-...
-cam2.setViewPort( 0.0f , 0.5f  ,  0.0f , 0.5f);
-...
-cam3.setViewPort( 0.0f , 0.5f  ,  0.5f , 1.0f);
-...
-cam4.setViewPort( 0.5f , 1.0f  ,  0.5f , 1.0f);
-
-----
-
-
-== Picture in Picture
-
-The following code snippet sets up two views, one covers the whole screen, and the second is a small view in the top center.
-
-[source]
-----
-
-       +-----+-----+
-       |   |cam|   |
-       |   | 2 |   |
-       +   +---+   +
-       |           |
-       |    cam    |
-       +-----+-----+
-
-----
-
-[source,java]
-----
-
-// Setup first full-window view
-cam.setViewPort(0f, 1f, 0f, 1f);
-cam.setLocation(new Vector3f(3.32f, 4.48f, 4.28f));
-cam.setRotation(new Quaternion(-0.07f, 0.92f, -0.25f, -0.27f));
-
-// Setup second, smaller PiP view
-Camera cam2 = cam.clone();
-cam2.setViewPort(.4f, .6f, 0.8f, 1f);
-cam2.setLocation(new Vector3f(-0.10f, 1.57f, 4.81f));
-cam2.setRotation(new Quaternion(0.00f, 0.99f, -0.04f, 0.02f));
-ViewPort viewPort2 = renderManager.createMainView("PiP", cam2);
-viewPort2.setClearFlags(true, true, true);
-viewPort2.attachScene(rootNode);
-
-----
-
-
-== ViewPort Settings
-
-You can customize the camera and the viewPort of each view individually. For example, each view can have a different background color:
-
-[source,java]
-----
-viewPort.setBackgroundColor(ColorRGBA.Blue);
-----
-
-You have full control to determine which Nodes the camera can see! It can see the full rootNode…
-
-[source,java]
-----
-viewPort1.attachScene(rootNode);
-----
-
-… or you can give each camera a special node whose content it can see:
-
-[source,java]
-----
-viewPort2.attachScene(spookyGhostDetectorNode);
-----

+ 0 - 7
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/graphics_pipeline/overview.adoc

@@ -1,7 +0,0 @@
-= OVERVIEW
-:author: yanmaoyuan
-:revnumber:
-:revdate: 2018/01/15 16:29
-:experimental:
-:keywords:
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]

+ 0 - 82
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/graphics_pipeline/read_graphic_card_capabilites.adoc

@@ -1,82 +0,0 @@
-= Read Graphic Card Capabilites
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-When different people test your new game, you may get feedback that the game doesn't run on their hardware, or that some details don't look as expected. You need to detect which fetaures the user's hardware supports, and offer a replacement for non-supported features on olde hardware (or deactivate them automatically).
-
-You can read (and print) the capabilities of the user's graphic card using the `com.jme3.renderer.Caps` class:
-
-[source,java]
-----
-
-Collection<Caps> caps = renderer.getCaps();
-Logger.getLogger(HelloWorld.class.getName()).log(Level.INFO, “Caps: {0}”, caps.toString());
-----
-
-[NOTE]
-====
-Replace `HelloWorld` by the name of the class where you are using this line.
-====
-
-
-== Examples
-
-A newer graphic card has modern capabilities, for example OpenGL 2.1 and NonPowerOfTwoTextures: 
-
-[source]
-----
-
-INFO: Running on jMonkeyEngine 3.0.0 
-INFO: Using LWJGL 2.8.2
-INFO: Selected display mode: 1280 x 720 x 0 @0Hz
-INFO: Adapter: null
-INFO: Driver Version: null
-INFO: Vendor: ATI Technologies Inc.
-INFO: OpenGL Version: 2.1 ATI-7.14.5
-INFO: Renderer: AMD Radeon HD 6770M OpenGL Engine
-INFO: GLSL Ver: 1.20
-INFO: Timer resolution: 1.000 ticks per second
-INFO: Capabilities: [FrameBuffer, FrameBufferMRT, FrameBufferMultisample, 
-OpenGL20, OpenGL21, ARBprogram, GLSL100, GLSL110, GLSL120, 
-VertexTextureFetch, TextureArray, FloatTexture, 
-FloatColorBuffer, FloatDepthBuffer, PackedFloatTexture, SharedExponentTexture, PackedFloatColorBuffer, 
-TextureCompressionLATC, NonPowerOfTwoTextures, MeshInstancing]
-
-----
-
-Here is an example of the capabilities of an semi-old graphic card that only supports OpenGL 2.0. If you use OpenGL 2.1 features you need to decide whether to branch to a low-quality replacement of the unsupported features (if you still want to support this card); or whether the game will not start at all and displays an error message explaining the user what capabilities his hardware is missing to be able to play the game.
-
-[source]
-----
-INFO: Running on jMonkey Engine 3 
-INFO: Using LWJGL 2.7.1
-INFO: Selected display mode: 1024 x 768 x 0 @0Hz
-INFO: Adapter: null
-INFO: Driver Version: null
-INFO: Vendor: ATI Technologies Inc.
-INFO: OpenGL Version: 2.0 ATI-1.6.36
-INFO: Renderer: ATI Radeon X1600 OpenGL Engine
-INFO: GLSL Ver: 1.20
-INFO: Timer resolution: 1.000 ticks per second
-INFO: Capabilities: [FrameBuffer, FrameBufferMRT, FrameBufferMultisample,
-OpenGL20, ARBprogram, GLSL100, GLSL110, GLSL120, 
-VertexTextureFetch, FloatTexture, 
-TextureCompressionLATC, NonPowerOfTwoTextures]
-
-----
-
-This next example is lacking `NonPowerOfTwoTextures`, this tells you that this user's graphic card cannot handle textures with sizes that are not square powers of two (such as “128x128).
-
-[source]
-----
-
-INFO: Capabilities: [FrameBuffer, FrameBufferMRT, FrameBufferMultisample, 
-OpenGL20, ARBprogram, GLSL100, GLSL110, GLSL120, 
-VertexTextureFetch, FloatTexture, TextureCompressionLATC]
-
-----

+ 0 - 173
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/hud.adoc

@@ -1,173 +0,0 @@
-= Head-Up Display (HUD)
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:keywords: gui, display, documentation, hud
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-////
-image::http://www.jmonkeyengine.com/wp-content/uploads/2010/10/grapplinghook.jpg[grapplinghook.jpg,width="256",height="192",align="right"]
-////
-
-A HUD (Head-Up Display) is part of a game's visual user interface. It's an overlay that displays additional information as (typically) 2-dimensional text or icons on the screen, on top of the 3D scene. Not all games have, or need a HUD. To avoid breaking the immersion and cluttering the screen, only use a HUD if it is the only way to convey certain information.
-
-HUDs are used to supply players with essential information about the game state.
-
-*  Status: Score, minimap, points, stealth mode, …
-*  Resources: Ammunition, lives/health, time, …
-*  Vehicle instruments: Cockpit, speedometer, …
-*  Navigational aides: Crosshairs, mouse pointer or hand, …
-
-You have multiple options how to create HUDs.
-[cols="3", options="header"]
-|===
-
-a|Option
-a|Pros
-a|Cons
-
-a|Attach elements to default guiNode:
-a|Easy to learn. jMonkeyEngine built-in +++<abbr title="Application Programming Interface">API</abbr>+++ for attaching plain images and bitmap text.
-a|Only basic features. +
-You will have to write custom controls / buttons / effects if you need them.
-
-a|Use advanced <<jme3/advanced/nifty_gui#,Nifty GUI>> integration:
-a|Full-featured interactive user interface. +
-Includes buttons, effects, controls. +Supports XML and Java layouts.
-a|Steeper learning curve.
-
-a|Use user contributed +++<abbr title="Graphical User Interface">GUI</abbr>+++ libraries such as <<jme3/contributions/tonegodgui#,tonegodgui>> or link:http://hub.jmonkeyengine.org/t/lemur-api-documentation/27209[Lemur]:
-a|Both have many features that would be difficult to do with Nifty +
-Includes buttons, effects, controls. +
-New features are still being released
-a|Are not necessarily guaranteed future updates, not as well documented
-
-|===
-
-Using the +++<abbr title="Graphical User Interface">GUI</abbr>+++ Node is the default approach in jme3 to create simple HUDs. If you just quickly want to display a line of text, or a simple icon on the screen, use the no-frills +++<abbr title="Graphical User Interface">GUI</abbr>+++ Node, it's easier.
-
-
-== Simple HUD: GUI Node
-
-You already know the `rootNode` that holds the 3-dimensional scene graph. jME3 also offers a 2-dimension (orthogonal) node, the `guiNode`.
-
-This is how you use the guiNode for HUDs:
-
-*  Create a +++<abbr title="Graphical User Interface">GUI</abbr>+++ element: a BitmapText or Picture object.
-*  Attach the element to the guiNode.
-*  Place the element in the orthogonal render queue using `setQueueBucket(Bucket.Gui)`.
-
-The BitmapTexts and Pictures appear as 2 dimensional element on the screen.
-
-
-[TIP]
-====
-By default, the guiNode has some scene graph statistics attached. To clear the guiNode before you attach your own +++<abbr title="Graphical User Interface">GUI</abbr>+++ elements, use the following methods:
-
-[source,java]
-----
-setDisplayStatView(false); setDisplayFps(false);
-----
-
-
-====
-
-
-
-=== Displaying Pictures in the HUD
-
-A simple image can be displayed using `com.jme3.ui.Picture`.
-
-[source,java]
-----
-Picture pic = new Picture("HUD Picture");
-pic.setImage(assetManager, "Textures/ColoredTex/Monkey.png", true);
-pic.setWidth(settings.getWidth()/2);
-pic.setHeight(settings.getHeight()/2);
-pic.setPosition(settings.getWidth()/4, settings.getHeight()/4);
-guiNode.attachChild(pic);
-
-----
-
-When you set the last boolean in setImage() to true, the alpha channel of your image is rendered transparent/translucent.
-
-
-=== Displaying Text in the HUD
-
-You use `com.jme3.font.BitmapText` to display text on the screen.
-
-[source,java]
-----
-
-BitmapText hudText = new BitmapText(guiFont, false);
-hudText.setSize(guiFont.getCharSet().getRenderedSize());      // font size
-hudText.setColor(ColorRGBA.Blue);                             // font color
-hudText.setText("You can write any string here");             // the text
-hudText.setLocalTranslation(300, hudText.getLineHeight(), 0); // position
-guiNode.attachChild(hudText);
-
-----
-
-The BitmapFont object `guiFont` is a default font provided by SimpleApplication. Copy you own fonts as .fnt plus .png files into the `assets/Interface/Fonts` directory and load them like this:
-
-[source]
-----
-BitmapFont myFont = assetManager.loadFont("Interface/Fonts/Console.fnt");
-hudText = new BitmapText(myFont, false);
-----
-
-
-=== Positioning HUD Elements
-
-*  When positioning +++<abbr title="Graphical User Interface">GUI</abbr>+++ text and images in 2D, the *bottom left corner* of the screen is `(0f,0f)`, and the *top right corner* is at `(settings.getWidth(),settings.getHeight())`.
-*  If you have several 2D elements in the +++<abbr title="Graphical User Interface">GUI</abbr>+++ bucket that overlap, define their depth order by specifing a Z value. For example use `pic.move(x, y, -1)` to move the picture to the background, or `hudText.setLocalTranslation(x,y,1)` to move text to the foreground.
-*  Size and length values in the orthogonal render queue are treated like pixels. A 20*20-wu big quad is rendered 20 pixels wide.
-
-
-=== Displaying Geometries in the HUD
-
-It is technically possible to attach Quads and 3D Geometries to the HUD. They show up as flat, static +++<abbr title="Graphical User Interface">GUI</abbr>+++ elements. The size unit for the guiNode is pixels, not world units. If you attach a Geometry that uses a lit Material, you must add a light to the guiNode.
-
-
-[IMPORTANT]
-====
-If you don't see an attached object in the +++<abbr title="Graphical User Interface">GUI</abbr>+++, check it's position and material (add a light to guiNode). Also verify whether it is not too tiny to be seen. For comparison: A 1 world-unit wide cube is only 1 pixel wide when attached to the guiNode! You may need to scale it bigger.
-====
-
-
-
-=== Keeping the HUD Up-To-Date
-
-Use the update loop to keep the content up-to-date.
-
-[source,java]
-----
-public void simpleUpdate(float tpf) {
-  ...
-  hudText.setText("Score: " + score);
-  ...
-  picture.setImage(assetManager, "Interface/statechange.png", true);
-  ...
-}
-----
-
-
-== Advanced HUD: Nifty GUI
-
-The recommended approach to create HUDs is using <<jme3/advanced/nifty_gui#,Nifty GUI>>.
-
-.  Lay out the +++<abbr title="Graphical User Interface">GUI</abbr>+++ in one or several Nifty XML or Java files.
-.  Write the controller classes in Java.
-.  Load the XML file with the controller object in your game's simpleInit() method.
-
-The advantage of Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ is that it is well integrated into jME and the jMonkeyEngine SDK, and that it offers all the features that you expect from a professional modern user interface.
-
-For HUDs, you basically follow the same instructions as for creating a normal <<jme3/advanced/nifty_gui#,Nifty GUI>>, you just don't pause the game while the HUD is up.
-
-
-== See also
-
-*  <<jme3/external/fonts#,Fonts>>

+ 0 - 618
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/loading_screen.adoc

@@ -1,618 +0,0 @@
-= loading_screen
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== Nifty Loading Screen (Progress Bar)
-
-//There is a good tutorial about creating a nifty progress bar here:
-//link:http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Create_your_own_Control_%28//A_Nifty_Progressbar%29[http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Create_yo//ur_own_Control_%28A_Nifty_Progressbar%29]
-
-This example will use the existing hello terrain as an example.
-It will require these 2 images inside Assets/Interface/ (save them as border.png and inner.png respectively).
-
-image:jme3/advanced/inner1.png[inner1.png,width="",height=""]
-
-image:jme3/advanced/border1.png[border1.png,width="",height=""]
-
-You need to add the jme3-niftygui and <<sdk/sample_code#jme3testdata-assets#,jme3-test-data>> libraries.
-
-You will need to set your projects source to JDK 8.
-
-This is the progress bar at 90%:
-
-image:jme3/advanced/loadingscreen.png[loadingscreen.png,width="",height=""]
-
-nifty_loading.xml
-
-[source,xml]
-----
-
-<?xml version="1.0" encoding="UTF-8"?>
-<nifty>
-    <useStyles filename="nifty-default-styles.xml" />
-    <useControls filename="nifty-default-controls.xml" />
-
-    <controlDefinition name = "loadingbar" controller = "jme3test.TestLoadingScreen">
-        <image filename="Interface/border.png" childLayout="absolute"
-               imageMode="resize:15,2,15,15,15,2,15,2,15,2,15,15">
-            <image id="progressbar" x="0" y="0" filename="Interface/inner.png" width="32px" height="100%"
-                   imageMode="resize:15,2,15,15,15,2,15,2,15,2,15,15" />
-        </image>
-    </controlDefinition>
-
-    <screen id="start" controller = "jme3test.TestLoadingScreen">
-        <layer id="layer" childLayout="center">
-            <panel id = "panel2" height="30%" width="50%" align="center" valign="center" childLayout="vertical"
-                   visibleToMouse="true">
-                <control id="startGame" name="button" backgroundColor="#0000" label="Load Game" align="center">
-                    <interact onClick="showLoadingMenu()" />
-                </control>
-            </panel>
-        </layer>
-    </screen>
-
-    <screen id="loadlevel" controller = "jme3test.TestLoadingScreen">
-        <layer id="loadinglayer" childLayout="center" backgroundColor="#000000">
-            <panel id = "loadingpanel" childLayout="vertical" align="center" valign="center" height="32px" width="70%">
-                <control name="loadingbar" align="center" valign="center" width="100%" height="100%" />
-                <control id="loadingtext" name="label" align="center"
-                         text="                                                  "/>
-            </panel>
-        </layer>
-    </screen>
-
-    <screen id="end" controller = "jme3test.TestLoadingScreen">
-    </screen>
-
-</nifty>
-
-----
-
-
-=== Understanding Nifty XML
-
-The progress bar and text is done statically using nifty XML.
-A custom control is created, which represents the progress bar.
-
-[source,xml]
-----
-
-    <controlDefinition name = "loadingbar" controller = "jme3test.TestLoadingScreen">
-        <image filename="Interface/border.png" childLayout="absolute"
-               imageMode="resize:15,2,15,15,15,2,15,2,15,2,15,15">
-            <image id="progressbar" x="0" y="0" filename="Interface/inner.png" width="32px" height="100%"
-                   imageMode="resize:15,2,15,15,15,2,15,2,15,2,15,15"/>
-        </image>
-    </controlDefinition>
-
-----
-
-This screen simply displays a button in the middle of the screen, which could be seen as a simple main menu UI.
-
-[source,xml]
-----
-
-    <screen id="start" controller = "jme3test.TestLoadingScreen">
-        <layer id="layer" childLayout="center">
-            <panel id = "panel2" height="30%" width="50%" align="center" valign="center" childLayout="vertical"
-                   visibleToMouse="true">
-                <control id="startGame" name="button" backgroundColor="#0000" label="Load Game" align="center">
-                    <interact onClick="showLoadingMenu()" />
-                </control>
-            </panel>
-        </layer>
-    </screen>
-
-----
-
-This screen displays our custom progress bar control with a text control.
-
-[source,xml]
-----
-
-    <screen id="loadlevel" controller = "jme3test.TestLoadingScreen">
-        <layer id="loadinglayer" childLayout="center" backgroundColor="#000000">
-            <panel id = "loadingpanel" childLayout="vertical" align="center" valign="center" height="32px" width="400px">
-                <control name="loadingbar" align="center" valign="center" width="400px" height="32px" />
-                <control id="loadingtext" name="label" align="center"
-                          text="                                                  "/>
-            </panel>
-        </layer>
-    </screen>
-
-----
-
-
-== Creating the bindings to use the Nifty XML
-
-There are 3 main ways to update a progress bar. To understand why these methods are necessary, an understanding of the graphics pipeline is needed.
-
-Something like this in a single thread will not work:
-
-[source,java]
-----
-
-load_scene();
-update_bar(30%);
-load_characters();
-update_bar(60%);
-load_sounds();
-update_bar(100%);
-
-----
-
-If you do all of this in a single frame, then it is sent to the graphics card only after the whole code block has executed. By this time the bar has reached 100% and the game has already begun – for the user, the progressbar on the screen would not have visibly changed.
-
-The 2 main good solutions are:
-
-.  Updating explicitly over many frames
-.  Multi-threading
-
-
-=== Updating progress bar over a number of frames
-
-The idea is to break down the loading of the game into discrete parts.
-
-[source,java]
-----
-
-package jme3test;
-
-import com.jme3.app.SimpleApplication;
-import com.jme3.material.Material;
-import com.jme3.niftygui.NiftyJmeDisplay;
-import static com.jme3.niftygui.NiftyJmeDisplay.newNiftyJmeDisplay;
-import com.jme3.renderer.Camera;
-import com.jme3.terrain.geomipmap.TerrainLodControl;
-import com.jme3.terrain.geomipmap.TerrainQuad;
-import com.jme3.terrain.heightmap.AbstractHeightMap;
-import com.jme3.terrain.heightmap.ImageBasedHeightMap;
-import com.jme3.texture.Texture;
-import com.jme3.texture.Texture.WrapMode;
-import de.lessvoid.nifty.Nifty;
-import de.lessvoid.nifty.controls.Controller;
-import de.lessvoid.nifty.controls.Parameters;
-import de.lessvoid.nifty.elements.Element;
-import de.lessvoid.nifty.elements.render.TextRenderer;
-import de.lessvoid.nifty.input.NiftyInputEvent;
-import de.lessvoid.nifty.screen.Screen;
-import de.lessvoid.nifty.screen.ScreenController;
-import de.lessvoid.nifty.tools.SizeValue;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This is the TestLoadingScreen Class of your Game. You should only do
- * initialization here. Move your Logic into AppStates or Controls
- *
- * @author normenhansen
- */
-public class TestLoadingScreen extends SimpleApplication implements
-        ScreenController, Controller {
-
-    private NiftyJmeDisplay niftyDisplay;
-    private Nifty nifty;
-    private Element progressBarElement;
-    private TerrainQuad terrain;
-    private Material mat_terrain;
-    private float frameCount = 0;
-    private boolean load = false;
-    private TextRenderer textRenderer;
-
-    public static void main(String[] args) {
-        TestLoadingScreen app = new TestLoadingScreen();
-        app.start();
-    }
-
-    @Override
-    public void simpleInitApp() {
-        flyCam.setEnabled(false);
-        niftyDisplay = newNiftyJmeDisplay(assetManager,
-                inputManager,
-                audioRenderer,
-                guiViewPort);
-        nifty = niftyDisplay.getNifty();
-
-        nifty.fromXml("Interface/nifty_loading.xml", "start", this);
-
-        guiViewPort.addProcessor(niftyDisplay);
-    }
-
-    @Override
-    public void simpleUpdate(float tpf) {
-
-        if (load) { //loading is done over many frames
-            if (frameCount == 1) {
-                Element element = nifty.getScreen("loadlevel").findElementById(
-                        "loadingtext");
-                textRenderer = element.getRenderer(TextRenderer.class);
-
-                mat_terrain = new Material(assetManager,
-                        "Common/MatDefs/Terrain/Terrain.j3md");
-                mat_terrain.setTexture("Alpha", assetManager.loadTexture(
-                        "Textures/Terrain/splat/alphamap.png"));
-                setProgress(0.2f, "Loading grass");
-
-            } else if (frameCount == 2) {
-                Texture grass = assetManager.loadTexture(
-                        "Textures/Terrain/splat/grass.jpg");
-                grass.setWrap(WrapMode.Repeat);
-                mat_terrain.setTexture("Tex1", grass);
-                mat_terrain.setFloat("Tex1Scale", 64f);
-                setProgress(0.4f, "Loading dirt");
-
-            } else if (frameCount == 3) {
-                Texture dirt = assetManager.loadTexture(
-                        "Textures/Terrain/splat/dirt.jpg");
-
-                dirt.setWrap(WrapMode.Repeat);
-                mat_terrain.setTexture("Tex2", dirt);
-                mat_terrain.setFloat("Tex2Scale", 32f);
-                setProgress(0.5f, "Loading rocks");
-
-            } else if (frameCount == 4) {
-                Texture rock = assetManager.loadTexture(
-                        "Textures/Terrain/splat/road.jpg");
-
-                rock.setWrap(WrapMode.Repeat);
-
-                mat_terrain.setTexture("Tex3", rock);
-                mat_terrain.setFloat("Tex3Scale", 128f);
-                setProgress(0.6f, "Creating terrain");
-
-            } else if (frameCount == 5) {
-                AbstractHeightMap heightmap = null;
-                Texture heightMapImage = assetManager.loadTexture(
-                        "Textures/Terrain/splat/mountains512.png");
-                heightmap = new ImageBasedHeightMap(heightMapImage.getImage());
-
-                heightmap.load();
-                terrain = new TerrainQuad("my terrain", 65, 513, heightmap.
-                        getHeightMap());
-                setProgress(0.8f, "Positioning terrain");
-
-            } else if (frameCount == 6) {
-                terrain.setMaterial(mat_terrain);
-
-                terrain.setLocalTranslation(0, -100, 0);
-                terrain.setLocalScale(2f, 1f, 2f);
-                rootNode.attachChild(terrain);
-                setProgress(0.9f, "Loading cameras");
-
-            } else if (frameCount == 7) {
-                List<Camera> cameras = new ArrayList<>();
-                cameras.add(getCamera());
-                TerrainLodControl control = new TerrainLodControl(terrain,
-                        cameras);
-                terrain.addControl(control);
-                setProgress(1f, "Loading complete");
-
-            } else if (frameCount == 8) {
-                nifty.gotoScreen("end");
-                nifty.exit();
-                guiViewPort.removeProcessor(niftyDisplay);
-                flyCam.setEnabled(true);
-                flyCam.setMoveSpeed(50);
-            }
-
-            frameCount++;
-        }
-    }
-
-    public void setProgress(final float progress, String loadingText) {
-        final int MIN_WIDTH = 32;
-        int pixelWidth = (int) (MIN_WIDTH + (progressBarElement.getParent().
-                getWidth() - MIN_WIDTH) * progress);
-        progressBarElement.setConstraintWidth(new SizeValue(pixelWidth + "px"));
-        progressBarElement.getParent().layoutElements();
-
-        textRenderer.setText(loadingText);
-    }
-
-    public void showLoadingMenu() {
-        nifty.gotoScreen("loadlevel");
-        load = true;
-    }
-
-    @Override
-    public void onStartScreen() {
-    }
-
-    @Override
-    public void onEndScreen() {
-    }
-
-    @Override
-    public void bind(Nifty nifty, Screen screen) {
-        progressBarElement = nifty.getScreen("loadlevel").findElementById(
-                "progressbar");
-    }
-
-    // methods for Controller
-    @Override
-    public boolean inputEvent(final NiftyInputEvent inputEvent) {
-        return false;
-    }
-
-    @Override
-    public void onFocus(boolean getFocus) {
-    }
-
-    @Override
-    public void bind(Nifty nifty, Screen screen, Element elmnt,
-            Parameters prmtrs) {
-        progressBarElement = elmnt.findElementById("progressbar");
-    }
-
-    @Override
-    public void init(Parameters prmtrs) {
-    }
-
-}
-
-----
-
-NOTE: Try and add all controls near the end, as their update loops may begin executing.
-
-
-=== Using multithreading
-
-For more info on multithreading: <<jme3/advanced/multithreading#,The jME3 Threading Model>>
-
-Make sure to change the XML file to point the controller to TestLoadingScreen*1*.
-
-[source,java]
-----
-
-package jme3test;
-
-import com.jme3.app.SimpleApplication;
-import com.jme3.material.Material;
-import com.jme3.niftygui.NiftyJmeDisplay;
-import static com.jme3.niftygui.NiftyJmeDisplay.newNiftyJmeDisplay;
-import com.jme3.renderer.Camera;
-import com.jme3.terrain.geomipmap.TerrainLodControl;
-import com.jme3.terrain.geomipmap.TerrainQuad;
-import com.jme3.terrain.heightmap.AbstractHeightMap;
-import com.jme3.terrain.heightmap.ImageBasedHeightMap;
-import com.jme3.texture.Texture;
-import com.jme3.texture.Texture.WrapMode;
-import de.lessvoid.nifty.Nifty;
-import de.lessvoid.nifty.controls.Controller;
-import de.lessvoid.nifty.controls.Parameters;
-import de.lessvoid.nifty.elements.Element;
-import de.lessvoid.nifty.elements.render.TextRenderer;
-import de.lessvoid.nifty.input.NiftyInputEvent;
-import de.lessvoid.nifty.screen.Screen;
-import de.lessvoid.nifty.screen.ScreenController;
-import de.lessvoid.nifty.tools.SizeValue;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public class TestLoadingScreen1 extends SimpleApplication implements
-        ScreenController, Controller {
-
-    private NiftyJmeDisplay niftyDisplay;
-    private Nifty nifty;
-    private Element progressBarElement;
-    private TerrainQuad terrain;
-    private Material mat_terrain;
-    private boolean load = false;
-    private ScheduledExecutorService exec = Executors.newScheduledThreadPool(2);
-    private Future loadFuture = null;
-    private TextRenderer textRenderer;
-    private static final Logger LOG = Logger.getLogger(TestLoadingScreen1.class.
-            getName());
-
-    public static void main(String[] args) {
-        TestLoadingScreen1 app = new TestLoadingScreen1();
-        app.start();
-    }
-
-    @Override
-    public void simpleInitApp() {
-        flyCam.setEnabled(false);
-        niftyDisplay = newNiftyJmeDisplay(assetManager,
-                inputManager,
-                audioRenderer,
-                guiViewPort);
-        nifty = niftyDisplay.getNifty();
-
-        nifty.fromXml("Interface/nifty_loading.xml", "start", this);
-
-        guiViewPort.addProcessor(niftyDisplay);
-    }
-
-    @Override
-    public void simpleUpdate(float tpf) {
-        if (load) {
-            if (loadFuture == null) {
-                //if we have not started loading, submit Callable to executor
-                loadFuture = exec.submit(loadingCallable);
-            }
-            //check if the execution on the other thread is done
-            if (loadFuture.isDone()) {
-                //these calls have to be done on the update loop thread,
-                //especially attaching the terrain to the rootNode
-                //after it is attached, it's managed by the update loop thread
-                // and may not be modified from any other thread anymore!
-                nifty.gotoScreen("end");
-                nifty.exit();
-                guiViewPort.removeProcessor(niftyDisplay);
-                flyCam.setEnabled(true);
-                flyCam.setMoveSpeed(50);
-                rootNode.attachChild(terrain);
-                load = false;
-            }
-        }
-    }
-    //This is the callable that contains the code that is run on the other
-    //thread.
-    //Since the assetmananger is threadsafe, it can be used to load data from
-    //any thread.
-    //We do *not* attach the objects to the rootNode here!
-    Callable<Void> loadingCallable = new Callable<Void>() {
-
-        @Override
-        public Void call() {
-
-            Element element = nifty.getScreen("loadlevel").findElementById(
-                    "loadingtext");
-            textRenderer = element.getRenderer(TextRenderer.class);
-
-            mat_terrain = new Material(assetManager,
-                    "Common/MatDefs/Terrain/Terrain.j3md");
-            mat_terrain.setTexture("Alpha", assetManager.loadTexture(
-                    "Textures/Terrain/splat/alphamap.png"));
-            //setProgress is thread safe (see below)
-            setProgress(0.2f, "Loading grass");
-
-            Texture grass = assetManager.loadTexture(
-                    "Textures/Terrain/splat/grass.jpg");
-            grass.setWrap(WrapMode.Repeat);
-            mat_terrain.setTexture("Tex1", grass);
-            mat_terrain.setFloat("Tex1Scale", 64f);
-            setProgress(0.4f, "Loading dirt");
-
-            Texture dirt = assetManager.loadTexture(
-                    "Textures/Terrain/splat/dirt.jpg");
-
-            dirt.setWrap(WrapMode.Repeat);
-            mat_terrain.setTexture("Tex2", dirt);
-            mat_terrain.setFloat("Tex2Scale", 32f);
-            setProgress(0.5f, "Loading rocks");
-
-            Texture rock = assetManager.loadTexture(
-                    "Textures/Terrain/splat/road.jpg");
-
-            rock.setWrap(WrapMode.Repeat);
-
-            mat_terrain.setTexture("Tex3", rock);
-            mat_terrain.setFloat("Tex3Scale", 128f);
-            setProgress(0.6f, "Creating terrain");
-
-            AbstractHeightMap heightmap = null;
-            Texture heightMapImage = assetManager.loadTexture(
-                    "Textures/Terrain/splat/mountains512.png");
-            heightmap = new ImageBasedHeightMap(heightMapImage.getImage());
-
-            heightmap.load();
-            terrain = new TerrainQuad("my terrain", 65, 513, heightmap.
-                    getHeightMap());
-            setProgress(0.8f, "Positioning terrain");
-
-            terrain.setMaterial(mat_terrain);
-
-            terrain.setLocalTranslation(0, -100, 0);
-            terrain.setLocalScale(2f, 1f, 2f);
-            setProgress(0.9f, "Loading cameras");
-
-            List<Camera> cameras = new ArrayList<>();
-            cameras.add(getCamera());
-            TerrainLodControl control = new TerrainLodControl(terrain, cameras);
-            terrain.addControl(control);
-            setProgress(1f, "Loading complete");
-
-            return null;
-        }
-    };
-
-    public void setProgress(final float progress, final String loadingText) {
-        //Since this method is called from another thread, we enqueue the
-        //changes to the progressbar to the update loop thread.
-        enqueue(() -> {
-            final int MIN_WIDTH = 32;
-            int pixelWidth = (int) (MIN_WIDTH + (progressBarElement.getParent().
-                    getWidth() - MIN_WIDTH) * progress);
-            progressBarElement.setConstraintWidth(new SizeValue(pixelWidth
-                    + "px"));
-            progressBarElement.getParent().layoutElements();
-
-            textRenderer.setText(loadingText);
-            return null;
-        });
-
-    }
-
-    public void showLoadingMenu() {
-        nifty.gotoScreen("loadlevel");
-        load = true;
-    }
-
-    @Override
-    public void onStartScreen() {
-    }
-
-    @Override
-    public void onEndScreen() {
-    }
-
-    @Override
-    public void bind(Nifty nifty, Screen screen) {
-        progressBarElement = nifty.getScreen("loadlevel").findElementById(
-                "progressbar");
-    }
-
-    // methods for Controller
-    @Override
-    public boolean inputEvent(final NiftyInputEvent inputEvent) {
-        return false;
-    }
-
-    @Override
-    public void onFocus(boolean getFocus) {
-    }
-
-    @Override
-    public void destroy() {
-        super.destroy();
-        shutdownAndAwaitTermination(exec);
-    }
-
-    //standard shutdown process for executor
-    private void shutdownAndAwaitTermination(ExecutorService pool) {
-        pool.shutdown(); // Disable new tasks from being submitted
-        try {
-            // Wait a while for existing tasks to terminate
-            if (!pool.awaitTermination(6, TimeUnit.SECONDS)) {
-                pool.shutdownNow(); // Cancel currently executing tasks
-                // Wait a while for tasks to respond to being cancelled
-                if (!pool.awaitTermination(6, TimeUnit.SECONDS)) {
-                    LOG.log(Level.SEVERE, "Pool did not terminate {0}", pool);
-                }
-            }
-        } catch (InterruptedException ie) {
-            // (Re-)Cancel if current thread also interrupted
-            pool.shutdownNow();
-            // Preserve interrupt status
-            Thread.currentThread().interrupt();
-        }
-    }
-
-    @Override
-    public void bind(Nifty nifty, Screen screen, Element elmnt,
-            Parameters prmtrs) {
-        progressBarElement = elmnt.findElementById("progressbar");
-    }
-
-    @Override
-    public void init(Parameters prmtrs) {
-    }
-
-}
-
-----

+ 0 - 113
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui.adoc

@@ -1,113 +0,0 @@
-= Creating JME3 User Interfaces with Nifty GUI
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:keywords: gui, documentation, nifty, hud
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-image::jme3/advanced/nifty-gui-13.png[nifty-gui-13.png,width="276",height="217",align="left"]
-
-
-You may want your players to press a button to save a game, you want a scrolling text field for highscores, a text label to display the score, drop-downs to select keymap preferences, or checkboxes to specify multi-media options. Usually you solve these tasks by using Swing controls. Although it is possible to embed a <<jme3/advanced/swing_canvas#,jME3 canvas>> in a Swing +++<abbr title="Graphical User Interface">GUI</abbr>+++, a 3D game typically runs full-screen, or in a window of its own.
-
-This document introduces you to link:https://github.com/nifty-gui/nifty-gui/[Nifty GUI], a Java library for building interactive graphical user interfaces (GUIs) for games or similar applications. Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ (the `de.lessvoid.nifty` package) is well integrated with jME3 through the `com.jme3.niftygui` package. You define the base +++<abbr title="Graphical User Interface">GUI</abbr>+++ layout in XML, and control it dynamically from your Java code. The necessary JAR libraries are included in your jME3 download, you do not need to install anything extra. (Just make sure they are on the classpath.)
-
-*  link:http://vimeo.com/25637085[Video demo of Nifty GUI 1.3]
-
-
-== Tutorial Overview
-
-Learn to add a Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ to your jME3 game by going through this multi-part tutorial:
-
-.  <<jme3/advanced/nifty_gui#,Understand the Nifty GUI Concepts>> described on this page.
-.  <<jme3/advanced/nifty_gui_best_practices#,Browse this short list of Best Practices>>
-.  Lay out your graphical user interface:
-**  <<jme3/advanced/nifty_gui_xml_layout#,Lay out the GUI in XML>> – or –
-**  <<jme3/advanced/nifty_gui_java_layout#,Lay out the GUI in Java>>
-
-.  Integrate the +++<abbr title="Graphical User Interface">GUI</abbr>+++ into the game:
-**  <<jme3/advanced/nifty_gui_overlay#,Overlay the User Interface Over the Screen>>  – or –
-**  <<jme3/advanced/nifty_gui_projection#,Project the User Interface Onto a Texture>>
-
-.  <<jme3/advanced/nifty_gui_java_interaction#,Interact with the GUI from Java>>
-
-
-== Must Know: Nifty GUI Concepts
-
-image:jme3/advanced/nifty-screen-layer-panel.png[nifty-screen-layer-panel.png,width="",height=""]
-
-Nifty GUIs are made up of the following *elements*:
-
-*  A Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ contains one or more *screens*.
-**  Only one screen is visible at a time.
-**  Name the first screen `start`. Name any others whatever you like.
-**  Screen are <<jme3/advanced/nifty_gui_java_interaction#,controlled by a Java Controller class>>.
-
-*  A screen contains one or more *layers*.
-**  Layers are containers that impose alignment on their contents (vertical, horizontal, or centered)
-**  Layers can overlap (z-order), and cannot be nested.
-
-*  A layer contains *panels*.
-**  Panels are containers that impose alignment on their contents (vertical, horizontal, or centered)
-**  Panels can be nested, and cannot overlap.
-
-*  A panel contains *images, text, or controls (buttons, etc)*.
-
-
-== Resources
-
-*  <<jme3/advanced/nifty_gui_best_practices#,Browse this short list of Best Practices before you start>>
-
-
-=== JME-Nifty Sample Code
-
-*  XML examples
-**  link:http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/test-data/Interface/Nifty/HelloJme.xml[HelloJme.xml]
-
-*  Java examples
-**  link:http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/niftygui/TestNiftyGui.java[TestNiftyGui.java]
-**  link:http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/niftygui/TestNiftyToMesh.java[TestNiftyToMesh.java]
-
-*  jME3-ready version of the Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ 1.3 demo (sample code, Java)
-**  link:http://files.seapegasus.org/NiftyGuiDemo.zip[NiftyGuiDemo.zip]
-
-*  Find more sample code in the link:http://nifty-gui.svn.sourceforge.net/viewvc/nifty-gui/nifty-default-controls-examples/trunk/[Nifty GUI source repository]
-
-
-=== External Documentation
-
-Learn more from the NiftyGUI page:
-
-*  link:http://sourceforge.net/projects/nifty-gui/files/nifty-gui/1.3.2/nifty-gui-the-manual-1.3.2.pdf/download[Nifty GUI - the Manual]
-*  link:http://nifty-gui.sourceforge.net/projects/1.3-SNAPSHOT/nifty/apidocs/index.html[Nifty 1.3 JavaDoc]
-*  link:http://nifty-gui.sourceforge.net/projects/1.3-SNAPSHOT/nifty-default-controls/apidocs/[Nifty 1.3 Controls JavaDoc]
-*  link:http://jmonkeyengine.org/groups/gui/forum/topic/anyone-succeeded-in-changing-text-in-nifty-programatically/#post-109510[Forum post: Changing Text in Nifty GUIs programmatically]
-*  <<jme3/advanced/nifty_gui/editor#,Official Nifty GUI Editor>>
-*  <<jme3/advanced/nifty_gui/new_editor#,New Nifty GUI Editor>>
-*  <<jme3/advanced/nifty_gui/groovy#,Nifty GUI with Groovy>>
-
-
-== Next Steps
-
-Now that you understand the concepts and know where to find more information, learn how to lay out a simple graphical user interface. Typically, you start doing this in XML.
-
-*  <<jme3/advanced/nifty_gui_xml_layout#,Lay out the GUI in XML>> (recommended)
-*  <<jme3/advanced/nifty_gui_java_layout#,Lay out the GUI in Java>> (optional)
-*  <<jme3/advanced/nifty_gui_editor#,Lay out the GUI in Editor>> (experimental)
-
-
-== Nifty Logging (Nifty 1.3.1)
-
-If you want to disable the nifty log lines, add this code after you created nifty:
-
-[source]
-----
-
-Logger.getLogger("de.lessvoid.nifty").setLevel(Level.SEVERE);
-Logger.getLogger("NiftyInputEventHandlingLog").setLevel(Level.SEVERE);
-
-----

+ 0 - 91
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui_best_practices.adoc

@@ -1,91 +0,0 @@
-= Nifty GUI - Best Practices
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-This page is a short list of best practices that you should know of when starting to use Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++. The JME3 tutorials focus on JME3-Nifty integration related details. You will find more features in the link:http://sourceforge.net/projects/nifty-gui/files/nifty-gui/nifty-gui-the-manual-v1.0.pdf/download[Nifty GUI Manual].
-
-.  <<jme3/advanced/nifty_gui#,Nifty GUI Concepts>>
-.  *Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ Best Practices*
-.  <<jme3/advanced/nifty_gui_xml_layout#,Nifty GUI XML Layout>> or <<jme3/advanced/nifty_gui_java_layout#,Nifty GUI Java Layout>>
-.  <<jme3/advanced/nifty_gui_overlay#,Nifty GUI Overlay>> or <<jme3/advanced/nifty_gui_projection#,Nifty GUI Projection>>
-.  <<jme3/advanced/nifty_gui_java_interaction#,Nifty GUI Java Interaction>>
-
-
-== XML or Java?
-
-You can build Nifty GUIs using XML or Java syntax. Which one should you choose? The XML and Java syntax are equivalent, so is it an either-or choice? Not quite. You typically use XML and Java together.
-
-*  Build your basic static UI layout using XML - it's cleaner to write and read. 
-*  Use Java syntax to control the dynamic parts of the +++<abbr title="Graphical User Interface">GUI</abbr>+++ at runtime - it's easier to interact with object-oriented code.
-*  *Example:* You design two UIs with slightly different XML layouts for mobile and desktop. If you use the same IDs for equivalent elements, your dynamic Java code works the same no matter which of the two base XML layout you use it on. This allows you to switch between a phone and a desktop UI by simply swapping one base XML file. 
-
-
-== Edit and Preview XML in the SDK
-
-*  Use the <<sdk#,jMonkeyEngine SDK>> New File wizard to create a new XML file (from the +++<abbr title="Graphical User Interface">GUI</abbr>+++ category, “Empty Nifty File). 
-*  The <<sdk#,jMonkeyEngine SDK>> includes an XML editor and a special previewer for Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ files. 
-*  When you open an XML file, you can switch between XML Editor and +++<abbr title="Graphical User Interface">GUI</abbr>+++ Preview mode.
-
-Tip: The +++<abbr title="Graphical User Interface">GUI</abbr>+++ category in the New File wizard also contains Nifty code samples.
-
-
-== Validate the XML before loading
-
-The link:http://nifty-gui.sourceforge.net/projects/nifty/apidocs/de/lessvoid/nifty/Nifty.html[Nifty class] has _validateXml()_ method that takes the same input XML argument as _fromXml()_. Nifty does not validate the Xml by default, and will blow up in surprising ways if your XML does not conform to the schema. Adding the validation step will save you debugging time. You can validate right before loading, or in your unit tests. 
-
-
-== Use Code Completion
-
-*  Include the following XML schema in the first line of your NiftyGUI XML files
-[source,xml]
-----
-
-<?xml version="1.0" encoding="UTF-8"?>
-<nifty xmlns="http://nifty-gui.sourceforge.net/nifty-1.3.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:schemaLocation="http://nifty-gui.sourceforge.net/nifty-1.3.xsd http://nifty-gui.sourceforge.net/nifty-1.3.xsd">
-     <!-- Your IDE now tells you that one <screen></screen> element is expected here, etc. -->
-</nifty>
-
-----
-
-*  Now your IDE (including the jMonkeyEngine SDK) will display extra info and do code completion for the Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ +++<abbr title="Application Programming Interface">API</abbr>+++.
-
-
-== Use the ID String Right
-
-*  If you want to interact with an element, give it an ID (String). 
-*  Use transparent ID-less panels as anonymous spacers.
-
-
-== Sizing Layers and Panels
-
-*  Specify widths and heights in percent to allow the +++<abbr title="Graphical User Interface">GUI</abbr>+++ to scale.
-*  Use `*` instead of a fixed value to make the element fill the remaining space automatically.
-*  Be cautious when specifying fixed sizes, and test the outcome in various resolutions.
-
-
-== Colorcode for Clarity
-
-Screens, layers, and panels…
-
-*  … can have an RGBA background color. +You can use temporary colors during the design phase to highlight which container is which.
-*  … can be transparent. +In the finished +++<abbr title="Graphical User Interface">GUI</abbr>+++, screens, layers, and panels are typically transparent; the visible elements are the images, text fields, and controls, inside the panels.
-
-
-[TIP]
-====
-During development (and during a tutorial), the following debug code makes all panels visible. This helps you arrange them and find errors. 
-
-[source,java]
-----
-nifty.setDebugOptionPanelColors(true);
-----
-
-Before the release, and during testing, set the debug view to false again.
-====
-

+ 0 - 83
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui_editor.adoc

@@ -1,83 +0,0 @@
-= nifty_gui_editor
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== Relucri's Nifty Editor
-
-Forum:
-
-link:http://hub.jmonkeyengine.org/forum/topic/nifty-gui-editor/[http://hub.jmonkeyengine.org/forum/topic/nifty-gui-editor/]
-
-Videos:
-
-Download:
-link:http://niftyeditor.it/[http://niftyeditor.it/]
-
-Manual :
-link:http://niftyeditor.it/home/[http://niftyeditor.it/home/]
-
-
-== Atomix's Nifty  Editor
-
-Base on reclucri's Editor, ported to Netbean plugin, with more features included.
-
-
-=== Why port?
-
-....
-   To integrate better with the SDK toolset. 
-   
-....
-
-
-[IMPORTANT]
-====
-Notice that even it from the same author of Atom framework but it can work separately and not depend on Atom framework. The Extended version of this Nifty Editor, which depend on Atom's component is called TeeHeeGUI!
-====
-
-
-Forum:
-
-Videos:
-
-Download:
-
-
-[IMPORTANT]
-====
-The below Manual belong to Atomix's Nifty Editor!!! You should find the Manual for the orginal Relucri's Nifty Editor above
-====
-
-
-
-==== Usage
-
-
-== Open XML file
-
-
-== Link to Style Def file
-
-
-== Link to Control Def file
-
-
-== Style pack file
-
-
-== Drag and drop Components
-
-
-== Java side
-
-
-== Wire up . Event & Control & Binding
-
-
-== Prototyping your UI

+ 0 - 323
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui_java_interaction.adoc

@@ -1,323 +0,0 @@
-= Interacting with the GUI from Java
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: gui, documentation, input, control, hud, nifty
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-.  <<jme3/advanced/nifty_gui#,Nifty GUI Concepts>>
-.  <<jme3/advanced/nifty_gui_best_practices#,Nifty GUI Best Practices>>
-.  <<jme3/advanced/nifty_gui_xml_layout#,Nifty GUI XML Layout>> or <<jme3/advanced/nifty_gui_java_layout#,Nifty GUI Java Layout>>
-.  <<jme3/advanced/nifty_gui_overlay#,Nifty GUI Overlay>> or <<jme3/advanced/nifty_gui_projection#,Nifty GUI Projection>>
-.  *Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ Java Interaction*
-
-In the previous parts of the tutorial, you created a two-screen user interface. But it is still static, and when you click the buttons, nothing happens yet. The purpose of the +++<abbr title="Graphical User Interface">GUI</abbr>+++ is to communicate with your Java classes: Your game needs to know what the users clicked, which settings they chose, which values they entered into a field, etc. Similarly, the user needs to know what the currently game state is (score, health, etc). 
-
-
-== Connect GUI to Java Controller
-
-To let a Nifty screen communicate with the Java application, you register a `ScreenController` to every NiftyGUI screen. You create a ScreenController by creating a Java class that implements the `de.lessvoid.nifty.screen.ScreenController` interface and its abstract methods.
-
-Create an AppState *MyStartScreen*.java file in your package. ( Rightclick on your package → New → Other… → JME3 Classes → New AppState)
-
-*Pro Tip:* Since you are writing a jME3 application, you can additionally make the ScreenController class extend the <<jme3/advanced/application_states#,AbstractAppState>> class! This gives the ScreenController access to the application object and to the update loop!
-
-Now add *implements ScreenController* to _public class MyStartScreen extends AbstractAppState{_ and add *import de.lessvoid.nifty.screen.ScreenController;*
-
-Continue with adding:
-
-[source,java]
-----
-
-import de.lessvoid.nifty.screen.Screen;
-    
-...
-    
-public void bind(Nifty nifty, Screen screen) {
-    throw new UnsupportedOperationException("Not supported yet."); 
-}
-
-public void onStartScreen() {
-    throw new UnsupportedOperationException("Not supported yet."); 
-}
-
-public void onEndScreen() {
-    throw new UnsupportedOperationException("Not supported yet.");
-}
-
-----
-
-[source,java]
-----
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package mygame;
-
-import com.jme3.app.Application;
-import com.jme3.app.state.AbstractAppState;
-import com.jme3.app.state.AppStateManager;
-import de.lessvoid.nifty.Nifty;
-import de.lessvoid.nifty.screen.Screen;
-import de.lessvoid.nifty.screen.ScreenController;
-
-public class MyStartScreen extends AbstractAppState implements ScreenController {
-    
-    @Override
-    public void initialize(AppStateManager stateManager, Application app) {
-        super.initialize(stateManager, app);
-        //TODO: initialize your AppState, e.g. attach spatials to rootNode
-        //this is called on the OpenGL thread after the AppState has been attached
-    }
-    
-    @Override
-    public void update(float tpf) {
-        //TODO: implement behavior during runtime
-    }
-    
-    @Override
-    public void cleanup() {
-        super.cleanup();
-        //TODO: clean up what you initialized in the initialize method,
-        //e.g. remove all spatials from rootNode
-        //this is called on the OpenGL thread after the AppState has been detached
-    }
-
-    public void bind(Nifty nifty, Screen screen) {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    public void onStartScreen() {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    public void onEndScreen() {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-}
-
-----
-
-The name and package of your custom ScreenController class (here `mygame.MyStartScreen`) goes into the controller parameter of the respective XML screen it belongs to. For example:
-
-[source,xml]
-----
-
-<nifty>
-  <screen id="start" controller="mygame.MyStartScreen">
-      <!-- layer and panel code ... -->
-  </screen>
-</nifty>
-
-----
-
-Or the same in a Java syntax, respectively:
-
-[source,java]
-----
-
-  nifty.addScreen("start", new ScreenBuilder("start") {{
-      controller(new mygame.MyStartScreen())}});
-
-----
-
-Now the Java class `MyStartScreen` and this +++<abbr title="Graphical User Interface">GUI</abbr>+++ screen (`start`) are connected. For this example you can also connect the `hud` screen to MyStartScreen.
-
-
-== Make GUI and Java Interact
-
-In most cases, you will want to pass game data in and out of the ScreenController. Note that you can pass any custom arguments from your Java class into your ScreenController constructor (`public MyStartScreen(GameData data) {}`).
-
-Use any combination of the three following approaches to make Java classes interact with the +++<abbr title="Graphical User Interface">GUI</abbr>+++.
-
-
-=== GUI Calls a Void Java Method
-
-This is how you respond to an +++<abbr title="Graphical User Interface">GUI</abbr>+++ interaction such as clicks in XML GUIs:
-
-.  Add `visibleToMouse=“true` to the parent element!
-.  Embed the `&lt;interact /&gt;` element into the parent element. 
-.  Specify the Java methods that you want to call when the users performs certain actions, such as clicking. +Example: `&lt;interact onClick=“startGame(hud) /&gt;`
-
-Or this is how you respond to an +++<abbr title="Graphical User Interface">GUI</abbr>+++ interaction such as clicks in Java GUIs:
-
-.  Add `visibleToMouse(true);` to the parent element!
-.  Embed one of the `interact…()` elements into the parent element
-.  Specify the Java method that you want to call after the interaction. +Example: `interactOnClick(“startGame(hud));`
-
-In the following example, we call the `startGame()` method when the player clicks the Start button, and `quitGame()` when the player clicks the Quit button.
-
-[source,xml]
-----
-
-        <panel id="panel_bottom_left" height="50%" width="50%" valign="center" childLayout="center">  
-          <control name="button" label="Start" id="StartButton" align="center" valign="center" 
-          visibleToMouse="true" > 
-            <interact onClick="startGame(hud)"/>
-          </control>
-        </panel>
-
-        <panel id="panel_bottom_right" height="50%" width="50%" valign="center" childLayout="center">  
-          <control name="button" label="Quit" id="QuitButton" align="center" valign="center" 
-          visibleToMouse="true" > 
-            <interact onClick="quitGame()"/>
-          </control>
-        </panel>
-
-----
-
-Or the same in a Java syntax, respectively:
-
-[source,java]
-----
-
-control(new ButtonBuilder("StartButton", "Start") {{
-  alignCenter();
-  valignCenter();
-  height("50%");
-  width("50%");
-  visibleToMouse(true);
-  interactOnClick("startGame(hud)");
-}});
-...
-
-control(new ButtonBuilder("QuitButton", "Quit") {{
-  alignCenter();
-  valignCenter();
-  height("50%");
-  width("50%");
-  visibleToMouse(true);
-  interactOnClick("quitGame()");
-}});
-
-----
-
-Back in the MyStartScreen class, you specify what the `startGame()` and `quitGame()` methods do. As you see, you can pass String arguments (here `hud`) in the method call. You also see that you have access to the app object.
-
-[source,java]
-----
-
-public class MyStartScreen implements ScreenController {
-  ...
-
-  /** custom methods */ 
-  public void startGame(String nextScreen) {
-    nifty.gotoScreen(nextScreen);  // switch to another screen
-    // start the game and do some more stuff...
-  }
-
-  public void quitGame() {
-    app.stop(); 
-  }
-  
-  ...
-}
-
-----
-
-The startGame() example simply switches the +++<abbr title="Graphical User Interface">GUI</abbr>+++ to the `hud` screen when the user clicks Start. Of course, in a real game, you would perform more steps here: Load the game level, switch to in-game input and navigation handling, set a custom `running` boolean to true, attach custom in-game AppStates – and lots more.
-
-The quitGame() example shows that you have access to the application `app` object because you made the ScreenController extend AbstractAppState.  (If you're creating code from this example, note that you'll need to make sure `app` is initialized before you can successfully call its methods.)
-
-
-=== GUI Gets Return Value from Java Method
-
-When the Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ is initialized, you can get data from Java. In this example, the Java class `getPlayerName()` in `MyStartScreen` defines the Text that is displayed in the textfield before the words `'s Cool Game`. 
-
-First define a Java method in the screen controller, in this example, `getPlayerName()`.
-
-[source,java]
-----
-
-public class MySettingsScreen implements ScreenController {
-  ...
-  public String getPlayerName(){
-    return System.getProperty("user.name");
-  }
-}
-
-----
-
-Nifty uses `${CALL.getPlayerName()}` to get the return value of the getPlayerName() method from your ScreenController Java class.
-
-[source,xml]
-----
-
-<text text="${CALL.getPlayerName()}'s Cool Game" font="Interface/Fonts/Default.fnt" width="100%" height="100%" />
-
-----
-
-Or the same in a Java syntax, respectively:
-
-[source,java]
-----
-text(new TextBuilder() {{
-  text("${CALL.getPlayerName()}'s Cool Game");
-  font("Interface/Fonts/Default.fnt");
-  height("100%");
-  width("100%");
-}});
-
-----
-
-You can use this for Strings and numeric values (e.g. when you read settings from a file, you display the results in the +++<abbr title="Graphical User Interface">GUI</abbr>+++) and also for methods with side effects.
-
-
-=== Java Modifies Nifty Elements and Events
-
-You can also alter the appearance and functions of your nifty elements from Java. Make certain that the element that you want to alter has its `id=“name` attribute set, so you can identy and address it.
-
-Here's an example of how to change an image called `playerhealth`:
-
-[source,java]
-----
-
-// load or create new image
-NiftyImage img = nifty.getRenderEngine().createImage("Interface/Images/face2.png", false);
-// find old image
-Element niftyElement = nifty.getCurrentScreen().findElementByName("playerhealth");
-// swap old with new image
-niftyElement.getRenderer(ImageRenderer.class).setImage(img);
-
-----
-
-The same is valid for other elements, for example a text label “score:
-
-[source,java]
-----
-
-// find old text
-Element niftyElement = nifty.getCurrentScreen().findElementByName("score");
-// swap old with new text
-niftyElement.getRenderer(TextRenderer.class).setText("124");
-
-----
-
-Similarly, to change the onClick() event of an element, create an `ElementInteraction` object:
-
-[source,java]
-----
-
-Element niftyElement = nifty.getCurrentScreen().findElementByName("myElement");
-niftyElement.getElementInteraction().getPrimary().setOnMouseOver(new NiftyMethodInvoker(nifty, "myCustomMethod()", this));
-
-----
-
-For this to work, there already needs to be a (possibly inactive) `&lt;interact /&gt;` tag inside your xml element:
-
-[source,xml]
-----
-<interact onClick="doNothing()"/>
-----
-
-
-== Next Steps
-
-You're done with the basic Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ for jME3 tutorial. You can proceed to advanced topics and learn how add controls and effects:
-
-*  <<jme3/advanced/nifty_gui_scenarios#, Nifty GUI Scenarios>>
-*  link:http://sourceforge.net/projects/nifty-gui/files/nifty-gui/nifty-gui-the-manual-v1.0.pdf/download[Nifty GUI - the Manual]

+ 0 - 572
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui_java_layout.adoc

@@ -1,572 +0,0 @@
-= Laying Out the GUI in Java
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:keywords: gui, documentation, nifty, hud
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-.  <<jme3/advanced/nifty_gui#,Nifty GUI Concepts>>
-.  <<jme3/advanced/nifty_gui_best_practices#,Nifty GUI Best Practices>>
-.  <<jme3/advanced/nifty_gui_xml_layout#,Nifty GUI XML Layout>> or *Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ Java Layout*
-.  <<jme3/advanced/nifty_gui_overlay#,Nifty GUI Overlay>> or <<jme3/advanced/nifty_gui_projection#,Nifty GUI Projection>>
-.  <<jme3/advanced/nifty_gui_java_interaction#,Interact with the GUI from Java>>
-
-*Work in progress* You can “draw the +++<abbr title="Graphical User Interface">GUI</abbr>+++ to the screen by writing Java code – alternatively to using XML. Typically you lay out the static base +++<abbr title="Graphical User Interface">GUI</abbr>+++ in XML, and use Java commands if you need to change the +++<abbr title="Graphical User Interface">GUI</abbr>+++ dynamically at runtime. In theory, you can also lay out the whole +++<abbr title="Graphical User Interface">GUI</abbr>+++ in Java (but we don't cover that here).
-
-
-== Sample Code
-
-Sample project
-
-*  *Original Source Code:* link:http://nifty-gui.svn.sourceforge.net/viewvc/nifty-gui/nifty-default-controls-examples/trunk/src/main/java/de/lessvoid/nifty/examples/[/nifty-default-controls-examples/trunk/src/main/java/de/lessvoid/nifty/examples/]. +
-*  *Download demo project:* link:http://files.seapegasus.org/NiftyGuiDemo.zip[http://files.seapegasus.org/NiftyGuiDemo.zip] (jme3-ready) +The full demo ZIP is based on `de.lessvoid.nifty.examples.controls.ControlsDemo.java`.
-..  The demo is a SimpleApplication-based game (use e.g. the BasicGame template in the jMonkeyEngine SDK).
-..  Copy images and sound files into your project's `assets/Interface/` directory. (In this example, I copied them from `nifty-default-controls-examples/trunk/src/main/resources/` to `assets/Interface/`).
-..  Make sure to use paths relative to your project's `assets/` directory.
-***  E.g. for .fnt/.png/.jpg files use `filename(“Interface/yang.png);` ( not `filename(“yang.png);`).
-***  E.g. for .wav/.ogg files use `filename(“Interface/sounds/gong.wav);` (not `filename(“sounds/gong.wav);`).
-
-
-
-Just so you get a quick picture what Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++'s Java Syntax looks like, here is the most basic example. It creates a screen with a layer and a panel that contains a button.
-
-[source,java]
-----
-package mygame;
-
-import com.jme3.app.SimpleApplication;
-import com.jme3.niftygui.NiftyJmeDisplay;
-import de.lessvoid.nifty.Nifty;
-import de.lessvoid.nifty.builder.ScreenBuilder;
-import de.lessvoid.nifty.builder.LayerBuilder;
-import de.lessvoid.nifty.builder.PanelBuilder;
-import de.lessvoid.nifty.controls.button.builder.ButtonBuilder;
-import de.lessvoid.nifty.screen.DefaultScreenController;
-
-/**
- * @author iamcreasy
-*/
-public class Main extends SimpleApplication {
-
-    public static void main(String[] args) {
-        Main app = new Main();
-        app.start();
-    }
-
-    @Override
-    public void simpleInitApp() {
-    NiftyJmeDisplay niftyDisplay = NiftyJmeDisplay.newNiftyJmeDisplay(
-            assetManager, inputManager, audioRenderer, guiViewPort);
-    Nifty nifty = niftyDisplay.getNifty();
-    guiViewPort.addProcessor(niftyDisplay);
-    flyCam.setDragToRotate(true);
-
-    nifty.loadStyleFile("nifty-default-styles.xml");
-    nifty.loadControlFile("nifty-default-controls.xml");
-
-    // <screen>
-    nifty.addScreen("Screen_ID", new ScreenBuilder("Hello Nifty Screen"){{
-        controller(new DefaultScreenController()); // Screen properties
-
-        // <layer>
-        layer(new LayerBuilder("Layer_ID") {{
-            childLayoutVertical(); // layer properties, add more...
-
-            // <panel>
-            panel(new PanelBuilder("Panel_ID") {{
-               childLayoutCenter(); // panel properties, add more...
-
-                // GUI elements
-                control(new ButtonBuilder("Button_ID", "Hello Nifty"){{
-                    alignCenter();
-                    valignCenter();
-                    height("5%");
-                    width("15%");
-                }});
-
-                //.. add more GUI elements here
-
-            }});
-            // </panel>
-          }});
-        // </layer>
-      }}.build(nifty));
-    // </screen>
-
-    nifty.gotoScreen("Screen_ID"); // start the screen
-    }
-}
-----
-
-
-== Implement Your GUI Layout
-
-
-image::jme3/advanced/gui-layout-draft.png[gui-layout-draft.png,width="",height="",align="right"]
-
-
-In this tutorial, you recreate the same screen as in the Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ XML example.
-
-Create an Screen.Java file in the `assets/Interfaces/` directory of your project. One Java file can contain several, or even all screens. As a reminder: Nifty displays one screen at a time; a screen contains several layers on top of one another; each layer contains panels that are embedded into another; the panels contain the actual content (text, images, or controls).
-
-
-=== Make Screens
-
-The following minimal Java file contains a start screen and a HUD screen. (Neither has been defined yet.)
-
-[source,java]
-----
-
-nifty.addScreen("start", new ScreenBuilder("start"){{
-    controller(new DefaultScreenController());
-    // <!-- ... -->
-  }}.build(nifty));
-
-nifty.addScreen("hud", new ScreenBuilder("hud"){{
-    controller(new DefaultScreenController());
-    // <!-- ... -->
-  }}.build(nifty));
-
-----
-
-Every Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ must have a start screen. The others (in this example, the HUD screen) are optional.
-
-
-=== Make Layers
-
-The following Java code shows how we add layers to the start screen and HUD screen:
-
-[source,java]
-----
-
-nifty.addScreen("start", new ScreenBuilder("start"){{
-        controller(new DefaultScreenController());
-
-         // layer added
-         layer(new LayerBuilder("background") {{
-            childLayoutCenter();
-            backgroundColor("#000f");
-
-            // <!-- ... -->
-         }});
-
-         layer(new LayerBuilder("foreground") {{
-                childLayoutVertical();
-                backgroundColor("#0000");
-
-            // <!-- ... -->
-         }});
-         // layer added
-
-      }}.build(nifty));
-----
-
-Repeat the same, but use
-
-[source]
-----
-nifty.addScreen("hud", new ScreenBuilder("hud"){{
-----
-
- for the HUD screen.
-
-In a layer, you can now add panels and arrange them. Panels are containers that mark the areas where you want to display text, images, or controls (buttons etc) later.
-
-
-=== Make Panels
-
-A panel is the inner-most container (that will contain the actual content: text, images, or controls). You place panels inside layers. The following panels go into in the `start` screen:
-
-[source,java]
-----
-
-    nifty.addScreen("start", new ScreenBuilder("start") {{
-        controller(new DefaultScreenController());
-        layer(new LayerBuilder("background") {{
-            childLayoutCenter();
-            backgroundColor("#000f");
-            // <!-- ... -->
-        }});
-
-        layer(new LayerBuilder("foreground") {{
-                childLayoutVertical();
-                backgroundColor("#0000");
-
-            // panel added
-            panel(new PanelBuilder("panel_top") {{
-                childLayoutCenter();
-                alignCenter();
-                backgroundColor("#f008");
-                height("25%");
-                width("75%");
-            }});
-
-            panel(new PanelBuilder("panel_mid") {{
-                childLayoutCenter();
-                alignCenter();
-                backgroundColor("#0f08");
-                height("50%");
-                width("75%");
-            }});
-
-            panel(new PanelBuilder("panel_bottom") {{
-                childLayoutHorizontal();
-                alignCenter();
-                backgroundColor("#00f8");
-                height("25%");
-                width("75%");
-
-                panel(new PanelBuilder("panel_bottom_left") {{
-                    childLayoutCenter();
-                    valignCenter();
-                    backgroundColor("#44f8");
-                    height("50%");
-                    width("50%");
-                }});
-
-                panel(new PanelBuilder("panel_bottom_right") {{
-                    childLayoutCenter();
-                    valignCenter();
-                    backgroundColor("#88f8");
-                    height("50%");
-                    width("50%");
-                }});
-            }}); // panel added
-        }});
-
-    }}.build(nifty));
-
-----
-
-The following panels go into in the `hud` screen:
-
-[source,Java]
-----
-
-    nifty.addScreen("hud", new ScreenBuilder("hud") {{
-        controller(new DefaultScreenController());
-
-        layer(new LayerBuilder("background") {{
-            childLayoutCenter();
-            backgroundColor("#000f");
-            // <!-- ... -->
-        }});
-
-        layer(new LayerBuilder("foreground") {{
-            childLayoutHorizontal();
-            backgroundColor("#0000");
-
-            // panel added
-            panel(new PanelBuilder("panel_left") {{
-                childLayoutVertical();
-                backgroundColor("#0f08");
-                height("100%");
-                width("80%");
-                // <!-- spacer -->
-            }});
-
-            panel(new PanelBuilder("panel_right") {{
-                childLayoutVertical();
-                backgroundColor("#00f8");
-                height("100%");
-                width("20%");
-
-                panel(new PanelBuilder("panel_top_right1") {{
-                    childLayoutCenter();
-                    backgroundColor("#00f8");
-                    height("15%");
-                    width("100%");
-                }});
-
-                panel(new PanelBuilder("panel_top_right2") {{
-                    childLayoutCenter();
-                    backgroundColor("#44f8");
-                    height("15%");
-                    width("100%");
-                }});
-
-                panel(new PanelBuilder("panel_bot_right") {{
-                    childLayoutCenter();
-                    valignCenter();
-                    backgroundColor("#88f8");
-                    height("70%");
-                    width("100%");
-                }});
-            }}); // panel added
-        }});
-    }}.build(nifty));
-----
-
-Try the sample. Remember to activate a screen using `nifty.gotoScreen(“start);` or `hud` respectively.
-The result should look as follows:
-
-
-image::jme3/advanced/nifty-gui-panels.png[nifty-gui-panels.png,width="",height="",align="center"]
-
-
-
-== Adding Content to Panels
-
-See also link:http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Layout_Introduction[Layout Introduction] on the Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ site.
-
-
-=== Add Images
-
-The start-background.png image is a fullscreen background picture. In the `start` screen, add the following image element:
-
-[source,java]
-----
-
-    nifty.addScreen("start", new ScreenBuilder("start") {{
-        controller(new DefaultScreenController());
-        layer(new LayerBuilder("background") {{
-            childLayoutCenter();
-            backgroundColor("#000f");
-
-            // add image
-            image(new ImageBuilder() {{
-                filename("Interface/tutorial/start-background.png");
-            }});
-
-        }});
-
-----
-
-The hud-frame.png image is a transparent frame that we use as HUD decoration. In the `hud` screen, add the following image element:
-
-[source,java]
-----
-    nifty.addScreen("hud", new ScreenBuilder("hud") {{
-        controller(new DefaultScreenController());
-
-        layer(new LayerBuilder("background") {{
-            childLayoutCenter();
-            backgroundColor("#000f");
-
-            // add image
-            image(new ImageBuilder() {{
-                filename("Interface/tutorial/hud-frame.png");
-            }});
-
-        }});
-----
-
-The face1.png image is an image that you want to use as a status icon.
-In the `hud` screen's `foreground` layer, add the following image element:
-
-[source,java]
-----
-                panel(new PanelBuilder("panel_top_right2") {{
-                    childLayoutCenter();
-                    backgroundColor("#44f8");
-                    height("15%");
-                    width("100%");
-
-                    // add image
-                    image(new ImageBuilder() {{
-                        filename("Interface/tutorial/face1.png");
-                        valignCenter();
-                        alignCenter();
-                        height("50%");
-                        width("30%");
-                    }});
-
-                }});
-----
-
-This image is scaled to use 50% of the height and 30% of the width of its container.
-
-
-=== Add Static Text
-
-The game title is a typical example of static text. In the `start` screen, add the following text element:
-
-[source,java]
-----
-
-           // panel added
-            panel(new PanelBuilder("panel_top") {{
-                childLayoutCenter();
-                alignCenter();
-                backgroundColor("#f008");
-                height("25%");
-                width("75%");
-
-                // add text
-                text(new TextBuilder() {{
-                    text("My Cool Game");
-                    font("Interface/Fonts/Default.fnt");
-                    height("100%");
-                    width("100%");
-                }});
-
-            }});
-----
-
-For longer pieces of static text, such as an introduction, you can use wrap=“true. Add the following text element to the `Start screen`:
-
-[source,java]
-----
-
-            panel(new PanelBuilder("panel_mid") {{
-                childLayoutCenter();
-                alignCenter();
-                backgroundColor("#0f08");
-                height("50%");
-                width("75%");
-                // add text
-                text(new TextBuilder() {{
-                    text("Here goes some text describing the game and the rules and stuff. "+
-                         "Incidentally, the text is quite long and needs to wrap at the end of lines. ");
-                    font("Interface/Fonts/Default.fnt");
-                    wrap(true);
-                    height("100%");
-                    width("100%");
-                }});
-
-            }});
-----
-
-The font used is jME3's default font “Interface/Fonts/Default.fnt which is included in the jMonkeyEngine.JAR. You can add your own fonts to your own `assets/Interface` directory.
-
-
-=== Add Controls
-
-Before you can use any control, you must load a Control Definition first. Add the following two lines _before_ your screen definitions:
-
-[source,java]
-----
-
-    nifty.loadStyleFile("nifty-default-styles.xml");
-    nifty.loadControlFile("nifty-default-controls.xml");
-----
-
-
-==== Label Control
-
-Use label controls for text that you want to edit dynamically from Java. One example for this is the score display.
-In the `hud` screen's `foreground` layer, add the following text element:
-
-[source,java]
-----
-                panel(new PanelBuilder("panel_top_right1") {{
-                    childLayoutCenter();
-                    backgroundColor("#00f8");
-                    height("15%");
-                    width("100%");
-
-                    control(new LabelBuilder(){{
-                        color("#000");
-                        text("123");
-                        width("100%");
-                        height("100%");
-                    }});
-----
-
-Note that the width and height do not scale the bitmap font, but make indirectly certain it is centered. If you want a different size for the font, you need to provide an extra bitmap font (they come with fixes sizes and don't scale well).
-
-
-==== Button Control
-
-Our +++<abbr title="Graphical User Interface">GUI</abbr>+++ plan asks for two buttons on the start screen. You add the Start and Quit buttons to the bottom panel of the `start` screen using the `&lt;control&gt;` element:
-
-[source,java]
-----
-
-                panel(new PanelBuilder("panel_bottom_left") {{
-                    childLayoutCenter();
-                    valignCenter();
-                    backgroundColor("#44f8");
-                    height("50%");
-                    width("50%");
-
-                    // add control
-                    control(new ButtonBuilder("StartButton", "Start") {{
-                      alignCenter();
-                      valignCenter();
-                      height("50%");
-                      width("50%");
-                    }});
-
-                }});
-
-                panel(new PanelBuilder("panel_bottom_right") {{
-                    childLayoutCenter();
-                    valignCenter();
-                    backgroundColor("#88f8");
-                    height("50%");
-                    width("50%");
-
-                    // add control
-                    control(new ButtonBuilder("QuitButton", "Quit") {{
-                      alignCenter();
-                      valignCenter();
-                      height("50%");
-                      width("50%");
-                    }});
-
-                }});
-----
-
-Note that these controls don't do anything yet – we'll get to that soon.
-
-
-==== Other Controls
-
-Nifty additionally offers many customizable controls such as check boxes, text fields, menus, chats, tabs, … See also link:http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Elements[Elements] on the Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ site.
-
-
-== Intermediate Result
-
-When you preview this code in the jMonkeyEngine SDK, our tutorial demo should looks as follows: A start screen with two buttons, and a game screen with a simple HUD frame and a blue cube (which stands for any jME3 game content).
-
-*Tip:* Remove all lines that set background colors, you only needed them to see the arrangement.
-
-
-image::jme3/advanced/nifty-gui-simple-demo.png[nifty-gui-simple-demo.png,width="",height="",align="center"]
-
-
-
-== Nifty Java Settings
-
-Before initializing the nifty screens, you set up properties and register media.
-[cols="2", options="header"]
-|===
-
-a| Nifty Method
-a| Description
-
-a| registerSound(“mysound, “Interface/abc.wav);
-a|
-
-a| registerMusic(“mymusic, “Interface/xyz.ogg);
-a|
-
-a| registerMouseCursor(“mypointer, “Interface/abc.png, 5, 4);
-a|
-
-a| registerEffect(?);
-a| ?
-
-a| setDebugOptionPanelColors(true);
-a| Highlight all panels, makes it easier to arrange them.
-
-|===
-
-Example:
-
-[source,java]
-----
-nifty.registerMouseCursor("hand", "Interface/mouse-cursor-hand.png", 5, 4);
-----
-
-
-== Next Steps
-
-Integrate the +++<abbr title="Graphical User Interface">GUI</abbr>+++ into the game. Typically, you will overlay the +++<abbr title="Graphical User Interface">GUI</abbr>+++.
-
-*  <<jme3/advanced/nifty_gui_overlay#,Nifty GUI Overlay>> (recommended)
-*  <<jme3/advanced/nifty_gui_projection#,Nifty GUI Projection>> (optional)

+ 0 - 82
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui_overlay.adoc

@@ -1,82 +0,0 @@
-= Integrating Nifty GUI: Overlay
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:keywords: gui, documentation, nifty, hud
-:relfileprefix: ../../
-:imagesdir: ../..
-:experimental:
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-.  <<jme3/advanced/nifty_gui#,Nifty GUI Concepts>>
-.  <<jme3/advanced/nifty_gui_best_practices#,Nifty GUI Best Practices>>
-.  <<jme3/advanced/nifty_gui_xml_layout#,Nifty GUI XML Layout>> or <<jme3/advanced/nifty_gui_java_layout#,Nifty GUI Java Layout>>
-.  *Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ Overlay* or <<jme3/advanced/nifty_gui_projection#,Nifty GUI Projection>>
-.  <<jme3/advanced/nifty_gui_java_interaction#,Interact with the GUI from Java>>
-
-
-image::jme3/advanced/nifty-gui-example.png[nifty-gui-example.png,width="300",height="200",align="left"]
-
-
-Typically, you define a key (for example escape) that switches the +++<abbr title="Graphical User Interface">GUI</abbr>+++ on and off. The +++<abbr title="Graphical User Interface">GUI</abbr>+++ can be a StartScreen, OptionsScreen, CharacterCreationScreen, etc. While the +++<abbr title="Graphical User Interface">GUI</abbr>+++ is up, you pause the running game, and then overlay the +++<abbr title="Graphical User Interface">GUI</abbr>+++. You also must switch to a different set of user inputs while the game is paused, so the player can use the mouse pointer and keyboard to interact with the +++<abbr title="Graphical User Interface">GUI</abbr>+++.
-
-You can also <<jme3/advanced/nifty_gui_projection#,project>> the +++<abbr title="Graphical User Interface">GUI</abbr>+++ as a texture onto a mesh texture (but then you cannot click to select).
-On this page, we look at the overlay variant, which is more commonly used in games.
-
-
-== Sample Code
-
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/niftygui/TestNiftyGui.java[TestNiftyGui.java]
-
-[TIP]
-====
-The jme3-niftygui library is included in jMonkeyEngine. If you installed jMonkeyEngine using one of the link:https://jmonkeyengine.github.io/wiki/#install[optional methods], it will be added to your projects Library folder as part of the installation. If you're using the jMonkeyEngine SDK, you add it to any project by btn:[RMB] selecting your projects `Library` folder, choosing `menu:Add Library[jme-niftygui]` followed by `Add Library`.
-====
-
-
-== Overlaying the User Interface Over the Screen
-
-This code shows you how to overlay anything on the screen with the +++<abbr title="Graphical User Interface">GUI</abbr>+++. This is the most common usecase.
-
-[source,java]
-----
-
-NiftyJmeDisplay niftyDisplay = NiftyJmeDisplay.newNiftyJmeDisplay(
-    assetManager, inputManager, audioRenderer, guiViewPort);
-/** Create a new NiftyGUI object */
-Nifty nifty = niftyDisplay.getNifty();
-/** Read your XML and initialize your custom ScreenController */
-nifty.fromXml("Interface/tutorial/step2/screen.xml", "start");
-// nifty.fromXml("Interface/helloworld.xml", "start", new MySettingsScreen(data));
-// attach the Nifty display to the gui view port as a processor
-guiViewPort.addProcessor(niftyDisplay);
-// disable the fly cam
-flyCam.setDragToRotate(true);
-
-----
-
-Currently you do not have a ScreenController – we will create one in the next exercise. As soon  as you have a screen controller, you will use the commented variant of the XML loading method:
-
-[source,java]
-----
-nifty.fromXml("Interface/helloworld.xml", "start", new MySettingsScreen());
-----
-
-The `MySettingsScreen` class is a custom de.lessvoid.nifty.screen.ScreenController in which you will implement your +++<abbr title="Graphical User Interface">GUI</abbr>+++ behaviour.
-
-If you have many screens or you want to keep them organized in separate files there is a method available that will just load an additional XML file. The content of the files are
-simply added to whatever XML data has been loaded before.
-
-[source,java]
-----
-nifty.addXml("Interface/mysecondscreen.xml");
-----
-
-
-== Next Steps
-
-Now that you have layed out and integrated the +++<abbr title="Graphical User Interface">GUI</abbr>+++ in your app, you want to respond to user input and display the current game. Time to create a ScreenController!
-
-*  <<jme3/advanced/nifty_gui_java_interaction#,Interact with the GUI from Java>>

+ 0 - 93
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui_popup_menu.adoc

@@ -1,93 +0,0 @@
-= Nifty GUI: Create a PopUp Menu
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-Even though you create and populate the popup menu in Java, you still need a “placeholder in your XML file.
-The popup element needs to be placed _outside_ of any screen!
-
-[source,xml]
-----
-
-<useControls filename="nifty-default-controls.xml"/>
-...
-<popup id="niftyPopupMenu" childLayout="absolute-inside"
-       controller="ControllerOfYourChoice" width="10%">
-  <interact onClick="closePopup()" onSecondaryClick="closePopup()" onTertiaryClick="closePopup()" />
-  <control id="#menu" name="niftyMenu" />
-</popup>
-...
-----
-
-A brief explanation of some the attributes above:
-
-*  The popup id is used within your Java code so that nifty knows which popup placeholder to create.
-*  The Controller tells Nifty which Java class handles MenuItemActivatedEvent.
-*  The on(Secondary/Tertiary)Click tells Nifty to close the popup if the user clicks anywhere except on the menu items (in this example; you have to define the closePopup()-method yourself, in the screen controller)
-*  The control id is used by the Java class to define a control type (i.e. Menu)
-
-The Java code within your defined ScreenController implementation:
-
-[source,java]
-----
-
-private Element popup;
-...
-public void createMyPopupMenu(){
-  popup = nifty.createPopup("niftyPopupMenu");
-  Menu myMenu = popup.findNiftyControl("#menu", Menu.class);
-  myMenu.setWidth(new SizeValue("100px")); // must be set
-  myMenu.addMenuItem("Click me!", "menuItemIcon.png", 
-    new menuItem("menuItemid", "blah blah")); // menuItem is a custom class
-  nifty.subscribe(
-    nifty.getCurrentScreen(), 
-    myMenu.getId(), 
-    MenuItemActivatedEvent.class, 
-    new MenuItemActivatedEventSubscriber());
-}
-
-public void showMenu() { // the method to trigger the menu
-  // If this is a menu that is going to be used many times, then
-  // call this in your constructor rather than here   
-  createMyPopupMenu() 
-  // call the popup to screen of your choice:
-  nifty.showPopup(nifty.getCurrentScreen(), popup.getId(), null); 
-}
-
-private class menuItem {
-  public String id;
-  public String name;
-  public menuItem(String id, String name){
-    this.id= id;
-    this.name = name;
-  }
-}
-
-----
-
-*  The createMyPopupMenu() method creates the menu with set width so that you can populate it.
-*  The showMenu() method is called by something to trigger the menu (i.e. could be a Key or some other method).
-*  Note: if you want to be able to access the popup via your id, use createPopupWithId(id, id) instead.
-
-To handle menu item events (i.e. calling a method when you click on a menu item), you register (subscribe) a EventTopicSubscriber&lt;MenuItemActivatedEvent&gt; class implementation to a nifty screen and element.
-
-[source,java]
-----
-
-  private class MenuItemActivatedEventSubscriber 
-    implements EventTopicSubscriber<MenuItemActivatedEvent> {
-    
-    @Override
-    public void onEvent(final String id, final MenuItemActivatedEvent event) {
-    	menuItem item = (menuItem) event.getItem();
-       if ("menuItemid".equals(item.id)) {
-		//do something !!!
-       }
-    }
-  };
-
-----

+ 0 - 79
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui_projection.adoc

@@ -1,79 +0,0 @@
-= Integrating Nifty GUI: Projection
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:keywords: gui, documentation, nifty, hud, texture
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-.  <<jme3/advanced/nifty_gui#,Nifty GUI Concepts>>
-.  <<jme3/advanced/nifty_gui_best_practices#,Nifty GUI Best Practices>>
-.  <<jme3/advanced/nifty_gui_xml_layout#,Nifty GUI XML Layout>> or <<jme3/advanced/nifty_gui_java_layout#,Nifty GUI Java Layout>>
-.  <<jme3/advanced/nifty_gui_overlay#,Nifty GUI Overlay>> or *Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ Projection*
-.  <<jme3/advanced/nifty_gui_java_interaction#,Interact with the GUI from Java>>
-
-
-image::jme3/advanced/nifty-gui.png[nifty-gui.png,width="310",height="250",align="left"]
-
-
-Typically you define a key (for example escape) to switch the +++<abbr title="Graphical User Interface">GUI</abbr>+++ on and off. Then you <<jme3/advanced/nifty_gui_overlay#,overlay>> the running game with the +++<abbr title="Graphical User Interface">GUI</abbr>+++ (you will most likely pause the game then).
-
-Alternatively, you can also project the +++<abbr title="Graphical User Interface">GUI</abbr>+++ as a texture onto a mesh textures inside the game. Allthough this looks cool and “immersive, this approach is rarely used since it is difficult to record clicks this way. You can only interact with this projected +++<abbr title="Graphical User Interface">GUI</abbr>+++ by keyboard, or programmatically. You can select input fields using the arrow keys, and trigger actions using the return key.
-
-This +++<abbr title="Graphical User Interface">GUI</abbr>+++ projection variant is less commonly used than the +++<abbr title="Graphical User Interface">GUI</abbr>+++ overlay variant. Usecases for +++<abbr title="Graphical User Interface">GUI</abbr>+++ projection are, for example, a player avatar using an in-game computer screen.
-
-
-== Sample Code
-
-*  link:http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/niftygui/TestNiftyToMesh.java[TestNiftyToMesh.java]
-
-
-== Projecting the User Interface Onto a Texture
-
-You can project the Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ onto a texture, load the texture into a material, and assign it to a Geometry (Quads or Boxes are best).
-
-[source,java]
-----
-
-/** Create a special viewport for the Nifty GUI */
-ViewPort niftyView = renderManager.createPreView("NiftyView", new Camera(1024, 768));
-niftyView.setClearEnabled(true);
-/** Create a new NiftyJmeDisplay for the integration */
-NiftyJmeDisplay niftyDisplay = NiftyJmeDisplay.newNiftyJmeDisplay(
-  assetManager,  inputManager,  audioRenderer,  niftyView);
-/** Create a new NiftyGUI object */
-Nifty nifty = niftyDisplay.getNifty();
-/** Read your XML and initialize your custom ScreenController */
-nifty.fromXml("Interface/helloworld.xml", "start", new MySettingsScreen(data));
-
-/** Prepare a framebuffer for the texture niftytex */
-niftyView.addProcessor(niftyDisplay);
-FrameBuffer fb = new FrameBuffer(1024, 768, 0);
-fb.setDepthBuffer(Format.Depth);
-Texture2D niftytex = new Texture2D(1024, 768, Format.RGB8);
-fb.setColorTexture(niftytex);
-niftyView.setClearEnabled(true);
-niftyView.setOutputFrameBuffer(fb);
-
-/** This is the 3D cube we project the GUI on */
-Box b = new Box(Vector3f.ZERO, 1, 1, 1);
-Geometry geom = new Geometry("Box", b);
-Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-mat.setTexture("m_ColorMap", niftytex); /** Here comes the texture! */
-geom.setMaterial(mat);
-rootNode.attachChild(geom);
-
-----
-
-The MySettingsScreen class is a custom de.lessvoid.nifty.screen.ScreenController in which you implement your +++<abbr title="Graphical User Interface">GUI</abbr>+++ behaviour.  The variable `data` contains an object that you use to exchange state info with the game. See <<jme3/advanced/nifty_gui_java_interaction#,Nifty GUI Java Interaction>> for details on how to create this class.
-
-Run the code sample. You select buttons on this +++<abbr title="Graphical User Interface">GUI</abbr>+++ with the arrow keys and then press return. Note that clicking on the texture will not work!
-
-
-== Next Steps
-
-Now that you have layed out and integrated the +++<abbr title="Graphical User Interface">GUI</abbr>+++ in your app, you want to respond to user input and display the current game.
-
-*  <<jme3/advanced/nifty_gui_java_interaction#,Interact with the GUI from Java>>

+ 0 - 299
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui_scenarios.adoc

@@ -1,299 +0,0 @@
-= Nifty GUI 1.3 - Usecase Scenarios
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: gui, documentation, nifty, hud, click, state, states, sound, effect
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-This document contains typical NiftyGUI usecase scenarios, such as adding effects, game states, and creating typical game screens. 
-
-Requirements: These tips assume that you have read and understood the <<jme3/advanced/nifty_gui#,Creating JME3 User Interfaces with Nifty GUI>> tutorial, and have already laid out a basic +++<abbr title="Graphical User Interface">GUI</abbr>+++ that interacts with your JME3 application. Here you learn how you integrate the +++<abbr title="Graphical User Interface">GUI</abbr>+++ better, and add effects and advanced controls.
-
-
-== Switch Game States
-
-In a JME game, you typically have three game states:
-
-.  Stopped: The game is stopped, a StartScreen is displayed. 
-.  Running: The game is running, the in-game HudScreen is displayed. 
-.  Paused: The game is paused, a PausedScreen is displayed.
-
-(Aside: Additionally, the Stopped state often contains a LoadScreen, LogonScreen, OptionsScreen, CharacterCreationScreen, HighScoreScreen, CreditsScreen, etc. Some games let you access the OptionsScreen in the Paused state as well. The Running state can also contain an InventoryScreen, ItemShopScreen, StatsScreen, SkillScreen, etc.)
-
-In JME, game states are implemented as custom <<jme3/advanced/application_states#,AppState>> objects. Write each AppState so it brings its own input mappings, rootNode content, update loop behaviour, etc with it.
-
-.  Stopped: StartScreen AppState + GuiInputs AppState
-.  Paused: PausedScreen AppState + GuiInputs AppState
-.  Running: HudScreen AppState + InGameInputs AppState + BulletAppState (jme physics), …
-
-When the player switches between game states, you detach one set of AppStates, and attach another. For example, when the player pauses the running game, you use a boolean switch to pause the game loop and deactivate the game inputs (shooting, navigation). The screen is overlayed with a PausedScreen, which contains a visible mouse pointer and a Continue button. When the player clicks Continue, the mouse pointer is deactivated, the in-game input and navigational mappings are activated, and the game loop continues.
-
-
-== Get Access to Application and Update Loop
-
-Since you are writing a jME3 application, you can additionally make any ScreenController class extend the <<jme3/advanced/application_states#,AbstractAppState>> class. 
-This gives the ScreenController access to the application object and to the update loop!
-
-[source,java]
-----
-
-public class StartScreenState extends AbstractAppState {
-
-  private ViewPort viewPort;
-  private Node rootNode;
-  private Node guiNode;
-  private AssetManager assetManager;
-  private Node localRootNode = new Node("Start Screen RootNode");
-  private Node localGuiNode = new Node("Start Screen GuiNode");
-  private final ColorRGBA backgroundColor = ColorRGBA.Gray;  
-
-public StartScreenState(SimpleApplication app){
-    this.rootNode     = app.getRootNode();
-    this.viewPort     = app.getViewPort();
-    this.guiNode      = app.getGuiNode();
-    this.assetManager = app.getAssetManager();  
-  }
-
-  @Override
-  public void initialize(AppStateManager stateManager, Application app) {
-    super.initialize(stateManager, app);
-    
-    rootNode.attachChild(localRootNode);
-    guiNode.attachChild(localGuiNode);
-    viewPort.setBackgroundColor(backgroundColor);
-    
-    /** init the screen */    
-  }
-
-  @Override
-  public void update(float tpf) {
-    /** any main loop action happens here */
-  }
-  
-  @Override
-  public void cleanup() {
-    rootNode.detachChild(localRootNode);
-    guiNode.detachChild(localGuiNode);
-    
-    super.cleanup();
-  }
-  
-}
-----
-
-
-[IMPORTANT]
-====
-It is not sufficient to just inherit from AbstractAppState. You need to instantiate your controller class, register it with app's stateManager and then pass it to nifty. See code sample below.
-====
-
-
-[source,java]
-----
-
-public class TestNiftyGui extends SimpleApplication {
-  public void simpleInitApp() {
-     StartScreenState startScreenState = new StartScreenState(this);
-     stateManager.attach(startScreenState);
-     // [...] boilerplate init nifty omitted
-     nifty.fromXml("Interface/myGui.xml", "start", startScreenState); //one of the XML screen elements needs to reference StartScreenState controller class
-  }
-}
-
-----
-
-
-== Know Your Variables
-[cols="2", options="header"]
-|===
-
-a|Variable
-a|Description
-
-a|${CALL.myMethod()} 
-a| Calls a method in the current ScreenController and gets the method's return String. The method can also be void and have a side effect, e.g. play a sound etc.
-
-a|${ENV.HOME}
-a| Returns the path to user's home directory.
-
-a|${ENV.key} 
-a| Looks up `key` in the environment variables. Use it like Java's System.getEnv(“key).
-
-a|${PROP.key}
-a| looks up `key` in the Nifty properties. Use Nifty.setGlobalproperties(properties) and Nifty.getGlobalproperties(“key). Or SystemGetProperties(key);
-
-|===
-
-See also: link:http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=MarkUp[http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=MarkUp]
-
-
-== Use ScreenControllers for Mutally Exclusive Functionality
-
-Technically you are free to create one ScreenController class for each screen, or reuse the same ScreenController for all or some of them. In the end it may be best to create individual ScreenControllers for functionality that is mutually exclusive.
-
-For example, create a `MyHudScreen.java` for the `hud` screen, and a `MyStartScreen.java` for the `start` screen.
-
-*  Include all user interface methods that are needed during the game (while the HUD is up) in `MyHudScreen.java`. Then make this class control all screens that can be up during the game (the HUD screen, a MiniMap screen, an Inventory screen, an Abilities or Skills screen, etc). All these screens possibly share data (game data, player data), so it makes sense to control them all with methods of the same `MyHudScreen.java` class.
-*  The start screen, however, is mostly independent of the running game. Include all user interface methods that are needed outside the game (while you are on the start screen) in `MyStartScreen.java`. Then make this class control all screens that can be up outside the game (the Start screen, a Settings/Options screen, a HighScore screen, etc). All these classes need to read and write saved game data, so it makes sense to control them all with methods of the same `MyStartScreen.java` class.
-
-
-== Create a "Loading..." Screen
-
-Get the full <<jme3/advanced/loading_screen#,Loading Screen>> tutorial here.
-
-
-== Create a Popup Menu
-
-Get the full <<jme3/advanced/nifty_gui_popup_menu#,Nifty GUI PopUp Menu>> tutorial here.
-
-
-== Add Visual Effects
-
-You can register effects to screen elements.
-
-*  Respond to element events such as onStartScreen, onEndScreen, onHover, onFocus, onActive,
-*  Trigger effects that change movement, blending, size, color, fading, and much more.
-
-Here is an example that moves a panel when the startScreen opens. You place an &lt; effect &gt; tag inside the element that you want to  be affected.
-
-[source,xml]
-----
-
-<panel height="25%" width="35%" ...>
-  <effect>
-    <onStartScreen name="move" mode="in" direction="top" length="300" startDelay="0" inherit="true"/>
-  </effect>
-</panel>
-
-----
-
-Learn more from the NiftyGUI page:
-
-*  link:http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Effects[http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Effects]
-
-
-== Add Sound Effects
-
-Playing sounds using Nifty is also possible with a `playSound` effect as trigger. Remember to first register the sound that you want to play:
-
-[source,xml]
-----
-
-<registerSound id="myclick" filename="Interface/sounds/ButtonClick.ogg" />
-...
-<label>
-  <effect>
-    <onClick name="playSound" sound="myclick"/>
-  </effect>
-</label>
-
-----
-
-
-== Pass ClickLoc From Nifty to Java
-
-After a mouse click, you may want to record the 2D clickLoc and send this info to your Java application. Typical ScreenController methods however only have a String argument. You'd have to convert the String to ints.
-
-To pass the clickLoc as two ints, you can use the special `(int x, int y)` syntax in the ScreenController:
-
-[source,java]
-----
-
-  public void clicked(int x, int y) {
-    // here you can use the x and y of the clickLoc
-  }
-
-----
-
-In the Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ screen code (e.g. XML file) you must call the `(int x, int y)` method _without_ any parameters! 
-
-[source,xml]
-----
-
-<interact onClick="clicked()"/>  
-
-----
-
-You can name the method (here `clicked`) what ever you like, as long as you keep the argument syntax.
-
-
-== Load Several XML Files
-
-The basic Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ example showed how to use the `nifty.fromXML()` method to load one XML file containing all Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ screens.
-The following code sample shows how you can load several XML files into one nifty object. Loading several files with `nifty.addXml()` allows you to split up each screen into one XML file, instead of all into one hard-to-read XML file. 
-
-[source,java]
-----
-
-NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager, inputManager, audioRenderer, viewPort);
-Nifty nifty = niftyDisplay.getNifty();
-nifty.addXml("Interface/Screens/OptionsScreen.xml");
-nifty.addXml("Interface/Screens/StartScreen.xml");
-nifty.gotoScreen("startScreen");
-StartScreenControl screenControl = (StartScreenControl) nifty.getScreen("startScreen").getScreenController();
-OptionsScreenControl optionsControl = (OptionsScreenControl) nifty.getScreen("optionsScreen").getScreenController();
-stateManager.attach(screenControl);
-stateManager.attach(optionsControl);
-guiViewPort.addProcessor(niftyDisplay);
-
-----
-
-
-== Register additional explicit screen controllers
-
-In addition to the `nifty.addXml()` methods to attach many nifty XML files, there exists a `nifty.registerScreenController()` method to explicitly attach more screen controllers. 
-
-The following code sample shows how you can explicitly attach several screen controllers before adding the XML file to nifty, which would otherwise cause nifty to implicitly instantiate the screen controller class. 
-
-[source,java]
-----
-
-NiftyJmeDisplay niftyDisplay = NiftyJmeDisplay.newNiftyJmeDisplay(assetManager, inputManager, audioRenderer, viewPort);
-Nifty nifty = niftyDisplay.getNifty();
-
-nifty.registerScreenController(new OptionsScreenController(randomConstructorArgument));
-nifty.addXml("Interface/Screens/OptionsScreen.xml");
-
-----
-
-
-== Design Your Own Styles
-
-By default, your Nifty XML screens use the built.in styles:
-
-[source,xml]
-----
- <useStyles filename="nifty-default-styles.xml" /> 
-----
-
-But you can switch to a set of custom styles in your game project's asset directory like this:
-
-[source,xml]
-----
- <useStyles filename="Interface/Styles/myCustomStyles.xml" /> 
-----
-
-Inside myCustomStyles.xml you define styles like this:
-
-[source,xml]
-----
-	
-<?xml version="1.0" encoding="UTF-8"?>
-<nifty-styles>
-  <useStyles filename="Interface/Styles/Font/myCustomFontStyle.xml" />
-  <useStyles filename="Interface/Styles/Button/myCustomButtonStyle.xml" />
-  <useStyles filename="Interface/Styles/Label/myCustomLabelStyle.xml" />
-  ...
-</nifty-styles>
-
-----
-
-Learn more about how to create styles by looking at the link:http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Build_from_Source[Nifty GUI source code] for “nifty-style-black”. Copy it as a template and change it to create your own style.
-'''
-
-Learn more from the NiftyGUI page:
-
-*  link:http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Effects[http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Effects]

+ 0 - 387
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/gui/nifty_gui/nifty_gui_xml_layout.adoc

@@ -1,387 +0,0 @@
-= Laying out the GUI in XML
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:keywords: gui, documentation, nifty, hud
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-.  <<jme3/advanced/nifty_gui#,Nifty GUI Concepts>>
-.  <<jme3/advanced/nifty_gui_best_practices#,Nifty GUI Best Practices>>
-.  *Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ XML Layout* or <<jme3/advanced/nifty_gui_java_layout#,Nifty GUI Java Layout>>
-.  <<jme3/advanced/nifty_gui_overlay#,Nifty GUI Overlay>> or <<jme3/advanced/nifty_gui_projection#,Nifty GUI Projection>>
-.  <<jme3/advanced/nifty_gui_java_interaction#,Interact with the GUI from Java>>
-
-You can “draw the +++<abbr title="Graphical User Interface">GUI</abbr>+++ to the screen by writing XML code (alternatively you can also use Java).
-
-
-== Plan Your GUI Layout
-
-
-image::jme3/advanced/gui-layout-draft.png[gui-layout-draft.png,width="",height="",align="right"]
-
-
-In this tutorial, you want to create two game screens: An out-of-game StartScreen that the players see before the game starts; and an in-game link:http://en.wikipedia.org/wiki/HUD_%28video_gaming%29[HUD] that displays info during the game. Before writing code, you plan the +++<abbr title="Graphical User Interface">GUI</abbr>+++ layout, either on paper or in a graphic application.
-
-The StartScreen contains:
-
-*  The background layer has a centered layout and contains an image.
-*  The top layer has a vertical layout, containing 3 panels:
-**  The top panel contains a label with the game title,
-**  The middle panel contains a text field with the game description.
-**  The bottom panel has a horizontal layout and contains two more panels:
-***  The left panel contains a Start button.
-***  The right panel contains a Quit button.
-
-
-
-The HUD contains:
-
-*  The background layer has a centered layout, and contains the partially transparent HUD image.
-*  The top layer has a horizontal layout, containing 2 panels:
-**  The left panel as transparent spacer.
-**  The right panel has a vertical layout containing 2 panels, a label and an image.
-
-
-
-== Implement Your GUI Layout
-
-
-image::jme3/advanced/nifty-screen-layer-panel.png[nifty-screen-layer-panel.png,width="366",height="136",align="right"]
-
-
-Create an empty *screen*.xml file in the `assets/Interface/` directory of your project. ( Rightclick on Interface → New → Other… → +++<abbr title="Graphical User Interface">GUI</abbr>+++ → Empty NiftyGui file)
-Afterwards create the directory `assets/Interface/Fonts` and add a new font e.g. Arial. ( *Rightclick on Interface → New → Other… →* Other → Folder and +++<abbr title="Graphical User Interface">GUI</abbr>+++ → Font)
-
-One XML file can contain several, or even all screens. As a reminder: Nifty displays one screen at a time; a screen contains several layers on top of one another; each layer contains panels that are embedded into another; the panels contain the actual content (text, images, or controls).
-
-
-=== Make Screens
-
-The following minimal XML file contains a start screen and a HUD screen. (Neither has been defined yet.)
-
-[source,xml]
-----
-
-<?xml version="1.0" encoding="UTF-8"?>
-<nifty xmlns="http://nifty-gui.sourceforge.net/nifty-1.3.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://nifty-gui.sourceforge.net/nifty-1.3.xsd http://nifty-gui.sourceforge.net/nifty-1.3.xsd">
-  <screen id="start">
-    <!-- ... -->
-  </screen>
-  <screen id="hud">
-    <!-- ... -->
-  </screen>
-</nifty>
-
-
-----
-
-Every Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ must have a start screen. The others (in this example, the HUD screen) are optional.
-
-*Note:* In the following examples, the XML schema header is abbreviated to just `&lt;nifty&gt;`.
-
-
-=== Make Layers
-
-The following minimal XML file shows how we added layers to the start screen and HUD screen.
-Delete all from the file and add following code:
-
-[source,xml]
-----
-
-<nifty>
-  <screen id="start">
-    <layer id="background" backgroundColor="#000f">
-      <!-- ... -->
-    </layer>
-    <layer id="foreground" backgroundColor="#0000" childLayout="vertical">
-      <!-- ... -->
-    </layer>
-  </screen>
-  <screen id="hud">
-    <layer id="background" backgroundColor="#000f">
-      <!-- ... -->
-    </layer>
-    <layer id="foreground" backgroundColor="#0000" childLayout="horizontal">
-      <!-- ... -->
-    </layer>
-  </screen>
-</nifty>
-
-----
-
-In a layer, you can now add panels and arrange them. Panels are containers that mark the areas where you want to display text, images, or controls (buttons etc) later.
-
-
-=== Make Panels
-
-A panel is the inner-most container (that will contain the actual content: text, images, or controls). You place panels inside layers. The following panels go into in the `start` screen's `foreground` layer:
-
-[source,xml]
-----
-
-      <panel id="panel_top" height="25%" width="75%" align="center" childLayout="center"
-             backgroundColor="#f008">
-      </panel>
-      <panel id="panel_mid" height="50%" width="75%" align="center" childLayout="center"
-             backgroundColor="#0f08">
-      </panel>
-      <panel id="panel_bottom" height="25%" width="75%" align="center" childLayout="horizontal"
-             backgroundColor="#00f8">
-        <panel id="panel_bottom_left" height="50%" width="50%" valign="center" childLayout="center"
-             backgroundColor="#44f8">
-        </panel>
-        <panel id="panel_bottom_right" height="50%" width="50%" valign="center" childLayout="center"
-             backgroundColor="#88f8">
-        </panel>
-      </panel>
-
-----
-
-The following panels go into in the `hud` screen's `foreground` layer:
-
-[source,xml]
-----
-
-      <panel id="panel_left" width="80%" height="100%" childLayout="vertical"
-      backgroundColor="#0f08">
-        <!-- spacer -->
-      </panel>
-      <panel id="panel_right" width="20%" height="100%" childLayout="vertical"
-      backgroundColor="#00f8" >
-        <panel id="panel_top_right1" width="100%" height="15%" childLayout="center"
-             backgroundColor="#00f8">
-        </panel>
-        <panel id="panel_top_right2" width="100%" height="15%" childLayout="center"
-             backgroundColor="#44f8">
-        </panel>
-        <panel id="panel_bot_right" width="100%" height="70%" valign="center"
-             backgroundColor="#88f8">
-        </panel>
-      </panel>
-
-----
-
-The result should look as follows:
-
-
-image::jme3/advanced/nifty-gui-panels.png[nifty-gui-panels.png,width="",height="",align="center"]
-
-
-
-== Adding Content to Panels
-
-See also link:http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Layout_Introduction[Layout Introduction] on the Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ site.
-
-
-=== Add Images
-
-The link:http://hub.jmonkeyengine.org/wiki/lib/exe/fetch.php/jme3:advanced:start-background.png[start-background.png] image is a fullscreen background picture. Add it to `Interface`. In the `start` screen, add the following image element:
-
-[source,xml]
-----
-
-    <layer id="background" childLayout="center">
-        <image filename="Interface/start-background.png"></image>
-    </layer>
-
-----
-
-The link:http://hub.jmonkeyengine.org/wiki/lib/exe/fetch.php/jme3:advanced:hud-frame.png[hud-frame.png] image is a transparent frame that we use as HUD decoration. Add it to `Interface`. In the `hud` screen, add the following image element:
-
-[source,xml]
-----
-
-    <layer id="background" childLayout="center">
-        <image filename="Interface/hud-frame.png"></image>
-    </layer>
-
-----
-
-In order to make the hud-frame.png independent of the screen resolution you are using, you could use the `imageMode` attribute on the image element link:http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Resizable_Images_(ImageMode%3Dresize)_explained[ Resizable Images (ImageMode=resize) explained]
-
-[source,xml]
-----
-
-    <layer id="background" childLayout="center">
-        <image filename="Interface/hud-frame.png" imageMode="resize:40,490,110,170,40,560,40,270,40,560,40,40" width="100%" height="100%"/>
-    </layer>
-
-----
-
-The link:http://hub.jmonkeyengine.org/wiki/lib/exe/fetch.php/jme3:advanced:face1.png[face1.png] image is an image that you want to use as a status icon. Add it to `Interface`.
-In the `hud` screen's `foreground` layer, add the following image element:
-
-[source,xml]
-----
-
-        <panel id="panel_top_right2" width="100%" height="15%" childLayout="center">
-            <image filename="Interface/face1.png" valign="center" align="center" height="50%" width="30%" >
-            </image>
-        </panel>
-
-----
-
-This image is scaled to use 50% of the height and 30% of the width of its container.
-
-
-=== Add Static Text
-
-The game title is a typical example of static text. In the `start` screen, add the following text element:
-
-[source,xml]
-----
-
-      <panel id="panel_top" height="25%" width="75%" align="center" childLayout="center">
-          <text text="My Cool Game" font="Interface/Fonts/Default.fnt" width="100%" height="100%" />
-      </panel>
-
-----
-
-For longer pieces of static text, such as an introduction, you can use wrap=“true. Add the following text element to the `Start screen`:
-
-[source,xml]
-----
-
-      <panel id="panel_mid" height="50%" width="75%" align="center" childLayout="center">
-        <text text="Here goes some text describing the game and the rules and stuff. Incidentally,
-         the text is quite long and needs to wrap at the end of lines. ..."
-        font="Interface/Fonts/Default.fnt" width="100%" height="100%" wrap="true" />
-      </panel>
-
-----
-
-The font used is jME3's default font “Interface/Fonts/Default.fnt which is included in the jMonkeyEngine.JAR. You can add your own fonts to your own `assets/Interface/Fonts` directory.
-Adjust the path to your font-name.
-
-
-=== Add Controls
-
-Before you can use any control, you must load a Control Definition first. Add the following two lines _before_ your screen definitions:
-
-[source,xml]
-----
-
-  <useStyles filename="nifty-default-styles.xml" />
-  <useControls filename="nifty-default-controls.xml" />
-
-----
-
-Note that the useStyles tag must be the first child of the nifty tag, otherwise you will see an error in design view.
-
-
-==== Label Control
-
-Use label controls for text that you want to edit dynamically from Java. One example for this is the score display.
-In the `hud` screen's `foreground` layer, add the following text element:
-
-[source,xml]
-----
-
-        <panel id="panel_top_right" height="100%" width="15%" childLayout="center">
-            <control name="label" color="#000" text="123" width="100%" height="100%" />
-        </panel>
-
-----
-
-Note that the width and height do not scale the bitmap font, but indirectly make certain it is centered. If you want a different size for the font, you need to provide an extra bitmap font (they come with fixed sizes and don't scale well).
-
-
-==== Button Control
-
-Our +++<abbr title="Graphical User Interface">GUI</abbr>+++ plan asks for two buttons on the start screen. You add the Start and Quit buttons to the bottom panel of the `start` screen using the `&lt;control&gt;` element:
-
-[source,xml]
-----
-
-        <panel id="panel_bottom_left" height="50%" width="50%" valign="center" childLayout="center">
-          <control name="button" label="Start" id="StartButton" align="center" valign="center">
-          </control>
-        </panel>
-        <panel id="panel_bottom_right" height="50%" width="50%" valign="center" childLayout="center">
-          <control name="button" label="Quit" id="QuitButton" align="center" valign="center">
-          </control>
-        </panel>
-
-----
-
-Note that these controls don't do anything yet – we'll get to that soon.
-
-Now remove all *backgroundColor=““* tags from your code. They were only needed to show the layout.
-
-Your screen.xml should look like this:
-
-[source,xml]
-----
-
-<?xml version="1.0" encoding="UTF-8"?>
-<nifty xmlns="http://nifty-gui.sourceforge.net/nifty-1.3.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://nifty-gui.sourceforge.net/nifty-1.3.xsd http://nifty-gui.sourceforge.net/nifty-1.3.xsd">
-  <useStyles filename="nifty-default-styles.xml" />
-  <useControls filename="nifty-default-controls.xml" />
-  <screen id="start">
-    <layer id="background" childLayout="center">
-      <image filename="Interface/start-background.png"></image>
-    </layer>
-    <layer id="foreground" childLayout="vertical">
-      <panel id="panel_top" height="25%" width="75%" align="center" childLayout="center">
-        <text text="My Cool Game" font="Interface/Fonts/Default.fnt" width="100%" height="100%" />
-      </panel>
-      <panel id="panel_mid" height="50%" width="75%" align="center" childLayout="center">
-        <text text="Here goes some text describing the game and the rules and stuff. Incidentally, the text is quite long and needs to wrap at the end of lines. ..." font="Interface/Fonts/Default.fnt" width="100%" height="100%" wrap="true" />
-      </panel>
-      <panel id="panel_bottom" height="25%" width="75%" align="center" childLayout="horizontal" >
-        <panel id="panel_bottom_left" height="50%" width="50%" valign="center" childLayout="center">
-          <control name="button" label="Start" id="StartButton" align="center" valign="center"></control>
-        </panel>
-        <panel id="panel_bottom_right" height="50%" width="50%" valign="center" childLayout="center">
-          <control name="button" label="Quit" id="QuitButton" align="center" valign="center"></control>
-        </panel>
-      </panel>
-    </layer>
-  </screen>
-  <screen id="hud">
-    <layer id="background" childLayout="center">
-      <image filename="Interface/hud-frame.png"></image>
-    </layer>
-    <layer id="foreground" childLayout="horizontal">
-      <panel id="panel_left" width="80%" height="100%" childLayout="vertical" ></panel>
-      <panel id="panel_right" width="20%" height="100%" childLayout="vertical">
-        <panel id="panel_top_right1" width="100%" height="15%" childLayout="center">
-          <control name="label" color="#000" text="123" width="100%" height="100%" />
-        </panel>
-        <panel id="panel_top_right2" width="100%" height="15%" childLayout="center">
-          <image filename="Interface/face1.png" valign="center" align="center" height="50%" width="30%" ></image>
-        </panel>
-        <panel id="panel_bot_right" width="100%" height="70%" valign="center" ></panel>
-      </panel>
-    </layer>
-  </screen>
-</nifty>
-
-----
-
-
-==== Other Controls
-
-Nifty additionally offers many customizable controls such as check boxes, text fields, menus, chats, tabs, … See also link:http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Elements[Elements] on the Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ site.
-
-
-== Intermediate Result
-
-When you preview this code in the jMonkeyEngine SDK, our tutorial demo should looks as follows: A start screen with two buttons, and a game screen with a simple HUD frame and a blue cube (which stands for any jME3 game content).
-
-
-image::jme3/advanced/nifty-gui-simple-demo.png[nifty-gui-simple-demo.png,width="",height="",align="center"]
-
-
-Compare this result with the layout draft above.
-
-
-== Next Steps
-
-Integrate the +++<abbr title="Graphical User Interface">GUI</abbr>+++ into the game. Typically, you will overlay the +++<abbr title="Graphical User Interface">GUI</abbr>+++.
-
-*  <<jme3/advanced/nifty_gui_overlay#,Nifty GUI Overlay>> (recommended)
-*  <<jme3/advanced/nifty_gui_projection#,Nifty GUI Projection>> (optional)

+ 0 - 219
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/input/combo_moves.adoc

@@ -1,219 +0,0 @@
-= Combo Moves
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: keyinput, input, documentation
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-The ComboMoves class allows you to define combinations of inputs that trigger special actions. Entering an input combo correctly can bring the player incremental rewards, such as an increased chance to hit, an increased effectiveness, or decreased change of being blocked, whatever the game designer chooses. link:http://en.wikipedia.org/wiki/Combo_%28video_gaming%29[More background info]
-
-Combos are usually a series of inputs, in a fixed order: For example a keyboard combo can look  like: “press Down, then Down+Right together, then Right. 
-
-Usage:
-
-.  Create input triggers 
-.  Define combos
-.  Detect combos in ActionListener 
-.  Execute combos in update loop 
-
-Copy the two classes ComboMoveExecution.java and ComboMove.java into your application and adjust them to your package paths.
-
-
-== Example Code
-
-*  link:http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/input/combomoves/TestComboMoves.java[TestComboMoves.java]
-*  link:http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/input/combomoves/ComboMoveExecution.java[ComboMoveExecution.java] ← required
-*  link:http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/input/combomoves/ComboMove.java[ComboMove.java] ← required
-
-
-== Create Input Triggers
-
-First you <<jme3/advanced/input_handling#,define your game's inputs>> as you usually do: Implement the com.jme3.input.controls.ActionListener interface for your class, and add triggers mappings such as com.jme3.input.controls.KeyTrigger and com.jme3.input.KeyInput. 
-
-For example:
-
-[source,java]
-----
-
-inputManager.addMapping("Left",    new KeyTrigger(KeyInput.KEY_LEFT));
-inputManager.addMapping("Right",   new KeyTrigger(KeyInput.KEY_RIGHT));
-inputManager.addMapping("Up",      new KeyTrigger(KeyInput.KEY_UP));
-inputManager.addMapping("Down",    new KeyTrigger(KeyInput.KEY_DOWN));
-inputManager.addMapping("Attack1", new KeyTrigger(KeyInput.KEY_SPACE));
-...
-inputManager.addListener(this, "Left", "Right", "Up", "Down", "Attack1");
-
-----
-
-
-== Define Combos
-
-For each of  your combo moves, you specify the series of inputs that will trigger it. The order in which you define them is the order the player has to press them for the step to be recorded. When all steps have been recorded, the combo is triggered. 
-
-The following example shows how a fireball combo move is triggered by pressing the navigation keys for “down, down+right, right, in this order.
-
-[source,java]
-----
-
-ComboMove fireball = new ComboMove("Fireball");
-fireball.press("Down").notPress("Right").done();
-fireball.press("Right", "Down").done();
-fireball.press("Right").notPress("Down").done();
-fireball.notPress("Right", "Down").done();
-fireball.setUseFinalState(false);
-
-----
-
-Also create a ComboMoveExecution object for each ComboMove. You need it later to execute the detected combo.
-
-[source,java]
-----
-
-ComboMoveExecution fireballExec = new ComboMoveExecution(fireball);
-
-----
-
-
-=== ComboMove Class Methods
-
-Use the following ComboMove methods to specify the combo:
-[cols="2", options="header"]
-|===
-
-a|ComboMove Method
-a|Description
-
-a|press(“A).done(); +press(“A,“B).done();
-a|Combo step is recorded if A is entered. +Combo step is recorded if A and B are entered simultaneously.
-
-a|notPress(“A).done(); +notPress(“A,“B).done();
-a|Combo step is recorded if A is released. +Combo step is recorded if A and B are both released.
-
-a|press(“A).notPress(“B).done();
-a|Combo step is recorded if A is entered, and not B
-
-a|press(“A).notPress(“B).timeElapsed(0.11f).done();
-a|Combo step is recorded a certain time after A and not B is entered. +etc, etc …
-
-a|setPriority(0.5f);
-a|If there is an ambiguity, a high-priority combo will trigger instead of a low-priority combo. This prevents that a similar looking combo step “hijacks another Combo. Use only once per ComboMove.
-
-a|setUseFinalState(false); +setUseFinalState(true);
-a|This is the final command of the series. +False: Do not wait on a final state, chain combo steps. (?) +True: This is the final state, do not chain combo steps. (?)
-
-|===
-
-The `press()` and `notPress()` methods accept sets of Input Triggers, e.g. `fireball.press(“A,“B,“C).done()`.
-
-The following getters give you more information about the game state:
-[cols="2", options="header"]
-|===
-
-a|ComboMove Method
-a|Usage
-
-a|getCastTime()
-a|Returns the time since the last step has been recorded. (?)
-
-a|getMoveName()
-a|Returns the string of the current combo
-
-a|getPriority()
-a|Returns the priority of this move
-
-|===
-
-
-== Detect Combos in ActionListener
-
-Now that you have specified the combo steps, you want to detect them. You do that in the onAction() method that you get from the ActionListener interface.
-
-Create a HashSet `pressMappings` to track curently pressed mappings, and a ComboMove object `currentMove` to track the current move. 
-
-We also track the cast time of a combo to determine if it has timed out (see update loop below).
-
-[source,java]
-----
-
-private HashSet<String> pressedMappings = new HashSet<String>();
-private ComboMove currentMove = null;
-private float currentMoveCastTime = 0;
-private float time = 0;
-...
-
-public void onAction(String name, boolean isPressed, float tpf) {
-    // Record pressed mappings
-    if (isPressed){
-        pressedMappings.add(name);
-    }else{
-        pressedMappings.remove(name);
-    }
-
-    // The pressed mappings have changed: Update ComboExecution objects
-    List<ComboMove> invokedMoves = new ArrayList<ComboMove>();
-    if (fireballExec.updateState(pressedMappings, time)){
-        invokedMoves.add(fireball);
-    }
-    // ... add more ComboExecs here...
-
-    // If any ComboMoves have been sucessfully triggered:
-    if (invokedMoves.size() > 0){
-        // identify the move with highest priority
-        float priority = 0;
-        ComboMove toExec = null;
-        for (ComboMove move : invokedMoves){
-            if (move.getPriority() > priority){
-                priority = move.getPriority();
-                toExec = move;
-            }
-        }
-        if (currentMove != null && currentMove.getPriority() > toExec.getPriority()){
-            return; // skip lower-priority moves
-        }
-
-        // If a ComboMove has been identified, store it in currentMove
-        currentMove = toExec;
-        currentMoveCastTime = currentMove.getCastTime();
-    }
-}
-
-----
-
-
-== Execute Combos in the Update Loop
-
-Now that you have detected the current move, you want to execute it. You do that in the update loop.
-
-[source,java]
-----
-
-@Override
-public void simpleUpdate(float tpf){
-    time += tpf;
-    fireballExec.updateExpiration(time); 
-    // ... update more ComboExecs here....
-
-    if (currentMove != null){
-        currentMoveCastTime -= tpf;
-        if (currentMoveCastTime <= 0){
-            System.out.println("THIS COMBO WAS TRIGGERED: " + currentMove.getMoveName());
-            // TODO: for each combo, implement special actions here
-            currentMoveCastTime = 0;
-            currentMove = null;
-        }
-    }
-}
-----
-
-Test `currentMove.getMoveName()` and proceed to call methods that implement any special actions and bonuses. This is up to you and depends individually on your game.
-
-
-== Why Combos?
-
-Depending on the game genre, the designer can reward the players' intrinsical or extrinsical skills:
-
-*  (intrinsical:) RPGs typically calculate the success of an attack from the character's in-game training level: The player plays the role of a character whose skill level is defined in numbers. RPGs typically do not offer any Combos.
-*  (extrinsical:) Sport and fighter games typically choose to reward the player's “manual skills: The success of a special move solely depends on the player's own dexterity. These games typically offer optional Combos.

+ 0 - 332
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/input/input_handling.adoc

@@ -1,332 +0,0 @@
-= Input Handling
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: keyinput, input, documentation
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-Users interact with your jME3 application with different input devices – the mouse, the keyboard, or a joystick. To respond to inputs we use the `inputManager` object in `SimpleApplication`.
-
-This is how you add interaction to your game:
-
-.  For each action, choose the trigger(s) (a key or mouse click etc)
-.  For each action, add a trigger mapping to the inputManager
-.  Create at least one listener in SimpleApplication
-.  For each action, register its mappings to a listener
-.  Implement each action in the listener
-
-
-== Code Samples
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/input/TestControls.java[TestControls.java]
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/input/TestJoystick.java[TestJoystick.java]
-
-
-== 1. Choose Trigger
-
-Choose one or several key/mouse events for the interaction. We use `KeyTrigger`, `MouseAxisTrigger`, `MouseButtonTrigger`, `JoyAxisTrigger` and `JoyButtonTrigger` constants from the `com.jme3.input.controls` package. 
-
-[NOTE]
-====
-The MouseAxis and JoyAxis triggers go along the X axis (right/left) or Y axis (up/down). These Triggers come with extra booleans for the negative half of the axis (left, down). Remember to write code that listens to the negative (true) and positive (false) axis!
-====
-
-[cols="2", options="header"]
-
-|===
-
-a| Trigger 
-a| Code 
-
-a| Mouse button: Left Click 
-a| MouseButtonTrigger(MouseInput.BUTTON_LEFT) 
-
-a| Mouse button: Right Click 
-a| MouseButtonTrigger(MouseInput.BUTTON_RIGHT) 
-
-a| Mouse button: Middle Click 
-a| MouseButtonTrigger(MouseInput.BUTTON_MIDDLE) 
-
-a| Mouse movement: Right 
-a| MouseAxisTrigger(MouseInput.AXIS_X, true) 
-
-a| Mouse movement: Left 
-a| MouseAxisTrigger(MouseInput.AXIS_X, false)
-
-a| Mouse movement: Up 
-a| MouseAxisTrigger(MouseInput.AXIS_Y, true) 
-
-a| Mouse movement: Down 
-a| MouseAxisTrigger(MouseInput.AXIS_Y, false) 
-
-a| Mouse wheel: Up 
-a| MouseAxisTrigger(MouseInput.AXIS_WHEEL,false) 
-
-a| Mouse wheel: Down 
-a| MouseAxisTrigger(MouseInput.AXIS_WHEEL,true) 
-
-a| NumPad: 1, 2, 3, … 
-a| KeyTrigger(KeyInput.KEY_NUMPAD1) … 
-
-a| Keyboard: 1, 2 , 3, … 
-a| KeyTrigger(KeyInput.KEY_1) … 
-
-a| Keyboard: A, B, C, … 
-a| KeyTrigger(KeyInput.KEY_A) … 
-
-a| Keyboard: Spacebar 
-a| KeyTrigger(KeyInput.KEY_SPACE) 
-
-a| Keyboard: Shift 
-a| KeyTrigger(KeyInput.KEY_RSHIFT), +
-KeyTrigger(KeyInput.KEY_LSHIFT) 
-
-a| Keyboard: F1, F2, … 
-a| KeyTrigger(KeyInput.KEY_F1) … 
-
-a| Keyboard: Return, Enter 
-<a| KeyTrigger(KeyInput.KEY_RETURN), +
-KeyTrigger(KeyInput.KEY_NUMPADENTER)  
-
-a| Keyboard: PageUp, PageDown 
-a| KeyTrigger(KeyInput.KEY_PGUP), +
-KeyTrigger(KeyInput.KEY_PGDN) 
-
-a| Keyboard: Delete, Backspace 
-a| KeyTrigger(KeyInput.KEY_BACK), +
-KeyTrigger(KeyInput.KEY_DELETE) 
-
-a| Keyboard: Escape 
-a| KeyTrigger(KeyInput.KEY_ESCAPE) 
-
-a| Keyboard: Arrows 
-a| KeyTrigger(KeyInput.KEY_DOWN), +
-KeyTrigger(KeyInput.KEY_UP) +
-KeyTrigger(KeyInput.KEY_LEFT), KeyTrigger(KeyInput.KEY_RIGHT) 
-
-a| Joystick Button: 
-a| JoyButtonTrigger(0, JoyInput.AXIS_POV_X), +
-JoyButtonTrigger(0, JoyInput.AXIS_POV_Y) ? 
-
-a| Joystick Movement: Right 
-a| JoyAxisTrigger(0, JoyInput.AXIS_POV_X, true) 
-
-a| Joystick Movement: Left 
-a| JoyAxisTrigger(0, JoyInput.AXIS_POV_X, false) 
-
-a| Joystick Movement: Forward 
-a| JoyAxisTrigger(0, JoyInput.AXIS_POV_Z, true) 
-
-a| Joystick Movement: Backward
-a| JoyAxisTrigger(0, JoyInput.AXIS_POV_Z, false) 
-
-|===
-
-In your IDE, use code completion to quickly look up Trigger literals. In the jMonkeyEngine SDK for example, press ctrl-space or ctrl-/ after `KeyInput.|` to choose from the list of all keys.
-
-
-== 2. Remove Default Trigger Mappings
-
-[source]
-----
-inputManager.deleteMapping( SimpleApplication.INPUT_MAPPING_MEMORY );
-----
-[cols="3", options="header"]
-|===
-
-a|Default Mapping
-a|Key
-a|Description
-
-a|INPUT_MAPPING_HIDE_STATS
-a|F5
-a|Hides the statistics in the bottom left.
-
-a|INPUT_MAPPING_CAMERA_POS
-a|KEY_C
-a|Prints debug output about the camera.
-
-a|INPUT_MAPPING_MEMORY
-a|KEY_M
-a|Prints debug output for memory usage.
-
-a|INPUT_MAPPING_EXIT
-a|KEY_ESCAPE
-a|Closes the application by calling `stop();`. Typically you do not remove this, unless you replace it by another way of quitting gracefully.
-
-|===
-
-
-== 3. Add Custom Trigger Mapping
-
-When initializing the application, add a Mapping for each Trigger. 
-
-Give the mapping a meaningful name. The name should reflect the action, not the button/key (because buttons/keys can change). Here some examples:
-
-[source,java]
-----
-
-inputManager.addMapping("Pause Game", new KeyTrigger(KeyInput.KEY_P));
-inputManager.addMapping("Rotate",     new KeyTrigger(KeyInput.KEY_SPACE));
-...
-
-----
-
-There are cases where you may want to provide more then one trigger for one action. For example, some users prefer the WASD keys to navigate, while others prefer the arrow keys. Add several triggers for one mapping, by separating the Trigger objects with commas:
-
-[source,java]
-----
-
-inputManager.addMapping("Left",  new KeyTrigger(KeyInput.KEY_A), 
-                                 new KeyTrigger(KeyInput.KEY_LEFT)); // A and left arrow
-inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D), 
-                                 new KeyTrigger(KeyInput.KEY_RIGHT)); // D and right arrow
-                                 ...
-
-----
-
-
-== 4. Create Listeners
-
-The jME3 input manager supports two types of event listeners for inputs: AnalogListener and ActionListener. You can use one or both listeners in the same application. Add one or both of the following code snippets to your main SimpleApplication-based class to activate the listeners.
-
-[NOTE]
-====
-The two input listeners do not know, and do not care, which actual key was pressed. They only know which _named input mapping_ was triggered. 
-====
-
-
-=== ActionListener
-
-`com.jme3.input.controls.ActionListener`
-
-*  Use for absolute “button pressed or released?, “on or off? actions. 
-**  Examples: Pause/unpause, a rifle or revolver shot, jump, click to select.
-
-*  JME gives you access to:
-**  The mapping name of the triggered action.
-**  A boolean whether the trigger is still pressed or has just been released.
-**  A float of the current time-per-frame as timing factor
-
-[source,java]
-----
-
-private ActionListener actionListener = new ActionListener() {
-  public void onAction(String name, boolean keyPressed, float tpf) {
-     /** TODO: test for mapping names and implement actions */
-  }
-};
-----
-
-
-=== AnalogListener
-
-`com.jme3.input.controls.AnalogListener`
-
-*  Use for continuous and gradual actions.
-**  Examples: Walk, run, rotate, accelerate vehicle, strafe, (semi-)automatic weapon shot
-
-*  JME gives you access to:
-**  The mapping name of the triggered action.
-**  A gradual float value between how long the trigger has been pressed.
-**  A float of the current time-per-frame as timing factor
-
-
-[source,java]
-----
-
-private AnalogListener analogListener = new AnalogListener() {
-  public void onAnalog(String name, float keyPressed, float tpf) {
-     /** TODO: test for mapping names and implement actions */
-  }
-};
-----
-
-
-== 4. Register Mappings to Listeners
-
-To activate the mappings, you must register them to a Listener. Write your registration code after the code block where you have added the mappings to the inputManager.
-
-In the following example, you register the “Pause Game mapping to the `actionListener` object, because pausing a game is in “either/or decision.
-
-[source,java]
-----
-inputManager.addListener(actionListener, new String[]{"Pause Game"});
-----
-
-In the following example, you register navigational mappings to the `analogListener` object, because walking is a continuous action. Players typically keep the key pressed to express continuity, for example when they want to “walk on or “accelerate.
-
-[source,java]
-----
-inputManager.addListener(analogListener, new String[]{"Left", "Right"});
-----
-
-As you see, you can add several listeners in one String array. You can call the addListener() method more than once, each time with a subset of your list, if that helps you keep you code tidy. Again, the Listeners do not care about actual which keys are configured, you only register named trigger mappings.
-
-
-[TIP]
-====
-Did you register an action, but it does not work? Check the string's capitalization and spelling, it's case sensitive!
-====
-
-
-
-== 5. Implement Actions in Listeners
-
-You specify the action to be triggered where it says TODO in the Listener code snippets. Typically, you write a series of if/else conditions, testing for all the mapping names, and then calling the respective action. 
-
-Make use of the distinction between `if` and `else if` in this conditional.
-
-*  If several actions can be triggered simultaneously, test for all of these with a series of bare `if`s. For example, a character can be running forward _and_ to the left.
-*  If certain actions exclude one another, test for them with `else if`, the the rest of the exclusive tests can be skipped and you save some miliseconds. For example, you either shoot or pick something up.
-
-
-=== ActionListener
-
-In the most common case, you want an action to be triggered once, in the moment when the button or key trigger is released. For example, when the player presses a key to open a door, or clicks to pick up an item. For these cases, use an ActionListener and test for `&amp;&amp; !keyPressed`, like shown in the following example. 
-
-[source,java]
-----
-private ActionListener actionListener = new ActionListener() {
-    public void onAction(String name, boolean keyPressed, float tpf) {
-
-      if (name.equals("Pause Game") && !keyPressed) { // test?
-        isRunning = !isRunning;                       // action!
-      } 
-      
-      if ...
-
-    }
-  };
-
-----
-
-
-=== AnalogListener
-
-The following example shows how you define actions with an AnalogListener. These actions are triggered continuously, as long (intensity `value`) as the named key or mouse button is down. Use this listeners for semi-automatic weapons and navigational actions.
-
-[source,java]
-----
-private AnalogListener analogListener = new AnalogListener() {
-    public void onAnalog(String name, float value, float tpf) {
-
-      if (name.equals("Rotate")) {         // test?
-        player.rotate(0, value*speed, 0);  // action!
-      } 
-      
-      if ...
-
-    }
-  };
-----
-
-
-== Let Users Remap Keys
-
-It is likely that your players have different keyboard layouts, are used to “reversed mouse navigation, or prefer different navigational keys than the ones that you defined. You should create an options screen that lets users customize their mouse/key triggers for your mappings. Replace the trigger literals in the `inputManager.addMapping()` lines with variables, and load sets of triggers when the game starts. 
-
-The abstraction of separating triggers and mappings has the advantage that you can remap triggers easily. Your code only needs to remove and add some trigger mappings. The core of the code (the listeners and actions) remains unchanged. 

+ 0 - 119
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/input/mouse_picking.adoc

@@ -1,119 +0,0 @@
-= Mouse Picking
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:keywords: documentation, node, ray, click, collision, keyinput, input
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-Mouse picking means that the user clicks an object in the scene to select it, or to interact with it otherwise. Games use picking to implement aiming and shooting, casting spells, picking up objects, selecting targets, dragging and moving objects, etc. Mouse picking can be done using fixed crosshairs, or using the mouse pointer.
-
-image:jme3/advanced/mouse-picking.png[mouse-picking.png,width="",height=""]
-
-See <<jme3/advanced/input_handling#,Input Handling>> for details on how to define the necessary input triggers, input mappings, and input listeners.
-
-
-== Pick a Target Using Fixed Crosshairs
-
-The following `pick target` input mapping implements an action that determines what a user clicked. It assumes that the mouse pointer is invisible and there are crosshairs painted in the center of the screen. It assumes that the user aims the crosshairs at an object in the scene and clicks. You use Ray Casting to identify the geometry that was picked by the user. Use this method together with a first-person flyCam.
-
-.  Activate the first-person camera: `flyCam.setEnabled(true);`
-.  Keep mouse pointer invisible using `inputManager.setCursorVisible(false)`.
-.  Map the `pick target` action to a MouseButtonTrigger.
-.  Implement the action in the Listener.
-
-The following example rotates Spatials named “Red Box or “Blue Box when they are clicked. Modify this code to do whatever your game needs to do with the identified target (shoot it, take it, move it, etc).
-
-[source,java]
-----
-
-  private AnalogListener analogListener = new AnalogListener() {
-    public void onAnalog(String name, float intensity, float tpf) {
-        if (name.equals("pick target")) {
-         // Reset results list.
-         CollisionResults results = new CollisionResults();
-         // Aim the ray from camera location in camera direction
-         // (assuming crosshairs in center of screen).
-         Ray ray = new Ray(cam.getLocation(), cam.getDirection());
-         // Collect intersections between ray and all nodes in results list.
-         rootNode.collideWith(ray, results);
-         // Print the results so we see what is going on
-         for (int i = 0; i < results.size(); i++) {
-           // For each “hit”, we know distance, impact point, geometry.
-           float dist = results.getCollision(i).getDistance();
-           Vector3f pt = results.getCollision(i).getContactPoint();
-           String target = results.getCollision(i).getGeometry().getName();
-           System.out.println("Selection #" + i + ": " + target + " at " + pt + ", " + dist + " WU away.");
-         }
-         // 5. Use the results -- we rotate the selected geometry.
-         if (results.size() > 0) {
-           // The closest result is the target that the player picked:
-           Geometry target = results.getClosestCollision().getGeometry();
-           // Here comes the action:
-           if(target.getName().equals("Red Box"))
-             target.rotate(0, - intensity, 0);
-           else if(target.getName().equals("Blue Box"))
-             target.rotate(0, intensity, 0);
-         }
-        } // else if ...
-    }
-  };
-
-----
-
-
-== Pick a Target Using the Mouse Pointer
-
-The following `pick target` input mapping implements an action that determines what a user clicked. It assumes that the mouse pointer is visible, and the user aims the cursor at an object in the scene. You use ray casting to determine the geometry that was picked by the user.
-
-*Note:* Picking with a visible mouse pointer implies that your application can no longer use the default flyCam where the MouseAxisTrigger rotates the camera. You have to deactivate the flyCam mappings and provide custom mappings. Either different inputs rotate the camera, or the camera is fixed.
-
-.  Map the `pick target` action to a MouseButtonTrigger.
-.  Make the mouse pointer visible using `inputManager.setCursorVisible(true)`.
-.  Remap the inputs for camera rotation, or deactivate camera rotation.
-.  Implement the action in the Listener.
-
-The following example rotates Spatials named “Red Box or “Blue Box when they are clicked. Modify this code to do whatever your game needs to do with the identified target (shoot it, take it, move it, etc).
-
-[source,java]
-----
-
-private AnalogListener analogListener = new AnalogListener() {
-    public void onAnalog(String name, float intensity, float tpf) {
-      if (name.equals("pick target")) {
-        // Reset results list.
-        CollisionResults results = new CollisionResults();
-        // Convert screen click to 3d position
-        Vector2f click2d = inputManager.getCursorPosition();
-        Vector3f click3d = cam.getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 0f).clone();
-        Vector3f dir = cam.getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 1f).subtractLocal(click3d).normalizeLocal();
-        // Aim the ray from the clicked spot forwards.
-        Ray ray = new Ray(click3d, dir);
-        // Collect intersections between ray and all nodes in results list.
-        rootNode.collideWith(ray, results);
-        // (Print the results so we see what is going on:)
-        for (int i = 0; i < results.size(); i++) {
-          // (For each “hit”, we know distance, impact point, geometry.)
-          float dist = results.getCollision(i).getDistance();
-          Vector3f pt = results.getCollision(i).getContactPoint();
-          String target = results.getCollision(i).getGeometry().getName();
-          System.out.println("Selection #" + i + ": " + target + " at " + pt + ", " + dist + " WU away.");
-        }
-        // Use the results -- we rotate the selected geometry.
-        if (results.size() > 0) {
-          // The closest result is the target that the player picked:
-          Geometry target = results.getClosestCollision().getGeometry();
-          // Here comes the action:
-          if (target.getName().equals("Red Box")) {
-            target.rotate(0, -intensity, 0);
-          } else if (target.getName().equals("Blue Box")) {
-            target.rotate(0, intensity, 0);
-          }
-        }
-      } // else if ...
-    }
-  };
-
-----

+ 0 - 459
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/input/walking_character.adoc

@@ -1,459 +0,0 @@
-= Walking Character
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:keywords: documentation, physics, input, animation, character, NPC, collision
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-In the <<jme3/beginner/hello_collision#,Hello Collision>> tutorial and the link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/bullet/TestQ3.java[TestQ3.java] code sample you have seen how to create collidable landscapes and walk around in a first-person perspective. The first-person camera is enclosed by a collision shape and is steered by the BetterCharacterControl.
-
-Other games however require a third-person perspective of the character: In these cases you use a CharacterControl on a Spatial. This example also shows how to set up custom navigation controls, so you can press WASD to make the third-person character walk; and how to implement dragging the mouse to rotate.
-
-
-[WARNING]
-====
-Some details on this page still need to be updated from old CharacterControl +++<abbr title="Application Programming Interface">API</abbr>+++ to BetterCharacterControl +++<abbr title="Application Programming Interface">API</abbr>+++.
-====
-
-
-
-== Sample Code
-
-Several related code samples can be found here:
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCharacter.java[TestPhysicsCharacter.java] (third-person view)
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/bullet/TestWalkingChar.java[TestWalkingChar.java] (third-person view)
-**  Uses also link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/bullet/BombControl.java[BombControl.java]
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/bullet/TestQ3.java[TestQ3.java] (first-person view)
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/helloworld/HelloCollision.java[HelloCollision.java] (first-person view)
-
-The code in this tutorial is a combination of these samples.
-
-
-== BetterCharacterControl
-
-Motivation: When you load a character model, give it a RigidBodyControl, and use forces to push it around, you do not get the desired behaviour: RigidBodyControl'ed objects (such as cubes and spheres) roll or tip over when pushed by physical forces. This is not the behaviour that you expect of a walking character. JME3's BulletPhysics integration offers a BetterCharacterControl with a `setWalkDirection()` method. You use it to create simple characters that treat floors and walls as solid, and always stays locked upright while moving.
-
-This code sample creates a simple upright Character:
-
-[source,java]
-----
-
-// Load any model
-Node myCharacter = (Node) assetManager.loadModel("Models/myCharacterModel.mesh.xml");
-rootNode.attachChild(myCharacter);
-// Create a appropriate physical shape for it
-CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1);
-CharacterControl myCharacter_phys = new CharacterControl(capsuleShape, 0.01f);
-// Attach physical properties to model and PhysicsSpace
-myCharacter.addControl(myCharacter_phys);
-bulletAppState.getPhysicsSpace().add(myCharacter_phys);
-
-----
-
-To use the BetterCharacterControl, you may load your character like this:
-
-[source,java]
-----
-
-// Load any model
-Spatial playerSpatial = assetManager.loadModel("Models/Oto/Oto.mesh.xml");
-player =  (Node)playerSpatial; // You can set the model directly to the player. (We just wanted to explicitly show that it's a spatial.)
-Node playerNode = new Node(); // You can create a new node to wrap your player to adjust the location. (This allows you to solve issues with character sinking into floor, etc.)
-playerNode.attachChild(player); // add it to the wrapper
-player.move(0,3.5f,0); // adjust position to ensure collisions occur correctly.
-player.setLocalScale(0.5f); // optionally adjust scale of model
-// setup animation:
-        control = player.getControl(AnimControl.class);
-        control.addListener(this);
-        channel = control.createChannel();
-        channel.setAnim("stand");
-playerControl = new BetterCharacterControl(1.5f, 6f, 1f); // construct character. (If your character bounces, try increasing height and weight.)
-playerNode.addControl(playerControl); // attach to wrapper
-// set basic physical properties:
-        playerControl.setJumpForce(new Vector3f(0,5f,0));
-        playerControl.setGravity(new Vector3f(0,1f,0));
-playerControl.warp(new Vector3f(0,10,10)); // warp character into landscape at particular location
-// add to physics state
-        bulletAppState.getPhysicsSpace().add(playerControl);
-        bulletAppState.getPhysicsSpace().addAll(playerNode);
-rootNode.attachChild(playerNode); // add wrapper to root
-
-----
-
-== Character Control
-
-
-[IMPORTANT]
-====
-The BulletPhysics CharacterControl only collides with “real PhysicsControls (RigidBody). It does not detect collisions with other CharacterControls! If you need additional collision checks, add GhostControls to your characters and create a custom <<jme3/advanced/physics_listeners#,collision listener>> to respond.
-====
-
-
-A CharacterControl is a special kinematic object with restricted movement. CharacterControls have a fixed “upward axis, this means they do not topple over when walking over an obstacle (as opposed to RigidBodyControls), which simulates a being's ability to balance upright. A CharacterControl can jump and fall along its upward axis, and it can scale steps of a certain height/steepness.
-[cols="2", options="header"]
-|===
-
-a| CharacterControl Method
-a| Property
-
-a| setUpAxis(1)
-a| Fixed upward axis. Values: 0 = X axis , 1 = Y axis , 2 = Z axis. +
-Default: 1, because for characters and vehicles, up is typically along the Y axis.
-
-a| setJumpSpeed(10f)
-a| Jump speed (movement along upward-axis)
-
-a| setFallSpeed(20f)
-a| Fall speed (movement opposite to upward-axis)
-
-a| setMaxSlope(1.5f)
-a| How steep the slopes and steps are that the character can climb without considering them an obstacle. Higher obstacles need to be jumped. Vertical height in world units.
-
-<a| setGravity(1f)
-a| The intensity of gravity for this CharacterControl'ed entity. Tip: To change the direction of gravity for a character, modify the up axis.
-
-a| setWalkDirection(new Vector3f(0f,0f,0.1f))
-a| (CharacterControl only) Make a physical character walk continuously while checking for floors and walls as solid obstacles. This should probably be called “setPositionIncrementPerSimulatorStep. This argument is neither a direction nor a velocity, but the amount to increment the position each physics tick: vector length = accuracy*speed in m/s. +
-Use `setWalkDirection(Vector3f.ZERO)` to stop a directional motion.
-
-|===
-
-For best practices on how to use `setWalkDirection()`, see the Navigation Inputs example below.
-
-
-== Walking Character Demo
-
-
-=== Code Skeleton
-
-[source,java]
-----
-public class WalkingCharacterDemo extends SimpleApplication
-        implements ActionListener, AnimEventListener {
-
-  public static void main(String[] args) {
-    WalkingCharacterDemo app = new WalkingCharacterDemo();
-    app.start();
-  }
-
-  public void simpleInitApp() { }
-
-  public void simpleUpdate(float tpf) { }
-
-  public void onAction(String name, boolean isPressed, float tpf) { }
-
-  public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) { }
-
-  public void onAnimChange(AnimControl control, AnimChannel channel, String animName) { }
-
-----
-
-
-=== Overview
-
-To create a walking character:
-
-.  (Unless you already have it) Activate physics in the scene by adding a <<jme3/advanced/physics#,BulletAppState>>.
-.  Init the scene by loading the game level model (terrain or floor/buildings), and giving the scene a MeshCollisionShape.
-.  Create the animated character:
-..  Load an animated character model.
-..  Add a CharacterControl to the model.
-
-.  Set up animation channel and controllers.
-.  Add a ChaseCam or CameraNode.
-.  Handle navigational inputs.
-
-
-=== Activate Physics
-
-[source,java]
-----
-
-private BulletAppState bulletAppState;
-...
-public void simpleInitApp() {
-    bulletAppState = new BulletAppState();
-    //bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
-    stateManager.attach(bulletAppState);
-    ...
-}
-
-----
-
-
-=== Initialize the Scene
-
-In the simpleInitApp() method you initialize the scene and give it a MeshCollisionShape. The sample in the jme3 sources uses a custom helper class that simply creates a flat floor and drops some cubes and spheres on it:
-
-[source,java]
-----
-
-public void simpleInitApp() {
-  ...
-  PhysicsTestHelper.createPhysicsTestWorld(rootNode,
-      assetManager, bulletAppState.getPhysicsSpace());
-  ...
-
-----
-
-In a real game, you would load a scene model here instead of a test world. You can load a model from a local or remote zip file, and scale and position it:
-
-[source,java]
-----
-
-private Node gameLevel;
-..
-public void simpleInitApp() {
-  ...
-  //assetManager.registerLocator("quake3level.zip", ZipLocator.class);
-  assetManager.registerLocator(
-  "http://jmonkeyengine.googlecode.com/files/quake3level.zip",
-    HttpZipLocator.class);
-  MaterialList matList = (MaterialList) assetManager.loadAsset("Scene.material");
-  OgreMeshKey key = new OgreMeshKey("main.meshxml", matList);
-  gameLevel = (Node) assetManager.loadAsset(key);
-  gameLevel.setLocalTranslation(-20, -16, 20);
-  gameLevel.setLocalScale(0.10f);
-  gameLevel.addControl(new RigidBodyControl(0));
-  rootNode.attachChild(gameLevel);
-  bulletAppState.getPhysicsSpace().addAll(gameLevel);
-  ...
-
-----
-
-Also, add a light source to be able to see the scene.
-
-[source,java]
-----
-
-  AmbientLight light = new AmbientLight();
-  light.setColor(ColorRGBA.White.mult(2));
-  rootNode.addLight(light);
-
-----
-
-
-=== Create the Animated Character
-
-You create an animated model, such as Oto.mesh.xml.
-
-.  Place the “Oto model into the `assets/Models/Oto/` directory of your project.
-.  Create the CollisionShape and adjust the capsule radius and height to fit your character model.
-.  Create the CharacterControl and adjust the stepheight (here 0.05f) to the height that the character can climb up without jumping.
-.  Load the visible model. Make sure its start position does not overlap with scene objects.
-.  Add the CharacterControl to the model and register it to the physicsSpace.
-.  Attach the visible model to the rootNode.
-
-[source,java]
-----
-
-private CharacterControl character;
-private Node model;
-...
-public void simpleInitApp() {
-  ...
-  CapsuleCollisionShape capsule = new CapsuleCollisionShape(3f, 4f);
-  character = new CharacterControl(capsule, 0.05f);
-  character.setJumpSpeed(20f);
-  model = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
-  model.addControl(character);
-  bulletAppState.getPhysicsSpace().add(character);
-  rootNode.attachChild(model);
-  ...
-
-----
-
-
-[TIP]
-====
-*Did you know?* A CapsuleCollisionShape is a cylinder with rounded top and bottom. A capsule rotated upright is a good collision shape for a humanoid character since its roundedness reduces the risk of getting stuck on obstacles.
-====
-
-
-
-=== Set Up AnimControl and AnimChannels
-
-Create several AnimChannels, one for each animation that can happen simultaneously. In this example, you create one channel for walking and one for attacking. (Because the character can attack with its arms and walk with the rest of the body at the same time.)
-
-[source,java]
-----
-
-private AnimChannel animationChannel;
-private AnimChannel attackChannel;
-private AnimControl animationControl;
-...
-public void simpleInitApp() {
-  ...
-  animationControl = model.getControl(AnimControl.class);
-  animationControl.addListener(this);
-  animationChannel = animationControl.createChannel();
-  attackChannel = animationControl.createChannel();
-  attackChannel.addBone(animationControl.getSkeleton().getBone("uparm.right"));
-  attackChannel.addBone(animationControl.getSkeleton().getBone("arm.right"));
-  attackChannel.addBone(animationControl.getSkeleton().getBone("hand.right"));
-  ...
-
-----
-
-The attackChannel only controls one arm, while the walking channels controls the whole character.
-
-
-=== Add ChaseCam / CameraNode
-
-[source,java]
-----
-
-private ChaseCamera chaseCam;
-
-...
-
-public void simpleInitApp() {
-  ...
-  flyCam.setEnabled(false);
-  chaseCam = new ChaseCamera(cam, model, inputManager);
-  ...
-
-----
-
-
-=== Handle Navigation
-
-Configure custom key bindings for WASD keys that you will use to make the character walk. Then calculate the vector where the user wants the character to move. Note the use of the special `setWalkDirection()` method below.
-
-[source,java]
-----
-
-// track directional input, so we can walk left-forward etc
-private boolean left = false, right = false, up = false, down = false;
-...
-
-public void simpleInitApp() {
-  ...
-  // configure mappings, e.g. the WASD keys
-  inputManager.addMapping("CharLeft", new KeyTrigger(KeyInput.KEY_A));
-  inputManager.addMapping("CharRight", new KeyTrigger(KeyInput.KEY_D));
-  inputManager.addMapping("CharForward", new KeyTrigger(KeyInput.KEY_W));
-  inputManager.addMapping("CharBackward", new KeyTrigger(KeyInput.KEY_S));
-  inputManager.addMapping("CharJump", new KeyTrigger(KeyInput.KEY_RETURN));
-  inputManager.addMapping("CharAttack", new KeyTrigger(KeyInput.KEY_SPACE));
-  inputManager.addListener(this, "CharLeft", "CharRight");
-  inputManager.addListener(this, "CharForward", "CharBackward");
-  inputManager.addListener(this, "CharJump", "CharAttack");
-  ...
-}
-
-----
-
-Respond to the key bindings by setting variables that track in which direction you will go. This allows us to steer the character forwards and to the left at the same time. *Note that no actual walking happens here yet!* We just track the input.
-
-[source,java]
-----
-
-@Override
-public void onAction(String binding, boolean value, float tpf) {
-  if (binding.equals("CharLeft")) {
-      if (value) left = true;
-      else left = false;
-  } else if (binding.equals("CharRight")) {
-      if (value) right = true;
-      else right = false;
-  } else if (binding.equals("CharForward")) {
-      if (value) up = true;
-      else up = false;
-  } else if (binding.equals("CharBackward")) {
-      if (value) down = true;
-      else down = false;
-  } else if (binding.equals("CharJump"))
-      character.jump();
-  if (binding.equals("CharAttack"))
-    attack();
-}
-
-----
-
-The player can attack and walk at the same time. `Attack()` is a custom method that triggers an attack animation in the arms. Here you should also add custom code to play an effect and sound, and to determine whether the hit was successful.
-
-[source,java]
-----
-
-private void attack() {
-    attackChannel.setAnim("Dodge", 0.1f);
-    attackChannel.setLoopMode(LoopMode.DontLoop);
-}
-
-----
-
-Finally, the update loop looks at the directional variables and moves the character accordingly. Since this is a special kinematic CharacterControl, we use the `setWalkDirection()` method.
-
-The variable `airTime` tracks how long the character is off the ground (e.g. when jumping or falling) and adjusts the walk and stand animations acccordingly.
-
-[source,java]
-----
-
-private Vector3f walkDirection = new Vector3f(0,0,0); // stop
-
-private float airTime = 0;
-
-public void simpleUpdate(float tpf) {
-  Vector3f camDir = cam.getDirection().clone();
-  Vector3f camLeft = cam.getLeft().clone();
-  camDir.y = 0;
-  camLeft.y = 0;
-  camDir.normalizeLocal();
-  camLeft.normalizeLocal();
-  walkDirection.set(0, 0, 0);
-
-  if (left)  walkDirection.addLocal(camLeft);
-  if (right) walkDirection.addLocal(camLeft.negate());
-  if (up) walkDirection.addLocal(camDir);
-  if (down) walkDirection.addLocal(camDir.negate());
-
-  if (!character.onGround()) { // use !character.isOnGround() if the character is a BetterCharacterControl type.
-      airTime += tpf;
-  } else {
-      airTime = 0;
-  }
-
-  if (walkDirection.lengthSquared() == 0) { //Use lengthSquared() (No need for an extra sqrt())
-      if (!"stand".equals(animationChannel.getAnimationName())) {
-        animationChannel.setAnim("stand", 1f);
-      }
-  } else {
-      character.setViewDirection(walkDirection);
-      if (airTime > .3f) {
-        if (!"stand".equals(animationChannel.getAnimationName())) {
-          animationChannel.setAnim("stand");
-        }
-      } else if (!"Walk".equals(animationChannel.getAnimationName())) {
-        animationChannel.setAnim("Walk", 0.7f);
-      }
-    }
-
-  walkDirection.multLocal(25f).multLocal(tpf);// The use of the first multLocal here is to control the rate of movement multiplier for character walk speed. The second one is to make sure the character walks the same speed no matter what the frame rate is.
-  character.setWalkDirection(walkDirection); // THIS IS WHERE THE WALKING HAPPENS
-}
-
-----
-
-This method resets the walk animation.
-
-[source,java]
-----
-
-public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
-        if (channel == attackChannel) channel.setAnim("stand");
-}
-
-public void onAnimChange(AnimControl control, AnimChannel channel, String animName) { }
-
-----
-
-
-== See also
-
-*  link:https://hub.jmonkeyengine.org/t/bettercharactercontrol-in-the-works/25242[https://hub.jmonkeyengine.org/t/bettercharactercontrol-in-the-works/25242]

+ 0 - 153
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/io/save_and_load.adoc

@@ -1,153 +0,0 @@
-= Saving and Loading Games (.j3o)
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: convert, j3o, models, load, save, documentation, serialization, import, export, spatial, node, mesh, geometry, scenegraph, sdk
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-Spatials (that is Nodes and Geometries) can contain audio and light nodes, particle emitters, controls, and user data (player score, health, inventory, etc). For your game distribution, you must convert all original models to a faster binary format. You save individual Spatials as well as scenes using `com.jme3.export.binary.BinaryExporter`. 
-
-The jMonkeyEngine's binary file format is called `.j3o`. You can convert, view and edit .j3o files and their materials in the jMonkeyEngine <<sdk#,SDK>> and compose scenes (this does not include editing meshes). For the conversion, you can either use the BinaryExporters, or a context menu in the SDK.
-
-
-[IMPORTANT]
-====
-The jMonkeyEngine's serialization system is the `com.jme3.export.Savable` interface. JME3's BinaryExporter can write standard Java objects, JME3 objects, and primitive data types that are included in a <<jme3/advanced/spatial#,spatial's user data>>. If you use custom game data classes, see below how to make them “Savable.
-====
-
-
-There is also a com.jme3.export.xml.XMLExporter and com.jme3.export.xml.XMLImporter that similarly converts jme3 spatials to an XML format. But you wouldn't use that to load models at runtime (quite slow).
-
-
-== Sample Code
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/tools/TestSaveGame.java[TestSaveGame.java]
-
-
-== Saving a Node
-
-The following example overrides `stop()` in SimpleApplication to save the rootNode to a file when the user quits the application. The saved rootNode is a normal .j3o binary file that you can open in the <<sdk#,SDK>>.
-
-
-[WARNING]
-====
-Note that when you save a model that has textures, the references to those textures are stored as absolute paths, so when loading the j3o file again, the textures have to be accessible at the exact location (relative to the assetmanager root, by default the `assets` directory) they were loaded from. This is why the SDK manages the conversion on the project level.
-====
-
-
-[source,java]
-----
-
-  /* This is called when the user quits the app. */
-  @Override
-  public void stop() {
-    String userHome = System.getProperty("user.home");
-    BinaryExporter exporter = BinaryExporter.getInstance();
-    File file = new File(userHome+"/Models/"+"MyModel.j3o");
-    try {
-      exporter.save(rootNode, file);
-    } catch (IOException ex) {
-      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, "Error: Failed to save game!", ex);
-    }
-    super.stop(); // continue quitting the game
-  }
-----
-
-
-== Loading a Node
-
-The following example overrides `simpleInitApp()` in SimpleApplication to load `Models/MyModel.j3o` when the game is initialized.
-
-[source,java]
-----
-  @Override
-  public void simpleInitApp() {
-     String userHome = System.getProperty("user.home");
-     assetManager.registerLocator(userHome, FileLocator.class);
-     Node loadedNode = (Node)assetManager.loadModel("Models/MyModel.j3o");
-     loadedNode.setName("loaded node");
-     rootNode.attachChild(loadedNode);
-  }
-   
-----
-
-
-[TIP]
-====
-Here you see why we save user data inside spatials – so it can be saved and loaded together with the .j3o file. If you have game data outside Spatials, you have to remember to save() and load(), and get() and set() it yourself.
-====
-
-
-
-== Custom Savable Class
-
-JME's BinaryExporter can write standard Java objects (String, ArrayList, buffers, etc), JME objects (Savables, such as Material), and primitive data types (int, float, etc). If you are using any custom class together with a Spatial, then the custom class must implement the `com.jme3.export.Savable` interface. There are two common cases where this is relevant:
-
-*  The Spatial is carrying any <<jme3/advanced/custom_controls#,Custom Controls>>. +
-Example: You used something like `mySpatial.addControl(myControl);`
-*  The Spatial's user data can contain a custom Java object. +
-Example: You used something like `mySpatial.setUserData("inventory", myInventory);`
-
-If your custom classes (the user data or the Controls) do not implement Savable, then the BinaryImporter/BinaryExporter cannot save the Spatial!
-
-So every time you create a custom Control or custom user data class, remember to implement Savable:
-
-[source,java]
-----
-
-import com.jme3.export.InputCapsule;
-import com.jme3.export.JmeExporter;
-import com.jme3.export.JmeImporter;
-import com.jme3.export.OutputCapsule;
-import com.jme3.export.Savable;
-import com.jme3.material.Material;
-import java.io.IOException;
-
-public class MyCustomClass implements Savable {
-    private int      someIntValue;   // some custom user data
-    private float    someFloatValue; // some custom user data
-    private Material someJmeObject;  // some custom user data
-
-    ...
-    // your other code...
-    ...
-
-    public void write(JmeExporter ex) throws IOException {
-        OutputCapsule capsule = ex.getCapsule(this);
-        capsule.write(someIntValue,   "someIntValue",   1);
-        capsule.write(someFloatValue, "someFloatValue", 0f);
-        capsule.write(someJmeObject,  "someJmeObject",  new Material());
-    }
-
-    public void read(JmeImporter im) throws IOException {
-        InputCapsule capsule = im.getCapsule(this);
-        someIntValue   = capsule.readInt(    "someIntValue",   1);
-        someFloatValue = capsule.readFloat(  "someFloatValue", 0f);
-        someJmeObject  = capsule.readSavable("someJmeObject",  new Material());
-    }
-}
-
-----
-
-To make a custom class savable:
-
-.  Implement `Savable` and add the `write()` and `read()` methods as shown in the example above.
-.  Do the following for each non-temporary class field: 
-**  Add one line that ``write()``s the data to the JmeExport output capsule. 
-***  Specify the variable to save, give it a String name (can be the same as the variable name), and specify a default value.
-
-**  Add one line that ``read…()``s the data to the JmeImport input capsule. 
-***  On the left side of the assignment, specify the class field that you are restoring
-***  On the right side, use the appropriate `capsule.read…()` method for the data type. Specify the String name of the variable (must be the same as you used in the `write()` method), and again specify a default value.
-
-
-
-
-[IMPORTANT]
-====
-As with all serialization, remember that if you ever change data types in custom classes, the updated read() methods will no longer be able to read your old files. Also there has to be a constructor that takes no Parameters.
-====
-

+ 0 - 293
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/light_and_shadow/light_and_shadow.adoc

@@ -1,293 +0,0 @@
-= Light and Shadow
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-image:jme3/advanced/shading-ani.gif[Examples of shading and lighting.,width="",height=""]
-
-Light and Shadow are two separate things in 3D engines, although we percieve them together in real life:
-
-*  Lighting means that an object is brighter on the side facing the light direction, and darker on the backside. Computationally, this is relatively easy. 
-*  Lighting does not mean that objects cast a shadow on the floor or other objects: Activating shadow processing is an additional step described here. Since casting shadows has an impact on performance, drop shadows and ambient occlusion shading are not activated by default.
-
-
-[IMPORTANT]
-====
-A light source with a direction or location is required for all Geometries with Lighting.j3md-based Materials. An ambient light is not sufficient. In a scene with no appropriate light sources, Geometries with Lighting.j3md-based Materials do not render. Only Geometries with Unshaded.j3md-based Materials are visible independent of any light sources.
-====
-
-
-
-== Light Sources and Colors
-
-
-image::jme3/advanced/light-sources.png[A lit scene with multiple light sources,width="300",height="200",align="right"]
-
-
-You can add several types of light sources to a scene using `rootNode.addLight(mylight)`. 
-
-The available light sources in `com.​jme3.​light` are:
-
-*  SpotLight 
-*  PointLight
-*  AmbientLight
-*  DirectionalLight
-
-You control the color and intensity of each light source. Typically you set the color to white (`new ColorRGBA(1.0f,1.0f,1.0f,1.0f)` or `ColorRGBA.White`), which makes all scene elements appear in their natural color. 
-
-You can choose to use lights in other colors than white, or darker colors. This influences the scene's atmosphere and will make the scene appear colder (e.g. `ColorRGBA.Cyan`) or warmer (`ColorRGBA.Yellow`), brighter (higher values) or darker (lower values).
-
-You can get a list of all lights added to a Spatial by calling `getWorldLightList()` (includes inherited lights) or `getLocalLightList()` (only directly added lights), and iterating over the result.
-
-
-=== PointLight
-
-
-image::jme3/advanced/elephant-pointlights.png[An elephant model illuminated by pointlights,width="300",height="205",align="right"]
-
-
-A PointLight has a location and shines from there in all directions as far as its radius reaches. The light intensity decreases with increased distance from the light source. A PointLight can be used to cast shadows along with a PointLightShadowRenderer (see the Casting Shadows section)
-
-*Typical example:* Lamp, lightbulb, torch, candle.
-
-[source,java]
-----
-PointLight lamp_light = new PointLight();
-lamp_light.setColor(ColorRGBA.Yellow);
-lamp_light.setRadius(4f);
-lamp_light.setPosition(new Vector3f(lamp_geo.getLocalTranslation()));
-rootNode.addLight(lamp_light);
-----
-
-
-=== DirectionalLight
-
-
-image::jme3/advanced/house-directionallight.png[A house model illuminated with a sun-like directional light,width="300",height="210",align="right"]
-
-
-A DirectionalLight has no position, only a direction. It sends out parallel beams of light and is considered “infinitely far away. You typically have one directional light per scene. A DirectionalLight can be used together with shadows. 
-
-*Typically example:* Sun light.
-
-[source,java]
-----
-DirectionalLight sun = new DirectionalLight();
-sun.setColor(ColorRGBA.White);
-sun.setDirection(new Vector3f(-.5f,-.5f,-.5f).normalizeLocal());
-rootNode.addLight(sun);
-----
-
-
-=== SpotLight
-
-
-image::jme3/advanced/spotlight.png[Spotlight,width="",height="",align="right"]
-
-
-A SpotLight sends out a distinct beam or cone of light. A SpotLight has a direction, a position, distance (range) and two angles. The inner angle is the central maximum of the light cone, the outer angle the edge of the light cone. Everything outside the light cone's angles is not affected by the light.
-
-*Typical Example:* Flashlight
-
-[source,java]
-----
-SpotLight spot = new SpotLight();
-spot.setSpotRange(100f);                           // distance
-spot.setSpotInnerAngle(15f * FastMath.DEG_TO_RAD); // inner light cone (central beam)
-spot.setSpotOuterAngle(35f * FastMath.DEG_TO_RAD); // outer light cone (edge of the light)
-spot.setColor(ColorRGBA.White.mult(1.3f));         // light color
-spot.setPosition(cam.getLocation());               // shine from camera loc
-spot.setDirection(cam.getDirection());             // shine forward from camera loc
-rootNode.addLight(spot);
-----
-
-If you want the spotlight to follow the flycam, repeat the setDirection(…) and setPosition(…) calls in the update loop, and kee syncing them with the camera position and direction.
-
-
-=== AmbientLight
-
-An AmbientLight simply influences the brightness and color of the scene globally. It has no direction and no location and shines equally everywhere. An AmbientLight does not cast any shadows, and it lights all sides of Geometries evenly, which makes 3D objects look unnaturally flat; this is why you typically do not use an AmbientLight alone without one of the other lights.  
-
-*Typical example:* Regulate overall brightness, tinge the whole scene in a warm or cold color. 
-
-[source,java]
-----
-AmbientLight al = new AmbientLight();
-al.setColor(ColorRGBA.White.mult(1.3f));
-rootNode.addLight(al);
-----
-
-
-[TIP]
-====
-You can increase the brightness of a light source gradually by multiplying the light color to values greater than 1.0f. +
-Example: `mylight.setColor(ColorRGBA.White.mult(1.3f));`
-====
-
-
-
-== Light Follows Spatial
-
-You can use a `com.jme3.scene.control.LightControl` to make a SpotLight or PointLight follow a Spatial. This can be used for a flashlight being carried by a character, or for car headlights, or an aircraft's spotlight, etc.
-
-[source,java]
-----
-
-PointLight myLight = new PointLight();
-rootNode.addLight(myLight);
-LightControl lightControl = new LightControl(myLight);
-spatial.addControl(lightControl); // this spatial controls the position of this light.
-
-----
-
-Obviously, this does not apply to AmbientLights, which have no position.
-
-
-== BasicShadowRenderer (deprecated)
-
-Full code sample
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/light/TestShadow.java[TestShadow.java]
-
-
-== Casting Shadows
-
-For each type of non-ambient light source, JME3 implements two ways to simulate geometries casting shadows on other geometries:
-
-*  a shadow renderer (which you apply to a viewport) and
-*  a shadow filter (which you can add to a viewport's filter post-processor).
-
-[cols="3", options="header"]
-|===
-
-a| light source class 
-a| shadow renderer class 
-a| shadow filter class 
-
-a| DirectionalLight 
-a| DirectionalLightShadowRenderer 
-a| DirectionalLightShadowFilter 
-
-a| PointLight 
-a| PointLightShadowRenderer 
-a| PointLightShadowFilter 
-
-a| SpotLight 
-a| SpotLightShadowRenderer 
-a| SpotLightShadowFilter 
-
-a| AmbientLight 
-a| (not applicable) 
-a| (not applicable) 
-
-|===
-
-You only need one shadow simulation per light source:  if you use shadow rendering, you won't need a shadow filter and vice versa.  Which way is more efficient depends partly on the complexity of your scene. All six shadow simulation classes have similar interfaces, so once you know how to use one, you can easily figure out the rest.
-
-Shadow calculations (cast and receive) have a performance impact, so use them sparingly.  With shadow renderers, you can turn off shadow casting and/or shadow receiving for individual geometries, for portions of the scene graph, or for the entire scene:
-
-[source,java]
-----
-
-spatial.setShadowMode(ShadowMode.Inherit);     // This is the default setting for new spatials.
-rootNode.setShadowMode(ShadowMode.Off);        // Disable shadows for the whole scene, except where overridden. 
-wall.setShadowMode(ShadowMode.CastAndReceive); // The wall can cast shadows and also receive them.
-floor.setShadowMode(ShadowMode.Receive);       // Any shadows cast by the floor would be hidden by it.
-airplane.setShadowMode(ShadowMode.Cast);       // There's nothing above the airplane to cast shadows on it.
-ghost.setShadowMode(ShadowMode.Off);           // The ghost is translucent: it neither casts nor receives shadows.
-
-----
-
-Both shadow renderers and shadow filters use shadow modes to determine which objects can cast shadows. However, only the shadow renderers pay attention to shadow modes when determining which objects receive shadows.  With a shadow filter, shadow modes have no effect on which objects receive shadows.
-
-Here's a sample application which demonstrates both DirectionalLightShadowRenderer and DirectionalLightShadowFilter:
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/light/TestDirectionalLightShadow.java[TestDirectionalLightShadow.java]
-
-Here is the key code fragment:
-
-[source,java]
-----
-
-        DirectionalLight sun = new DirectionalLight();
-        sun.setColor(ColorRGBA.White);
-        sun.setDirection(cam.getDirection());
-        rootNode.addLight(sun);
-
-        /* Drop shadows */
-        final int SHADOWMAP_SIZE=1024;
-        DirectionalLightShadowRenderer dlsr = new DirectionalLightShadowRenderer(assetManager, SHADOWMAP_SIZE, 3);
-        dlsr.setLight(sun);
-        viewPort.addProcessor(dlsr);
-
-        DirectionalLightShadowFilter dlsf = new DirectionalLightShadowFilter(assetManager, SHADOWMAP_SIZE, 3);
-        dlsf.setLight(sun);
-        dlsf.setEnabled(true);
-        FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
-        fpp.addFilter(dlsf);
-        viewPort.addProcessor(fpp);
-
-----
-
-Constructor arguments:
- * your AssetManager object
- * size of the rendered shadow maps, in pixels per side (512, 1024, 2048, etc…)
- * the number of shadow maps rendered (more shadow maps = better quality, but slower)
-
-Properties you can set:
- * setDirection(Vector3f) – the direction of the light
- * setLambda(0.65f) – to reduce the split size
- * setShadowIntensity(0.7f) – shadow darkness (1=black, 0=invisible)
- * setShadowZextend(float) – distance from camera to which shadows will be computed
-
-
-== Parallel-Split Shadow Map (deprecated)
-
-Full sample code
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/light/TestPssmShadow.java[TestPssmShadow.java]
-
-
-image::jme3/advanced/shadow.png[A lit scene with PSSM drop shadows,width="300",height="200",align="right"]
-
-
-[source,java]
-----
-private PssmShadowRenderer pssmRenderer;
-...
-public void simpleInitApp() {
-    ....
-    pssmRenderer = new PssmShadowRenderer(assetManager, 1024, 3);
-    pssmRenderer.setDirection(new Vector3f(-.5f,-.5f,-.5f).normalizeLocal()); // light direction
-    viewPort.addProcessor(pssmRenderer);
-
-----
-
-
-== Screen Space Ambient Occlusion
-
-Full sample code
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/post/TestSSAO.java[TestSSAO.java] – Screen-Space Ambient Occlusion shadows
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/post/TestTransparentSSAO.java[TestTransparentSSAO.java] – Screen-Space Ambient Occlusion shadows plus transparancy
-*  link:https://hub.jmonkeyengine.org/t/ssao-for-monkeys/13369[Screen Space Ambient Occlusion for jMonkeyEngine (article)]
-
-Ambient Occlusion refers to the shadows which nearby objects cast on each other under an ambient lighting. Screen Space Ambient Occlusion (SSAO) approximates how light radiates in real life.
-
-In JME3, SSAO is implemented by adding an instance of `com.jme3.post.SSAOFilter` to a viewport which already simulates shadows using another method such as DirectionalLightShadowRenderer.
-
-[source,java]
-----
-
-FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
-SSAOFilter ssaoFilter = new SSAOFilter(12.94f, 43.92f, 0.33f, 0.61f);
-fpp.addFilter(ssaoFilter);
-viewPort.addProcessor(fpp);
-
-----
-
-image:jme3/advanced/shading-textured-ani.gif[Shading with and without Ambient Occlusion,width="",height=""]

+ 0 - 7
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/light_and_shadow/overview.adoc

@@ -1,7 +0,0 @@
-= OVERVIEW
-:author: yanmaoyuan
-:revnumber:
-:revdate: 2018/01/15 16:29
-:experimental:
-:keywords:
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]

+ 0 - 154
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/localization.adoc

@@ -1,154 +0,0 @@
-= Localizing jME 3 Games
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== Scope
-
-Localizing an application can mean several things: 
-
-*  At minimum you translate all messages and dialogs in the user interface to your target languages.
-*  You should also translate the “read me, help, and other documentation.
-*  Also translating web content related to the application makes sure international users find out about your localized game.
-*  If you go the whole way of internationalization, you also “translate metaphors in icons or symbols used. +
-E.g. For localizations to right-to-left languages, you must also adjust the whole flow of the UI (order of menus and buttons).
-
-There are tools that assist you with localizing Java Swing GUIs. jME3 applications do not typically have a Swing +++<abbr title="Graphical User Interface">GUI</abbr>+++, so those tools are not of much help. Just stick to the normal Java rules about using Bundle Properties:
-
-
-== Preparing the Localization
-
-[TIP]
-====
-The jMonkeyEngine SDK supports opening and editing Bundle.properties files. Also note the Tools &gt; Localization menu.
-====
-
-To prepare the application for localization, you have to first identify all hard-coded messages.
-
-.  Find every line in your jME3 game where you hard-coded message strings, e.g. 
-+
-[source,java]
-----
-System.out.print("Hello World!");
-UiText.setText("Score: " + score);
-----
-
-.  Create one file named `Bundle.properties` in each directory where there are Java file that contain messages.
-.  For every hard-coded message, you add one line to the `Bundle.properties` file: First specify a unique key that identifies this string; then an equal sign; and the literal string itself. 
-+
-[source]
-----
-greeting=Hello World!
-score.display=Score: 
-----
-
-.  In the source code, replace every occurence of a hard-coded message with the appropriate Resource Bundle call to its unique key: 
-+
-[source,java]
-----
-System.out.print(ResourceBundle.getBundle("Bundle").getString("greeting"));
-UiText.setText(ResourceBundle.getBundle("Bundle").getString("score.display") + score);
-----
-
-
-The language used in the Bundle.properties files will be the default language for your game.
-
-
-== Translating the Messages
-
-Each additional language comes in a set of files that is marked with a (usually) two-letter suffix. Common locales are de for German, en for English, fr for French, ja for Japanese, pt for Portuguese, etc.
-
-To translate the messages to another language, for example, German:
-
-.  Make a copy of the `Bundle.properties` files.
-.  Name the copy `Bundle_de.properties` for German. Note the added suffix _de.
-.  Translate all strings (text on the right side of the equal sign) in the `Bundle_de.properties` to German. 
-+
-[source]
-----
-greeting=Hallo Welt!
-score.display=Spielstand: 
-----
-+
-[IMPORTANT]
-====
-Do not modify any of the keys (text to the left of the equal sign)!
-====
-
-.  To test the German localization, start the application from the command line with `-Duser.language=de`. Note the parameter `de`.
-+
-[TIP]
-====
-In the jMonkeyEngine SDK, you set this VM Option in the Project properties under Run. Here you can also save individual run configuraions for each language you want to test.
-====
-
-To get the full list of language suffixes use 
-
-[source,java]
-----
-System.out.println(Arrays.toString(Locale.getISOLanguages()));
-----
-
-
-== Which Strings Not to Translate
-
-[IMPORTANT]
-====
-In the Bundle.properties file, do not include any strings that are asset paths, node or geometry names, input mappings, or material layers.
-====
-
-*  Keep material layers: 
-+
-[source,java]
-----
-mat.setTexture("ColorMap", tex);
-----
-
-*  Keep paths: 
-+
-[source,java]
-----
-teapot = assetManager.loadModel("Models/Teapot/Teapot.obj");
-----
-
-*  Keep geometry and node names: 
-+
-[source,java]
-----
-Geometry thing=new Geometry("A thing", mesh);
-Node vehicle = new Node("Vehicle");
-----
-
-*  Keep mappings: 
-+
-[source,java]
-----
-inputManager.addMapping("Shoot", trigger);
-inputManager.addListener(actionListener, "Shoot");
-----
-
-
-Only localize messages and UI text!
-
-
-== Common Localization Problems
-
-Typical problems include:
-
-*  Localized strings will be of vastly different lengths and will totally break your UI layout. ⇒ Test every localization.
-*  Strings with variable text or numbers don't work the same in different languages. ⇒ Either work in grammatical cases/numbers/gender for each language, or use link:http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms[gettext] or link:http://userguide.icu-project.org/formatparse/messages[ICU4J].
-*  The localizer only sees the strings, without any context. E.g. does “Search History mean “display the history of searches, or “search through the history? ⇒ Use clear key labels. Work closely with the localizers if they require extra info, and add that info as comments to the translation file.
-*  Broken international characters ⇒ Make sure the files are saved with the same character encoding as the font file(s) you're using. Nowadays, that usually means UTF-8 since font files tend to come for Unicode.
-*  Missing international characters ⇒ Make sure that there's a glyph for every needed character in your font, either by using more complete font files or by having the translation changed.
-
-
-== More Documentation
-
-link:http://java.sun.com/developer/technicalArticles/Intl/ResourceBundles/[http://java.sun.com/developer/technicalArticles/Intl/ResourceBundles/]
-
-link:http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Localisation[http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Localisation]

+ 0 - 346
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/material/j3m_material_files.adoc

@@ -1,346 +0,0 @@
-= Saving and Loading Materials with .j3m Files
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: material, texture, file, sdk, wireframe, documentation
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-In the <<jme3/advanced/material_definitions#,Material Definitions>> article you learned how to configure <<jme3/advanced/materials_overview#,Materials>>  programmatically in Java code. If you have certain commonly used Materials that never change, you can clean up the amount of Java code that clutters your init method, by moving material settings into .j3m files. Then later in your code, you only need to call one setter instead of several to apply the material.
-
-If you want to colorize simple shapes (one texture all around), then .j3m are the most easily customizable solution. J3m files can contain texture mapped materials, but as usual you have to create the textures in an external editor, especially if you use UV-mapped textures. 
-
-
-== Writing the .j3m File
-
-.  For every Material, create a file and give it a name that describes it: e.g. `SimpleBump.j3m`
-.  Place the file in your project's `assets/Materials/` directory, e.g. `MyGame/src/assets/Materials/SimpleBump.j3m`
-.  Edit the file and add content using the following Syntax, e.g.:
-[source]
-----
-
-Material shiny bumpy rock : Common/MatDefs/Light/Lighting.j3md {
-     MaterialParameters {
-         Shininess: 8.0
-         NormalMap: Textures/bump_rock_normal.png
-         UseMaterialColors : true
-         Ambient  : 0.0 0.0 0.0 1.0
-         Diffuse  : 1.0 1.0 1.0 1.0
-         Specular : 0.0 0.0 0.0 1.0
-     }
-}
-
-----
-
-
-How this file is structured:
-
-.  Header
-..  `Material` is a fixed keyword, keep it.
-..  `shiny bumpy rock` is a descriptive string that you can make up. Choose a name to help you remember for what you intend to use this material.
-..  After the colon, specify on which <<jme3/advanced/materials_overview#,Material>> definition you base this Material.
-
-.  Now look up the choosen Material Definition's parameters and their parameter types from the <<jme3/advanced/materials_overview#,Material>> table. Add one line for each parameter.
-**  For example: The series of four numbers in the example above represent RGBA color values.
-
-.  Check the detailed syntax reference below if you are unsure.
-
-
-[TIP]
-====
-In the jMonkeyEngine SDK, use File→New File→Material→Empty Material File to create .j3m files. You can edit .j3m files directly in the SDK. On the other hand, they are plain text files, so you can also create them in any plain text editor.
-====
-
-
-
-== How to Use .j3m Materials
-
-This is how you use the prepared .j3m Material on a Spatial. Since you have saved the .j3m file to your project's Assets directory, the .j3m path is relative to `MyGame/src/assets/…`.
-
-[source,java]
-----
-myGeometry.setMaterial(assetManager.loadMaterial("Materials/SimpleBump.j3m"));
-----
-
-[TIP]
-====
-In the jMonkeyEngine SDK, open Windows&gt;Palette and drag the `JME Material: Set J3M` snippet into your code.
-====
-
-
-== Syntax Reference for .j3m Files
-
-
-=== Paths
-
-Make sure to get the paths to the textures (.png, .jpg) and material definitions (.j3md) right. 
-
-*  The paths to the built-in .j3md files are relative to jME3's Core Data directory. Just copy the path stated in the <<jme3/advanced/materials_overview#,Material>> table. +
-`Common/MatDefs/Misc/Unshaded.j3md` is resolved to `jme3/src/src/core-data/Common/MatDefs/Misc/Unshaded.j3md`.
-*  The paths to your textures are relative to your project's assets directory. +
-`Textures/bump_rock_normal.png` is resolved to `MyGame/src/assets/Textures/bump_rock_normal.png`
-
-
-=== Data Types
-
-All data types (except Color) are specified in com.jme3.shader.VarType.
-“Color is specified as Vector4 in J3MLoader.java.
-[cols="3", options="header"]
-|===
-
-a|Name
-a|jME Java class
-a|.j3m file syntax
-
-a| Float
-a| (basic Java type) 
-a| a float (e.g. 0.72) , no comma or parentheses 
-
-a| Vector2
-a| `com.jme3.math.Vector2f`
-a| Two floats, no comma or parentheses 
-
-a| Vector3 
-a| `com.jme3.math.Vector3f` 
-a| Three floats, no comma or parentheses 
-
-a| Vector4
-a| `com.jme3.math.Vector4f` 
-a| Four floats, no comma or parentheses 
-
-a| Texture2D 
-a| `com.jme3.texture.Texture2D` 
-a| Path to texture in `assets` directory, no quotation marks 
-
-a| Texture3D
-a| `com.jme3.texture.Texture3D` 
-a| Same as texture 2D except it is interpreted as a 3D texture 
-
-a| TextureCubeMap
-a| `com.jme3.texture.TextureCubeMap` 
-a| Same as texture 2D except it is interpreted as a cubemap texture 
-
-a| Boolean
-a| (basic Java type) 
-a| `true` or `false` 
-
-a| Int
-a| (basic Java type) 
-a| Integer number, no comma or parentheses 
-
-a| Color 
-a| `com.jme3.math.ColorRGBA` 
-a| Four floats, no comma or parentheses 
-
-a| FloatArray
-a| 
-a| (Currently not supported in J3M) 
-
-a| Vector2Array
-a| 
-a| (Currently not supported in J3M) 
-
-a| Vector3Array
-a| 
-a| (Currently not supported in J3M) 
-
-a| Vector4Array
-a| 
-a| (Currently not supported in J3M) 
-
-a| Matrix3
-a| 
-a| (Currently not supported in J3M) 
-
-a| Matrix4
-a| 
-a| (Currently not supported in J3M) 
-
-a| Matrix3Array
-a| 
-a| (Currently not supported in J3M) 
-
-a| Matrix4Array
-a| 
-a| (Currently not supported in J3M) 
-
-a| TextureBuffer
-a| 
-a| (Currently not supported in J3M) 
-
-a| TextureArray
-a| 
-a| (Currently not supported in J3M) 
-
-|===
-
-
-=== Flip and Repeat Syntax
-
-*  A texture can be flipped using the following syntax `NormalMap: Flip Textures/bump_rock_normal.png`
-*  A texture can be set to repeat using the following syntax `NormalMap: Repeat Textures/bump_rock_normal.png`
-*  If a texture is set to both being flipped and repeated, Flip must come before Repeat
-
-
-=== Syntax for Additional Render States
-
-*  A Boolean can be “On or “Off
-*  Float is “123.0 etc
-*  Enum - values depend on the enum
-
-See the link:http://javadoc.jmonkeyengine.org/com/jme3/material/RenderState.html[RenderState] javadoc for a detailed explanation of render states.
-[cols="3", options="header"]
-|===
-
-a|Name
-a|Type
-a|Purpose
-
-a| link:http://javadoc.jmonkeyengine.org/com/jme3/material/RenderState.html#setWireframe(boolean)[Wireframe] 
-a|(Boolean)
-a| Enable wireframe rendering mode 
-
-a| link:http://javadoc.jmonkeyengine.org/com/jme3/material/RenderState.html#setFaceCullMode(com.jme3.material.RenderState.FaceCullMode)[FaceCull] 
-a|(Enum: FaceCullMode)
-a| Set face culling mode (Off, Front, Back, FrontAndBack) 
-
-a| link:http://javadoc.jmonkeyengine.org/com/jme3/material/RenderState.html#setDepthWrite(boolean)[DepthWrite] 
-a|(Boolean)
-a| Enable writing depth to the depth buffer 
-
-a| link:http://javadoc.jmonkeyengine.org/com/jme3/material/RenderState.html#setDepthTest(boolean)[DepthTest] 
-a|(Boolean)
-a| Enable depth testing 
-
-a| link:http://javadoc.jmonkeyengine.org/com/jme3/material/RenderState.html#setBlendMode(com.jme3.material.RenderState.BlendMode)[Blend] 
-a|(Enum: BlendMode)
-a| Set the blending mode 
-
-a| link:http://javadoc.jmonkeyengine.org/com/jme3/material/RenderState.html#setAlphaFallOff(float)[AlphaTestFalloff] 
-a|(Float)
-a| Set the alpha testing alpha falloff value (if set, it will enable alpha testing) 
-
-a| link:http://javadoc.jmonkeyengine.org/com/jme3/material/RenderState.html#setPolyOffset(float,float)[PolyOffset] 
-a|(Float, Float)
-a| Set the polygon offset factor and units 
-
-a| link:http://javadoc.jmonkeyengine.org/com/jme3/material/RenderState.html#setColorWrite(boolean)[ColorWrite] 
-a|(Boolean)
-a| Enable color writing
-
-a| link:http://javadoc.jmonkeyengine.org/com/jme3/material/RenderState.html#setPointSprite(boolean)[PointSprite] 
-a|(Boolean)
-a| Enable point sprite rendering for point meshes 
-
-|===
-
-
-== Examples
-
-
-=== Example 1: Shiny
-
-[source,java]
-----
-
-Spatial signpost = (Spatial) assetManager.loadAsset(
-    new OgreMeshKey("Models/Sign Post/Sign Post.mesh.xml", null));
-signpost.setMaterial( assetManager.loadMaterial(
-    new AssetKey("Models/Sign Post/Sign Post.j3m")));
-TangentBinormalGenerator.generate(signpost);
-rootNode.attachChild(signpost);
-
-----
-
-The file `assets/Models/Sign Post/Sign Post.j3m` contains:
-
-[source]
-----
-
-Material Signpost : Common/MatDefs/Light/Lighting.j3md {
-    MaterialParameters {
-         Shininess: 4.0
-         DiffuseMap:  Models/Sign Post/Sign Post.jpg
-         NormalMap:   Models/Sign Post/Sign Post_normal.jpg
-         SpecularMap: Models/Sign Post/Sign Post_specular.jpg
-         UseMaterialColors : true
-         Ambient  : 0.5 0.5 0.5 1.0
-         Diffuse  : 1.0 1.0 1.0 1.0
-         Specular : 1.0 1.0 1.0 1.0
-    }
-}
-
-----
-
-The JPG files are in the same directory, `assets/Models/Sign Post/…`.
-
-
-=== Example 2: Repeating Texture
-
-[source,java]
-----
-
-Material mat = assetManager.loadMaterial(
-    "Textures/Terrain/Pond/Pond.j3m");
-mat.setColor("Ambient", ColorRGBA.DarkGray);
-mat.setColor("Diffuse", ColorRGBA.White);
-mat.setBoolean("UseMaterialColors", true);
-
-----
-
-The file `assets/Textures/Terrain/Pond/Pond.j3m` contains:
-
-[source]
-----
-
-Material Pong Rock : Common/MatDefs/Light/Lighting.j3md {
-     MaterialParameters {
-         Shininess: 8.0
-         DiffuseMap: Repeat Textures/Terrain/Pond/Pond.png
-         NormalMap:  Repeat Textures/Terrain/Pond/Pond_normal.png
-     }
-}
-
-----
-
-The PNG files are in the same directory, `assets/Textures/Terrain/Pond/`
-
-
-=== Example 3: Transparent
-
-The file `assets/Models/Tree/Leaves.j3m` contains:
-
-[source]
-----
-
-Material Leaves : Common/MatDefs/Light/Lighting.j3md {
-
-    Transparent On
-
-    MaterialParameters {
-        DiffuseMap : Models/Tree/Leaves.png
-        UseAlpha : true
-        AlphaDiscardThreshold : 0.5
-        UseMaterialColors : true
-        Ambient : .5 .5 .5 .5
-        Diffuse : 0.7 0.7 0.7 1
-        Specular : 0 0 0 1
-        Shininess : 16
-    }
-    AdditionalRenderState {
-        Blend Alpha
-        AlphaTestFalloff 0.50
-        FaceCull Off
-    }
-}
-
-----
-
-The PNG file is in the same directory, `assets/Models/Tree/…`
-
-
-== Related Links
-
-*  <<jme3/advanced/material_specification#,Developer specification of the jME3 material system (.j3md,.j3m)>>

+ 0 - 158
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/material/material_definitions.adoc

@@ -1,158 +0,0 @@
-= How to Use Material Definitions (.j3md)
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: Material, SDK, MatDef, file, documentation
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-All Geometries need a Material to be visible. Every Material is based on a Material Definition. Material definitions provide the “logic for the material, and a shader draws the material according to the parameters specified in the definition. The J3MD file abstracts the shader and its configuration away from the user, allowing a simple interface where the user can simply set a few parameters on the material to change its appearance and the way its handled by the shaders. 
-
-The most common Material Definitions are included in the engine, advanced users can create custom ones. In this case you will also be interested in the <<jme3/advanced/material_specification#,in-depth developer specification of the jME3 material system>>.
-
-*Example:*
-
-[source,java]
-----
-Spatial myGeometry = assetManager.loadModel("Models/Teapot/Teapot.j3o");
-Material mat = new Material(assetManager,  // Create new material and...
-    "Common/MatDefs/Misc/Unshaded.j3md");  // ... specify a Material Definition file, here "Unshaded.j3md"!
-mat.setColor("Color", ColorRGBA.Blue);     // Set one or more material parameters.
-myGeometry.setMaterial(mat);               // Use material on this Geometry.
-
-----
-
-
-[TIP]
-====
-If you use one custom material with certain settings very often, learn about storing material settings in <<jme3/advanced/j3m_material_files#,j3m Material Files>>. You either <<sdk/material_editing#,use the jMonkeyEngine SDK to create .j3m files>> (user-friendly), or you <<jme3/advanced/j3m_material_files#,write .j3m files in a text editor>> (IDE-independent).
-====
-
-
-
-== Preparing a Material
-
-In the <<jme3/advanced/materials_overview#,Materials Overview>> list:
-
-.  Choose a Material Definition that has the features that you need. 
-**  Tip: If you don't know, start with `Unshaded.j3md` or `Lighting.j3md`.
-
-.  Look at the applicable parameters of the Material Definition and determine which parameters you need to achieve the desired effect (e.g. “glow or “color). Most parameters are optional! 
-.  Create and save the necessary Texture files to your `assets/Textures` directory.
-**  E.g. mytex_diffuse.png as ColorMap / DiffuseMap, mytex_normal.png as NormalMap, mytex_alpha.png as AlphaMap, etc…
-
-.  Determine the required values to achieve the effect that you want.
-**  E.g. set colors, floats, booleans, etc… 
-
-
-
-== Using a Material
-
-In your Java code,
-
-.  Create a Material object based on the chosen Material Definition (.j3md file): 
-+
-[source,java]
-----
-Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-----
-
-.  Configure your Material by setting the appropriate values listed in the <<jme3/advanced/materials_overview#,Materials Overview>> table. 
-+
-[source,java]
-----
-mat.setColor("Color", ColorRGBA.Yellow ); // and more
-----
-
-.  Apply your prepared Material to a Geometry: 
-+
-[source,java]
-----
-myGeometry.setMaterial(mat);
-----
-
-.  (Optional) Adjust the texture scale of the mesh: 
-+
-[source,java]
-----
-myGeometryMesh.scaleTextureCoordinates(new Vector2f(2f, 2f));
-----
-
-
-For details see also: <<jme3/intermediate/how_to_use_materials#,How to Use Materials>>
-
-
-=== Examples
-
-Here are examples of the methods that set the different data types:
-
-*  `mat.setColor(   “Color,       ColorRGBA.White );` 
-*  `mat.setTexture( “ColorMap,    assetManager.loadTexture(“Interface/Logo/Monkey.png ));`
-*  `mat.setFloat(   “Shininess,   5f);`
-*  `mat.setBoolean( “SphereMap,   true);`
-*  `mat.setVector3( “NormalScale, new Vector3f(1f,1f,1f));`
-
-A simpled textured material.
-
-[source,java]
-----
-
-Material mat = new Material(assetManager, 
-    "Common/MatDefs/Misc/Unshaded.j3md");
-mat.setTexture("ColorMap", assetManager.loadTexture(
-    "Interface/Logo/Monkey.jpg"));
-
-----
-
-A textured material with a color bleeding through transparent areas.
-
-[source,java]
-----
-
-Material mat = new Material(assetManager, 
-    "Common/MatDefs/Misc/Unshaded.j3md");
-mat.setTexture("ColorMap", assetManager.loadTexture(
-    "Textures/ColoredTex/Monkey.png"));
-mat.setColor("Color", ColorRGBA.Blue);
-
-----
-
-You can test these examples within the following code snippet. It creates a box and applies the material:
-
-[source,java]
-----
- Box b = new Box(Vector3f.ZERO, 1, 1, 1);
-Geometry geom = new Geometry("Box", b);
-// ... insert Material definition...
-geom.setMaterial(mat);
-rootNode.attachChild(geom);
-
-----
-
-
-[TIP]
-====
-You can find these and other common code snippets in the jMonkeyEngine SDK Code Palette. Drag and drop them into your source code.
-====
-
-
-
-== Creating a Custom Material Definition
-
-First read the <<jme3/advanced/material_specification#,developer specification of the jME3 material system (.j3md,.j3m)>>. Also check out the <<jme3/build_from_sources#,engine source code>> and have a look at how some Material Definitions are implemented. 
-
-You can create your own Material Definitions and place them in your project's `assets/MatDefs` directory.
-
-.  Find the existing MatDefs in `engine/src/core-data/Common/MatDefs/`. 
-.  Open a Something.j3md file in a text editor. You see that this .j3md file defines Material Parameters and Techniques.
-**  Material Parameters are the ones that you set in Materials, as shown in the examples above.
-**  The Techniques rely on VertexShaders and FragmentShaders: You find those in the files Something.vert and Something.frag in the same directory.
-
-.  Learn about GLSL (OpenGL Shading Language) to understand the .vert and .frag syntax, then write your own.
-
-
-== Related Links
-
-*  <<jme3/advanced/material_specification#,Developer specification of the jME3 material system (.j3md,.j3m)>>

+ 0 - 303
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/material/material_specification.adoc

@@ -1,303 +0,0 @@
-= jMonkeyEngine3 Material Specification
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== General Syntax
-
-Material definitions and material instance files are formatted similarly to curly-bracket languages, in other words, you have “blocks and other “blocks nested in them, surrounded by curly-brackets. There are statements inside the blocks, the next statement begins after a new line, or a semi-colon to allow two statements on the same line. Comments are made by prefixing with two slashes, the `/* */` style comments are not allowed.
-
-*Example:*
-
-[source]
-----
-RootBlock {
-  // Comment
-  SubBlock NameForTheBlock {
-    Statement1 // Another comment
-  }
-  SubBlock2 {
-    SubSubBlock {
-      Statement2
-      Statement3
-      // two statements on the same line
-      Statement4; Statement5
-    }
-  }
-  SubBlock3
-    { // bracket can be on next line as well
-    }
-}
-----
-
-The syntax for J3MD and J3M files follows from this base format.
-
-
-== Material Definition files (J3MD)
-
-Material definitions provide the “logic for the material. Usually a shader that will handle drawing the object, and corresponding parameters that allow configuration of the shader. The J3MD file abstracts the shader and its configuration away from the user, allowing a simple interface where one can simply set a few parameters on the material to change its appearance and the way it's handled.
-
-Material definitions support multiple techniques, each technique describes a different way to draw the object. For example, currently in jME3, an additional technique is used to render shadow maps for example.
-
-
-=== Shaders
-
-Shader support inside J3MD files is rather sophisticated. First, shaders may reference shader libraries, in a similar way to Java's “import statement, or C++'s “include pre-processor directive. Shader libraries in turn, can also reference other shader libraries this way. In the end, it is possible for a shader to use many functions together from many libraries and combine them in ways to create a more advanced effect. For example, any shader that wishes to take advantage of hardware skinning, can just import the skinning shader library and use the function, without having to write the specific logic needed for hardware skinning.
-
-Shaders can also take advantage of “defines that are specified inside material definitions.
-The defines “bind into material parameters, so that a change in a material parameter can apply or remove a define from the corresponding shader. This allows the shader to completely change in behavior during run-time.
-
-Although it is possible to use shader uniforms for the very same purpose, those may introduce slowdowns in older GPUs, that do not support branching. In that case, using defines can allow changing the way the shader works without using shader uniforms. In order to introduce a define into a shader, however, its source code must be changed, and therefore, it must be re-compiled. It is therefore not recommended to change define bound parameters often.
-
-
-=== Syntax of a J3MD file
-
-All J3MD files begin with `MaterialDef` as the root block, following that, is the name of the material def (in this example `Test Material 123`). The name is not used for anything important currently, except for debugging. The name is typed as is without quotes, and can have spaces.
-
-*Example of a first line of a J3MD file:*
-
-[source]
-----
-MaterialDef Test Material 123 {
-----
-
-Inside a MaterialDef block, there can be at most one MaterialParameters block, and one or more `Technique` blocks.
-
-Techniques may have an optional name, which specifies the name of the technique. If no name is specified for a technique, then its name is “Default, and it is used by default if the user does not specify another technique to use for the material.
-
-*Example of J3MD:*
-
-[source]
-----
-MaterialDef Test Material 123 { 
-  MaterialParameters { }
-  Technique { }
-  Technique NamedTech { } 
-}
-----
-
-Inside the MaterialParameters block, the parameters are specified. Every parameter has a type and a name. Material parameters are similar to Java variables in that aspect.
-
-*Example of a MaterialParameters block:*
-
-[source]
-----
-MaterialParameters {
-    Texture2D TexParam
-    Color     ColorParam
-    Vector3   VectorParam
-    Boolean   BoolParam
-// ...
-}
-----
-
-Whereas in the J3MD file, the parameter names and types are specified, in a J3M (Material instance) file, the values for these parameters are assigned, as will be shown later. This is how the materials are configured.
-
-At the time of writing, the following types of parameters are allowed inside J3MD files: Int, Boolean, Float, Vector2, Vector3, Vector4, Texture2D, TextureCubeMap.
-
-You can specify a default value for material parameters, inside material definitions, in the case that no value is specified in the material instance. 
-
-[source]
-----
-MaterialParameters {
-     Float MyParam : 1
-// ...
-}
-----
-
-1 will be used as the default value and sent to the shader if it has not been set by a meterial.setFloat() call.
-
-
-=== Techniques
-
-Techniques are more advanced blocks than the MaterialParameters block. Techniques may have nested blocks, any many types of statements.
-
-In this section, the statements and nested blocks that are allowed inside the Technique block will be described.
-
-The two most important statements, are the `FragmentShader` and `VertexShader` statements. These statements specify the shader to use for the technique, and are required inside the “Default technique. Both operate in the same way, after the statement, the language of the shader is specified, usually with a version number as well, for example `GLSL100` for OpenGL Shading Language version 1.00. Followed by a colon and an absolute path for an asset describing the actual shader source code. For GLSL, it is permitted to specify .glsl, .frag, and .vert files.
-
-When the material is applied to an object, the shader has its uniforms set based on the material parameter values specified in the material instance. but the parameter is prefixed with an“m_.
-
-For example, assuming the parameter `Shininess` is defined in the MaterialParameters block like so:
-
-[source]
-----
-MaterialParameters {
-  Float Shininess
-}
-----
-
-The value of that parameter will map into an uniform with same name with the “m_ prefix in the GLSL shader:
-
-[source]
-----
-uniform float m_Shininess;
-----
-
-The letter `m` in the prefix stands for material.
-
-
-=== World/Global parameters
-
-An important structure, that also relates to shaders, is the WorldParameters structure. It is similar in purpose to the MaterialParameters structure; it exposes various parameters to the shader, but it works differently. Whereas the user specified material parameters, world parameters are specified by the engine. In addition, the WorldParameters structure is nested in the Technique, because it is specific to the shader being used. For example, the Time world parameter specifies the time in seconds since the engine started running, the material can expose this parameter to the shader by specifying it in the WorldParameters structure like so:
-
-[source]
-----
-WorldParameters {
-  Time
-// ...
-}
-----
-
-The shader will be able to access this parameter through a uniform, also named `Time` but prefixed with `g_`:
-
-[source]
-----
-uniform float g_Time;
-----
-
-The `g` letter stands for “global, which is considered a synonym with “world in the context of parameter scope.
-
-There are many world parameters available for shaders, a comprehensive list will be specified elsewhere.
-
-
-=== RenderState
-
-The RenderState block specifies values for various render states in the rendering context. The RenderState block is nested inside the Technique block. There are many types of render states, and a comprehensive list will not be included in this document.
-
-The most commonly used render state is alpha blending, to specify it for a particular technique, including a RenderState block with the statement `Blend Alpha`.
-
-*Example:*
-
-[source]
-----
-RenderState {
- Blend Alpha
-}
-----
-
-*Full Example of a J3MD*
-
-Included is a full example of a J3MD file using all the features learned:
-
-[source]
-----
-MaterialDef Test Material 123 { 
-  MaterialParameters {
-    Float m_Shininess
-    Texture2D m_MyTex
-  }
-  Technique {
-    VertexShader GLSL100 : Common/MatDefs/Misc/MyShader.vert
-    FragmentShader GLSL100 : Common/MatDefs/Misc/MyShader.frag
-    WorldParameters {
-      Time
-    }
-    RenderState {
-      Blend Alpha
-    }
-  } 
-}
-----
-
-
-== Material Instance files (J3M)
-
-In comparison to J3MD files, material instance (J3M) files are significantly simpler. In most cases, the user will not have to modify or create his/her own J3MD files.
-
-All J3M files begin with the word `Material` followed by the name of the material (once again, used for debugging only). Following the name, is a colon and the absolute asset path to the material definition (J3MD) file extended or implemented, followed by a curly-bracket.
-
-*Example:*
-
-[source]
-----
-Material MyGrass : Common/MatDefs/Misc/TestMaterial.j3md {
-----
-
-The material definition is a required component, depending on the material definition being used, the appearance and functionality of the material changes completely. Whereas the material definition provided the “logic for the material, the material instance provides the configuration for how this logic operates.
-
-The J3M file includes only a single structure; MaterialParameters, analogous to the same-named structure in the J3MD file. Whereas the J3MD file specified the parameter names and types, the J3M file specifies the values for these parameters. By changing the parameters, the configuration of the parent J3MD changes, allowing a different effect to be achieved.
-
-To specify a value for a parameter, one must specify first the parameter name, followed by a colon, and then followed by the parameter value. For texture parameters, the value is an absolute asset path pointing to the image file. Optionally, the path can be prefixed with the word “Flip in order to flip the image along the Y-axis, this may be needed for some models.
-
-*Example of a MaterialParameters block in J3M:*
-
-[source]
-----
-MaterialParameters {
-  m_Shininess : 20.0 
-}
-----
-[cols="2", options="header"]
-|===
-
-a|Param type
-a|Value example
-
-a|Int
-a|123
-
-a|Boolean
-a|true
-
-a|Float
-a|0.1
-
-a|Vector2
-a|0.1 5.6
-
-a|Vector3
-a|0.1 5.6 2.99
-
-a|Vector4=Color
-a|0.1 5.6 2.99 3
-
-a|Texture2D=TextureCubeMap
-a|Textures/MyTex.jpg
-
-|===
-
-
-The formatting of the value, depends on the type of the value that was specified in the J3MD file being extended. Examples are provided for every parameter type:
-
-*Full example of a J3M*
-
-[source]
-----
-Material MyGrass : Common/MatDefs/Misc/TestMaterial.j3md { 
-  MaterialParameters {
-    m_MyTex : Flip Textures/GrassTex.jpg
-    m_Shininess : 20.0
-  }
-}
-----
-
-
-=== Java interface for J3M
-
-It is possible to generate an identical J3M file using Java code, by using the classes in the com.jme3.material package. Specifics of the link:http://javadoc.jmonkeyengine.org/com/jme3/material/Material.html[Material API] will not be provided in this document. The J3M file above is represented by this Java code:
-
-[source,java]
-----
-
-// Create a material instance
-Material mat = new Material(assetManager, "Common/MatDefs/Misc/
-    TestMaterial.j3md");
-// Load the texture. Specify "true" for the flip flag in the TextureKey
-Texture tex =
-assetManager.loadTexture(new TextureKey("Textures/GrassTex.jpg", true));
-// Set the parameters
-mat.setTexture("MyTex", tex);
-mat.setFloat("Shininess", 20.0f);
-
-----
-
-
-== Conclusion
-
-Congratulations on being able to read this entire document! To reward your efforts, jMonkeyEngine.com will offer a free prize, please contact Momoko_Fan aka “Kirill Vainer with the password “bananapie to claim.

+ 0 - 422
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/material/materials_overview.adoc

@@ -1,422 +0,0 @@
-= Material Definition Properties
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: material, texture, MatDefs, light, culling, RenderStates, documentation
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-In jMonkeyEngine 3, colors and textures are represented as Material objects.
-
-*  All Geometries must have Materials. To improve performance, reuse Materials for similar models, don't create a new Material object for every Geometry. (E.g. use one bark Material for several tree models.) 
-*  Each Material is based on one of jme3's default Material Definitions (.j3md files) that are included in the engine. Advanced users can create additional custom Material Definitions (see how it's done in the <<jme3/build_from_sources#,jme3 sources>>).
-
-
-[TIP]
-====
-Find out quickly <<jme3/intermediate/how_to_use_materials#,How to Use Materials>>, including the most commonly used code samples and RenderStates. +
-Or find more background info on <<jme3/advanced/material_definitions#,How to use Material Definitions>>.
-====
-
-
-
-== All Materials Definition Properties
-
-The following Materials table shows you the Material Definitions that jMonkeyEngine 3 supports. 
-
-
-[TIP]
-====
-Looks confusing? +
-1) Start learning about `Unshaded.j3md` and `Lighting.j3md`, they cover 90% of the cases. +
-2) Use <<sdk/material_editing#,the SDK's visual material editor>> to try out and save material settings easily. +
-3) The <<sdk/code_editor#,SDK's Palette>> contains drag&drop code snippets for loading materials. 
-====
-
-
-Most Material parameters are optional. For example, it is okay to specify solely the `DiffuseMap` and `NormalMap` when using `Lighting.j3md`, and leave the other texture maps empty. In this case, you are only using a subset of the possible features, but that's fine if it already makes in the material look the way that you want. You can always add more texture maps later.
-
-
-=== Unshaded Coloring and Textures
-
-jMonkeyEngine supports illuminated and unshaded Material Definitions.
-
-*  Phong Illuminated materials look more naturalistic.
-*  Unshaded materials look more abstract. 
-
-“Unshaded materials look somewhat abstract because they ignore lighting and shading. Unshaded Materials work even if the scene does not include a light source. These Materials can be single-colored or textured. For example, they are used for cards and tiles, for the sky, billboards and UI elements, for toon-style games, or for testing.
-
-[cols="20,40,40", options="header"]
-.Standard Unshaded
-|===
-
-a| Material Definition 
-a| Usage 
-<a| Material Parameters  
-
-a| Common/MatDefs/Misc/ +
-Unshaded.j3md 
-a| Standard, non-illuminated Materials. +
-Use this for simple coloring and texturing, glow, and transparency. +
-See also: <<jme3/beginner/hello_material#,Hello Material>> 
-a| *Texture Maps* +
-setTexture(“ColorMap, assetManager.loadTexture(“)); +
-setBoolean(“SeparateTexCoord,true); +
-setTexture(“LightMap, assetManager.loadTexture(“)); +
-*Colors* +
-setColor(“Color, ColorRGBA.White); +
-setBoolean(“VertexColor,true); +
-*Glow* +
-setTexture(“GlowMap, assetManager.loadTexture(“)); +
-setColor(“GlowColor, ColorRGBA.White); 
-
-|===
-
-Other useful, but less commonly used material definitions:
-
-[cols="20,40,40", options="header"]
-.Special Unshaded
-|===
-
-a| Material Definition 
-a| Usage 
-<a| Material Parameters  
-
-<a| Common/MatDefs/Misc/ +
-Sky.j3md            
-a| A solid skyblue, or use with a custom SkyDome texture. +
-See also: <<jme3/advanced/sky#,Sky>> 
-a| setTexture(“TextureCubeMap, assetManager.loadTexture(“)); +
-setBoolean(“SphereMap,true); +
-setVector3(“NormalScale, new Vector3f(0,0,0)); 
-
-a| Common/MatDefs/Terrain/ +
-Terrain.j3md 
-a| Splat textures for e.g. terrains. +
-See also: <<jme3/beginner/hello_terrain#,Hello Terrain>> 
-a| setTexture(“Tex1, assetManager.loadTexture(“)); +
-(red) +
-setFloat(“Tex1Scale,1f); +
-setTexture(“Tex2, assetManager.loadTexture(“)); +
-(green) +
-setFloat(“Tex2Scale,1f); +
-setTexture(“Tex3, assetManager.loadTexture(“)); +
-(blue) +
-setFloat(“Tex3Scale,1f); +
-setTexture(“Alpha, assetManager.loadTexture(“)); 
-
-a|Common/MatDefs/Terrain/ +
-HeightBasedTerrain.j3md
-a|A multi-layered texture for terrains. +
-Specify four textures and a Vector3f describing the region in which each texture should appear: +
-X = start height, +
-Y = end height, +
-Z = texture scale. +
-Texture regions can overlap. +
-For example: Specify a seafloor texture for the lowest areas, +
-a sandy texture for the beaches, +
-a grassy texure for inland areas, +
-and a rocky texture for mountain tops.
-a| setFloat(“terrainSize,512f); +
-setTexture(“region1ColorMap, assetManager.loadTexture(“)); +
-setTexture(“region2ColorMap, assetManager.loadTexture(“)); +
-setTexture(“region3ColorMap, assetManager.loadTexture(“)); +
-setTexture(“region4ColorMap, assetManager.loadTexture(“)); +
-setVector3(“region1, new Vector3f(0,0,0)); +
-setVector3(“region2, new Vector3f(0,0,0)); +
-setVector3(“region3, new Vector3f(0,0,0)); +
-setVector3(“region4, new Vector3f(0,0,0)); +
-*Settings for steep areas:* +
-setTexture(“slopeColorMap, assetManager.loadTexture(“)); +
-setFloat(“slopeTileFactor,1f);
-
-<a| Common/MatDefs/Misc/ +
-Particle.j3md       
-a| Used with texture masks for particle effects, or for point sprites. +
-The Quadratic value scales the particle for perspective view (link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-core/src/main/java/com/jme3/effect/ParticleEmitter.java[formula]). +
-Does support an optional colored glow effect. +
-See also: <<jme3/beginner/hello_effects#,Hello Effects>> 
-a| setTexture(“Texture, assetManager.loadTexture(“)); +
-setTexture(“GlowMap, assetManager.loadTexture(“)); +
-setColor(“GlowColor, ColorRGBA.White); +
-setFloat(“Quadratic,1f); +
-setBoolean(“PointSprite,true); 
-
-|===
-
-
-=== Phong Illuminated
-
-jMonkeyEngine supports illuminated and unshaded Material Definitions.
-
-*  Phong Illuminated materials look more naturalistic.
-*  Unshaded materials look more abstract.
-
-Illuminated materials require a <<jme3/advanced/light_and_shadow#,light source>> added to at least one of their parent nodes! (e.g. rootNode.) Illuminated materials are darker on the sides facing away from light sources. They use Phong illumination model (default), or the Ward isotropic gaussian specular shader (WardIso) which looks more like plastic. They do not cast <<jme3/advanced/light_and_shadow#,drop shadows>> unless you use a FilterPostProcessor. 
-
-[cols="20,40,40", options="header"]
-.Standard Illuminated
-|===
-
-a|Material Definition 
-a| Usage 
-a| Material Parameters 
-
-<a| Common/MatDefs/Light/ +
-Lighting.j3md      
-a| Commonly used Material with Phong illumination. +
-Use this material together with DiffuseMap, SpecularMap, BumpMap (NormalMaps, ParalaxMap) textures. +
-Supports shininess, transparency, and plain material colors (Diffuse, Ambient, Specular colors). +
-See also: <<jme3/beginner/hello_material#,Hello Material>> 
-<a| *Texture Maps* +
-setTexture(“DiffuseMap, assetManager.loadTexture(“)); +
-setBoolean(“UseAlpha,true); footnote:[UseAlpha specifies whether DiffuseMap uses the alpha channel]  +
-setTexture(“NormalMap, assetManager.loadTexture(“)); +
-setBoolean(“LATC,true); footnote:[LATC Specifies whether NormalMap is BC5/ATI2n/LATC/3Dc-compressed]  +
-setTexture(“SpecularMap, assetManager.loadTexture(“)); +
-setFloat(“Shininess,64f); +
-setTexture(“ParallaxMap, assetManager.loadTexture(“)); +
-setTexture(“AlphaMap, assetManager.loadTexture(“)); +
-setFloat(“AlphaDiscardThreshold,1f); +
-setTexture(“ColorRamp, assetManager.loadTexture(“)); +
-*Glow* +
-setTexture(“GlowMap, assetManager.loadTexture(“)); +
-setColor(“GlowColor, ColorRGBA.White); +
-*Performance and quality* +
-setBoolean(“VertexLighting,true); +
-setBoolean(“UseVertexColor,true); +
-setBoolean(“LowQuality,true); +
-setBoolean(“HighQuality,true); +
-*Material Colors* +
-setBoolean(“UseMaterialColors,true); +
-setColor(“Diffuse, ColorRGBA.White); +
-setColor(“Ambient, ColorRGBA.White); +
-setColor(“Specular, ColorRGBA.White); +
-*Tangent shading:* +
-setBoolean(“VTangent,true); +
-setBoolean(“Minnaert,true); footnote:[Minnaert is a shader type.] +
-setBoolean(“WardIso,true); footnote:[WardIso is a shader type.]  
-
-|===
-
-[cols="20,40,40", options="header"]
-.Special Illuminated
-|===
-
-a|Material Definitions 
-a| Usage 
-a| Material Parameters 
-
-a|Common/MatDefs/Terrain/ +
-TerrainLighting.j3md
-a|Same kind of multi-layered splat texture as Terrain.j3md, but with illumination and shading. +
-Typically used for terrains, but works on any mesh. +
-For every 3 splat textures, you need one alpha map. +
-You can use a total of 11 texture maps in the terrain's splat texture: +
-Note that diffuse and normal maps all count against that. +
-For example, you can use a maximum of 9 diffuse textures, two of which can have normal maps; +
-or, five textures with both diffuse and normal maps.
-a|*Texture Splat Maps* +
-setTexture(“DiffuseMap, assetManager.loadTexture(“)); +
-setFloat(“DiffuseMap_0_scale,1f); +
-setTexture(“NormalMap, assetManager.loadTexture(“)); +
-setTexture(“DiffuseMap_1, assetManager.loadTexture(“)); +
-setFloat(“DiffuseMap_1_scale,1f); +
-setTexture(“NormalMap_1, assetManager.loadTexture(“)); +
-setTexture(“DiffuseMap_2, assetManager.loadTexture(“)); +
-setFloat(“DiffuseMap_2_scale,1f); +
-setTexture(“NormalMap_2, assetManager.loadTexture(“)); +
-setTexture(“DiffuseMap_3, assetManager.loadTexture(“)); +
-setFloat(“DiffuseMap_3_scale,1f); +
-setTexture(“NormalMap_3, assetManager.loadTexture(“)); +
-etc, up to 11. +
-*Alpha Maps* +
-setTexture(“AlphaMap, assetManager.loadTexture(“)); +
-setTexture(“AlphaMap_1, assetManager.loadTexture(“)); +
-setTexture(“AlphaMap_2, assetManager.loadTexture(“)); +
-*Glowing* +
-setTexture(“GlowMap, assetManager.loadTexture(“)); +
-setColor(“GlowColor, ColorRGBA.White); +
-*Miscellaneous* +
-setColor(“Diffuse, ColorRGBA.White); +
-setColor(“Ambient, ColorRGBA.White); +
-setFloat(“Shininess,64f); +
-setColor(“Specular, ColorRGBA.White); +
-setTexture(“SpecularMap, assetManager.loadTexture(“)); +
-setBoolean(“WardIso,true); +
-setBoolean(“useTriPlanarMapping,true); +
-setBoolean(“isTerrainGrid,true); 
-
-<a| Common/MatDefs/Light/ +
-Reflection.j3md    
-a| Reflective glass material with environment map (CubeMap/SphereMap). See also: link:http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/texture/TestCubeMap.java[TestCubeMap.java] 
-a| setTexture(“Texture, assetManager.loadTexture(“)); +
-setBoolean(“SphereMap,true); 
-
-|===
-
-
-=== Other: Test and Debug
-
-[cols="20,80", options="header"]
-.Testing
-|===
-
-<a| Material Definition                     
-a| Usage 
-
-<a| Common/MatDefs/Misc/ +
-ShowNormals.j3md    
-a| A color gradient calculated from the model's surface normals. You can use this built-in material to debug the generation of normals in meshes, to preview models that have no material and no lights, or as fall-back default material. This built-in material has no parameters. 
-
-|===
-
-
-== RenderStates
-
-
-[cols="3", options="header"]
-.Transparancy
-|===
-
-a|Material Option
-a|Description
-a|Example
-
-a|getAdditionalRenderState(). +
-setBlendMode(BlendMode.Off);
-a|This is the default, no transparency.
-a|Use for all opaque objects like walls, floors, people…
-
-a|getAdditionalRenderState() +
-.setBlendMode(BlendMode.Alpha);
-a|Interpolates the background pixel with the current pixel by using the current pixel's alpha.
-a|Use this for normal every-day translucency: Frosted window panes, ice, glass, alpha-blended vegetation textures… 
-
-a|getAdditionalRenderState() +
-.setDepthWrite(false);
-a|Disables writing of the pixel's depth value to the depth buffer.
-a|Use this on Materials if you have several transparent/translucent objects obscuring one another, but you want to see through both.
-
-a|getAdditionalRenderState() +
-.setAlphaFallOff(0.5f); +
-getAdditionalRenderState() +
-.setAlphaTest(true)
-a|Enables Alpha Testing with a “AlphaDiscardThreshold in the AlphaMap.
-a|Activate Alpha Testing for (partially) *transparent* objects such as foliage, hair, etc. +
-Deactivate Alpha Testing for gradually *translucent* objects, such as colored glass, smoked glass, ghosts.
-
-a|getAdditionalRenderState() +
-.setBlendMode(BlendMode.Additive);
-a|Additive alpha blending adds colors in a commutative way, i.e. the result does not depend on the order of transparent layers, since it adds the scene's background pixel color to the current pixel color. This is useful if you have lots of transparent textures overlapping and don't care about the order. +
-*Note:* Viewed in front of a white background, Additive textures become fully transparent! 
-a| This is the default for Particle.j3md-based textures that have a black color background. 
-
-a|getAdditionalRenderState() +
-.setBlendMode(BlendMode.AlphaAdditive);
-a|Same as “Additive, except first it multiplies the current pixel color by the pixel alpha.
-a|This can be used for particle effects that have alpha as background. 
-
-a|getAdditionalRenderState() +
-.setBlendMode(BlendMode.Color);
-a|Blends by color.
-a|Generally useless.
-
-a|getAdditionalRenderState() +
-.setBlendMode(BlendMode.Modulate);
-a|Multiplies the background pixel by the current pixel.
-a|?
-
-a|getAdditionalRenderState() +
-.setBlendMode(BlendMode.ModulateX2);
-a|Same as “Modulate, except the result is doubled.
-a|?
-
-a|getAdditionalRenderState() +
-.setBlendMode(BlendMode.PremultAlpha);
-a|Pre-multiplied alpha blending. E.g. if the color of the object has already been multiplied by its alpha, this is used instead of “Alpha blend mode.
-a|For use with Premult Alpha textures.
-
-|===
-
-If the DiffuseMap has an alpha channel, use:
-
-[source,java]
-----
-mat.setBoolean("UseAlpha",true);
-----
-
-Later, put the Geometry (not the Material!) in the appropriate render queue.
-[source,java]
-----
-geo.setQueueBucket(Bucket.Translucent);
-----
-or
-[source,java]
-----
-geo.setQueueBucket(Bucket.Transparent);
-----
-
-
-
-[cols="3", options="header"]
-.Culling
-|===
-
-a|Material Option
-a|Usage
-a|Example
-
-a|getAdditionalRenderState() +
-.setFaceCullMode(FaceCullMode.Back); 
-a|Activates back-face culling. Mesh faces that are facing away from the camera are not rendered, which saves time. *Backface culling is activated by default as a major optimization.* 
-a|The invisible backsides and insides of models are not calculated. 
-
-a|getAdditionalRenderState() +
-.setFaceCullMode(FaceCullMode.Off); 
-a|No meshes are culled. Both mesh faces are rendered, even if they face away from the camera. Slow.
-a|Sometimes used to debug custom meshes if you messed up some of the polygon sides, or for special shadow effects.
-
-a|getAdditionalRenderState() +
-.setFaceCullMode(FaceCullMode.Front); 
-a|Activates front-face culling. Mesh faces facing the camera are not rendered.
-a|No example – Typically not used because you wouldn't see anything meaningful.
-
-a|getAdditionalRenderState() +
-.setFaceCullMode(FaceCullMode.FrontAndBack)
-a|Culls both backfaces and frontfaces.
-a|Use this as an efficient way to make an object temporarily invisible, while keeping all its other in-game properties (such as node attachment, collision shapes, interactions, etc) active.
-
-|===
-
-
-[cols="3", options="header"]
-.Miscellaneous
-|===
-
-a|Material Option
-a|Useage
-a|Example
-
-a|getAdditionalRenderState() +
-.setColorWrite(false);
-a|Disable writing the color of pixels.
-a|Use this together with setDepthWrite(true) to write pixels only to the depth buffer, for example. 
-
-a|getAdditionalRenderState() +
-.setPointSprite(true);
-a|Enables point-sprite mode, e.g. meshes with “Mode.Points will be rendered as textured sprites. Note that gl_PointCoord must be set in the shader.
-a|Point sprites are used internally for hardware accelerated particle effects.
-
-a|getAdditionalRenderState() +
-.setPolyOffset();
-a|Enable polygon offset.
-a|Use this when you have meshes that have triangles really close to each over (e.g. link:http://en.wikipedia.org/wiki/Coplanarity[Coplanar]), it will shift the depth values to prevent link:http://en.wikipedia.org/wiki/Z-fighting[Z-fighting].
-
-|===
-
-*Related Links*
-
-*  <<jme3/advanced/material_specification#,Developer specification of the jME3 material system (.j3md,.j3m)>>

+ 0 - 128
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/material/pbr_part1.adoc

@@ -1,128 +0,0 @@
-= Physically Based Rendering – Part one
-
-I’ve been looking at Physically Based Rendering (PBR from now on) since a few weeks, because that’s what all the cool kids are talking about these days. I read almost all the interweb about it and finally somehow wrapped my head around the mechanics behind the concept.
-
-None of the papers I read gave me the epiphany though, the understanding came little by little, literally reading some of the papers 10 times.
-
-The intent of this series of posts is first to brush up the concept of PBR from the artist point of view (the easy part :D), and then to explain the physical concepts behind it and what you have to understand as a developer.
-
-This paper aims to present PBR as I would explain it to my mother. You shouldn’t need a degree in image rendering theories, neither should you need to be a genius to understand what’s coming.
-
-There are a lot of papers out there, with a lot of complicated words and equations, that assume a solid background knowledge of image rendering, lighting, shading etc…
-
-I won’t assume this here.
-
-Of course, I’d like this to be as accurate as possible, so if you have more information, or if explanations are not clear, feel free to chime in.
-
-*I’m an artist, I want to know what PBR is :*
-
-So you’re an artist, and have some experience in making assets for games. The most commonly used model for describing a material is the Phong reflection model (from link:https://en.wikipedia.org/wiki/Bui_Tuong_Phong[Bui Tuong Phong], a clever guy that died very young).
-
-This model describes how light reflects on a material by splitting it in 3 factors: Ambient color, Diffuse color, Specular color. This should sound familiar to 3D game artists.
-
-This model is a very rough approximation of what’s really going on when light hit a surface of a real life material, but until then it was pretty much enough for a video game. Of course there are dozens of other models and even modification of Phong model, but this one is the most used, and that’s the one we use in jMonkeyEngine.
-
-The issue with this model is that it’s complicated to have a material that looks consistent under different lighting environment.
-
-   * Ambient is supposed to represent Ambient lighting, being some sort of omnipresent dim light, that tries to fake indirect lighting coming from reflection of light on the surrounding objects.
-   * Diffuse is more straightforward: it’s the actual color of the object when it’s under a white light.
-   * Specular represent the color of the reflected highlights, and the intensity is driven by a “shininess” parameter (at least in jME but that’s pretty common). The issue is that the specular color also drives the intensity because the brighter the color the more intense the specular will be.
-
-All of this leads to a lot of tweaking to look correct, and may not look as good as it should under a different lighting environment. It also relies heavily on an artist’s best guesses about the material.
-
-So here comes Physically Based Rendering. Not that the previous one was not physically based…but whatever, that sounds pretty cool.
-
-Everybody has their own way to implement PBR, but every implementation share common goals and concepts.
-
-*Goals :*
-
-   * Ease the artist’s material workflow.
-   * More “photo realistic” rendering.
-
-*Concepts :*
-
-   * Every surface has a reflection (specular); even the rougher ones at grazing angles.
-   * Energy conservation: a surface cannot reflect more light that it has received.
-
-This wraps up the entire concept but how does it translate in practice?
-
-A material can now be described with 3 parameters :
-
-*Base color :* Base color is the raw color of the material, it’s also often referred as the Albedo. It’s similar to the Diffuse color you know from Phong model, but with some crucial differences :
-
-   * It should not contain any shading information. Very often with phong model, Ambient Occlusion (AO) is baked into the diffuse map. Here Base color must be the raw color of the material
-   * It does not only influence the diffuse color, but also the specular color of the material.
-
-*Metalness :* The degree of metallicity of the material. What does that mean? is your material rather metallic or rather not (non metallic materials are called dielectric materials in the literature). Some implementation calls that parameter “specular”, but I found it pretty misleading as it’s completely different as the specular we know today. In practice, just start out with extreme values to get the feel for it: 1 for metallic, 0 for dielectric.
-
-image::metalness.png[metalness,width="320",height="250",align="center"]
-Here is the same material with metalness of 0 (dielectric) on the left and 1 (metallic) on the right.
-
-Of course there are intermediary values, but from my reading, most dielectric material should vary from 0.04 and 0.1, and metallic are usually 1. Those values are based on real life measures and you can find some references about them link:https://seblagarde.wordpress.com/2012/04/30/dontnod-specular-and-glossiness-chart/[here] and link:https://seblagarde.wordpress.com/2014/04/14/dontnod-physically-based-rendering-chart-for-unreal-engine-4/[here]. Note that those values are not subject to interpretation, and are “known” factors and artist may follow them if they want to keep realistic look.
-
-*Roughness :* The degree of roughness of the material : Is your material smooth or rough. 0 means smooth, 1 means rough. Some implementations refer to this as Smoothness or Glossiness. That’s essentially the same except it’s the other way around. 1 is smooth and 0 is rough. I find the term “Roughness” pretty much self explanatory and doesn’t leave room for misinterpretation.
-
-image::Roughness.png[Roughness,width="320",height="250",align="center"]
-Here is the same material with different level of roughness from 0 (left) to 1 (right). As opposed to metalness, this parameter is very artist driven. The roughness of a material does not really depend on physics, it’s more related to micro scratches, wearing, etc… So that’s where artists should be creative!
-
-These parameters are the basics of PBR. Of course, each of them can be stored in a texture, and more common additional parameters can be used.
-
-*For example :*
-
-   * Normal map : the same as with phong model.
-   * AO map : since we can’t bake AO in diffuse anymore, it’s now an extra channel.
-
-The nice thing is that Metalness, Roughness and AO are grey scaled textures, so basically they only use one channel of a texture. So you can pack those 3 maps in one texture.
-
-You can find an example asset that should work in a typical PBR implementation link:http://artisaverb.info/PBT.html[here]. This page showcases pretty well what the textures should look like.
-
-That’s it for PBR from the artist point of view. Next week I’ll explain what’s under the hood for you fellow developers 😉
-
-*Updates (01/01/2015)*
-
-Since this post I had some discussions about it and it appears, it lacks some informations about the different art pipeline you may come across, the differences and what to expect from them.
-
-The post above is about the *Metalness Workflow*.
-
-The question I had frequently about it is “how one specify the specular color if you just have a black and white metalness texture?”.
-
-The answer is you do in the albedo map.
-
-In the metalness workflow the albedo map is used for both diffuse color and specular color. When the metalness is zero (dielectric material) the base color is the diffuse color of the material. When the metalness is one (metallic material), the base color is the specular color.
-
-So if you wonder what this base color should be, just look at it in the most naive way. “What color is that thing?” and don’t care if that’s diffuse or specular.
-
-The other common workflow is called the *Specular workflow* as it uses a specular color map instead of the metalness map. In this workflow, the albedo map is the diffuse color, the specular map is the specular color, and you have a gray scale gloss map that is the same as the roughness map but inverted (1 is smooth and 0 is rough).
-
-Now there are pro and cons on using one or the other. Here are the main points :
-
-== Metalness workflow :
-
-*Pros*
-
-   * Use less texture space. Albedo map is an rgba map, metal and roughness can be packed in another rgba map and you have 2 additional channels for whatever you want (AO, cavity, …w/e)
-
-   * Harder to make implausible materials (some may see this as a con thought). it’s not more physically accurate, but you’re sure to follow the energy conservation paradigm.
-   * Easier color concept : base color is the color of the material.
-
-*Cons*
-
-   * May produce some white artifacts at the junction between metal and non metal
-   * Harder to make implausible materials, not impossible though.
-
-== Specular workflow
-
-*Pros*
-
-   * Closer to the current phong workflow : diffuse map, specular map. Must be easier for seasoned artists to transition to PBR.
-
-*Cons*
-
-   * You’re in charge of the energy conservation paradigm (may be seen as a + for some).
-   * More memory used : 2 rgba textures for diffuse and specular, you may be able to pack glossiness in the alpha channel of specular map, but you have no room left for anything and you may have to use a third texture.
-
-
-
-IMO, the metalness workflow is more suited to real time 3D engine. And as an artist I find it more intuitive.
-
-That  said, as a developer making his PBR pipeline; especially for an engine mainly used by Indie devs; whatever pipeline you choose, you can’t ignore the other. Free or charged PBR ready model you can find are done with whatever workflow suited the artist. some conversion are possible, but that’s easier for user to be able to use the model as is. That’s why I decided to support both in my implementation.

+ 0 - 172
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/material/pbr_part2.adoc

@@ -1,172 +0,0 @@
-= Physically Based Rendering – Part Two
-
-<<pbr_part1#,In previous post>>, I explained what you had to know about Physically Based Rendering if you were an artist. If you’re a developer, and reading this article, you may have tried, or are planning  to implement your own PBR system. If you started to read some of the available literature, you’ve probably been struck by the math complexity of it, and by the lack of explanation of the big picture. You usually see articles that focus on specifics parts of the process, and don’t talk much about other parts as they are assumed easier. At some point you have to assemble all these parts, and I had a hard time figuring out how to do it in my readings. I guess it’s considered basic stuff for other authors, but I think it deserves its proper explanation.
-
-I don’t pretend these articles will enlighten you to the point you are ready to implement your own system, but I hope they will give you solid basis and understanding to start reading the literature without saying “WTF?? on every line as I did.
-
-You can find a lexical, at the end, with all the strange words you’ll come across and their explanations.
-
-So here is what I figured out about using PBR and lighting in general in a 3D rendering pipeline.
-
-
-**Ligthing**
-
-So first, lets talk about lighting in games. It all boils down to 2 things :
-
-   * Computing *Diffuse* reflection: This represent the light that reflects off a surface in all directions
-   * Computing *Specular* reflection : This represent the light that reflects off a surface directly to your eye.
-
-This image from wikipedia is the most simple and yet the most helpful to understand this
-
-image::Lambert2.png[Lambert2,width="320",height="250",align="center"]
-By GianniG46 (Own work) [CC-BY-SA-3.0 (http://creativecommons.org/licenses/by-sa/3.0) or GFDL (http://www.gnu.org/copyleft/fdl.html)], via Wikimedia Commons
-
-To compute each of these factors, we’re going to use a function. This function answers to the delicate name of *Bidirectional Reflectance Distribution Function or BRDF*.
-
-Don’t be scared by this, it’s a big name for just a function really. Usually, it will be a shader function.
-
-
-
-Of course there are different BRDFs depending on what you want to compute, and on the lighting model you use. The BRDFs are usually called by the name of the guys that discovered/elaborated them.
-
-Also, most of the time, in implementations for real time rendering, those BRDFs are approximated for the sake of performance. And incidentally, those approximations also have names, that can be people names or technique names…
-
-
-== Lighting in PBR
-
-Computing lighting for PBR is exactly the same as with the current rendering ( the system we use today with ambient, diffuse, specular, sometimes called ad-hoc system in the literature) :
-
-For each light source, compute the diffuse factor and the specular factor. The main difference is that the BRDFs used are different, more physically accurate, and works predictably under different light sources with few parameter entries.
-
-
-
-So what is a light source?
-
-=== Direct light source
-
-Something that emits light. In games the most common light sources are Directional lights (think of the sun), Spot lights (think of a torch light), Point lights (think of a light bulb).
-
-That’s what is commonly used in the ad-hoc system, and PBR also handle those types of lights.
-
-
-=== Indirect light source
-
-Something that reflects light and indirectly lights its surroundings. Think for example of a red wall next to a car at daytime, the sunlight hits the wall and the wall reflects red light that, in turn, lights up the car.
-
-This is not handled by the ad-hoc system, or very poorly faked with ambient lighting.
-
-This part is optional for PBR, but that’s actually the part you really want. because that’s what make things pretty!
-
-In games, indirect lighting is done by using an environment map as a light source. This technique is called *Image Based Lighting (IBL)*.
-
-
-
-So let’s say we’re looking for the full package. we need to compute diffuse and specular contribution for each light source be it direct or indirect.
-
-To do so we need a BRDF for diffuse and a BRDF for specular, and stick to them for each light source for consistency. Also those BRDF should accept as entry the parameters we want to expose for the artists (base color, metalness, roughness), or derived parameters with minimal transformation.
-
-
-
-So the pseudo code for a complete lighting is this :
-[source]
-----
-//direct lighting
-for each directLightSource {
-    directDiffuseFactor = DiffuseBRDF(directlightSource)
-    directSpecularFactor = SpecularBRDF(directLightSource)
-    directLighting += Albedo * directDiffuseFactor + SpecColor * directSpecularFactor
-}
-
-//Indirect Lighting, done through Image Based Rendering with an environment map
-indirectDiffuseFactor = DiffuseBRDF(EnvMap)
-indirectSpecularFactor = SpecularBRDF(EnvMap)
-
-indirectLighting = Albedo * indirectDiffuseFactor + SpecColor * indirectSpecularFactor
-
-Lighting = directLighting + indirectLighting
-----
-
-I’ll go into more details, in the posts serie, on how to compute each factors, but that’s pretty much it.
-
-
-== Choosing your BRDFs
-
-There is a vast choice of BRDF, and I’m not going to talk about all of them but focus on the ones that I use in my implementation. I’ll just guide you to alternatives and provide links to relevant articles for more details.
-
-I chose to use the same BRDF as the ones used in Unreal Engine 4 from link:http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf[this article] by Brian Karis, as I completely trust his judgement. The provided code helped a great deal, but it was far from straight forward to integrate. In the end I had to fully research, and understand all the whereabouts of BRDFs.
-
-
-=== Diffuse BRDF : Lambert
-
-The most used diffuse BRDF in games. It’s very popular because it’s very cheap to compute and gives good results. This is the most simple way of computing diffuse.  link:https://en.wikipedia.org/wiki/Lambertian_reflectance[here are the details]
-
-image::DiffuseLambert.jpg[DiffuseLambert,width="320",height="250",align="center"]
-Diffuse Lambert factor for a direct light source (directional light) with a yellow surface color.
-
-Some Alternatives :
-
-*Oren-Nayar* : Gives better visual results than classic Lambert, and has the advantage of using an entry parameter called roughness…rings a bell? Unfortunately, the additional computation cost is not really worth it,IMO. link:https://en.wikipedia.org/wiki/Oren%E2%80%93Nayar_reflectance_model[Details here]
-
-*Harahan-Krueger* : Takes into consideration sub-surface scattering for diffuse lighting (every material surface has layers and light scatters into those different layers before going out of the material in a random direction). A lot of computations compared to Lambert, but may be important if you want to have a good sub surface scattering look for skin for example.  link:http://cseweb.ucsd.edu/~ravir/6998/papers/p165-hanrahan.pdf[more details in this paper]
-
-
-
-
-=== Specular BRDF : Cook-Torrance
-
-This is a bit more complicated for specular. We need a physically plausible BRDF. We use what is called a *Microfacet BRDF*. So what is it?
-
-It states that at a micro level a surface is not plane, but formed of a multitude of little randomly aligned surfaces, the microfacets. Those surfaces acts as small mirrors that reflects incoming light. The idea behind this BRDF is that only some of those facets may be oriented so that the incoming light reflects to your eye. The smoother the surface, the more all facets are aligned, and the most neat is the light reflection. In the contrary, if a surface is rough, the facets are more randomly oriented so the light reflection is scattered on the surface, and the reflection looks more blurry.
-
-image::Specular.png[Specular,width="320",height="250",align="center"]
-Microfacet specular factor for a direct light source. On the left a smooth surface, on the right a rough one. Note how the reflection is scattered on the surface when it’s rough.
-
-The microfacet BRDF we use is called Cook-Torrance. From my readings, I couldn’t find any implementation that use another specular BRDF. It seems like this is the global form of any microfacet BRDF.
-
-[source]
-----
-f = D * F * G / (4 * (N.L) * (N.V));
-----
-*N.L* is the dot product between the normal of the shaded surface and the light direction.
-
-*N.V* is the dot product between the normal of the shaded surface and the view direction.
-
-The other terms are :
-
-   * *Normal Distribution Function called D* (for distribution). You may also find some references to it as NDF. It computes the distribution of the microfacets for the shaded surface
-   * *Fresnel factor called F*. Discovered by Augustin Fresnel (frenchies are sooo clever), it describes how light reflects and refracts at the intersection of two different media (most often in computer graphics : Air and the shaded surface)
-   * *Geometry shadowing term G*. Defines the shadowing from the microfacets
-
-That’s where it gets complicated. For each of these terms, there are several models or approximations to computed them.
-
-I’ve settled to use those models and approximations :
-
-   * *D : Trowbridge-Reitz/GGX* normal Distribution function.
-   * *F : Fresnel term Schlick*’s link:http://www.cs.virginia.edu/~jdl/bib/appearance/analytic%20models/schlick94b.pdf[approximation]
-   * *G : Schlick-GGX* approximation
-
-I won’t go into the details of all the alternatives I just want to expose an overview of the whole process first.  But I’ll dive into more technical details on the terms I use, in following posts. To have a neat overview of all alternatives you can see this link:http://graphicrants.blogspot.fr/2013/08/specular-brdf-reference.html[post] on  Brian Karis’s blog.
-
-
-
-That sums up the whole process, but there is still much to explain. In next post I’ll make a focus on indirect lighting, as it’s the part that gave me the hardest time to wrap my head around. I’ll explain the Image Based Lighting technique used, and how you can compute diffuse and specular from an Environment Map.
-
-<<pbr_part3#,Next Post>>
-
-== Lexical :
-
-*Diffuse reflection :* light that reflects from a surface in every direction.
-
-*Specular reflection :* light that reflects from a surface toward the viewer.
-
-*Bidirectional Reflectance Distribution Function or BRDF :* a function to compute Diffuse or Specular reflection.
-
-*Image Based Rendering or IBL :* a technique that uses an image as a light source
-
-*Microfacet Specular BRDF :* A specular BRDF that assumes a surface is made of a multitude of very small randomly aligned surfaces: the microfacets. it depends on 3 factors called D, F and G.
-
-*Normal Distribution Function called D* (for distribution). You may also find some references to it as NDF. It computes the distribution of the microfacets for the shaded surface
-
-*Fresnel factor called F*. Discovered by Augustin Fresnel (frenchies are sooo clever), it describes how light reflects and refracts at the intersection of two different media (most often in computer graphics : Air and the shaded surface)
-
-*Geometry shadowing term G*. Defines the shadowing from the micro facets

+ 0 - 189
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/material/pbr_part3.adoc

@@ -1,189 +0,0 @@
-= Physically Based Rendering – Part Three
-
-image::irradianceMap.png[irradianceMap,width="320",height="250",align="center"]
-*Note* : after several discussions in the team, I realized that some points were not clear in the  “PBR for artists” post. I’ve made an update with additional information on how to handle metalness and specular. <<pbr_part1#,I invite you to read it>>.
-
-== Image Based Lighting in PBR
-
-In the <<pbr_part2#,previous post>>, I talked about the basics of PBR for developers, and explained the different steps of the lighting process with PBR.
-
-As said before, PBR does not necessarily imply to have indirect lighting, But that’s what makes it look so good.
-
-Today I’m gonna focus on a technique called Image Based Lighting (IBL), that will allow us to cheaply compute this indirect lighting.
-
-As before you can find at the end of the article a lexical with definitions of various unusual terms you’ll come across.
-
-== Indirect Lighting for PBR with Image Based Lighting.
-
-Direct lighting is usually pretty clear for everyone as it uses common light sources (point light, directional light,…).
-
-However indirect lighting is not that obvious. First you need to understand what we want to simulate with indirect light.
-
-It is often referred as *Global Illumination (or GI)*. This represents the light bouncing on surrounding objects that is lighting the shaded surface. There are several techniques to implement global illumination, but the most common is *Image Based Lighting (IBL)*. It is very often associated with PBR pipelines.
-
-So basically, a light source in game is a color, and optionally other parameters like direction, position, radius, etc… An image has color informations, and this color can be considered as a light source.
-
-For global Illumination light is coming from everywhere. So a good way to simulate GI with IBL is to consider an environment map as a light source.
-
-=== Reminder on environment maps :
-
-Most often, in-game environment maps are cube maps.
-
-How do we fetch a pixel from an environment map? We need a vector. Often called the reflect vector (refVec), because thats the reflection vector of the view direction on the shaded surface.
-
-A picture worth thousand words
-
-image::Cube_mapped_reflection_example.jpg[Cube_mapped_reflection_example,width="320",height="250",align="center"]
-from wikipedia : TopherTH at the English language Wikipedia [GFDL (http://www.gnu.org/copyleft/fdl.html), GFDL (http://www.gnu.org/copyleft/fdl.html) or CC-BY-SA-3.0 (http://creativecommons.org/licenses/by-sa/3.0/)], via Wikimedia Commons Here the reflected Ray is our reflection vector.
-
-Here the reflected Ray is our reflection vector.
-
-Unfortunately we can’t take each pixel of the env map and compute light as if it was a direct light source and hope for the best.
-
-There’s crazy math around that topic, and to be honest I didn’t get all of it myself. So instead of explaining difficult math equations that may be confusing, I’m gonna go straight to the point : How are we going to compute lighting from the environment map?
-
-=== IBL Diffuse
-
-First we need to compute Diffuse factor from the environment map. Remember our diffuse BRDF from last post? *Lambert*.
-
-To simplify, Lambert diffuse BRDF, as it’s used in game, is the light color multiplied by a visibility factor.
-
-This visibility factor is a function of the normal of the shaded geometry and the light direction.
-
-Let’s say you have a direct light source lighting the front side of a geometry. The back side of this geometry is in the dark. Meaning the front side visibility factor is 1 and the back side visibility factor is 0.
-
-For indirect lighting, we can ditch out this visibility factor because the light is coming from everywhere. So all of this simplifies in Diffuse factor = light color.
-
-But what’s the light color for a given point?
-
-Technically, every pixel in the environment map is a light source, so a shaded point is lighten by a vast amount of pixels.
-
-image::irradiance.png[irradiance,width="320",height="250",align="center"]
-
-In this picture the orange area represent the light rays coming from the cube map to the shaded pixel, that we have to consider to properly compute the light color. So the idea would be, for each shaded pixel, to fetch all that texels and combine the colors.
-
-As you can image that’s not practical for a real time rendering pipeline. Even with a 128×128 env map that’s around 50k texture fetches per pixel.
-
-Fortunately, We can use something called an *Irradiance map*. An irradiance map is basically the afford mentioned computation…except that it’s precomputed and baked into a texture. In practice here is what it looks like.
-
-image::irradianceMap.png[irradianceMap,width="320",height="250",align="center"]
-On the left the original cube map, on the right, the pre computed irradiance map.
-
-So at run time you just have to do one texture fetch in that map with the reflection vector. Pretty cool heh?
-
-Except that to pre-compute that map we still have to sample the cube map literally billions of times, and even if it’s at design time…it’s painfully long.
-
-*Spherical Harmonics (SH) to the rescue*
-
-What’s that again? I won’t go into explaining them in details (because I can’t actually ;-P ), but just know that it’s once again some math magic with a big name on it. Here is a post where it’s explained with simple words, in terms of what you can use them for.
-
-To put it simple, SH can help us to compute the irradiance map way faster. This article explains that it all boils down to compute only 9 spherical harmonics coefficients to efficiently approximate an irradiance factor.
-
-At this point you can even skip the pre computation of the irradiance map, and use those coefficients directly in your shader for each shaded pixels. That’s fast enough to be real time, and use less memory than a cube map.
-
-But still…it’s slower than one texture fetch, so I chose to compute the Irradiance map and use it in the shader.
-
-With this technique I can compute a 128X128 irradiance cube map on the CPU in Java in about 200ms. Too slow to be done on each frame, but at design time that’s the blink of an eye.
-
-image::DiffuseIBL.png[DiffuseIBL,width="320",height="250",align="center"]
-Here is the diffuse effect of indirect lighting using an irradiance cube map
-
-=== IBL Specular
-
-Indirect diffuse is cool, but we want “shiny”!! Shiny implies specular lighting.
-
-It’s important to understand what we want as a specular reflection. We want it to be very neat when the roughness is low and very blurry when it’s high.
-
-image::Roughness.png[Roughness,width="320",height="250",align="center"]
-As roughness increase the reflection gets more blurry.
-
-To do this, we have to resolve an integral called the *radiance integral.*
-
-There is a method to do it quite fast that is called *importance sampling*. However it requires a lot of samples to get correct results, and therefore it’s pretty slow.
-
-As an example, for the previous shot, I was using this method, with 1024 samples. It was barely interactive, because it ran at 16 fps on a GTX 670.
-
-=== Thanks Epic games!
-
-Epic games came with a solution to this issue for Unreal Engine 4. Others did too, actually, but Epic games made it public in this paper, from Brian Karis. I can’t thank them enough for this.
-
-In this link:http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf[paper], they explain how they do it in UE4. They use a method they called the *Split Sum Approximation*. It doesn’t make the computation faster, but it transforms it so that it can be baked in two prefiltered textures.
-
-   * The prefiltered environment map
-
-We are going to pre process an env map on the CPU.
-
-As explained before, we need the reflection to be more blurry as the roughness increase. The main idea here is to store different levels of roughness in the env map mip maps. The first mip map level will match roughness = 0 and the last will match roughness = 1.
-
-From mip levels to mip levels we’re going to convolve (blur) the images depending on the roughness. The more the roughness increase the more samples we’re going to use, and the more spread out they will be.
-
-But that’s not all, we also want to “bake” the specular BRDF in the map, so for each pixel we are going to compute the Cook-Torrentz microfacet BRDF (remember last post).
-
-But, as we are preprocessing the map, we don’t have any information about the shaded surface normal and view direction. So we are going to assume they are all the same, and equal to the envVector we’ll use to fetch pixels from the map. Also we assume that the shading point is exactly at the center of the cube map.
-
-image::prefilteredEnvMapSampling.png[prefilteredEnvMapSampling,width="320",height="250",align="center"]
-
-This is an approximation again, and it has a cost in quality, but we’re all for approximation as long as it’s perform faster while still looking good, right?
-
-Here is what the result looks like
-
-image::PrefilteredEnvMap.png[PrefilteredEnvMap,width="320",height="250",align="center"]
-The prefiltered environment map, with the different mip levels. notice how the blur increases through them.
-
-So now we can evaluate the first sum of the split sum approximation with a single texture fetch. We are going to compute the Lod level (the mip level where to fetch the texel) according to the roughness.
-
-Note that the image needs to be set up so that textureCube interpolates linearly between mip maps so that if the roughness value is not right on the mip level, it will interpolate between the two closest mip levels.
-
-   * The BRDF integration Map
-
-Now we need the second sum of the split sum approximation.
-
-It’s an integration that has two inputs, the *roughness* that varies from 0 to 1, and the dot product between the normal and the light direction (*N.L*, read N dot L) that also varies from 0 to 1.
-
-The outputs are a *scale*, and a *bias*, also varying from 0 to 1.
-
-So basically we can bake all combinations into a 2D map. roughness and N.L will be the texture coordinate. the red channel of the map will be the scale, and the green channel will be the bias. (the blue channel is not used)
-
-Here is what it looks like :
-
-image::integrateBrdf.png[integrateBrdf,width="320",height="250",align="center"]
-
-The nice part is that this map is constant for white light. It does not depends on the environment. So you can bake it once and for all then use it as an asset in your shaders.
-
-Now we have to combine values fetched from these maps to get the specular lighting.
-
-Here is what indirect specular alone, looks like, with a roughness of 0.1.
-
-image::IndirectSpeculra.png[IndirectSpeculra,width="320",height="250",align="center"]
-
-*So in the end :*
-
-Our indirect lighting pseudo code looks like this :
-[source]
-----
-//diffuse
-indirectDiffuse = textureCube(IrradianceMap, refVec)  * diffuseColor
-
-//specular
-lod = getMipLevelFromRoughness(roughness)
-prefilteredColor =  textureCube(PrefilteredEnvMap, refVec, lod)
-envBRDF = texture2D(BRDFIntegrationMap,vec2(roughness, ndotv)).xy
-indirectSpecular = prefilteredColor * (specularColor * envBRDF.x + envBRDF.y)
-
-indirectLighting = indirectDiffuse + indirectSpecular
-----
-That concludes the post. Quite a lot of information to process. Now you should have an idea of the whole thing. Next time, we are going to go under the hood, and YOU GONNA HAZ CODE!!
-
-== Lexical :
-
-*Global Illumination (GI):* A concept that represent all the lighting of a scene that is not coming from a direct light source.
-
-*Image Based Lighting (IBL):* A technique that uses an image as a light source
-
-*Irradiance map :* Precomputed environment map that contains diffuse lighting data of the environment.
-
-*Spherical Harmonics (SH):* link:https://dickyjim.wordpress.com/2013/09/04/spherical-harmonics-for-beginners/[Read this]
-
-*Importance Sampling :* A math technique to approximate the result of an integral.
-
-*Split Sum Approximation :* A way,used in Unreal Engine 4, to transform the specular radiance integral into 2 sums that can be easily baked into prefiltered textures.

+ 0 - 802
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/math/math.adoc

@@ -1,802 +0,0 @@
-= Introduction to Mathematical Functionality
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../
-:imagesdir: ..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-It's a fact of life, math is hard. Unfortunately, 3D graphics require a fair bit of knowledge about the subject. Fortunately, jME is able to hide the majority of the details away from the user. Vectors are the fundamental type in the 3D environment, and it is used extensively. Matrices are also a basic necessity of 3D for representing linear systems. <<jme3/quaternion#,Quaternions>> are perhaps the most powerful and complicated of the basic types and are used for rotation in jME.
-
-I'll discuss how these are used in the system for the core functionality. Including Transforming, Visibility Determination, Collision Detection, and the Coordinate System. Note, that these are low level details. Further chapters will discuss how to use these various systems from a high level perspective.
-
-To get a visual introduction to math in jME3 for the absolute beginner, check out our <<jme3/math_for_dummies#,Math for Dummies>> introduction class.
-
-
-== Coordinate System
-
-
-=== Definition
-
-A _coordinate system_ consists of an origin (single point in space) and three coordinate axes that are each unit length and mutually perpendicular. The axes can be written as the column of a Matrix, R = [U1|U2|U3]. In fact, this is exactly how CameraNode works. The coordinate system defined by Camera is stored in a Matrix.
-
-jME uses a Right-Handed coordinate system (as OpenGL does).
-
-The definition of a coordinate system is defined in jME by the properties sent to Camera. There are no error checks to insure that: 1) the coordinate system is right-handed and 2) The axes are mutually perpendicular. Therefore, if the user sets the axes incorrectly, they are going to experience very odd rendering artifacts (random culling, etc).
-
-
-image::jme3/intermediate/coordinate-system.png[coordinate-system.png,width="235",height="210",align="center"]
-
-
-
-=== Homogenous coordinates
-
-Homogenous coordinates have an additional _W_ value tacked on to the end. The XYZ values are to be divided by W to give the true coordinates.
-
-This has several advantages, one technical, some relevant to application programmers:
-
-Technically, it simplifies some formulae used inside the vector math. For example, some operations need to apply the same factor to the XYZ coordinates. Chain multiple operations of that kind (and vector math tends to do that), and you can save a lot of multiplications by simply keeping the scaling factor around and doing the multiplication to XYZ at the end of the pipeline, in the 3D card (which does accept homogenous coordinates).
-It also simplifies some formulae, in particular anything that is related to rotations.
-
-For application programmers, this means you can express infinitely long vectors that still have a direction - these tend to be used in lighting. Just use a W value of 0.0.
-
-
-== Transformations
-
-Transformations define an operation that converts points from one coordinate system to another. This includes translation, rotation and scaling. In jME, local transforms are used to represent the positioning of objects relative to a parent coordinate system. While, world transforms are used to represent the positioning of objects in a global coordinate system.
-
-
-== Visibility Determination
-
-Visibility Determination concerns itself with minimizing the amount of data that is sent to the graphics card for rendering. Specifically, we do not want to send data that will not be seen. Data not sent to the graphics card is said to be culled. The primary focus of this section is Frustum Culling based on the Camera's view frustum. In essence, this frustum creates six standard view planes. The BoundingVolume of an object is tested against the frustum planes to determine if it is contained in the frustum. If at any point the object's bounding is outside of the plane, it is tossed out and no longer processed for rendering. This also includes any children that it managed, allowing fast culling of large sections of the scene.
-
-
-=== Fundamental Types
-
-
-== ColorRGBA
-
-
-=== Definition
-
-ColorRGBA defines a color value in the jME library. The color value is made of three components, red, green and blue. A fourth component defines the alpha value (transparent) of the color. Every value is set between [0, 1]. Anything less than 0 will be clamped to 0 and anything greater than 1 will be clamped to 1.
-
-*Note:* If you would like to “convert an ordinary RGB value (0-255) to the format used here (0-1), simply multiply it with: 1/255.
-
-
-=== jME Class
-
-ColorRGBA defines a few static color values for ease of use. That is, rather than:
-
-[source,java]
-----
-
-ColorRGBA red = new ColorRGBA(1,0,0,1);
-object.setSomeColor(red);
-
-----
-
-you can simply say:
-
-[source,java]
-----
-
-object.setSomeColor(ColorRGBA.red)
-
-----
-
-ColorRGBA will also handle interpolation between two colors. Given a second color and a value between 0 and 1, a the owning ColorRGBA object will have its color values altered to this new interpolated color.
-
-
-== Matrix
-
-See link:http://javadoc.jmonkeyengine.org/com/jme3/math/Matrix3f.html[Matrix3f Javadoc] and link:http://javadoc.jmonkeyengine.org/com/jme3/math/Matrix4f.html[Matrix4f Javadoc]
-
-
-=== Definition
-
-A Matrix is typically used as a _linear transformation_ to map vectors to vectors. That is: Y = MX where X is a Vector and M is a Matrix applying any or all transformations (scale, <<jme3/rotate#,rotate>>, translate).
-
-There are a few special matrices:
-
-_zero matrix_ is the Matrix with all zero entries.
-[cols="3", options="header"]
-|===
-
-a|0
-a|0
-a|0
-
-a|0
-a|0
-a|0
-
-a|0
-a|0
-a|0
-
-|===
-
-The _Identity Matrix_ is the matrix with 1 on the diagonal entries and 0 for all other entries.
-[cols="3", options="header"]
-|===
-
-a|1
-a|0
-a|0
-
-a|0
-a|1
-a|0
-
-a|0
-a|0
-a|1
-
-|===
-
-A Matrix is _invertible_ if there is a matrix _M^-1^_ where _MM^-1^ = M^-1^M = I_.
-
-The _transpose_ of a matrix _M = [m~ij~]_ is _M^T^ = [m~ji~]_. This causes the rows of _M_ to become the columns of _M^T^_.
-[cols="7", options="header"]
-|===
-
-a|1
-a|1
-a|1
-<a|
-a|1
-a|2
-a|3
-
-a|2
-a|2
-a|2
-a| ⇒
-a|1
-a|2
-a|3
-
-a|3
-a|3
-a|3
-<a|
-a|1
-a|2
-a|3
-
-|===
-
-A Matrix is symmetric if _M_ = _M^T^_.
-[cols="3", options="header"]
-|===
-
-a|X
-a|A
-a|B
-
-a|A
-a|X
-a|C
-
-a|B
-a|C
-a|X
-
-|===
-
-Where X, A, B, and C equal numbers
-
-jME includes two types of Matrix classes: Matrix3f and Matrix4f. Matrix3f is a 3x3 matrix and is the most commonly used (able to handle scaling and rotating), while Matrix4f is a 4x4 matrix that can also handle translation.
-
-
-=== Transformations
-
-Multiplying a vector with a Matrix allows the vector to be transformed. Either rotating, scaling or translating that vector.
-
-
-==== Scaling
-
-If a _diagonal Matrix_, defined by D = [d~ij~] and d~ij~ = 0 for i != j, has all positive entries it is a _scaling matrix_. If d~i~ is greater than 1 then the resulting vector will grow, while if d~i~ is less than 1 it will shrink.
-
-
-==== Rotation
-
-A _rotation matrix_ requires that the transpose and inverse are the same matrix (R^-1^ = R^T^). The _rotation matrix_ R can then be calculated as: R = I + (sin(angle)) S + (1 - cos(angle)S^2^ where S is:
-[cols="3", options="header"]
-|===
-
-a|0
-a|u~2~
-a|-u~1~
-
-a|-u~2~
-a|0
-a|u~0~
-
-a|u~1~
-a|-u~0~
-a|0
-
-|===
-
-
-==== Translation
-
-Translation requires a 4x4 matrix, where the vector (x,y,z) is mapped to (x,y,z,1) for multiplication. The _Translation Matrix_ is then defined as:
-[cols="2", options="header"]
-|===
-
-a|M
-a|T
-
-a|S^T^
-a|1
-
-|===
-
-where M is the 3x3 matrix (containing any rotation/scale information), T is the translation vector and S^T^ is the transpose Vector of T. 1 is just a constant.
-
-
-=== jME Class
-
-Both Matrix3f and Matrix4f store their values as floats and are publicly available as (m00, m01, m02, …, mNN) where N is either 2 or 3.
-
-Most methods are straight forward, and I will leave documentation to the Javadoc.
-
-
-== Vector
-
-See link:http://javadoc.jmonkeyengine.org/com/jme3/math/Vector3f.html[Vector3f Javadoc] and link:http://javadoc.jmonkeyengine.org/com/jme3/math/Vector2f.html[Vector2f Javadoc]
-
-
-=== Definition
-
-Vectors are used to represent a multitude of things in jME, points in space, vertices in a triangle mesh, normals, etc. These classes (Vector3f in particular) are probably the most used class in jME.
-
-A Vector is defined by an n-tuple of real numbers. *V* = &lt;V~1~, V~2~,…, V~n~&gt;.
-
-We have two Vectors (2f and 3f) meaning we have tuples of 2 float values or 3 float values.
-
-
-=== Operations
-
-
-==== Multiplication by Scalar
-
-A Vector can be multiplied by a scalar value to produce a second Vector with the same proportions as the first. a**V** = **V**a = &lt;aV~1~, aV~2~,…,aV~n~&gt;
-
-
-==== Addition and Subtraction
-
-Adding or subtracting two Vectors occurs component-wise. That is the first component is added (subtracted) with the first component of the second Vector and so on.
-
-*P* + *Q* = &lt;P~1~+Q~1~, P~2~+Q~2~, …, P~n~+Q~n~&gt;
-
-
-==== Magnitude
-
-The _magnitude_ defines the length of a Vector. A Vector of magnitude 1 is _unit length_.
-
-For example, if *V* = (x, y, z), the magnitude is the square root of (x^2^ + y^2^ + z^2^).
-
-A Vector can be _normalized_ or made _unit length_ by multiplying the Vector by (1/magnitude).
-
-
-==== Dot Products
-
-The dot product of two vectors is defined as:
-*P* dot *Q* = P~x~Q~x~ + P~y~Q~y~ + P~z~Q~z~
-
-Using the dot product allows us to determine how closely two Vectors are pointing to the same point. If the dot product is negative they are facing in relatively opposite directions, while postive tells us they are pointing in the relative same direction.
-
-If the dot product is 0 then the two Vectors are _orthogonal_ or 90 degrees off.
-
-
-==== Cross Product
-
-The Cross Product of two Vectors returns a third Vector that is prependicular to the two Vectors. This is very useful for calculating surface normals.
-
-*P* X *Q* = &lt;P~y~Q~z~ - P~z~Q~y~, P~z~Q~x~ - P~x~Q~z~, P~x~Q~y~ - P~y~Q~x~&gt;
-
-
-==== jME Class
-
-Vector3f and Vector2f store their values (x, y, z) and (x, y) respectively as floats. Most methods are straight forward, and I will leave documentation to the Javadoc.
-
-
-== Quaternion
-
-See link:http://javadoc.jmonkeyengine.org/com/jme3/math/Quaternion.html[Quaternion Javadoc]
-
-
-=== Definition
-
-Quaternions define a subset of a hypercomplex number system. Quaternions are defined by (i^2^ = j^2^ = k^2^ = ijk = -1). jME makes use of Quaternions because they allow for compact representations of rotations, or correspondingly, orientations, in 3D space. With only four float values, we can represent an object's orientation, where a rotation matrix would require nine. They also require fewer arithmetic operations for concatenation.
-
-Additional benefits of the Quaternion is reducing the chance of link:http://en.wikipedia.org/wiki/Gimbal_lock[Gimbal Lock] and allowing for easily interpolation between two rotations (spherical linear interpolation or slerp).
-
-While Quaternions are quite difficult to fully understand, there are an exceeding number of convenience methods to allow you to use them without having to understand the math behind it. Basically, these methods involve nothing more than setting the Quaternion's x,y,z,w values using other means of representing rotations. The Quaternion is then contained in the <<jme3/advanced/spatial#,Spatial>> as its local rotation component.
-
-Quaternion *q* has the form
-
-*q* = &lt;_w,x,y,z_&gt; = _w + xi + yj + zk_
-
-or alternatively, it can be written as:
-
-*q* = *s* + *v*, where *s* represents the scalar part corresponding to the w-component of *q*, and *v* represents the vector part of the (x, y, z) components of *q*.
-
-Multiplication of Quaternions uses the distributive law and adheres to the following rules with multiplying the imaginary components (i, j, k):
-
-`i^2^ = j^2^ = k^2^ = -1`+
-`ij = -ji = k`+
-`jk = -kj = i`+
-`ki = -ik = j`
-
-However, Quaternion multiplication is _not_ commutative, so we have to pay attention to order.
-
-*q~1~q~2~* = s~1~s~2~ - *v~1~* dot *v~2~* + s~1~*v~2~* + s~2~*v~1~* + *v~1~* X *v~2~*
-
-Quaternions also have conjugates where the conjugate of *q* is (s - *v*)
-
-These basic operations allow us to convert various rotation representations to Quaternions.
-
-
-=== Angle Axis
-
-You might wish to represent your rotations as Angle Axis pairs. That is, you define a axis of rotation and the angle with which to <<jme3/rotate#,rotate>> about this axis. <<jme3/quaternion#,Quaternion>> defines a method `fromAngleAxis` (and `fromAngleNormalAxis`) to create a Quaternion from this pair. This is acutally used quite a bit in jME demos to continually rotate objects. You can also obtain a Angle Axis rotation from an existing Quaternion using `toAngleAxis`.
-
-
-==== Example - Rotate a Spatial Using fromAngleAxis
-
-[source,java]
-----
-
-//rotate about the Y-Axis by approximately 1 pi
-Vector3f axis = Vector3f.UNIT_Y;
-// UNIT_Y equals (0,1,0) and does not require to create a new object
-float angle = 3.14f;
-s.getLocalRotation().fromAngleAxis(angle, axis);
-
-----
-
-
-=== Three Angles
-
-You can also represent a rotation by defining three angles. The angles represent the rotation about the individual axes. Passing in a three-element array of floats defines the angles where the first element is X, second Y and third is Z. The method provided by Quaternion is `fromAngles` and can also fill an array using `toAngles`
-
-
-==== Example - Rotate a Spatial Using fromAngles
-
-[source,java]
-----
-
-//rotate 1 radian on the x, 3 on the y and 0 on z
-float[] angles = {1, 3, 0};
-s.getLocalRotation().fromAngles(angles);
-
-----
-
-
-=== Three Axes
-
-If you have three axes that define your rotation, where the axes define the left axis, up axis and directional axis respectively) you can make use of `fromAxes` to generate the Quaternion. It should be noted that this will generate a new <<jme3/matrix#,Matrix>> object that is then garbage collected, thus, this method should not be used if it will be called many times. Again, `toAxes` will populate a Vector3f array.
-
-
-==== Example - Rotate a Spatial Using fromAxes
-
-[source,java]
-----
-
-//rotate a spatial to face up ~45 degrees
-Vector3f[] axes = new Vector3f[3];
-axes[0] = new Vector3f(-1, 0, 0); //left
-axes[1] = new Vector3f(0, 0.5f, 0.5f); //up
-axes[2] = new Vector3f(0, 0.5f, 0.5f); //dir
-
-s.getLocalRotation().fromAxes(axes);
-
-----
-
-
-=== Rotation Matrix
-
-Commonly you might find yourself with a <<jme3/matrix#,Matrix>> defining a rotation. In fact, it's very common to contain a rotation in a <<jme3/matrix#,Matrix>> create a Quaternion, rotate the Quaternion, and then get the <<jme3/matrix#,Matrix>> back. Quaternion contains a `fromRotationMatrix` method that will create the appropriate Quaternion based on the give <<jme3/matrix#,Matrix>>. The `toRotationMatrix` will populate a given <<jme3/matrix#,Matrix>>.
-
-
-==== Example - Rotate a Spatial Using a Rotation Matrix
-
-[source,java]
-----
-
-
-Matrix3f mat = new Matrix3f();
-mat.setColumn(0, new Vector3f(1,0,0));
-mat.setColumn(1, new Vector3f(0,-1,0));
-mat.setColumn(2, new Vector3f(0,0,1));
-
-s.getLocalRotation().fromRotationMatrix(mat);
-
-----
-
-As you can see there are many ways to build a Quaternion. This allows you to work with rotations in a way that is conceptually easier to picture, but still build Quaternions for internal representation.
-
-
-=== Slerp
-
-One of the biggest advantages to using Quaternions is allowing interpolation between two rotations. That is, if you have an initial Quaternion representing the original orientation of an object, and you have a final Quaternion representing the orientation you want the object to face, you can do this very smoothly with slerp. Simply supply the time, where time is [0, 1] and 0 is the initial rotation and 1 is the final rotation.
-
-
-==== Example - Use Slerp to Rotate Between two Quaternions
-
-[source,java]
-----
-
-/*
-You can interpolate rotations between two quaternions using spherical linear
-interpolation (slerp).
-*/
-Quaternion Xroll45 = new Quaternion();
-Xroll45.fromAngleAxis(45 * FastMath.DEG_TO_RAD, Vector3f.UNIT_X);
-//
-Quaternion Yroll45 = new Quaternion();
-Yroll45.fromAngleAxis(45 * FastMath.DEG_TO_RAD, Vector3f.UNIT_Y);
-
-//the rotation half - way between these two
-
-Quaternion halfBetweenXroll45Yroll45 = new Quaternion();
-halfBetweenXroll45Yroll45.slerp(Xroll45, Yroll45, 0.5f);
-geom2.setLocalRotation(halfBetweenXroll45Yroll45);
-
-----
-
-
-=== Multiplication
-
-You can concatenate (add) rotations: This means you turn the object first around one axis, then around the other, in one step.
-
-[source,java]
-----
-Quaternion myRotation = pitch90.mult(roll45); /* pitch and roll */
-----
-
-To rotate a Vector3f around its origin by the Quaternion amount, use the multLocal method of the Quaternion:
-
-[source,java]
-----
-Quaternion myRotation = pitch90;
-Vector3f myVector = new Vector3f(0,0,-1);
-myRotation.multLocal(myVector);
-
-----
-
-
-==== Utility Classes
-
-Along with the base Math classes, jME provides a number of Math classes to make development easier (and, hopefully, faster). Most of these classes find uses throughout the jME system internally. They can also prove beneficial to users as well.
-
-
-== Fast Math
-
-See link:http://javadoc.jmonkeyengine.org/com/jme3/math/FastMath.html[FastMath Javadoc]
-
-
-=== Definition
-
-FastMath provides a number of convience methods, and where possible faster versions (although this can be at the sake of accuracy).
-
-
-=== Usage
-
-FastMath provides a number of constants that can help with general math equations. One important attribute is `USE_FAST_TRIG` if you set this to true, a look-up table will be used for trig functions rather than Java's standard Math library. This provides significant speed increases, but might suffer from accuracy so care should be taken.
-
-There are five major categories of functions that FastMath provides.
-
-
-==== Trig Functions
-
-* cos and acos - provide link:http://en.wikipedia.org/wiki/cosine[cosine] and link:https://en.wikipedia.org/wiki/Inverse_trigonometric_functions[arc cosine] values (make use of the look-up table if `USE_FAST_TRIG` is true)
-* sin and asin - provide link:http://en.wikipedia.org/wiki/sine[sine] and link:https://en.wikipedia.org/wiki/Inverse_trigonometric_functions[arc sine] values (make use of the look-up table if `USE_FAST_TRIG` is true)
-* tan and atan - provide link:http://en.wikipedia.org/wiki/tangent[tangent] and link:https://en.wikipedia.org/wiki/Inverse_trigonometric_functions[arc tangent] values
-
-
-==== Numerical Methods
-
-* ceil - provides the ceiling (smallest value that is greater than or equal to a given value and an integer)of a value.
-* floor - provides the floor (largest value that is less than or equal to a given value and an integer) of a value.
-* exp - provides the link:http://en.wikipedia.org/wiki/Euler_number[euler number] (e) raised to the provided value.
-* sqr - provides the square of a value (i.e. value * value).
-* pow - provides the first given number raised to the second.
-* isPowerOfTwo - provides a boolean if a value is a power of two or not (e.g. 32, 64, 4).
-* abs - provides the link:http://en.wikipedia.org/wiki/Absolute_value[absolute value] of a given number.
-* sign - provides the sign of a value (1 if positive, -1 if negative, 0 if 0).
-* log - provides the link:http://en.wikipedia.org/wiki/Natural_logarithm[natural logarithm] of a value.
-* sqrt - provides the link:http://en.wikipedia.org/wiki/Square_root[square root] of a value.
-* invSqrt - provides the inverse link:http://en.wikipedia.org/wiki/Square_root[square root] of a value (1 / sqrt(value).
-
-
-==== Linear Algebra
-
-* LERP - calculate the link:http://en.wikipedia.org/wiki/Linear_interpolation[linear interpolation] of two points given a time between 0 and 1.
-* determinant - calculates the link:http://en.wikipedia.org/wiki/determinant[determinant] of a 4x4 matrix.
-
-
-==== Geometric Functions
-
-* counterClockwise - given three points (defining a triangle), the winding is determined. 1 if counter-clockwise, -1 if clockwise and 0 if the points define a line.
-* pointInsideTriangle - calculates if a point is inside a triangle.
-* sphericalToCartesian - converts a point from link:https://en.wikipedia.org/wiki/Spherical_coordinate_system[spherical coordinates] to link:https://en.wikipedia.org/wiki/Cartesian[cartesian coordinates].
-* cartesianToSpherical - converts a point from link:https://en.wikipedia.org/wiki/Cartesian[cartesian coordinates] to link:https://en.wikipedia.org/wiki/Spherical_coordinate_system[spherical coordinates].
-
-
-==== Misc.
-
-* newRandomFloat - obtains a random float.
-
-
-== Line
-
-See link:http://javadoc.jmonkeyengine.org/com/jme3/math/Line.html[Line Javadoc]
-
-
-=== Definition
-
-A line is a straight one-dimensional figure having no thickness and extending infinitely in both directions. A line is defined by two points *A* and *B* with the line passing through both.
-
-
-=== Usage
-
-jME defines a Line class that is defined by an origin and direction. In reality, this Line class is typically used as a _line segment_. Where the line is finite and contained between these two points.
-
-`random` provides a means of generate a random point that falls on the line between the origin and direction points.
-
-
-=== Example 1 - Find a Random Point on a Line
-
-[source,java]
-----
-
-Line l = new Line(new Vector3f(0,1,0), new Vector3f(3,2,1));
-Vector3f randomPoint = l.random();
-
-----
-
-
-== Plane
-
-See link:http://javadoc.jmonkeyengine.org/com/jme3/math/Plane.html[Plane Javadoc]
-
-
-=== Definition
-
-A plane is defined by the equation *N* . (*X* - *X~0~*) = 0 where *N* = (a, b, c) and passes through the point *X~0~* = (x~0~, y~0~, z~0~). *X* defines another point on this plane (x, y, z).
-
-*N* . (*X* - *X~0~*) = 0 can be described as (*N* . *X*) + (*N* . -*X~0~*) = 0
-
-or
-
-(ax + by + cz) + (-ax~0~-by~0~-cz~0~) = 0
-
-where (-ax~0~-by~0~-cz~0~) = d
-
-Where d is the negative value of a point in the plane times the unit vector describing the orientation of the plane.
-
-This gives us the general equation: (ax + by + cz + d = 0)
-
-
-=== Usage in jME
-
-jME defines the Plane as ax + by + cz = -d. Therefore, during creation of the plane, the normal of the plane (a,b,c) and the constant d is supplied.
-
-The most common usage of Plane is <<jme3/advanced/camera#,Camera>> frustum planes. Therefore, the primary purpose of Plane is to determine if a point is on the positive side, negative side, or intersecting a plane.
-
-Plane defines the constants:
-
-* `NEGATIVE_SIDE` - represents a point on the opposite side to which the normal points.
-* `NO_SIDE` - represents a point that lays on the plane itself.
-* `POSITIVE_SIDE` - represents a point on the side to which the normal points.
-
-These values are returned on a call to `whichSide`.
-
-
-=== Example 1 - Determining if a Point is On the Positive Side of a Plane
-
-[source,java]
-----
-
-Vector3f normal = new Vector3f(0,1,0);
-float constant = new Vector3f(1,1,1).dot(normal);
-Plane testPlane = new Plane(normal, constant);
-
-int side = testPlane.whichSide(new Vector3f(2,1,0));
-
-if(side == Plane.NO_SIDE) {
-   System.out.println("This point lies on the plane");
-}
-
-----
-
-
-=== Example 2 - For the Layperson
-
-Using the standard constructor Plane(Vector3f normal, float constant), here is what you need to do to create a plane, and then use it to check which side of the plane a point is on.
-
-[source,java]
-----
-
-package test;
-
-import java.util.logging.Logger;
-
-import com.jme.math.*;
-
-/**
- *@author Nick Wiggill
- */
-
-public class TestPlanes
-{
-  public static final Logger logger = Logger.getLogger(LevelGraphBuilder.class.getName());
-
-  public static void main(String[] args) throws Exception
-  {
-    //***Outline.
-    //This example shows how to construct a plane representation using
-    //com.jme.math.Plane.
-    //We will create a very simple, easily-imagined 3D plane. It will
-    //be perpendicular to the x axis (it's facing). It's "centre" (if
-    //such a thing exists in an infinite plane) will be positioned 1
-    //unit along the positive x axis.
-
-    //***Step 1.
-    //The vector that represents the normal to the plane, in 3D space.
-    //Imagine a vector coming out of the origin in this direction.
-    //There is no displacement yet (see Step 2, below).
-    Vector3f normal = new Vector3f(5f,0,0);
-
-    //***Step 2.
-    //This is our displacement vector. The plane remains facing in the
-    //direction we've specified using the normal above, but now we are
-    //are actually giving it a position other than the origin.
-    //We will use this displacement to define the variable "constant"
-    //needed to construct the plane. (see step 3)
-    Vector3f displacement = Vector3f.UNIT_X;
-    //or
-    //Vector3f displacement = new Vector3f(1f, 0, 0);
-
-    //***Step 3.
-    //Here we generate the constant needed to define any plane. This
-    //is semi-arcane, don't let it worry you. All you need to
-    //do is use this same formula every time.
-    float constant = displacement.dot(normal);
-
-    //***Step 4.
-    //Finally, construct the plane using the data you have assembled.
-    Plane plane = new Plane(normal, constant);
-
-    //***Some tests.
-    logger.info("Plane info: "+plane.toString()); //trace our plane's information
-
-    Vector3f p1  = new Vector3f(1.1f,0,0); //beyond the plane (further from origin than plane)
-    Vector3f p2  = new Vector3f(0.9f,0,0); //before the plane (closer to origin than plane)
-    Vector3f p3  = new Vector3f(1f,0,0); //on the plane
-
-    logger.info("p1 position relative to plane is "+plane.whichSide(p1)); //outputs NEGATIVE
-    logger.info("p2 position relative to plane is "+plane.whichSide(p2)); //outputs POSITIVE
-    logger.info("p3 position relative to plane is "+plane.whichSide(p3)); //outputs NONE
-  }
-}
-
-----
-
-
-== Ray
-
-See link:http://javadoc.jmonkeyengine.org/com/jme3/math/Ray.html[Ray Javadoc]
-
-
-=== Definition
-
-Ray defines a line that starts at a point *A* and continues in a direction through *B* into infinity.
-
-This Ray is used extensively in jME for <<jme3/beginner/hello_picking#,Picking>>. A Ray is cast from a point in screen space into the scene. Intersections are found and returned. To create a ray supply the object with two points, where the first point is the origin.
-
-
-=== Example 1 - Create a Ray That Represents Where the Camera is Looking
-
-[source,java]
-----
-
-Ray ray = new Ray(cam.getLocation(), cam.getDirection());
-
-----
-
-
-== Rectangle
-
-See link:http://javadoc.jmonkeyengine.org/com/jme3/math/Rectangle.html[Rectangle Javadoc]
-
-
-=== Definition
-
-Rectangle defines a finite plane within three dimensional space that is specified via three points (A, B, C). These three points define a triangle with the forth point defining the rectangle ( (B + C) - A ).
-
-
-=== jME Usage
-
-Rectangle is a straight forward data class that simply maintains values that defines a Rectangle in 3D space. One interesting use is the `random` method that will create a random point on the Rectangle. The <<jme3/advanced/effects_overview#,Particle System>> makes use of this to define an area that generates <<jme3/advanced/particle_emitters#,Particles>>.
-
-
-=== Example 1 : Define a Rectangle and Get a Point From It
-
-[source,java]
-----
-
-Vector3f v1 = new Vector3f(1,0,0);
-Vector3f v2 = new Vector3f(1,1,0);
-Vector3f v3 = new Vector3f(0,1,0);
-Rectangle r = new Rectangle(v1, v2, v3);
-Vector3f point = r.random();
-
-----
-
-
-== Triangle
-
-See link:http://javadoc.jmonkeyengine.org/com/jme3/math/Triangle.html[Triangle Javadoc]
-
-
-=== Definition
-
-A triangle is a 3-sided polygon. Every triangle has three sides and three angles, some of which may be the same. If the triangle is a right triangle (one angle being 90 degrees), the side opposite the 90 degree angle is the hypotenuse, while the other two sides are the legs. All triangles are link:http://en.wikipedia.org/wiki/Convex_polygon[convex] and link:http://mathworld.wolfram.com/BicentricPolygon.html[bicentric].
-
-
-=== Usage
-
-jME's Triangle class is a simple data class. It contains three <<jme3/terminology.html#vectors#,Vector3f>> objects that represent the three points of the triangle. These can be retrieved via the `get` method. The `get` method, obtains the point based on the index provided. Similarly, the values can be set via the `set` method.
-
-
-=== Example 1 - Creating a Triangle
-
-[source,java]
-----
-
-//the three points that make up the triangle
-Vector3f p1 = new Vector3f(0,1,0);
-Vector3f p2 = new Vector3f(1,1,0);
-Vector3f p3 = new Vector3f(0,1,1);
-Triangle t = new Triangle(p1, p2, p3);
-
-----
-
-
-==== Tips and Tricks
-
-
-== How do I get height/width of a spatial?
-
-Cast the spatial to com.jme3.bounding.BoundingBox to be able to use getExtent().
-
-[source,java]
-----
-Vector3f extent = ((BoundingBox) spatial.getWorldBound()).getExtent(new Vector3f());
-float x = ( (BoundingBox)spatial.getWorldBound()).getXExtent();
-float y = ( (BoundingBox)spatial.getWorldBound()).getYExtent();
-float z = ( (BoundingBox)spatial.getWorldBound()).getZExtent();
-
-----
-
-
-== How do I position the center of a Geomtry?
-
-[source,java]
-----
-geo.center().move(pos);
-----
-
-
-=== See Also
-
-*  <<jme3/rotate#,Rotate>>
-*  <<jme3/quaternion#,Quaternion>>

+ 0 - 25
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/math/math_for_dummies.adoc

@@ -1,25 +0,0 @@
-= math_for_dummies
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../
-:imagesdir: ..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== jMonkeyEngine3 Math for Dummies
-
-+++
-<iframe src=https://jmonkeyengine.github.io/wiki/tutorials/math width="100%" height="850px" alt=""></iframe>
-+++
-
-//iframe::https://jmonkeyengine.github.io/wiki/tutorials/math[width="100%", height="850px", alt="", scroll="true",border="true",align="false"]
-
-[TIP]
-====
-
-*  You can open this presentation in link:https://jmonkeyengine.github.io/wiki/tutorials/math[Fullscreen Mode].
-*  When using link:http://www.apple.com/safari/[Safari] as a browser the presentation is animated.
-
-====

+ 0 - 24
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/math/math_video_tutorials.adoc

@@ -1,24 +0,0 @@
-= math_video_tutorials
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../
-:imagesdir: ..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-*jME3 Math Video Tutorials*
-
-*  link:http://www.youtube.com/watch?v=q7NZU1nlHJs[Video: Trigonometry]
-*  link:http://www.youtube.com/watch?v=u7jpTUoNC0k[Video: Vector Math]
-*  link:http://www.youtube.com/watch?v=EEeHeRgDYQY[Video: Dot Product]
-*  link:http://www.youtube.com/watch?v=GgGbZP1g-Ec[Video: Spatial.lookAt()]
-*  link:http://www.youtube.com/watch?v=0XYzLskcCNE[Video: Camera]
-*  link:http://www.youtube.com/watch?v=mY24CpUbQHc[Video: Rotations (Part 1)]
-*  link:http://www.youtube.com/watch?v=tYZdqmsegFY[Video: Rotations (Part 2)]
-*  link:http://www.youtube.com/watch?v=-Y5SbbiRGPk[Video: Cross Product]
-*  link:http://www.youtube.com/watch?v=YC8vV6IBZpg[Video: Rays]
-*  link:http://www.youtube.com/watch?v=MPYBHa2xT3o[Video: Reflections (Part 1)]
-*  link:http://www.youtube.com/watch?v=3gLf7IClTFM[Video: Reflections (Part 2)]
-*  link:http://www.youtube.com/watch?v=myKReCR0Dtc[Video: Reflections (Part 3)]
-*  link:http://www.youtube.com/watch?v=749Y3Lla7oI[Video: Line of Sight]

+ 0 - 165
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/math/matrix.adoc

@@ -1,165 +0,0 @@
-= matrix
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../
-:imagesdir: ..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== Matrix
-
-See link:http://javadoc.jmonkeyengine.org/com/jme3/math/Matrix3f.html[Javadoc of Matrix3f] and link:http://javadoc.jmonkeyengine.org/com/jme3/math/Matrix4f.html[Javadoc of Matrix4f]
-
-
-=== Definition
-
-A Matrix is typically used as a _linear transformation_ to map vectors to vectors. That is: Y = MX where X is a Vector and M is a Matrix applying any or all transformations (scale, rotate, translate).
-
-There are a few special matrices:
-
-_zero matrix_ is the Matrix with all zero entries.
-[cols="3", options="header"]
-|===
-
-a|0
-a|0
-a|0
-
-a|0
-a|0
-a|0
-
-a|0
-a|0
-a|0
-
-|===
-
-The _Identity Matrix_ is the matrix with 1 on the diagonal entries and 0 for all other entries.
-[cols="3", options="header"]
-|===
-
-a|1
-a|0
-a|0
-
-a|0
-a|1
-a|0
-
-a|0
-a|0
-a|1
-
-|===
-
-A Matrix is _invertible_ if there is a matrix _M^-1^_ where _MM^-1^ = M^-1^ = I_.
-
-The _transpose_ of a matrix _M = [m~ij~]_ is _M^T^ = [m~ji~]_. This causes the rows of _M_ to become the columns of _M^T^_.
-[cols="7", options="header"]
-|===
-
-a|1
-a|1
-a|1
-<a|
-a|1
-a|2
-a|3
-
-a|2
-a|2
-a|2
-a| ⇒
-a|1
-a|2
-a|3
-
-a|3
-a|3
-a|3
-<a|
-a|1
-a|2
-a|3
-
-|===
-
-A Matrix is symmetric if _M_ = _M^T^_.
-[cols="3", options="header"]
-|===
-
-a|X
-a|A
-a|B
-
-a|A
-a|X
-a|C
-
-a|B
-a|C
-a|X
-
-|===
-
-Where X, A, B, and C equal numbers
-
-jME includes two types of Matrix classes: Matrix3f and Matrix4f. Matrix3f is a 3x3 matrix and is the most commonly used (able to handle scaling and rotating), while Matrix4f is a 4x4 matrix that can also handle translation.
-
-
-=== Transformations
-
-Multiplying a <<jme3/vector#,Vector>> with a Matrix allows the <<jme3/vector#,Vector>> to be transformed. Either rotating, scaling or translating that <<jme3/vector#,Vector>>.
-
-
-==== Scaling
-
-If a _diagonal Matrix_, defined by D = [d~ij~] and d~ij~ = 0 for i != j, has all positive entries it is a _scaling matrix_. If d~i~ is greater than 1 then the resulting <<jme3/vector#,Vector>> will grow, while if d~i~ is less than 1 it will shrink.
-
-
-==== Rotation
-
-A _rotation matrix_ requires that the transpose and inverse are the same matrix (R^-1^ = R^T^). The _rotation matrix_ R can then be calculated as: R = I + (sin(angle)) S + (1 - cos(angle)S^2^ where S is:
-[cols="3", options="header"]
-|===
-
-a|0
-a|u~2~
-a|-u~1~
-
-a|-u~2~
-a|0
-a|u~0~
-
-a|u~1~
-a|-u~0~
-a|0
-
-|===
-
-
-==== Translation
-
-Translation requires a 4x4 matrix, where the <<jme3/vector#,Vector>> (x,y,z) is mapped to (x,y,z,1) for multiplication. The _Translation Matrix_ is then defined as:
-[cols="2", options="header"]
-|===
-
-a|M
-a|T
-
-a|S^T^
-a|1
-
-|===
-
-where M is the 3x3 matrix (containing any rotation/scale information), T is the translation <<jme3/vector#,Vector>> and S^T^ is the transpose Vector of T. 1 is just a constant.
-
-
-=== jME Class
-
-Both Matrix3f and Matrix4f store their values as floats and are publicly available as (m00, m01, m02, …, mNN) where N is either 2 or 3.
-
-Most methods are straight forward, and I will leave documentation to the Javadoc.

+ 0 - 143
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/math/quaternion.adoc

@@ -1,143 +0,0 @@
-= quaternion
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../
-:imagesdir: ..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== Quaternion
-
-See link:http://javadoc.jmonkeyengine.org/com/jme/math/Quaternion.html[Javadoc]
-
-
-=== Definition
-
-Quaternions define a subset of a hypercomplex number system. Quaternions are defined by (i^2^ = j^2^ = k^2^ = ijk = -1). jME makes use of Quaternions because they allow for compact representations of rotations, or correspondingly, orientations, in 3D space. With only four float values, we can represent an object's orientation, where a rotation matrix would require nine. They also require fewer arithmetic operations for concatenation. 
-
-Additional benefits of the Quaternion is reducing the chance of link:http://en.wikipedia.org/wiki/Gimbal_lock[Gimbal Lock] and allowing for easily interpolation between two rotations (spherical linear interpolation or slerp).
-
-While Quaternions are quite difficult to fully understand, there are an exceeding number of convenience methods to allow you to use them without having to understand the math behind it. Basically, these methods involve nothing more than setting the Quaternion's x,y,z,w values using other means of representing rotations. The Quaternion is then contained in <<jme3/advanced/spatial#,Spatial>> as its local rotation component.
-
-Quaternion *q* has the form
-
-*q* = &lt;_w,x,y,z_&gt; = _w + xi + yj + zk_
-
-or alternatively, it can be written as:
-
-*q* = *s* + *v*, where *s* represents the scalar part corresponding to the w-component of *q*, and *v* represents the vector part of the (x, y, z) components of *q*.
-
-Multiplication of Quaternions uses the distributive law and adheres to the following rules with multiplying the imaginary components (i, j, k):
-
-`i^2^ = j^2^ = k^2^ = -1`+
-`ij = -ji = k`+
-`jk = -kj = i`+
-`ki = -ik = j`
-
-However, Quaternion multiplication is _not_ commutative, so we have to pay attention to order.
-
-*q~1~q~2~* = s~1~s~2~ - *v~1~* dot *v~2~* + s~1~*v~2~* + s~2~*v~1~* + *v~1~* X *v~2~*
-
-Quaternions also have conjugates where the conjugate of *q* is (s - *v*)
-
-These basic operations allow us to convert various rotation representations to Quaternions.
-
-
-=== Angle Axis
-
-You might wish to represent your rotations as Angle Axis pairs. That is, you define a axis of rotation and the angle with which to rotate about this axis. Quaternion defines a method `fromAngleAxis` (and `fromAngleNormalAxis`) to create a Quaternion from this pair. This is acutally used quite a bit in jME demos to continually rotate objects. You can also obtain a Angle Axis rotation from an existing Quaternion using `toAngleAxis`.
-
-
-==== Example - Rotate a Spatial Using fromAngleAxis
-
-[source,java]
-----
-
-//rotate about the Y-Axis by approximately 1 pi
-Vector3f axis = Vector3f.UNIT_Y; // this equals (0, 1, 0) and does not require to create a new object
-float angle = 3.14f;
-s.getLocalRotation().fromAngleAxis(angle, axis);
-
-----
-
-
-=== Three Angles
-
-You can also represent a rotation by defining three angles. The angles represent the rotation about the individual axes. Passing in a three-element array of floats defines the angles where the first element is X, second Y and third is Z. The method provided by Quaternion is `fromAngles` and can also fill an array using `toAngles`
-
-
-==== Example - Rotate a Spatial Using fromAngles
-
-[source,java]
-----
-
-//rotate 1 radian on the x, 3 on the y and 0 on z
-float[] angles = {1, 3, 0};
-s.getLocalRotation().fromAngles(angles);
-
-----
-
-
-=== Three Axes
-
-If you have three axes that define your rotation, where the axes define the left axis, up axis and directional axis respectively) you can make use of `fromAxes` to generate the Quaternion. It should be noted that this will generate a new <<jme3/matrix#,Matrix>> object that is then garbage collected, thus, this method should not be used if it will be called many times. Again, `toAxes` will populate a <<jme3/vector#,Vector3f>> array.
-
-
-==== Example - Rotate a Spatial Using fromAxes
-
-[source,java]
-----
-
-//rotate a spatial to face up ~45 degrees
-Vector3f[] axes = new Vector3f[3];
-axes[0] = new Vector3f(-1, 0, 0); //left
-axes[1] = new Vector3f(0, 0.5f, 0.5f); //up
-axes[2] = new Vector3f(0, 0.5f, 0.5f); //dir
-
-s.getLocalRotation().fromAxes(axes);
-
-----
-
-
-=== Rotation Matrix
-
-Commonly you might find yourself with a <<jme3/matrix#,Matrix>> defining a rotation. In fact, it's very common to contain a rotation in a <<jme3/matrix#,Matrix>> create a Quaternion, rotate the Quaternion, and then get the <<jme3/matrix#,Matrix>> back. Quaternion contains a `fromRotationMatrix` method that will create the appropriate Quaternion based on the give <<jme3/matrix#,Matrix>>. The `toRotationMatrix` will populate a given <<jme3/matrix#,Matrix>>.
-
-
-==== Example - Rotate a Spatial Using a Rotation Matrix
-
-[source,java]
-----
-
-
-Matrix3f mat = new Matrix3f();
-mat.setColumn(0, new Vector3f(1,0,0));
-mat.setColumn(1, new Vector3f(0,-1,0));
-mat.setColumn(2, new Vector3f(0,0,1));
-
-s.getLocalRotation().fromRotationMatrix(mat);
-
-----
-
-As you can see there are many ways to build a Quaternion. This allows you to work with rotations in a way that is conceptually easier to picture, but still build Quaternions for internal representation.
-
-
-=== Slerp
-
-One of the biggest advantages to using Quaternions is allowing interpolation between two rotations. That is, if you have an initial Quaternion representing the original orientation of an object, and you have a final Quaternion representing the orientation you want the object to face, you can do this very smoothly with slerp. Simply supply the time, where time is [0, 1] and 0 is the initial rotation and 1 is the final rotation.
-
-
-==== Example - Use Slerp to Rotate Between two Quaternions
-
-[source,java]
-----
-
-Quaternion q1;
-Quaternion q2;
-
-//the rotation half-way between these two
-Quaternion q3 = q1.slerp(q2, 0.5f);
-
-----

+ 0 - 173
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/math/rotate.adoc

@@ -1,173 +0,0 @@
-= 3-D Rotation
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../
-:imagesdir: ..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-_Bad news: 3D rotation is done using matrix calculus. +
-Good news: If you do not understand calculus, there are two simple rules how you get it right._
-
-
-*3D rotation* is a crazy mathematical operation where you need to multiply all vertices in your object by four floating point numbers; the multiplication is referred to as concatenation, the array of four numbers {x,y,z,w} is referred to as quaternion. Don't worry, the 3D engine does the tough work for you. All you need to know is:
-
-*The Quaternion* is an object capable of deep-freezing and storing a rotation that you can apply to a 3D object.
-
-
-
-== Using Quaternions for Rotation
-
-To store a rotation in a Quaternion, you must specify two things: The angle and the axis of the rotation.
-
-*  The rotation angle is defined as a multiple of the number PI.
-*  The rotation axis is defined by a vector: Think of them in terms of “pitch, “yaw, and “roll.
-
-Example:
-
-[source,java]
-----
-
-/* This quaternion stores a 180 degree rolling rotation */
-Quaternion roll180 = new Quaternion();
-roll180.fromAngleAxis( FastMath.PI , new Vector3f(0,0,1) );
-/* The rotation is applied: The object rolls by 180 degrees. */
-thingamajig.setLocalRotation( roll180 );
-
-----
-
-So how to choose the right numbers for the Quaternion parameters? I'll give you my cheat-sheet:
-
-[cols="3", options="header"]
-|===
-
-a| *Rotation around Axis?*
-a| *Use this Axis Vector!*
-a| *Examples for this kind of rotation*
-
-a|X axis
-a| (1,0,0)
-a| A plane pitches. Nodding your head.
-
-a|Y axis
-a| (0,1,0)
-a| A plane yaws. A vehicle turns. Shaking your head.
-
-a|Z axis
-a| (0,0,1)
-a| A plane rolls or banks. Cocking your head.
-
-|===
-
-[NOTE]
-====
-These are the three most common examples – technically you can rotate around any axis expressed by a vector.
-====
-
-[cols="3", options="header"]
-|===
-
-a| *Angle?*
-a| *Use Radians!*
-a| *Examples*
-
-<a|45 degrees
-a| FastMath.PI / 4
-a| eighth of a circle
-
-<a|90 degrees
-a| FastMath.PI / 2
-a| quarter circle, 3 o'clock
-
-a|180 degrees
-a| FastMath.PI
-a| half circle, 6 o'clock
-
-a|270 degrees
-a| FastMath.PI * 3 / 2
-a| three quarter circle, 9 o'clock
-
-a|360 degrees
-a| FastMath.PI * 2
-a| full circle, 12  o'clock emoji:wink
-
-a|`g` degrees
-a| FastMath.PI * g / 180
-a| any angle `g`
-
-|===
-
-[IMPORTANT]
-====
-You must specify angles in link:http://en.wikipedia.org/wiki/Radian[Radian]s (multiples or fractions of PI). If you use degrees, you will just get useless results.
-====
-
-How to use these tables to speficy a certain rotation:
-
-.  Pick the appropriate vector from the axis table.
-.  Pick the appropriate radians value from the angle table.
-.  Create a Quaternion to store this rotation. `… fromAngleAxis( radians , vector )`
-.  Apply the Quaternion to a node to rotate it. `… setLocalRotation(…)`
-
-Quaternion objects can be used as often as you want, so give them meaningfull names, like `roll90, pitch45, yaw180`.
-
-link:http://moddb.wikia.com/wiki/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation[More about Quaternions]…
-
-
-
-== Code Sample
-
-[source,java]
-----
-
-/* We start out with a horizontal object */
-Cylinder cylinder = new Cylinder("post", 10, 10, 1, 10);
-cylinder.setModelBound(new BoundingBox());
-/* Create a 90-degree-pitch Quaternion. */
-Quaternion pitch90 = new Quaternion();
-pitch90.fromAngleAxis(FastMath.PI/2, new Vector3f(1,0,0));
-/* Apply the rotation to the object */
-cylinder.setLocalRotation(pitch90);
-/* Update the model. Now it's vertical. */
-cylinder.updateModelBound();
-cylinder.updateGeometry();
-
-----
-
-
-== Interpolating Rotations
-
-You can specify two rotations, and then have jme calculate (interpolate) the steps between two rotations:
-
-*  com.jme3.math.Quaternion, slerp() – store an interpolated step between two rotations
-**  link:http://javadoc.jmonkeyengine.org/com/jme3/math/Quaternion.html[com.jme3.math.Quaternion]
-**  link:http://javadoc.jmonkeyengine.org/com/jme/math/TransformQuaternion.html[com.jme.math.TransformQuaternion]
-
-
-
-== "Adding" Rotations
-
-You can concatenate (add) rotations: This means you turn the object first around one axis, then around the other, in one step. +
-`Quaternion myRotation =  pitch90.mult(roll45); /* pitch and roll */`
-
-
-
-== Troubleshooting Rotations
-
-Does the object end up in an unexpected location, or at an unexpected angle? If you are getting weird results, check the following:
-
-.  3-D transformations are non-commutative! This means it often makes a huge difference whether you first move a node and then rotate it around an axis, or first rotate the node around an axis and then move it. Make sure you code does what you mean to do.
-.  Are you intending to rotate around the object's origin along an axis, or around another pivot point outside the object? If you are trying to _rotate an object around a pivot point_, you have to create an (invisible) pivot node first, and attach the object to it. Then apply the rotation to the _parental pivot node_, not to the child object itself!
-.  Did you enter the angle in degrees (0 - 360°) or radians (0 - 2*PI)? A 3D engine expects radians, so make sure to convert your values! Formula: `g° = FastMath.PI * g / 180`
-
-
-
-== Tip: Transformation Matrix
-
-This here is just about rotation, but there are three types of 3-D transformation: <<jme3/rotate#,rotate>>, scale, and translate.
-
-You can do all transformations in individual steps (and then update the objects geometry and bounds), or you can combine them and transform the object in one step. If you have a lot of repetitive movement going on in your game it's worth learning more about Transformation Matrices for optimization. JME can also help you interpolate the steps between two fixed transformations.
-
-*  com.jme3.math.Transform, interpolateTransforms() – interpolate a step between two transformations
-**  link:http://javadoc.jmonkeyengine.org/com/jme3/math/Transform.html[com.jme.math.Transform]

+ 0 - 0
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/math/vectors.adoc


+ 0 - 211
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/multithread/multithreading.adoc

@@ -1,211 +0,0 @@
-= Multithreading Optimization
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: loop, game, performance, state, states, documentation
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== The jME3 Threading Model
-
-jME3 is similar to Swing in that, for speed and efficiency, all changes to the scene graph must be made in a single update thread. If you make changes only in Control.update(), AppState.update(), or SimpleApplication.simpleUpdate(), this will happen automatically.  However, if you pass work to another thread, you may need to pass results back to the main jME3 thread so that scene graph changes can take place there.
-
-[source,java]
-----
-
-public void rotateGeometry(final Geometry geo, final Quaternion rot) {
-    mainApp.enqueue(new Callable<Spatial>() {
-        public Spatial call() throws Exception {
-            return geo.rotate(rot);
-        }
-    });
-}
-
-----
-
-[NOTE]
-====
-This example does not fetch the returned value by calling `get()` on the Future object returned from `enqueue()`. This means that the example method `rotateGeometry()` will return immediately and will not wait for the rotation to be processed before continuing.
-
-If the processing thread needs to wait or needs the return value then `get()` or the other methods in the returned Future object such as `isDone()` can be used.
-====
-
-First, make sure you know what <<jme3/advanced/application_states#,Application States>> and <<jme3/advanced/custom_controls#,Custom Controls>> are.
-
-More complex games may feature complex mathematical operations or artificial intelligence calculations (such as path finding for several NPCs). If you make many time-intensive calls on the same thread (in the update loop), they will block one another, and thus slow down the game to a degree that makes it unplayable. If your game requires long running tasks, you should run them concurrently on separate threads, which speeds up the application considerably.
-
-Often multithreading means having separate detached logical loops going on in parallel, which communicate about their state. (For example, one thread for AI, one Sound, one Graphics). However we recommend to use a global update loop for game logic, and do multithreading within that loop when it is appropriate. This approach scales way better to multiple cores and does not break up your code logic. 
-
-Effectively, each for-loop in the main update loop might be a chance for multithreading, if you can break it up into self-contained tasks.
-
-
-=== Java Multithreading
-
-The java.util.concurrent package provides a good foundation for multithreading and dividing work into tasks that can be executed concurrently (hence the name). The three basic components are the Executor (supervises threads), Callable Objects (the tasks), and Future Objects (the result). You can link:http://download.oracle.com/javase/tutorial/essential/concurrency/[read about the concurrent package more here], I will give just a short introduction.
-
-*  A Callable is one of the classes that gets executed on a thread in the Executor. The object represents one of several concurrent tasks (e.g, one NPC's path finding task). Each Callable is started from the updateloop by calling a method named `call()`.
-*  The Executor is one central object that manages all your Callables. Every time you schedule a Callable in the Executor, the Executor returns a Future object for it. 
-*  A Future is an object that you use to check the status of an individual Callable task. The Future also gives you the return value in case one is returned.
-
-
-=== Multithreading in jME3
-
-So how do we implement multithreading in jME3?
-
-Let's take the example of a Control that controls an NPC Spatial. The NPC Control has to compute a lengthy pathfinding operation for each NPC. If we would execute the operations directly in the simpleUpdate() loop, it would block the game  each time a NPC wants to move from A to B. Even if we move this behaviour into the update() method of a dedicated NPC Control, we would still get annoying freeze frames, because it still runs on the same update loop thread. 
-
-To avoid slowdown, we decide to keep the pathfinding operations in the NPC Control, _but execute it on another thread_.
-
-
-== Executor
-
-You create the executor object in a global AppState (or the initSimpleApp() method), in any case in a high-level place where multiple controls can access it. 
-
-[source,java]
-----
-
-/* This constructor creates a new executor with a core pool size of 4. */
-ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(4);
-
-----
-
-Pool size means the executor will keep four threads alive at any time. Having more threads in the pool means that more tasks can run concurrently. But a bigger pool only results in a speed gain if the PC can handle it! Allocating a pool  that is uselessly large just wastes memory, so you need to find a good compromise: About the same to double the size of the number of cores in the computer makes sense. 
-
-[WARNING]
-====
-Executor needs to be shut down when the application ends, in order to make the process die properly
-In your simple application you can override the destroy method and shutdown the executor: 
-====
-
-[source,java]
-----
-
-    @Override
-    public void destroy() {
-        super.destroy();
-        executor.shutdown();
-    }
-
-----
-
-
-== Control Class Fields
-
-In the NPC Control, we create the individual objects that the thread manipulates. In our example case (the pathfinding control), the task is about locations and path arrays, so we need the following variables:
-
-[source,Java]
-----
-
-//The vector to store the desired location in:
-Vector3f desiredLocation = new Vector3f();
-//The MyWayList object that contains the result waylist:
-MyWayList wayList = null;
-//The future that is used to check the execution status:
-Future future = null;
-
-----
-
-Here we also created the Future variable to track the state of this task.
-
-
-== Control Update() Method
-
-Next let's look at the update() call of the Control where the time-intensive task starts. In our example, the task is the `findWay` Callable (which contains the pathfinding process). So instead of spelling out the pathfinding process  in the Control's update() loop, we start the process via `future = executor.submit(findWay);`.
-
-[source,java]
-----
-
-public void update(float tpf) {
-    try{
-        //If we have no waylist and not started a callable yet, do so!
-        if(wayList == null && future == null){
-            //set the desired location vector, after that we should not modify it anymore
-            //because it's being accessed on the other thread!
-            desiredLocation.set(getGoodNextLocation());
-            //start the callable on the executor
-            future = executor.submit(findWay);    //  Thread starts!
-        }
-        //If we have started a callable already, we check the status
-        else if(future != null){
-            //Get the waylist when its done
-            if(future.isDone()){
-                wayList = future.get();
-                future = null;
-            }
-            else if(future.isCancelled()){
-                //Set future to null. Maybe we succeed next time...
-                future = null;
-            }
-        }
-    } 
-    catch(Exception e){ 
-      Exceptions.printStackTrace(e);
-    }
-    if(wayList != null){
-        //.... Success! Let's process the wayList and move the NPC...
-    }
-}
-----
-
-Note how this logic makes its decision based on the Future object.
-
-Remember not to mess with the class fields after starting the thread, because they are being accessed and modified on the new thread. In more obvious terms: You cannot change the “desired location of the NPC while the path finder is calculating a different path. You have to cancel the current Future first.
-
-
-== The Callable
-
-The next code sample shows the Callable that is dedicated to performing the long-running task (here, wayfinding). This is the task that used to block the rest of the application, and is now executed on a thread of its own. You implement the task in the Callable always in an inner method named `call()`.
-
-The task code in the Callable should be self-contained! It should not write or read any data of objects that are managed by the scene graph or OpenGL thread directly. Even reading locations of Spatials can be problematic! So ideally all data that is needed for the wayfinding process should be available to the new thread when it starts already, possibly in a cloned version so no concurrent access to the data happens.
-
-In reality, you might need access to the game state. If you must read or write a current state from the scene graph, you must have a clone of the data in your thread. There are only two ways:
-
-*  Use the execution queue `application.enqueue()` to create a sub-thread that clones the info. Only disadvantage is, it may be slower. +
-The example below gets the `Vector3f location` from the scene object `mySpatial` using this way.
-*  Create a separate World class that allows safe access to its data via synchronized methods to access the scene graph. Alternatively it can also internally use `application.enqueue()`. +
-The following example gets the object `Data data = myWorld.getData();` using this way.
-
-These two ways are thread-safe, they don't mess up the game logic, and keep the Callable code readable.
-
-[source,java]
-----
-
-// A self-contained time-intensive task:
-private Callable<MyWayList> findWay = new Callable<MyWayList>(){
-    public MyWayList call() throws Exception {
-
-        //Read or write data from the scene graph -- via the execution queue:
-        Vector3f location = application.enqueue(new Callable<Vector3f>() {
-            public Vector3f call() throws Exception {
-                //we clone the location so we can use the variable safely on our thread
-                return mySpatial.getLocalTranslation().clone();
-            }
-        }).get();
-
-        // This world class allows safe access via synchronized methods
-        Data data = myWorld.getData(); 
-
-        //... Now process data and find the way ...
-
-        return wayList;
-    }
-};
-
-
-----
-
-
-=== Useful Links
-
-High level description which describes how to manage the game state and the rendering in different threads: +
-link:http://jahej.com/alt/2011_07_03_threading-and-your-game-loop.html[Threading and your game loop]. + 
-A C++ example can be found at: +
-link:http://gamasutra.com/blogs/AndreaMagnorsky/20130527/193087/Multithreading_rendering_in_a_game_engine_with_CDouble_buffer_implementation.php[Multithreading-rendering in a game engine with CDouble buffer implementation].
-
-
-=== Conclusion
-
-The cool thing about this approach is that every entity creates one self-contained Callable for the Executor, and they are all executed in parallel. In theory, you can have one thread per entity without changing anything else but the settings of the executor.

+ 0 - 497
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/networking/networking.adoc

@@ -1,497 +0,0 @@
-= SpiderMonkey: Multi-Player Networking
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: documentation, network, spidermonkey
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-This document introduces you to the SpiderMonkey networking +++<abbr title="Application Programming Interface">API</abbr>+++. You use this +++<abbr title="Application Programming Interface">API</abbr>+++ when you develop games where several players compete with one another in real time. A multi-player game is made up of several clients connecting to a server:
-
-*  The central server (one headless SimpleApplication) coordinates the game in the background.
-*  Each player runs a game client (a standard SimpleApplication) and connects to the central server.
-
-Each Client keeps the Server informed about its player's moves and actions. The Server centrally maintains the game state and broadcasts the state info back to all connected clients. This network synchronization allows all clients to share the same game world. Each client then displays the game state to one player from this player's perspective.
-
-
-== SpiderMonkey API Overview
-
-The SpiderMonkey +++<abbr title="Application Programming Interface">API</abbr>+++ is a set of interfaces and helper classes in the 'com.jme3.network' package.  For most users, this package and the 'message' package is all they need to worry about.  (The 'base' and 'kernel' packages only come into play when implementing custom network transports or alternate client/server protocols, which is now possible).
-
-The SpiderMonkey +++<abbr title="Application Programming Interface">API</abbr>+++ assists you in creating a Server, Clients, and Messages. Once a Server instance is created and started, the Server accepts remote connections from Clients, and you can send and receive Messages. Client objects represent the client-side of the client-server connection.  Within the Server, these Client objects are referred to as HostedConnections. HostedConnections can hold application-defined client-specific session attributes that the server-side listeners and services can use to track player information, etc.
-[cols="3", options="header"]
-|===
-
-a| Seen from the Client 
-a| 
-a| Seen from the Server 
-
-a| com.jme3.network.Client 
-a| == 
-a| com.jme3.network.HostedConnection 
-
-|===
-
-You can register several types of listeners to be notified of changes.
-
-*  MessageListeners on both the Client and the Server are notified when new messages arrive.  You can use MessageListeners to be notified about only specific types of messages.
-*  ClientStateListeners inform the Client of changes in its connection state, e.g. when the client gets kicked from the server.
-*  ConnectionListeners inform the Server about HostedConnection arrivals and removals, e.g. if a client joins or quits.
-*  ErrorListeners inform the Client about network exceptions that have happened, e.g. if the server crashes, the client throws a ConnectorException, this can be picked up so that the application can do something about it.
-
-
-== Client and Server
-
-
-=== Creating a Server
-
-The game server is a “headless com.jme3.app.SimpleApplication:
-
-[source,java]
-----
-
-public class ServerMain extends SimpleApplication {
-  public static void main(String[] args) {
-    ServerMain app = new ServerMain();
-    app.start(JmeContext.Type.Headless); // headless type for servers!
-  }
-}
-
-----
-
-
-[TIP]
-====
-A `Headless` SimpleApplication executes the simpleInitApp() method and runs the update loop normally. But the application does not open a window, and it does not listen to user input. This is the typical behavior for a server application.
-====
-
-
-Create a com.jme3.network.Server in the `simpleInitApp()` method and specify a communication port, for example 6143.
-
-[source,java]
-----
-
-  public void simpleInitApp() {
-    ...
-    Server myServer = Network.createServer(6143);
-    myServer.start();
-    ...
-  }
-
-----
-
-When you run this app on a host, the server is ready to accept clients. Let's create a client next.
-
-
-=== Creating a Client
-
-A game client is a standard com.jme3.app.SimpleApplication.
-
-[source,java]
-----
-
-public class ClientMain extends SimpleApplication {
-  public static void main(String[] args) {
-    ClientMain app = new ClientMain();
-    app.start(JmeContext.Type.Display); // standard display type
-  }
-}
-
-----
-
-
-[TIP]
-====
-A standard SimpleApplication in `Display` mode executes the simpleInitApp() method, runs the update loop, opens a window for the rendered video output, and listens to user input. This is the typical behavior for a client application.
-====
-
-
-Create a com.jme3.network.Client in the `simpleInitApp()` method and specify the servers IP address, and the same communication port as for the server, here 6143.
-
-[source,java]
-----
-
-public void simpleInitApp() {
-   ...
-   Client myClient = Network.connectToServer("localhost", 6143);
-   myClient.start();
-   ...
-
-----
-
-The server address can be in the format “localhost or “127.0.0.1 (for local testing), or an IP address of a remote host in the format “123.456.78.9”. In this example, we assume the server is running on the localhost.
-
-When you run this client, it connects to the server.
-
-
-=== Getting Info About a Client
-
-The server refers to a connected client as com.jme3.network.HostedConnection objects. The server can get info about clients as follows:
-[cols="2", options="header"]
-|===
-
-a|Accessor
-a|Purpose
-
-a|myServer.getConnections()
-a|Server gets a collection of all connected HostedConnection objects (all connected clients).
-
-a|myServer.getConnections().size()
-a|Server gets the number of all connected HostedConnection objects (number of clients).
-
-a|myServer.getConnection(0)
-a|Server gets the first (0), second (1), etc, connected HostedConnection object (one client).
-
-|===
-
-Your game can define its own game data based on whatever criteria you want, typically these include player ID and state. If the server needs to look up player/client-specific information, you can store this information directly on the HostedConnection object. The following examples read and write a custom Java object `MyState` in the HostedConnection object `conn`:
-[cols="2", options="header"]
-|===
-
-a|Accessor
-a|Purpose
-
-a| conn.setAttribute(“MyState, new MyState()); 
-a| Server can change an attribute of the HostedConnection. 
-
-a| MyState state = conn.getAttribute(“MyState)
-a| Server can read an attribute of the HostedConnection. 
-
-|===
-
-
-== Messaging
-
-
-=== Creating Message Types
-
-Each message represents data that you want to transmit between client and server. Common message examples include transformation updates or game actions. For each message type, create a message class that extends com.jme3.network.AbstractMessage. Use the @Serializable annotation from com.jme3.network.serializing.Serializable and create an empty default constructor. Custom constructors, fields, and methods are up to you and depend on the message data that you want to transmit.
-
-[source,java]
-----
-
-@Serializable
-public class HelloMessage extends AbstractMessage {
-  private String hello;       // custom message data
-  public HelloMessage() {}    // empty constructor
-  public HelloMessage(String s) { hello = s; } // custom constructor
-}
-
-----
-
-You must register each message type to the com.jme3.network.serializing.Serializer, in both server and client!
-
-[source,java]
-----
-Serializer.registerClass(HelloMessage.class);
-----
-
-
-=== Responding to Messages
-
-After a Message was received, a Listener responds to it. The listener can access fields of the message, and send messages back, start new threads, etc. There are two listeners, one on the server, one on the client. For each message type, you implement the responses in either Listeners’ `messageReceived()` method.
-
-
-==== ClientListener.java
-
-Create one ClientListener.java and make it extend `com.jme3.network.MessageListener`.
-
-[source,java]
-----
-public class ClientListener implements MessageListener<Client> {
-  public void messageReceived(Client source, Message message) {
-    if (message instanceof HelloMessage) {
-      // do something with the message
-      HelloMessage helloMessage = (HelloMessage) message;
-      System.out.println("Client #"+source.getId()+" received: '"+helloMessage.getSomething()+"'");
-    } // else...
-  }
-----
-
-For each message type, register a client listener to the client.
-
-[source,java]
-----
-myClient.addMessageListener(new ClientListener(), HelloMessage.class);
-----
-
-
-==== ServerListener.java
-
-Create one ServerListener.java and make it extend `com.jme3.network.MessageListener`.
-
-[source,java]
-----
-public class ServerListener implements MessageListener<HostedConnection> {
-  public void messageReceived(HostedConnection source, Message message) {
-    if (message instanceof HelloMessage) {
-      // do something with the message
-      HelloMessage helloMessage = (HelloMessage) message;
-      System.out.println("Server received '" +helloMessage.getSomething() +"' from client #"+source.getId() );
-    } // else....
-  }
-----
-
-For each message type, register a server listener to the server:
-
-[source,java]
-----
-myServer.addMessageListener(new ServerListener(), HelloMessage.class);
-----
-
-
-=== Creating and Sending Messages
-
-Let's create a new message of type HelloMessage:
-
-[source,java]
-----
-Message message = new HelloMessage("Hello World!");
-----
-
-Now the client can send this message to the server:
-
-[source,java]
-----
-myClient.send(message);
-----
-
-Or the server can broadcast this message to all HostedConnection (clients):
-
-[source,java]
-----
-Message message = new HelloMessage("Welcome!");
-myServer.broadcast(message);
-----
-
-Or the server can send the message to a specific subset of clients (e.g. to HostedConnection conn1, conn2, and conn3): 
-
-[source,java]
-----
-myServer.broadcast( Filters.in( conn1, conn2, conn3 ), message );
-----
-
-Or the server can send the message to all but a few selected clients (e.g. to all HostedConnections but conn4):
-
-[source,java]
-----
-myServer.broadcast( Filters.notEqualTo( conn4 ), message );
-----
-
-The last two broadcasting methods use com.jme3.network.Filters to select a subset of recipients. If you know the exact list of recipients, always send the messages directly to them using the Filters; avoid flooding the network with unnecessary broadcasts to all.
-
-
-== Identification and Rejection
-
-The ID of the Client and HostedConnection are the same at both ends of a connection. The ID is given out authoritatively by the Server.
-
-[source,java]
-----
-... myClient.getId() ...
-----
-
-A server has a game version and game name property. Each client expects to communicate with a server with a certain game name and version. Test first whether the game name matches, and then whether game version matches, before sending any messages! If they do not match, SpiderMoney will reject it for you, you have no choice in the mater. This is so the client and server can avoid miscommunication.
-
-
-[TIP]
-====
-Typically, your networked game defines its own attributes (such as player ID) based on whatever criteria you want. If you want to look up player/client-specific information beyond the game version, you can set this information directly on the Client/HostedConnection object (see Getting Info About a Client).
-====
-
-
-
-== Closing Clients and Server Cleanly
-
-
-=== Closing a Client
-
-You must override the client's destroy() method to close the connection cleanly when the player quits the client:
-
-[source,java]
-----
-
-  @Override
-  public void destroy() {
-      ... // custom code
-      myClient.close();
-      super.destroy();
-  }
-----
-
-
-=== Closing a Server
-
-You must override the server's destroy() method to close the connection when the server quits:
-
-[source,java]
-----
-
-  @Override
-  public void destroy() {
-      ... // custom code
-      myServer.close();
-      super.destroy();
-  }
-----
-
-
-=== Kicking a Client
-
-The server can kick a HostedConnection to make it disconnect. You should provide a String with further info (an explanation to the user what happened, e.g. “Shutting down for maintenance) for the server to send along. This info message can be used (displayed to the user) by a ClientStateListener. (See below)
-
-[source,java]
-----
-conn.close("We kick cheaters.");
-----
-
-
-== Listening to Connection Notification
-
-The server and clients are notified about connection changes.
-
-
-=== ClientStateListener
-
-The com.jme3.network.ClientStateListener notifies the Client when the Client has fully connected to the server (including any internal handshaking), and when the Client is kicked (disconnected) from the server.
-
-
-[TIP]
-====
-The ClientStateListener when it receives a network exception applies the default close action. This just stops the client and you'll have to build around it so your application knows what to do. If you need more control when a network exception happens and the client closes, you may want to investigate in a ErrorListener.
-====
-
-[cols="2", options="header"]
-|===
-
-a| ClientStateListener interface method 
-a| Purpose 
-
-a| public void clientConnected(Client c){} 
-a| Implement here what happens as soon as this client has fully connected to the server. 
-
-a| public void clientDisconnected(Client c, DisconnectInfo info){} 
-a| Implement here what happens after the server kicks this client. For example, display the DisconnectInfo to the user. 
-
-|===
-
-First implement the ClientStateListener interface in the Client class. Then register it to myClient in MyGameClient's simpleInitApp() method:
-
-[source,java]
-----
-myClient.addClientStateListener(this);
-----
-
-
-=== ConnectionListener
-
-The com.jme3.network.ConnectionListener notifies the Server whenever new HostedConnections (clients) come and go.  The listener notifies the server after the Client connection is fully established (including any internal handshaking).
-[cols="2", options="header"]
-|===
-
-a| ConnectionListener interface method 
-a| Purpose 
-
-a| public void connectionAdded(Server s, HostedConnection c){} 
-a| Implemenent here what happens after a new HostedConnection has joined the Server. 
-
-a| public void connectionRemoved(Server s, HostedConnection c){} 
-a| Implement here what happens after a HostedConnection has left. E.g. a player has quit the game and the server removes his character. 
-
-|===
-
-First implement the ConnectionListener interface in the Server class. Then register it to myServer in MyGameServer's simpleInitApp() method. 
-
-[source,java]
-----
-myServer.addConnectionListener(this);
-----
-
-
-=== ErrorListener
-
-The com.jme3.network.ErrorListener is a listener for when network exception happens. This listener is built so that you can override the default actions when a network exception happens.
-
-
-[IMPORTANT]
-====
-If you intend on using the default network mechanics, *don't* use this!
-If you do override this, make sure you add a mechanic that can close the client otherwise your client will get stuck open and cause errors.
-====
-
-[cols="2", options="header"]
-|===
-
-a| ErrorListener interface method 
-a| Purpose 
-
-a| public void handleError(Client c, Throwable t){} 
-a| Implemenent here what happens after a exception affects the network . 
-
-|===
-
-
-[TIP]
-====
-This interface was built for the client and server, but the code has never been put on the server to handle this listener.
-====
-
-
-First implement the ErrorListener interface in the client class. Then you need to register it to myClient in MyGameClients's simpleInitApp() method.
-
-[source,java]
-----
-myClient.addErrorListener(this);
-----
-
-In the class that implements the ErrorListener, a method would of been added call handleError(Client s, Throwable t). Inside this method to get you started, you going to want to listen for an error. To do this you're going to want a bit of code like this.
-
-[source,java]
-----
-if(t instanceof exception) {
-     //Add your own code here
-}
-----
-
-Replace *exception* part in the *if* statement for the type of exception that you would like it to handle.
-
-
-== UDP versus TCP
-
-SpiderMonkey supports both UDP (unreliable, fast) and TCP (reliable, slow) transport of messages.
-
-[source,java]
-----
-message1.setReliable(true); // TCP
-message2.setReliable(false); // UDP
-----
-
-*  Choose reliable and slow transport for messages, if you want to make certain the message is delivered (resent) when lost, and if the order of a series of messages is relevant. E.g. game actions such as “1. wield weapon, 2. attack, 3. dodge.
-*  Choose unreliable and fast transport for messages if the next message makes any previously delayed or lost message obsolete and synchronizes the state again. E.g. a series of new locations while walking.
-
-
-== Important: Use Multi-Threading
-
-
-[IMPORTANT]
-====
-*You cannot modify the scenegraph directly from the network thread.* A common example for such a modification is when you synchronize the player's position in the scene. You have to use Java Multithreading.
-====
-
-
-Multithreading means that you create a Callable. A Callable is a Java class representing any (possibly time-intensive) self-contained task that has an impact on the scene graph (such as positioning the player). You enqueue the Callable in the Executor of the client's OpenGL thread. The Callable ensures to executes the modification in sync with the update loop.
-
-[source,java]
-----
-app.enqueue(callable);
-----
-
-Learn more about using <<jme3/advanced/multithreading#,multithreading>> in jME3 here.
-
-For general advice, see the articles link:https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking[MultiPlayer Networking] and link:https://developer.valvesoftware.com/wiki/Latency_Compensating_Methods_in_Client/Server_In-game_Protocol_Design_and_Optimization[Latency Compensating Methods in Client/Server In-game Protocol Design and Optimization] by the Valve Developer Community.
-
-
-== Troubleshooting
-
-If you have set up a server in your home network, and the game clients cannot reach the server from the outside, it's time to learn about link:http://portforward.com/[port forwarding].

+ 0 - 20
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/networking/networking_video_tutorials.adoc

@@ -1,20 +0,0 @@
-= networking_video_tutorials
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-*jME3 Networking Video Tutorials*
-
-*  link:http://www.youtube.com/watch?v=5IbmPL_m9t4[Video: General Introduction to the networking series]
-*  link:http://www.youtube.com/watch?v=-fzMIOUIKGo[Video: Introduction to the internet]
-*  link:http://www.youtube.com/watch?v=vm4BtptrmRc[Video: Introduction to the web]
-*  link:http://www.youtube.com/watch?v=1v8aplAFlFs[Video: Cheating in games]
-*  link:http://www.youtube.com/watch?v=e4MheUDfxJg[Video: Introduction to SpiderMonkey (Part 1/2)]
-*  link:http://www.youtube.com/watch?v=uJuO-JPl14I[Video: Introduction to SpiderMonkey (Part 2/2)]
-*  link:http://www.youtube.com/watch?v=4medGxTsz_U[Video: Our first Networked game (Part 1/3)]
-*  link:http://www.youtube.com/watch?v=IuYDNS8qGeo[Video: Our first Networked game (Part 2/3)]
-*  link:http://www.youtube.com/watch?v=mvORSLiYRuo[Video: Our first Networked game (Part 3/3)]

+ 0 - 63
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/networking/spidermonkey.adoc

@@ -1,63 +0,0 @@
-= SpiderMonkey (Deprecated!)
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:keywords: documentation, network
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-[WARNING]
-====
-This article covers a deprecated +++<abbr title="Application Programming Interface">API</abbr>+++! See <<jme3/advanced/networking#,networking>> for current documentation. See <<spidermonkey/migration#,migration>> for migration instructions.
-====
-
-SpiderMonkey is a high performance Java networking engine, aiming to provide game developers a stable and efficient networking system. It's also perfectly capable of doing anything other than game networking. SpiderMonkey is part of jME3 and can be found in the src/networking directory.
-*Author:* Lars 'Levia' Wesselius+
-*License:* link:http://www.opensource.org/licenses/bsd-license.php[New BSD license]+
-*Blog:* link:http://codeninja.me/tag/spidermonkey/[http://codeninja.me/tag/spidermonkey/]+
-*Forum:* link:http://jmonkeyengine.org/groups/spidermonkey/forum/[http://jmonkeyengine.org/groups/spidermonkey/forum/]+
-A tutorial trail can be found below, and below that all different aspects of SpiderMonkey are explained. These tutorials are to be updated upon SVN HEAD, so if new features are added in SVN, you should tutorials arriving of them soon.
-
-
-== Tutorial trail
-
-.  <<spidermonkey/tutorial/connection#,Connections>>
-.  <<spidermonkey/tutorial/sending_and_receiving_messages#,Sending and receiving messages>>
-.  <<spidermonkey/tutorial/serializing#,Serialization>>
-.  <<spidermonkey/tutorial/compression#,Compression>>
-.  <<spidermonkey/tutorial/services#,Services>>
-.  <<spidermonkey/tutorial/streaming#,Streaming>>
-
-
-=== Explanation of SpiderMonkey's inner workings
-
-
-== Connection protocols
-
-SpiderMonkey supports both TCP and UDP, and is also extendable to provide others. Possible future protocols may be RUDP, UDP Lite, and SCTP. SCTP will be added in Java 7, and will therefore probably added to SpiderMonkey after it's released. Please note that the language level of SpiderMonkey is 1.5, so it will definitely not be part of the standard +++<abbr title="Application Programming Interface">API</abbr>+++ for a few years.
-
-
-== Clients
-
-SpiderMonkey creates two connections by default. A TCP connection for a reliable connection, and an UDP 'connection' footnote:[UDP is connectionless] for fast message handling. A problem arises here: these two connections mean that even though there are two connections, there's only one client to represent both the connections. In SpiderMonkey you don't have to worry about that. The server has a client manager which deals with this problem. Upon connecting, clients have to send a ClientRegistration message to link their TCP and UDP connections together. Upon receiving those two messages, server combines the clients into one, and provides this client to you. This means you can call both TCP and UDP methods on the client. If you still want to receive the 'local' client of a connection, you can do so by calling the appropriate messages in the Server class.
-
-
-== Serializing
-
-Serializing is an aspect that received a lot of attention. I wanted it to be simple for people to register their own messages, but also be able to register serializers for their own object types. The system works by registering classes to serializers. Generally, a serializer does not exist without a class it can serialize - simply because it doesn't have to: Why have a serializer when there's nothing to serialize. A lot of work has been put into making it as efficient as possible. What can be left out, is left out, and what can optimized, is optimized.
-
-
-=== Field serializer
-
-The default serializer requires some explanation. This serializer serializes all classes that have no (registered) serializer. The field serializer works by saving all fields internally, so it can access them on serialization faster. The fields are taken, and their types are checked. They are put through a serializer again (which serializer depends, of course, on the data type). Then they are ready to be written to the buffer. As you can tell, this is quite a simple serializer, and should be used if your message don't require extra attention. See <<spidermonkey/tutorial/serializing#,this tutorial>> if you want to know how to register your own messages or serializers.
-
-
-== Service system
-
-The service system is in fact a tiny system. It's meant to solve a small, but annoying problem. Imagine you have SpiderMonkey as your networking library, and other people have made extra's for it. Excellent, of course, but they may all require different initialization! Perhaps you have to instantiate one yourself by using new, or maybe another works by calling a factory method; the service system exists to avoid that problem. All extras should use this system. Please see <<spidermonkey/tutorial/services#,the service tutorial>> on how to use this system.
-
-
-== Compression
-
-By default SpiderMonkey supports compressing messages. It's been made to where you have complete freedom over what messages you wish to compress. See <<spidermonkey/tutorial/compression#,this tutorial>> on how to use these special messages.

+ 0 - 57
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/physics/bullet_multithreading.adoc

@@ -1,57 +0,0 @@
-= Multithreading Bullet Physics in jme3
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: documentation, physics, threading
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== Introduction
-
-Since bullet is not (yet) multithreaded or GPU accelerated, the jME3 implementation allows to run each physics space on a separate thread that is executed in parallel to rendering.
-
-
-== How is it handled in jme3 and bullet?
-
-A SimpleApplication with a BulletAppState allows setting the threading type via 
-
-[source]
-----
-setThreadingType(ThreadingType type);
-----
-
- where ThreadingType can be either SEQUENTIAL or PARALLEL. By default, it's SEQUENTIAL.
-
-You can activate PARALLEL threading in the simpleInitApp() method:
-
-[source,java]
-----
-bulletAppState = new BulletAppState();
-bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
-stateManager.attach(bulletAppState);
-----
-
-Now the physics update happens in parallel to render(), that is, after the user's changes in the update() call have been applied. During update() the physics update loop pauses. This way the loop logic is still maintained: the user can set and change values in physics and scenegraph objects before render() and physicsUpdate() are called in parallel. This allows you to use physics methods in update() as if it was single-threaded.
-[cols="2", options="header"]
-|===
-
-a|PARALLEL
-a|SEQUENTIAL
-
-a|1. update(), 2. render() and physics update().
-<a|1. update(), 2. render(), 3. physics update().  
-
-a|Physics Debug View is rendered inaccurately (out of sync)
-a|Physics Debug View is rendered accurately.
-
-|===
-
-
-[TIP]
-====
-You can add more physics spaces by using multiple PARALLEL bulletAppStates. You would do that if you have sets physical objects that never collide (for example, underground bolders and flying cannon balls above ground), so you put those into separate physics spaces, which improves performances (less collisions to check!). 
-====
-

+ 0 - 34
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/physics/bullet_pitfalls.adoc

@@ -1,34 +0,0 @@
-= Bullet Physics Pitfalls
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-Bullet physics is not without its problems. Unfortunately, many of those are outside of the control of the jMonkeyEngine Core Team and thus cannot be fixed.
-
-
-== Sweep Test Issues
-
-.  When using link:http://jmonkeyengine.org/javadoc/com/jme3/bullet/PhysicsSpace.html#sweepTest(com.jme3.bullet.collision.shapes.CollisionShape, com.jme3.math.Transform, com.jme3.math.Transform)[PhysicsSpace.sweepTest()], ensure that the distance between the transforms is at least 0.4wu or greater.
-.  Note that the sweep will not detect collisions if it done inside of a collision shape. It must be on the edge of a collision shape to detect any collisions.
-
-
-== Ghost Control AABB Collision only
-
-As the javadoc for link:http://jmonkeyengine.org/javadoc/com/jme3/bullet/objects/PhysicsGhostObject.html[PhysicsObjectControl] says, the ghost object collision detection uses AABB (Axis-aligned bounding box) collision only, regardless of the collision shape it has been assigned.
-
-*Workaround:*+
-Please use PhysicsSpace.sweepTest() instead, or kinematic physics objects with link:http://jmonkeyengine.org/javadoc/com/jme3/bullet/PhysicsSpace.html#addCollisionListener(com.jme3.bullet.collision.PhysicsCollisionListener)[collision listeners].
-
-
-== Rigid bodies fall through ground
-
-This usually happens if the ground physics object has large triangles or consists of a large BoxCollisionShape. 
-
-*Workaround:*+
-
-*  For meshes with large triangles - Subdivide the mesh in a model editor such as Blender.
-*  For large boxes - seperate into smaller boxes or use a MeshCollisionShape for terrain instead of BoxCollisionShape.

+ 0 - 162
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/physics/hinges_and_joints.adoc

@@ -1,162 +0,0 @@
-= Physical Hinges and Joints
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: documentation, physics, joint
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-The jMonkeyEngine3 has built-in support for link:http://jbullet.advel.cz[jBullet physics] via the `com.jme3.bullet` package.
-
-Game Physics are not only employed to calculate collisions, but they can also simulate hinges and joints. Think of pulley chains, shaky rope bridges, swinging pendulums, or (trap)door and chest hinges. Physics are a great addition to e.g. an action or puzzle game.
-
-In this example, we will create a pendulum. The joint is the (invisible) connection between the pendulum body and the hook. You will see that you can use what you learn from the simple pendulum and apply it to other joint/hinge objects (rope bridges, etc).
-
-
-== Sample Code
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsHingeJoint.java[TestPhysicsHingeJoint.java]
-
-
-== Overview of this Physics Application
-
-.  Create a SimpleApplication with a <<jme3/advanced/physics#,BulletAppState>> 
-**  This gives us a PhysicsSpace for PhysicsControls
-
-.  For the pendulum, we use a Spatial with a PhysicsControl, and we apply physical forces to them.
-**  The parts of the “pendulum are Physics Control'ed Spatials with Collision Shapes. 
-**  We create a fixed `hookNode` and a dynamic `pendulumNode`. 
-
-.  We can “crank the handle and rotate the joint like a hinge, or we can let loose and expose the joints freely to gravity. 
-**  For physical forces we will use the method `joint.enableMotor();`
-
-
-
-== Creating a Fixed Node
-
-The hookNode is the fixed point from which the pendulum hangs. It has no mass. 
-
-[source,java]
-----
-
-Node hookNode=PhysicsTestHelper.createPhysicsTestNode(
-    assetManager, new BoxCollisionShape(new Vector3f( .1f, .1f, .1f)),0);
-hookNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f,0,0f));
-
-rootNode.attachChild(hookNode);
-getPhysicsSpace().add(hookNode);
-
-----
-
-For a rope bridge, there would be two fixed nodes where the bridge is attached to the mountainside.
-
-
-== Creating a Dynamic Node
-
-The pendulumNode is the dynamic part of the construction. It has a mass. 
-
-[source,java]
-----
-
-Node pendulumNode=PhysicsTestHelper.createPhysicsTestNode(
-    assetManager, new BoxCollisionShape(new Vector3f( .3f, .3f, .3f)),1);
-pendulumNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f,-1,0f));
-rootNode.attachChild(pendulumNode);
-getPhysicsSpace().add(pendulumNode);
-
-----
-
-For a rope bridge, each set of planks would be one dynamic node. 
-
-
-== Understanding DOF, Joints, and Hinges
-
-A PhysicsHingeJoint is an invisible connection between two nodes – here between the pendulum body and the hook. Why are hinges and joints represented by the same class? Hinges and joints have something in common: They constrain the _mechanical degree of freedom_ (DOF) of another object. 
-
-Consider a free falling, “unchained object in physical 3D space: It has 6 DOFs:
-
-*  It translates along 3 axes
-*  It rotates around 3 axes
-
-Now consider some examples of objects with joints:
-
-*  An individual chain link is free to spin and move around, but joined into a chain, the link's movement is restricted to stay with the surrounding links.
-*  A person's arm can rotate around some axes, but not around others. The shoulder joint allows one and restricts the other.
-*  A door hinge is one of the most restricted types of joint: It can only rotate around one axis. 
-
-You'll understand that, when creating any type of joint, it is important to correctly specify the DOFs that the joint restricts, and the DOFs that the joint allows. For the typical DOF of a <<jme3/advanced/ragdoll#,ragDoll>> character's limbs, jME even offers a special joint, `ConeJoint`.
-
-
-== Creating the Joint
-
-You create the HingeJoint after you have created the nodes that are to be chained together. In the code snippet you see that the HingeJoint constructor requires the two node objects. You also have to specify axes and pivots – they are the degrees of freedom that you just heard about.
-
-[source,java]
-----
-
-private HingeJoint joint;
-...
-  public void simpleInitApp() {
-    ...
-    // hookNode and pendulumNode are created here...
-    ...
-    
-    joint=new HingeJoint(hookNode.getControl(RigidBodyControl.class), // A
-                     pendulumNode.getControl(RigidBodyControl.class), // B
-                     new Vector3f(0f, 0f, 0f),  // pivot point local to A
-                     new Vector3f(0f, 1f, 0f),  // pivot point local to B 
-                     Vector3f.UNIT_Z,           // DoF Axis of A (Z axis)
-                     Vector3f.UNIT_Z  );        // DoF Axis of B (Z axis)
-
-----
-
-The pivot point's position will be at `(0,0,0)` in the global 3D space. In A's local space that is at `(0,0,0)` and in B's local space (remember B's position was set to `(0,-1,0)`) that is at `(0,1,0)`.
-
-Specify the following parameters for each joint:
-
-*  PhysicsControl A and B – the two nodes that are to be joined
-*  Vector3f pivot A and pivot B – coordinates of the attachment point relative to A and B
-**  The points typically lie on the surface of the PhysicsControl's Spatials, rarely in the middle.
-
-*  Vector3f axisA and axisB – around which axes each node is allowed to spin.
-**  In our example, we constrain the pendulum to swing only along the Z axis.
-
-
-Remember to add all joint objects to the physicsSpace, just like you would do with any physical objects.
-
-[source,java]
-----
-bulletAppState.getPhysicsSpace().add(joint);
-----
-
-*Tip:* If you want the joint to be visible, attach a geometry to the dynamic node, and translate it to its start position.
-
-
-== Apply Physical Forces
-
-You can apply forces to dynamic nodes (the ones that have a mass), and see how other joined (“chained) objects are dragged along. 
-
-Alternatively, you can also apply forces to the joint itself. In a game, you may want to spin an automatic revolving door, or slam a door closed in a spooky way, or dramatically open the lid of a treasure chest.
-
-The method to call on the joint is `enableMotor()`.
-
-[source,java]
-----
-joint.enableMotor(true, 1, .1f);
-joint.enableMotor(true, -1, .1f);
-----
-
-.  Switch the motor on by supplying `true`
-.  Specify the velocity with which the joint should rotate around the specified axis. 
-**  Use positive and negative numbers to change direction.
-
-.  Specify the impulse for this motor. Heavier masses need a bigger impulse to be moved.
-
-When you disable the motor, the chained nodes are exposed to gravity again:
-
-[source,java]
-----
-joint.enableMotor(false, 0, 0);
-----

+ 0 - 207
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/physics/physics_listeners.adoc

@@ -1,207 +0,0 @@
-= Physics Listeners
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: documentation, physics, collision, forces, interaction
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-You can control physical objects (push them around) by applying physical forces to them. Typically, you also want to respond to the resulting collisions, e.g. by substracting health points or by playing a sound. To specify how the game responds to such physics events, you use Physics Listeners.
-
-
-== Sample Code
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/bullet/TestCollisionListener.java[TestCollisionListener.java]
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/bullet/TestAttachGhostObject.java[TestAttachGhostObject.java]
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/bullet/TestGhostObject.java[TestGhostObject.java]
-
-
-== PhysicsGhostObjects
-
-Attach a com.jme3.bullet.control.GhostControl to any Spatial to turn it into a PhysicsGhostObject. Ghost objects automatically follow their spatial and detect collisions. The attached ghost itself is invisible and non-solid (!) and doesn't interfere with your game otherwise, it only passively reports collisions. 
-
-You can leave the GhostControl non-solid and invisible and attach it to an (invisible) Node in the scene to create something like a motion detector. But a GhostControl also works fine when added to spatials that are solid (with RigidBodyControl) and visible (with Geometry). One use case for GhostControls is to check for collisions among <<jme3/advanced/walking_character#,CharacterControls>> when the characters are walking.
-
-The shape of the ghost depends on the CollisionShape that you gave the GhostControl. This means that the GhostControl's shape can be different from the RigidBodyControl's shape. For example, the non-solid ghost shape can be bigger than the solid shape of the Spatial (so you can “feel ahead).
-
-[source,java]
-----
-
-GhostControl ghost = new GhostControl(
-  new BoxCollisionShape(new Vector3f(1,1,1)));  // a box-shaped ghost
-Node node = new Node("a ghost-controlled thing");
-node.addControl(ghost);                         // the ghost follows this node
-// Optional: Add a Geometry, or other controls, to the node if you need to
-...
-// attach everything to activate it
-rootNode.attachChild(node);
-getPhysicsSpace().add(ghost);
-
-----
-[cols="2", options="header"]
-|===
-
-a|Ghost methods
-a|Usage
-
-a|getOverlappingObjects()
-a|Returns the List of objects that are currently colliding (overlapping) with the ghost.
-
-a|getOverlappingCount()
-a|Returns the number of currently colliding objects.
-
-a|getOverlapping(i)
-a|Get PhysicsCollisionObject number i.
-
-|===
-
-
-== Physics Tick Listener
-
-The jBullet Physics implementation is stepped at a constant 60 physics ticks per second frame rate.
-Applying forces or checking for overlaps only has an effect right at a physics update cycle, which is not every frame. If you do physics interactions at arbitrary spots in the simpleUpdate() loop, calls will be dropped at irregular intervals, because they happen out of cycle.
-
-
-=== When (Not) to Use Tick Listener?
-
-When you write game mechanics that apply forces, you must implement a tick listener (com.jme3.bullet.PhysicsTickListener) for it. The tick listener makes certain the forces are not dropped, but applied in time for the next physics tick.
-
-Also, when you check for overlaps of two physical objects using a GhostControl, you cannot just go `ghost.getOverLappingObjects()` somewhere outside the update loop. You have to make certain 1 physics tick has passed before the overlapping objects list is filled with data. Again, the PhysicsTickListener does the timing for you.
-
-When your game mechanics however just poll the current state (e.g. getPhysicsLocation()) of physical objects, or if you only use the GhostControl like a sphere trigger inside an update loop, then you don't need an extra PhysicsTickListener.
-
-
-=== How to Listen to Physics Ticks
-
-Here's is the declaration of an examplary Physics Control that listens to ticks. (The example shows a RigidBodyControl, but it can also be GhostControl.)
-
-[source,java]
-----
-public class MyCustomControl
-    extends RigidBodyControl implements PhysicsTickListener { ... }
-----
-
-When you implement the interface, you have to implement `physicsTick()` and `preTick()` methods.
-
-*  `prePhysicsTick(PhysicsSpace space, float tpf)` is called before each step, here you apply forces (change the state).
-*  `physicsTick(PhysicsSpace space, float tpf)` is called after each step, here you poll the results (get the current state).
-
-The tpf value is time per frame in seconds. You can use it as a factor to time actions so they run equally on slow and fast machines.
-
-[source,java]
-----
-
-@override
-public void prePhysicsTick(PhysicsSpace space, float tpf){
-  // apply state changes ...
-}
-@override
-public void physicsTick(PhysicsSpace space, float tpf){
-  // poll game state ...
-}
-
-----
-
-
-== Physics Collision Listener
-
-
-=== When (Not) to Use Collision Listener
-
-If you do not implement the Collision Listener interface (com.jme3.bullet.collision.PhysicsCollisionListener), a collisions will just mean that physical forces between solid objects are applied automatically. If you just want “Balls rolling, bricks falling you do not need a listener.
-
-If however you want to respond to a collision event (com.jme3.bullet.collision.PhysicsCollisionEvent) with a custom action, then you need to implement the PhysicsCollisionListener interface. Typical actions triggered by collisions include:
-
-*  Increasing a counter (e.g. score points)
-*  Decreasing a counter (e.g. health points)
-*  Triggering an effect (e.g. explosion)
-*  Playing a sound (e.g. explosion, ouch)
-*  … and countless more, depending on your game
-
-
-=== How to Listen to Collisions
-
-You need to add the PhysicsCollisionListener to the physics space before collisions will be listened for. Here's an example of a Physics Control that uses a collision listener. (The example shows a RigidBodyControl, but it can also be GhostControl.)
-
-[source,java]
-----
-public class MyCustomControl extends RigidBodyControl
-    implements PhysicsCollisionListener {
-    public MyCustomControl() {
-        bulletAppState.getPhysicsSpace().addCollisionListener(this);
-        ...
-    }
-----
-
-To respond to the PhysicsCollisionEvent you now have to override the `collision()` method in MyCustomControl. This gives you access to the `event` object. Mostly you will be interested in the identity of any two nodes that collided: `event.getNodeA()` and `event.getNodeB()`.
-
-After you identify the colliding nodes, specify the action to trigger when this pair collides. Note that you cannot know which one will be Node A or Node B, you have to deal with either variant.
-
-[source,java]
-----
-
-    public void collision(PhysicsCollisionEvent event) {
-        if ( event.getNodeA().getName().equals("player") ) {
-            final Node node = event.getNodeA();
-            /** ... do something with the node ... */
-        } else if ( event.getNodeB().getName().equals("player") ) {
-            final Node node = event.getNodeB();
-            /** ... do something with the node ... */
-        }
-    }
-----
-
-
-[IMPORTANT]
-====
-Note that after the collision() method ends, the PhysicsCollisionEvent is cleared. You must get all objects and values you need within the collision() method.
-====
-
-
-
-=== Reading Details From a PhysicsCollisionEvent
-
-The PhysicsCollisionEvent `event` gives you access to detailed information about the collision. You already know the event objects can identify which nodes collided, but it even knows how hard they collided:
-[cols="2", options="header"]
-|===
-
-<a|Method                        
-a|Purpose
-
-<a| getObjectA() +
-getObjectB()     
-a| The two participants in the collision. You cannot know in advance whether some node will be recorded as A or B, you always have to consider both cases. 
-
-<a| getAppliedImpulse()          
-a| A float value representing the collision impulse 
-
-<a| getAppliedImpulseLateral1()  
-a| A float value representing the lateral collision impulse 
-
-<a| getAppliedImpulseLateral2()  
-a| A float value representing the lateral collision impulse 
-
-<a| getCombinedFriction()        
-a| A float value representing the collision friction 
-
-<a| getCombinedRestitution()     
-a| A float value representing the collision restitution (bounciness) 
-
-|===
-
-Note that after the collision method has been called the object is not valid anymore so you should copy any data you want to keep into local variables.
-
-
-=== Collision Groups
-
-You can improve performance by resricting the number of tests that collision detection has to perform. If you have a case where you are only interested in collisions between certain objects but not others, you can assign sets of physical obejcts to different collision groups.
-
-For example, for a click-to-select, you only care if the selection ray collides with a few selectable objects such as dropped weapons or powerups (one group), but not with non-selectables such as floors or walls (different group). 
-
-[source,java]
-----
-myNode.getControl(RigidBodyControl.class).setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_02);
-myNode.getControl(RigidBodyControl.class).setCollideWithGroups(PhysicsCollisionObject.COLLISION_GROUP_02);
-----

+ 0 - 177
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/physics/ragdoll.adoc

@@ -1,177 +0,0 @@
-= Ragdoll Physics
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:keywords: documentation, physics, character, NPC, forces, collisions
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-The jMonkeyEngine3 has built-in support for link:http://jbullet.advel.cz[jBullet physics] via the `com.jme3.bullet` package. Physics are not only responsible for handing collisions, but they also make <<jme3/advanced/hinges_and_joints#,hinges and joints>> possible. One special example of physical joints are ragdoll physics, shown here.
-
-
-image::jme3/advanced/ragdoll.png[ragdoll.png,width="",height="",align="center"]
-
-
-
-== Sample Code
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/bullet/TestRagDoll.java[TestRagDoll.java] (Tip: Click to pull the ragdoll up)
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/bullet/TestBoneRagdoll.java[TestBoneRagdoll.java] – This ragdoll replaces a rigged model of a character in the moment it is “shot to simulate a collapsing person. (Also note DoF of the limbs.)
-
-
-== Preparing the Physics Game
-
-.  Create a SimpleApplication with a <<jme3/advanced/physics#,BulletAppState>>
-**  This gives us a PhysicsSpace for PhysicControls
-
-.  Add a physical floor (A box collision shape with mass zero)
-
-
-== Creating the Ragdoll
-
-A ragdoll is a simple “person (dummy) that you build out of cylinder collision shapes. The ragdoll has 11 limbs: 1 for shoulders, 1 for the body, 1 for hips; plus 2 arms and 2 legs that are made up of two limbs each. In your game, you will likely replace the cylinders with your own (better looking) limb models. In this example here we just use simple cylinders.
-
-
-=== Limbs
-
-Since you're just creating the ragdoll for this example, all the limbs have the same shape, and you can write a simple helper method to create them. The function returns a PhysicsControl with CollisionShape with the width, height, location, and rotation (vertical or horizontal) that you specify. You choose a CapsuleCollisionShape (a cylinder with rounded top and bottom) so the limbs collide smoothly against one another.
-
-[source,java]
-----
-
-private Node createLimb(float width, float height, Vector3f location, boolean rotate) {
-        int axis = rotate ? PhysicsSpace.AXIS_X : PhysicsSpace.AXIS_Y;
-        CapsuleCollisionShape shape = new CapsuleCollisionShape(width, height, axis);
-        Node node = new Node("Limb");
-        RigidBodyControl rigidBodyControl = new RigidBodyControl(shape, 1);
-        node.setLocalTranslation(location);
-        node.addControl(rigidBodyControl);
-        return node;
-}
-
-----
-
-You write a custom helper method to initialize the limbs. Look at the screenshot above for orientation.
-
-*  All cylinders have the same diameter, 0.2f.
-*  You make the body and shoulders longer than the other limbs, 1.0f instead of 0.5f.
-*  You determine the coordinates for positioning the limbs to form a person.
-*  The shoulders and hips are _vertical_ cylinders, this is why we set the rotation to true.
-
-[source,java]
-----
-
-Node shoulders = createLimb(0.2f, 1.0f, new Vector3f( 0.00f, 1.5f, 0), true);
-Node     uArmL = createLimb(0.2f, 0.5f, new Vector3f(-0.75f, 0.8f, 0), false);
-Node     uArmR = createLimb(0.2f, 0.5f, new Vector3f( 0.75f, 0.8f, 0), false);
-Node     lArmL = createLimb(0.2f, 0.5f, new Vector3f(-0.75f,-0.2f, 0), false);
-Node     lArmR = createLimb(0.2f, 0.5f, new Vector3f( 0.75f,-0.2f, 0), false);
-Node      body = createLimb(0.2f, 1.0f, new Vector3f( 0.00f, 0.5f, 0), false);
-Node      hips = createLimb(0.2f, 0.5f, new Vector3f( 0.00f,-0.5f, 0), true);
-Node     uLegL = createLimb(0.2f, 0.5f, new Vector3f(-0.25f,-1.2f, 0), false);
-Node     uLegR = createLimb(0.2f, 0.5f, new Vector3f( 0.25f,-1.2f, 0), false);
-Node     lLegL = createLimb(0.2f, 0.5f, new Vector3f(-0.25f,-2.2f, 0), false);
-Node     lLegR = createLimb(0.2f, 0.5f, new Vector3f( 0.25f,-2.2f, 0), false);
-
-----
-
-You now have the outline of a person. But if you ran the application now, the individual limbs would fall down independently of one another – the ragdoll is still lacking joints.
-
-
-=== Joints
-
-As before, you write a small helper method. This time its purpose is to quickly join two limbs A and B at the connection point that we specify.
-
-*  Convert A's and B's connectionPoint vector from world coordinate space to local coordinate space.
-*  Use a ConeJoint, a special joint that approximates the degree of freedom that limbs typically have. The ConeJoint constructor requires the two nodes, and the two local pivot coordinates that we just determined.
-*  Set the joints limits to allow swinging, but not twisting.
-[source,java]
-----
-private PhysicsJoint join(Node A, Node B, Vector3f connectionPoint) {
-        Vector3f pivotA = A.worldToLocal(connectionPoint, new Vector3f());
-        Vector3f pivotB = B.worldToLocal(connectionPoint, new Vector3f());
-        ConeJoint joint = new ConeJoint(A.getControl(RigidBodyControl.class),
-                                        B.getControl(RigidBodyControl.class),
-                                        pivotA, pivotB);
-        joint.setLimit(1f, 1f, 0);
-        return joint;
-}
-----
-
-
-Use the helper method to connect all limbs with joints where they belong, at one end of the limb.
-
-[source,java]
-----
-
-join(body,  shoulders, new Vector3f( 0.00f,  1.4f, 0));
-join(body,       hips, new Vector3f( 0.00f, -0.5f, 0));
-join(uArmL, shoulders, new Vector3f(-0.75f,  1.4f, 0));
-join(uArmR, shoulders, new Vector3f( 0.75f,  1.4f, 0));
-join(uArmL,     lArmL, new Vector3f(-0.75f,  0.4f, 0));
-join(uArmR,     lArmR, new Vector3f( 0.75f,  0.4f, 0));
-join(uLegL,      hips, new Vector3f(-0.25f, -0.5f, 0));
-join(uLegR,      hips, new Vector3f( 0.25f, -0.5f, 0));
-join(uLegL,     lLegL, new Vector3f(-0.25f, -1.7f, 0));
-join(uLegR,     lLegR, new Vector3f( 0.25f, -1.7f, 0));
-----
-
-Now the ragdoll is connected. If you ran the app now, the doll would collapse, but the limbs would stay together.
-
-
-=== Attaching Everything to the Scene
-
-We create one (non-physical) Node named ragDoll, and attach all other nodes to it.
-
-[source,java]
-----
-
-ragDoll.attachChild(shoulders);
-ragDoll.attachChild(body);
-ragDoll.attachChild(hips);
-ragDoll.attachChild(uArmL);
-ragDoll.attachChild(uArmR);
-ragDoll.attachChild(lArmL);
-ragDoll.attachChild(lArmR);
-ragDoll.attachChild(uLegL);
-ragDoll.attachChild(uLegR);
-ragDoll.attachChild(lLegL);
-ragDoll.attachChild(lLegR);
-----
-
-To use the ragdoll in a scene, we attach its main node to the rootNode, and to the PhysicsSpace.
-
-[source,java]
-----
-
-rootNode.attachChild(ragDoll);
-bulletAppState.getPhysicsSpace().addAll(ragDoll);
-
-----
-
-
-== Applying Forces
-
-To pull the doll up, you could add an input handler that triggers the following action:
-
-[source,java]
-----
-
-Vector3f upforce = new Vector3f(0, 200, 0);
-shoulders.applyContinuousForce(true, upforce);
-
-----
-
-We can use the action to pick the doll up and put it back on its feet, or what ever. Read more about <<jme3/advanced/physics#forcesmoving_physical_objects,Forces>> here.
-
-
-== Detecting Collisions
-
-Read the <<jme3/advanced/physics#responding_to_a_physicscollisionevent,Responding to a PhysicsCollisionEvent>> chapter in the general physics documentation on how to detect collisions. You can detect collisions between limbs or between limbs and the floor, and trigger game events.
-
-
-== Best Practices
-
-If you experience weird behaviour in a ragdoll – such as exploding into pieces and then reassembling – check your collision shapes. Verify you did not position the limbs too close to one another when assmebling the ragdoll. You typically see physical nodes being ejected when their collision shapes intersect, which puts physics in an impossible state.

+ 0 - 286
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/physics/softbody.adoc

@@ -1,286 +0,0 @@
-= Physics : SoftBody
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-[WARNING]
-====
-Writing in progress, checkout the forum for additional infos link:http://hub.jmonkeyengine.org/t/bullet-softbody-in-jme3-1/33110[http://hub.jmonkeyengine.org/t/bullet-softbody-in-jme3-1/33110]
-====
-
-what is a soft body ?
-
-how a soft body is simulated ? (  node, link, face ; spring &amp; damper )
-
-link:https://en.wikipedia.org/wiki/Soft_body_dynamics[https://en.wikipedia.org/wiki/Soft_body_dynamics]
-
-
-== Getting Started
-
-The dynamics libraries for softbody (.so , .dll …) isn't (yet) prebuild for your platform so you have to checkout the entire project from GitHub then build the project.
-
-
-=== How to :
-
-.   checkout the project from link:https://github.com/Dokthar/jmonkeyengine/tree/bullet_SoftBody[GitHub].
-.   go into the file gradle.propeties and set the line : buildNativeProjecte = true .
-.   run the command : ./gradlew build
-.   then build the sdk : ant -f ./sdk/ build-zip (or build the sdk installer)
-.   create a new project and make sure you use the following libraries : jme3-bullet-native and jme3-bullet (instead of jme3-jBullet)
-
-
-== Simple Example
-
-[source,java]
-----
-
-public void simpleInitApp() {
-    softBodyAppState = new BulletSoftBodyAppState();
-    getStateManager().attach(softBodyAppState);
-
-    SoftBodyWorldInfo sbwi = softBodyAppState.getPhysicsSoftSpace().getWorldInfo();
-    sbwi.setGravity(Vector3f.UNIT_Y.mult(-0.981f));
-
-    Geometry bunny = new Geometry("b", StandfordBunny.getMesh().deepClone());
-    Material matN = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md");
-    bunny.setMaterial(matN);
-    rootNode.attachChild(bunny);
-    bunny.addControl(new SoftBodyControl(false));
-
-    PhysicsSoftBody soft = bunny.getControl(SoftBodyControl.class);
-    soft.generateClusters(8);
-    soft.config().setDynamicFrictionCoef(0.8f);
-    soft.config().setPoseMatchingCoef(0.2f);
-
-    soft.config().setCollisionsFlags(PhysicsSoftBody.Config.CL_SS + PhysicsSoftBody.Config.CL_RS);
-
-    soft.setPose(false, true);
-    soft.setTotalMass(100, true);
-    soft.randomizeConstraints();
-    softBodyAppState.getPhysicsSoftSpace().add(soft);
-
-    Box floorMesh = new Box(100f, 0.5f, 100f);
-    Geometry floor = new Geometry("floor", floorMesh);
-    floor.move(0, -5f, 0);
-    floor.addControl(new RigidBodyControl(0));
-    softBodyAppState.getPhysicsSpace().add(floor);
-}
-
-----
-
-
-== Documentation
-
-soft mesh / surface
-
-Cluster ?
-
-(generate) bending constraint ?
-
-config collision flag ?
-
-
-=== Ropes
-
-A rope can be created by creating a new SoftBody on a Mesh with Mesh.Mode.Lines.
-More informations on creating <<jme3/advanced/custom_meshes#,custom meshes>>.
-
-
-==== Example
-
-[source,java]
-----
-
-Mesh ropeMesh = new Mesh();
-Vector3f[] vertices = {
-   new Vector3f(0.00f, 0, 0),
-   new Vector3f(0.50f, 0, 0),
-   new Vector3f(1.00f, 0, 0),
-   new Vector3f(1.50f, 0, 0),
-   new Vector3f(2.00f, 0, 0),
-   new Vector3f(2.50f, 0, 0),
-   new Vector3f(3.00f, 0, 0),
-   new Vector3f(3.50f, 0, 0),
-   new Vector3f(4.00f, 0, 0)};
-int[] indices = {
-   0, 1,
-   1, 2,
-   2, 3,
-   3, 4,
-   4, 5,
-   5, 6,
-   6, 7,
-   7, 8};
-ropeMesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
-ropeMesh.setBuffer(VertexBuffer.Type.Index, 2, BufferUtils.createIntBuffer(indices));
-ropeMesh.setMode(Mesh.Mode.Lines);
-ropeMesh.updateBound();
-
-----
-
-Once you have a Line Mesh, you can do as follow :
-
-[source,java]
-----
-
-Geometry t = new Geometry("softRope", ropeMesh);
-t.move(0, 5, 0);
-t.addControl(new SoftBodyControl(false));
-
-----
-
-
-==== Anchors
-
-An Anchors act like a weld between a SoftBody and a RigidBody.
-Adding a anchors to a soft body require to specify the SoftBody's node and the RigidBody to weld with.
-
-[source,java]
-----
-
-soft.appendAnchor(nodeId, rigid);
-
-----
-
-
-=== Note
-
-An anchor bind a SoftBody's node (or Vertex) to a RigidBody, the node will be attached to a RigidBody even if there are space in between.
-
-
-[WARNING]
-====
- Anchors are not yet Serialized
-====
-
-
-
-==== Example
-
-[source,java]
-----
-
-Geometry t = new Geometry("softRope", ropeMesh);
-Box box = new Box(1f, 1f, 1f);
-Geometry b = new Geometry("rigidBox", box);
-t.move(0, 5, 0);
-b.move(3f, 5, 0);
-
-t.addControl(new SoftBodyControl(false));
-soft = t.getControl(SoftBodyControl.class);
-soft.setMass(0, 0); // make the first ndoe static
-
-b.addControl(new RigidBodyControl(1));
-rigid = b.getControl(RigidBodyControl.class);
-
-softBodyAppState.getPhysicsSpace().add(rigid);
-softBodyAppState.getPhysicsSoftSpace().add(soft);
-
-soft.appendAnchor(8, rigid); //where 8 is the last node of the rope
-
-----
-
-Anchors can be removed as below. Note that you have to keep the node and RigidBody bind with.
-
-[source,java]
-----
-
-soft.removeAnchor(8,rigid);
-
-----
-
-
-==== Joints
-
-Joints require SoftBodies with Clusters ( see generateClusters(int k) ).
-
-
-[WARNING]
-====
- joint don't use values pivotA & pivotB (not yet)
-====
-
-
-
-=== LinearJoint
-
-[source,java]
-----
-
-public SoftLinearJoint(Vector3f position, PhysicsSoftBody nodeA, PhysicsRigidBody nodeB, Vector3f pivotA, Vector3f pivotB);
-public SoftLinearJoint(Vector3f position, PhysicsSoftBody nodeA, PhysicsSoftBody nodeB, Vector3f pivotA, Vector3f pivotB);
-
-----
-
-
-=== AngularJoint
-
-[source,java]
-----
-
-public SoftAngularJoint(Vector3f axis, PhysicsSoftBody nodeA, PhysicsRigidBody nodeB, Vector3f pivotA, Vector3f pivotB);
-public SoftAngularJoint(Vector3f axis, PhysicsSoftBody nodeA, PhysicsSoftBody nodeB, Vector3f pivotA, Vector3f pivotB);
-
-----
-
-
-==== Examples
-
-
-=== LinearJoint
-
-[source,java]
-----
-
-Box box = new Box(3f, 1f, 3f);
-Geometry b = new Geometry("rigidBox", box);
-b.move(0, 5f, 0);
-b.addControl(new RigidBodyControl(1));
-rigid = b.getControl(RigidBodyControl.class);
-
-Torus torus = new Torus(20, 10, 1f, 1.5f);
-Geometry t = new Geometry("softTorus", torus);
-t.addControl(new SoftBodyControl(true, false));
-soft = t.getControl(SoftBodyControl.class);
-soft.generateBendingConstraints(4, soft.material());
-soft.generateClusters(4);
-
-softBodyAppState.getPhysicsSpace().add(rigid);
-softBodyAppState.getPhysicsSoftSpace().add(soft);
-
-joint = new SoftLinearJoint(Vector3f.UNIT_X, soft, rigid, new Vector3f(0f,2,0f), new Vector3f(0f,-2,0f));
-softBodyAppState.getPhysicsSoftSpace().add(joint);
-
-----
-
-
-=== AngularJoint
-
-[source,java]
-----
-
-Box box = new Box(1f, 1f, 1f);
-Geometry b = new Geometry("rigidBox", box);
-b.move(0, 5f, 0);
-b.addControl(new RigidBodyControl(1));
-rigid = b.getControl(RigidBodyControl.class);
-
- Torus torus = new Torus(20, 10, 1f, 1.5f);
-Geometry t = new Geometry("softTorus", torus);
-t.addControl(new SoftBodyControl(true, false));
-soft = t.getControl(SoftBodyControl.class);
-soft.generateBendingConstraints(4, soft.material());
-soft.generateClusters(4);
-
-softBodyAppState.getPhysicsSpace().add(rigid);
-softBodyAppState.getPhysicsSoftSpace().add(soft);
-
-joint = new SoftAngularJoint(Vector3f.UNIT_X, soft, rigid, new Vector3f(0,0,2), new Vector3f(0, 0, 2));
-softBodyAppState.getPhysicsSoftSpace().add(joint);
-
-----

+ 0 - 285
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/physics/vehicles.adoc

@@ -1,285 +0,0 @@
-= Controlling a Physical Vehicle
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:keywords: documentation, physics, vehicle, collision
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-For physical vehicles, jME's uses the jBullet ray-cast vehicle. In this vehicle implementation, the physical chassis 'floats' along on four non-physical vertical rays.
-
-Internally, each wheel casts a ray down, and using the ray's intersection point, jBullet calculates the suspension length, and the suspension force. The suspension force is applied to the chassis, keeping it from hitting the ground. The friction force is calculated for each wheel where the ray intersects with the ground. Friction is applied as a sideways and forwards force. footnote:[ link:https://docs.google.com/Doc?docid=0AXVUZ5xw6XpKZGNuZG56a3FfMzU0Z2NyZnF4Zmo&hl=en[https://docs.google.com/Doc?docid=0AXVUZ5xw6XpKZGNuZG56a3FfMzU0Z2NyZnF4Zmo&amp;hl=en] ]
-
-This article shows how you use this vehicle implementation in a jME3 application.
-
-
-image::jme3/advanced/physics-vehicle.png[physics-vehicle.png,width="",height="",align="center"]
-
-
-
-== Sample Code
-
-Full code samples are here:
-
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCar.java[TestPhysicsCar.java]
-*  link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/bullet/TestFancyCar.java[TestFancyCar.java]
-
-
-== Overview of this Physics Application
-
-The goal is to create a physical vehicle with wheels that can be steered and that interacts (collides with) with the floor and obstacles.
-
-.  Create a SimpleApplication with a <<jme3/advanced/physics#,BulletAppState>>
-**  This gives us a PhysicsSpace for PhysicsNodes
-
-.  Create a VehicleControl + CompoundCollisionShape for the physical vehicle behaviour
-..  Set physical properties of the vehicle, such as suspension.
-
-.  Create a VehicleNode for the car model
-..  Create a box plus 4 cylinders as wheels (using `vehicle.addWheel()`).
-..  Add the VehicleControl behaviour to the VehicleNode geometry.
-
-.  Create a RigidBodyControl and CollisionShape for the floor
-.  Map key triggers and add input listeners
-**  Navigational commands Left, Right, Foward, Brake.
-
-.  Define the steering actions to be triggered by the key events.
-**  `vehicle.steer()`
-**  `vehicle.accelerate()`
-**  `vehicle.brake()`
-
-
-
-== Creating the Vehicle Chassis
-
-The vehicle that we create here in the link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/bullet/TestPhysicsCar.java[TestPhysicsCar.java] example is just a “box on wheels, a basic vehicle shape that you can replace with a fancy car model, as demonstrated in link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/bullet/TestFancyCar.java[TestFancyCar.java].
-
-Every physical object must have a collision shape, that we prepare first. For the vehicle, we choose a compound collision shape that is made up of a box-shaped body of the right size for the vehicle. We will add the wheels later.
-
-[source,java]
-----
-
-CompoundCollisionShape compoundShape = new CompoundCollisionShape();
-BoxCollisionShape box = new BoxCollisionShape(new Vector3f(1.2f, 0.5f, 2.4f));
-
-----
-
-*Best Practice:* We attach the BoxCollisionShape (the vehicle body) to the CompoundCollisionShape at a Vector of (0,1,0): This shifts the effective center of mass of the BoxCollisionShape downwards to 0,-1,0 and makes a moving vehicle more stable!
-
-[source,java]
-----
-compoundShape.addChildShape(box, new Vector3f(0, 1, 0));
-----
-
-Any kind of geometry can make up the visible part of the vehicle, here we use a wireframe box. We create a node that we use to group the geometry.
-
-[source,java]
-----
-Node vehicleNode=new Node("vehicleNode");
-vehicle = new VehicleControl(compoundShape, 400);
-vehicleNode.addControl(vehicle);
-----
-
-We initialize the Vehicle Control with the compound shape, and set its mass to a heavy value, 400f. The Vehicle Control represents the car's physical behaviour.
-
-[source,java]
-----
-vehicle = new VehicleControl(compoundShape, 400);
-----
-
-Finally we add the behaviour (VehicleControl) to the visible Geometry (node).
-
-[source,java]
-----
-vehicleNode.addControl(vehicle);
-----
-
-We configure the physical properties of the vehicle's suspension: Compresion, Damping, Stiffness, and MaxSuspenionForce. Picking workable values for the wheel suspension can be tricky – for background info have a look at these link:https://docs.google.com/Doc?docid=0AXVUZ5xw6XpKZGNuZG56a3FfMzU0Z2NyZnF4Zmo&hl=en[Suspension Settings Tips]. For now, let's work with the following values:
-
-[source,java]
-----
-float stiffness = 60.0f;//200=f1 car
-float compValue = .3f; //(should be lower than damp)
-float dampValue = .4f;
-vehicle.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness));
-vehicle.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness));
-vehicle.setSuspensionStiffness(stiffness);
-vehicle.setMaxSuspensionForce(10000.0f);
-----
-
-We now have a node `vehicleNode` with a visible “car geometry, which acts like a vehicle. One thing that's missing are wheels.
-
-
-== Adding the Wheels
-
-We create four wheel Geometries and add them to the vehicle. Our wheel geometries are simple, non-physical discs (flat Cylinders), they are just visual decorations. Note that the physical wheel behaviour (the com.jme3.bullet.objects.VehicleWheel objects) is created internally by the `vehicle.addWheel()` method.
-
-The `addWheel()` method sets following properties:
-
-*  Vector3f connectionPoint – Coordinate where the suspension connects to the chassis (internally, this is where the Ray is casted downwards).
-*  Vector3f direction – Wheel direction is typically a (0,-1,0) vector.
-*  Vector3f axle – Axle direction is typically a (-1,0,0) vector.
-*  float suspensionRestLength – Suspension rest length in world units
-*  float wheelRadius – Wheel radius in world units
-*  boolean isFrontWheel – Whether this wheel is one of the steering wheels. +
-Front wheels are the ones that rotate visibly when the vehicle turns.
-
-We initialize a few variables that we will reuse when we add the four wheels. yOff, etc, are the particular wheel offsets for our small vehicle model.
-
-[source,java]
-----
-
-Vector3f wheelDirection = new Vector3f(0, -1, 0);
-Vector3f wheelAxle = new Vector3f(-1, 0, 0);
-float radius = 0.5f;
-float restLength = 0.3f;
-float yOff = 0.5f;
-float xOff = 1f;
-float zOff = 2f;
-
-----
-
-We create a Cylinder mesh shape that we use to create the four visible wheel geometries.
-
-[source,java]
-----
-Cylinder wheelMesh = new Cylinder(16, 16, radius, radius * 0.6f, true);
-----
-
-For each wheel, we create a Node and a Geometry. We attach the Cylinder Geometry to the Node. We rotate the wheel by 90° around the Y axis. We set a material to make it visible. Finally we add the wheel (plus its properties) to the vehicle.
-
-[source,java]
-----
-
-Node node1 = new Node("wheel 1 node");
-Geometry wheels1 = new Geometry("wheel 1", wheelMesh);
-node1.attachChild(wheels1);
-wheels1.rotate(0, FastMath.HALF_PI, 0);
-wheels1.setMaterial(mat);
-
-vehicle.addWheel(node1, new Vector3f(-xOff, yOff, zOff),
-    wheelDirection, wheelAxle, restLength, radius, true);
-
-----
-
-The three next wheels are created in the same fashion, only the offsets are different. Remember to set the Boolean parameter correctly to indicate whether it's a front wheel.
-
-[source,java]
-----
-
-...
-vehicle.addWheel(node2, new Vector3f(xOff, yOff, zOff),
-  wheelDirection, wheelAxle, restLength, radius, true);
-...
-vehicle.addWheel(node3, new Vector3f(-xOff, yOff, -zOff),
-  wheelDirection, wheelAxle, restLength, radius, false);
-...
-vehicle.addWheel(node4, new Vector3f(xOff, yOff, -zOff),
-  wheelDirection, wheelAxle, restLength, radius, false);
-
-----
-
-Attach the wheel Nodes to the vehicle Node to group them, so they move together.
-
-[source,java]
-----
-
-vehicleNode.attachChild(node1);
-vehicleNode.attachChild(node2);
-vehicleNode.attachChild(node3);
-vehicleNode.attachChild(node4);
-
-----
-
-As always, attach the vehicle Node to the rootNode to make it visible, and add the Vehicle Control to the PhysicsSpace to make the car physical.
-
-[source,java]
-----
-
-rootNode.attachChild(vehicleNode);
-getPhysicsSpace().add(vehicle);
-
-----
-
-Not shown here is that we also created a Material `mat`.
-
-
-== Steering the Vehicle
-
-Not shown here is the standard way how we map the input keys to actions (see full code sample). Also refer to <<jme3/advanced/input_handling#,Input Handling>>).
-
-In the ActionListener, we implement the actions that control the vehicle's direction and speed. For the four directions (accelerate=up, brake=down, left, right), we specify how we want the vehicle to move.
-
-*  The braking action is pretty straightforward: +
-`vehicle.brake(brakeForce)`
-*  For left and right turns, we add a constant to `steeringValue` when the key is pressed, and subtract it when the key is released. +
-`vehicle.steer(steeringValue);`
-*  For acceleration we add a constant to `accelerationValue` when the key is pressed, and substract it when the key is released. +
-`vehicle.accelerate(accelerationValue);`
-*  Because we can and it's fun, we also add a turbo booster that makes the vehicle jump when you press the assigned key (spacebar). +
-`vehicle.applyImpulse(jumpForce, Vector3f.ZERO);`
-
-[source,java]
-----
-public void onAction(String binding, boolean value, float tpf) {
-  if (binding.equals("Lefts")) {
-      if (value) { steeringValue += .5f; } else { steeringValue += -.5f; }
-      vehicle.steer(steeringValue);
-  } else if (binding.equals("Rights")) {
-      if (value) { steeringValue += -.5f; } else { steeringValue += .5f; }
-      vehicle.steer(steeringValue);
-  } else if (binding.equals("Ups")) {
-      if (value) {
-        accelerationValue += accelerationForce;
-      } else {
-        accelerationValue -= accelerationForce;
-      }
-      vehicle.accelerate(accelerationValue);
-  } else if (binding.equals("Downs")) {
-      if (value) { vehicle.brake(brakeForce); } else { vehicle.brake(0f); }
-  } else if (binding.equals("Space")) {
-      if (value) {
-        vehicle.applyImpulse(jumpForce, Vector3f.ZERO);
-      }
-  } else if (binding.equals("Reset")) {
-      if (value) {
-        System.out.println("Reset");
-        vehicle.setPhysicsLocation(Vector3f.ZERO);
-        vehicle.setPhysicsRotation(new Matrix3f());
-        vehicle.setLinearVelocity(Vector3f.ZERO);
-        vehicle.setAngularVelocity(Vector3f.ZERO);
-        vehicle.resetSuspension();
-      } else {
-    }
-  }
-}
-----
-
-For your reference, this is how we initialized the constants for this example:
-
-[source,java]
-----
-
-private final float accelerationForce = 1000.0f;
-private final float brakeForce = 100.0f;
-private float steeringValue = 0;
-private float accelerationValue = 0;
-private Vector3f jumpForce = new Vector3f(0, 3000, 0);
-
-----
-
-Remember, the standard input listener code that maps the actions to keys can be found in the code samples.
-
-
-== Detecting Collisions
-
-Read the <<jme3/advanced/physics#responding_to_a_physicscollisionevent,Responding to a PhysicsCollisionEvent>> chapter in the general physics documentation on how to detect collisions. You would do this if you want to react to collisions with custom events, such as adding points or substracting health.
-
-
-== Best Practices
-
-This example shows a very simple but functional vehicle. For a game you would implement steering behaviour and acceleration with values that are typical for the type of vehicle that you want to simulate. Instead of a box, you load a chassis model. You can consider using an <<jme3/advanced/input_handling#,AnalogListener>> to respond to key events in a more sophisticated way.
-
-For a more advanced example, look at link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/bullet/TestFancyCar.java[TestFancyCar.java].

+ 0 - 173
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/scenegraph/level_of_detail.adoc

@@ -1,173 +0,0 @@
-= Level of Detail (LOD) Optimization
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-:experimental:
-:uri-jme3: https://github.com/jMonkeyEngine/jmonkeyengine/blob/master
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-A mesh with a high level of detail has lots of polygons and looks good close up. But when the mesh is further away (and the detail is not visible), the high-polygon count slows down performance unnecessarily.
-
-One solution for this problem is to use high-detail meshes for objects close to the camera, and low-detail meshes for objects far from the camera. As the player moves through the scene, you must keep replacing close objects by more detailed meshes, and far objects by less detailed meshes. The goal is to keep few high-quality slow-rendering objects in the foreground, and many low-quality fast-rendering objects in the background. (Experienced users can compare this approach to <<jme3/advanced/terrain#,JME's TerraMonkey terrain system>>, which internally uses the specialized GeoMipMapping algorithm to generate a terrain's Levels of Detail.)
-
-You see now why you may want to be able to generate Levels of Detail for complex Geometries automatically. JME3 supports a Java implementation of the Ogre engine's LOD generator (originally by Péter Szücs and Stan Melax): You use link:{uri-jme3}/jme3-core/src/tools/java/jme3tools/optimize/LodGenerator.java[jme3tools.optimize.LodGenerator] in conjunction with link:{uri-jme3}/jme3-core/src/main/java/com/jme3/scene/control/LodControl.java[com.jme3.scene.control.LodControl].
-
-For a demo, run link:{uri-jme3}/jme3-examples/src/main/java/jme3test/stress/TestLodGeneration.java[TestLodGeneration.java] from <<sdk/sample_code#,JmeTests>>, then press +/- and spacebar to experiment. The following screenshots show a monkey model with three reduced Levels of Detail:
-
-image::jme3/advanced/jmonkey-lod.gif[jmonkey-lod.gif,width="",height="",align="center"]
-
-
-
-== Usage
-
-To activate this optimization:
-
-.  Pick a reduction method and values for the Geometry. (Trial and error…)
-.  Generate LODs for the Geometry, either in the SDK or in code.
-.  Add an LOD control to the Geometry.
-
-
-== Pick Reduction Methods and Values
-
-There are several reduction methods to generate a low-polygon version from a high-polygon model. Don't worry, the reduction does not modify the original model.
-[cols="35,55,10", options="header"]
-|===
-
-a|Reduction Method
-a|Description
-a|Reduction Value
-
-a|LodGenerator.TriangleReductionMethod.COLLAPSE_COST
-a|Collapses polygon vertices from the mesh until the reduction cost (= amount of ugly artifacts caused) exceeds the given threshold.
-a|0.0f - 1.0f
-
-a|LodGenerator.TriangleReductionMethod.PROPORTIONAL
-a|Removes the given percentage of polygons from the mesh.
-a| 0.0f - 1.0f
-
-a|LodGenerator.TriangleReductionMethod.CONSTANT
-a|Removes the given number of polygons from the mesh.
-a| integer
-
-|===
-
-If you don't know which to choose, experiment. For example start by trying COLLAPSE_COST and .5f-.9f.
-
-
-== Generate LOD
-
-You must generate and cache several LODs for each mesh, ranging from many to few polygons. The LOD generator algorithm attempts to collaps vertices automatically, while avoiding ugly artifacts. The LOD generator doesn't generate new meshes, it only creates separate reduced index buffers for the more highly reduced levels.
-
-*  If you create geometries manually (3D models), use the SDK to generate LODs.
-*  If you create geometries programmatically, generate LODs from your Java code.
-
-
-=== Generating LODs in the SDK
-
-The SDK contains a user-friendly interface to generate LODs for a model (.j3o file).
-
-.  Open the Projects or Files window.
-.  Select the .j3o file in the `Project Assets/Models` directory.
-.  Choose `menu:Window[Edit in SceneExplorer]` if the SceneExplorer is not open. Info about the selected model is now displayed in the SceneExplorer.
-.  btn:[RMB] select the model in SceneExplorer. Choose the `menu:Tools[Generate Levels of Detail]` menu. +
-image:jme3/advanced/jme-sdk-generate-lod-menu.png[The Tools Generate LOD context menu in the SceneExplorer,width="300",height="180"]
-.  The `Generate LOD` settings wizard opens: +
-image:jme3/advanced/jme-sdk-generate-lod-window.png[The Generate LOD settings wizard,width="300",height="150"]
-.  Choose a reduction method and reduction values for one or more levels.
-+
-[TIP]
-====
-Enter higher reduction values for higher levels.
-====
-
-.  Click btn:[Finish] to generate the LODs for this model.
-
-The LODs are saved in the .j3o model file.
-
-
-[TIP]
-====
-Choose `menu:Window[Properties]` if the Properties window is not open. Choose the generated LODs from the dropdown in the Properties window, and verify their quality in the SceneComposer.
-====
-
-
-
-image::jme3/advanced/jme-sdk-generate-lod-full.png[jme-sdk-generate-lod-full.png,width="",height="",align="center"]
-
-
-
-=== Generating LODs in Code
-
-The `jme3tools.optimize.LodGenerator` utility class helps you generate LODs for an arbitrary mesh (a Geometry object) programmatically from your Java code. You create and bake one LodGenerator for each Geometry.
-
-[source,java]
-----
-LodGenerator lod = new LodGenerator(geometry);
-lod.bakeLods(reductionMethod,reductionValue);
-----
-
-The LODs are stored inside the Geometry object.
-
-*Example:* How to generate an LOD of myPrettyGeo's mesh with the same settings as used in the SDK example above:
-
-[source,java]
-----
-LodGenerator lod = new LodGenerator(myPrettyGeo);
-lod.bakeLods(LodGenerator.TriangleReductionMethod.PROPORTIONAL,0.25, 0.5f, 0.75f);
-----
-
-
-== Activate the LOD Control
-
-After generating the LODs for the geometry, you create and add a `com.jme3.scene.control.LodControl` to the geometry. Adding the LodControl activates the LOD optimizaton for this geometry.
-
-[source,java]
-----
-LodControl lc = new LodControl();
-myPrettyGeo.addControl(lc);
-rootNode.attachChild(myPrettyGeo);
-----
-
-The LodControl internally gets the camera from the game's viewport to calculate the distance to this geometry. Depending on the distance, the LodControl selects an appropriate level of detail, and passes more (or less) detailed vertex data to the renderer.
-
-
-== Impact on Quality and Speed
-[cols="10,30,20,20,20", options="header"]
-|===
-
-a|Level number
-a|Purpose
-a|Distance
-a|Rendering Speed
-a|Rendering Quality
-
-a|Level 0
-a|The original mesh is used automatically for close-ups, and it's the default if no LODs have been generated.
-a|Closest
-a|Slowest.
-a|Best.
-
-a|Level 1 +
-Level 2 +
-Level 3
-a|If you generated LODs, JME3 uses them automatically as soon as the object moves into the background.
-a|The higher the level, +
-the further away.
-a|The higher the level, +
-the faster.
-a|The higher the level, +
-the lower the quality.
-
-|===
-
-
-== See also
-
-*  link:https://hub.jmonkeyengine.org/t/brand-new-lod-generator/26341[https://hub.jmonkeyengine.org/t/brand-new-lod-generator/26341]
-*  link:https://github.com/worldforge/ember/tree/master/src/components/ogre/lod[https://github.com/worldforge/ember/tree/master/src/components/ogre/lod]
-*  link:http://www.melax.com/polychop[http://www.melax.com/polychop]
-*  link:http://sajty.elementfx.com/progressivemesh/GSoC2012.pdf[http://sajty.elementfx.com/progressivemesh/GSoC2012.pdf]
-*  <<jme3/advanced/terrain#,JME3 TerraMonkey Terrain>>

+ 0 - 166
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/scenegraph/mesh.adoc

@@ -1,166 +0,0 @@
-= Polygon Meshes
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:keywords: spatial, node, mesh, geometry, scenegraph
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-image::jme3/dolphin-mesh.png[dolphin-mesh.png,width="",height="",align="right"]
-
-
-All visible game elements in a scene, whether it is a Model or a Shape, are made up of polygon meshes. JME3 has a http://javadoc.jmonkeyengine.org/com/jme3/scene/Mesh.html[com.jme3.scene.Mesh] class that represents all meshes.
-
-*  Meshes are made up of triangles: `getTriangleCount(…)` and `getTriangle(…)`
-*  Each mesh has a unique ID: `getId()`
-*  Meshes have transformations: Location (local translation), rotation, scale.
-*  Meshes have a bounding volume. jME3 can detect intersections (that is, non-physical collisions) between meshes, or between meshes and 2D elements such as rays: `collideWith()`.
-*  Meshes are locked with `setStatic()` and unlocked with `setDynamic()`.
-**  Static Meshes cannot be modified, but are more optimized and faster (they can be precalculated).
-**  Dynamic Meshes can be modified live, but are not optimized and slower.
-
-
-You have several options when <<jme3/advanced/spatial#,creating Geometries from meshes>>:
-
-*  Use built-in <<jme3/advanced/shape#,Shape>>s as meshes;
-*  Load <<jme3/advanced/3d_models#,3D models>> (that is, meshes created in external applications); or
-*  Create free-form <<jme3/advanced/custom_meshes#,custom meshes>> programmatically.
-
-
-== Vertex Buffer
-
-The VertexBuffer contains a particular type of geometry data used by Meshes. Every VertexBuffer set on a Mesh is sent as an attribute to the vertex shader to be processed.
-
-
-=== Mesh Vertex Buffers
-
-Here is the list of http://javadoc.jmonkeyengine.org/com/jme3/scene/VertexBuffer.Type.html[VertexBuffer] types.
-
-[cols="2", options="header"]
-|===
-
-a|Vertex Buffer Type
-a|Description
-
-a|Type.Position
-a|Position of the vertex (3 floats)
-
-a|Type.Index
-a| Specifies the index buffer, must contain integer data.
-
-a|Type.TexCoord
-a| Texture coordinate
-
-a|Type.TexCoord2
-a| Texture coordinate #2
-
-a|Type.Normal
-a| Normal vector, normalized.
-
-a|Type.Tangent
-a| Tangent vector, normalized.
-
-a|Type.Binormal
-a| Binormal vector, normalized.
-
-a|Type.Color
-a| Color and Alpha (4 floats)
-
-a|Type.Size
-a|The size of the point when using point buffers.
-
-a|Type.InterleavedData
-a| Specifies the source data for various vertex buffers when interleaving is used.
-
-a|Type.BindPosePosition
-a| Inital vertex position, used with animation.
-
-a|Type.BindPoseNormal
-a| Inital vertex normals, used with animation
-
-a|Type.BoneWeight
-a| Bone weights, used with animation
-
-a|Type.BoneIndex
-a| Bone indices, used with animation
-
-|===
-
-
-=== Mesh Properties
-
-Some Mesh properties from the http://javadoc.jmonkeyengine.org/com/jme3/scene/Mesh.html[Mesh] class.
-
-[cols="2", options="header"]
-|===
-
-a|Mesh method
-a|Description
-
-a|setBound(boundingVolume)
-a|if you need to specifiy a custom optimized bounding volume
-
-a|setStatic()
-a|Locks the mesh so you cannot modify it anymore, thus optimizing its data (faster).
-
-a|setDynamic()
-a|Unlocks the mesh so you can modified it, but this will un-optimize the data (slower).
-
-a|setMode(Mesh.Mode.Points)
-a|Used to set mesh rendering modes, see below.
-
-a|getId()
-a|returns the Mesh ID, default value is -1
-
-a|getTriangle(int,tri)
-a|returns data of triangle number `int` into variable `tri`
-
-a|scaleTextureCoordinates(Vector2f)
-a|How the texture will be stretched over the whole mesh.
-
-|===
-
-
-=== Mesh Rendering Modes
-
-Here is the list of http://javadoc.jmonkeyengine.org/com/jme3/scene/Mesh.Mode.html[Mesh rendering modes].
-
-[cols="2", options="header"]
-|===
-
-a|Mesh Mode
-a|Description
-
-a|Mesh.Mode.Points
-a|Show only corner points (vertices) of mesh
-
-a|Mesh.Mode.Lines
-a|Show lines (edges) of mesh
-
-a|Mesh.Mode.LineLoop
-a|?
-
-a|Mesh.Mode.LineStrip
-a|?
-
-a|Mesh.Mode.Triangles
-a|?
-
-a|Mesh.Mode.TriangleStrip
-a|?
-
-a|Mesh.Mode.TriangleFan
-a|?
-
-a|Mesh.Mode.Hybrid
-a|?
-
-|===
-
-
-=== Level of Detail
-
-Optionally, custom meshes can have a LOD (level of detail optimization) that renders more or less detail, depending on the distance of the mesh from the camera. You have to specify several vertex buffers, one for each level of detail you want (very far away with few details, close up with all details, and something in the middle). Use `setLodLevels(VertexBuffer[] lodLevels)`.

+ 0 - 190
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/scenegraph/shape.adoc

@@ -1,190 +0,0 @@
-= Shapes
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: spatial, node, mesh, geometry, scenegraph
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-The simplest type of Meshes are the built-in JME Shapes. You can create Shapes without using the AssetManager.
-
-
-== 3D shapes
-
-
-[.float-group]
---
-[.right.text-left]
-image::jme3/advanced/box.png[box.png,width="108",height=""]
-*  com.jme3.scene.shape.Box – A cube or cuboid. Single-sided Quad faces (outside only). 
-*  com.jme3.scene.shape.StripBox – A cube or cuboid. Solid filled faces (inside and outside).
---
-
-[.float-group]
---
-[.right.text-left]
-image::jme3/advanced/cylinder.png[cylinder.png,width="108",height=""]
-*  com.jme3.scene.shape.Cylinder – A disk or pillar.
---
-
-[.float-group]
---
-[.right.text-left]
-image::jme3/advanced/sphere.png[sphere.png,width="108",height=""]
-*  com.jme3.scene.shape.Sphere – A ball or elipsoid. 
---
-
-[.float-group]
---
-[.right.text-left]
-image::jme3/advanced/dome.png[dome.png,width="108",height=""]
-*  com.jme3.scene.shape.Dome – A semi-sphere, e.g. SkyDome.
---
-
-[.float-group]
---
-[.right.text-left]
-image::jme3/advanced/cone.png[cone.png,width="108",height=""]
-*  For a cone, set the Dome's radialSamples&gt;4 and planes=2. 
---
-
-[.float-group]
---
-[.right.text-left]
-image::jme3/advanced/pyramid.png[pyramid.png,width="108",height=""]
-*  For a pyramid, set the Dome's radialSamples=4 and planes=2. 
---
-
-[.float-group]
---
-[.right.text-left]
-image::http://i204.photobucket.com/albums/bb19/mike_ch_1/torus.png[Torus,width="108",height="80"]
-*  com.jme3.scene.shape.Torus – An single-holed torus or “donut.
---
-
-[.float-group]
---
-[.right.text-left]
-image::jme3/advanced/220px-trefoil_knot_arb.png[PQ torus knoz,width="108",height="80"]
-*  com.jme3.scene.shape.PQTorus – A parameterized torus. A PQ-Torus looks like a link:http://en.wikipedia.org/wiki/Torus_knot[donut knotted into spirals].
---
-
-[.float-group]
---
-[.right.text-left]
-image::jme3/advanced/nurbs_3-d_surface.png[NURBS surface,width="108",height="80"]
-*  com.jme3.scene.shape.Surface – A curved surface (called link:http://en.wikipedia.org/wiki/File:NURBS_3-D_surface.gif[NURBS]) described by knots, weights and control points. Compare with shape.Curve.
---
-
-
-== Non-3D shapes
-
-*  com.jme3.scene.shape.Quad – A flat 2D rectangle (single-sided, center is in bottom-left corner)
-*  com.jme3.scene.shape.Line – A straight 1D line defined by a start and end point.
-*  com.jme3.scene.shape.Curve – A curved 1D spline. Compare with shape.Surface.
-
-
-=== com.jme3.math versus com.jme3.shape?
-
-Do not mix up these visible com.jme3.shapes with similarly named classes from the com.jme3.math package. Choose the right package when letting your IDE fill in the import statements!
-
-*  com.jme3.math.Line – is invisible, has a direction, goes through a point, infinite length.
-*  com.jme3.math.Ray – is invisible, has a direction and start point, but no end.
-*  com.jme3.math.Spline – is an invisible curve.
-*  etc
-
-These maths objects are invisible and are used for collision testing (ray casting) or to describe motion paths. They cannot be wrapped into a Geometry.
-
-
-== Usage
-
-
-=== Basic Usage
-
-To add a shape to the scene:
-
-.  Create the base mesh shape.
-.  Wrap the mesh into a Geometry.
-.  Assign a Material to the Geometry.
-.  Attach the Geometry to the rootNode to make it visible.
-
-
-[TIP]
-====
-Create one static shape as mesh and use it in several geometries, or clone() the geometries.
-====
-
-
-
-=== Complex Shapes
-
-You can compose more complex custom Geometries out of simple Shapes. Think of the buildings in games like Angry Birds, or the building blocks in Second Life (“prims) and in Tetris (“Tetrominos).
-
-.  Create a Node. By default it is located at the origin (0/0/0) – leave the Node there for now.
-.  Create your shapes and wrap each into a Geometry, as just described.
-.  Attach each Geometry to the Node.
-.  Arrange the Geometries around the Node (using `setLocalTranslation()`) so that the Node is in the center of the new constellation. The central Node is the pivot point for transformations (move/scale/rotate).
-.  Move the pivot Node to its final location in the scene. Moving the pivot Node moves the attached constellation of Geometries with it.
-
-The order is important: First arrange around origin, then transform. Otherwise, transformations are applied around the wrong center (pivot). Of course, you can attach your constellation to other pivot Nodes to create even more complex shapes (a chair, a furnished room, a house, a city, …), but again, arrange them around the origin first before you transform them. Obviously, such composed Geometries are simpler than hand-sculpted meshes from a mesh editor.
-
-
-== Code Examples
-
-Create the Mesh shape:
-
-[source,java]
-----
-Sphere mesh = new Sphere(32, 32, 10, false, true);
-----
-
-[source,java]
-----
-Dome mesh = new Dome(Vector3f.ZERO, 2, 4, 1f,false); // Pyramid
-----
-
-[source,java]
-----
-Dome mesh = new Dome(Vector3f.ZERO, 2, 32, 1f,false); // Cone
-----
-
-[source,java]
-----
-Dome mesh = new Dome(Vector3f.ZERO, 32, 32, 1f,false); // Small hemisphere
-----
-
-[source,java]
-----
-Dome mesh = new Dome(Vector3f.ZERO, 32, 32, 1000f,true); // SkyDome
-----
-
-[source,java]
-----
-PQTorus mesh = new PQTorus(5,3, 2f, 1f, 32, 32); // Spiral torus
-----
-
-[source,java]
-----
-PQTorus mesh = new PQTorus(3,8, 2f, 1f, 32, 32); // Flower torus
-----
-
-Use one of the above examples together with the following geometry in a scene:
-
-[source,java]
-----
-
-Geometry geom = new Geometry("A shape", mesh); // wrap shape into geometry
-Material mat = new Material(assetManager,      
-    "Common/MatDefs/Misc/ShowNormals.j3md");   // create material
-geom.setMaterial(mat);                         // assign material to geometry
-// if you want, transform (move, rotate, scale) the geometry.
-rootNode.attachChild(geom);                    // attach geometry to a node
-
-----
-
-
-== See also
-
-* <<jme3/intermediate/optimization#,Optimization>> – The GeometryBatchFactory class combines several of your shapes with the same texture into one mesh with one texture.

+ 0 - 220
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/scenegraph/spatial.adoc

@@ -1,220 +0,0 @@
-= Spatial
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:keywords: spatial, node, mesh, geometry, scenegraph
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-This is an introduction to the concept of Spatials, the elements of the 3D scene graph. The scene graph is a data structure that manages all objects in your 3D world. For example, the scene graph keeps track of the 3D models that you load and position. When you extend a Java class from com.jme3.app.SimpleApplication, you automatically inherit the scene graph and its rootNode.
-
-The rootNode is the central element of the scene graph. Even if the scene graph is empty, it always contains at least the rootNode. We _attach_ Spatials to the rootNode. Attached Spatials are always in a _parent-child relationship_. Every time you attach a Spatial to something, it is implicitly detached from its previous parent. A Spatial can have only one parent. A Spatial can have several children.
-
-If you think you need to understand the scene graph concept better, please read <<jme3/scenegraph_for_dummies#,Scenegraph for dummies>> first.
-
-
-== Node versus Geometry
-
-In your Java code, a Spatial is either an instance of `com.jme3.scene.Node` or a `com.jme3.scene.Geometry` instance. You use the two types of Spatials for different purposes:
-
-
-image::jme3/intermediate/scene-graph.png[scene-graph.png,width="",height="",align="center"]
-
-[cols="10,45,45", options="header"]
-|===
-
-a|
-2+a|com.jme3.scene.Spatial
-
-a| Purpose:
-2+a| A Spatial is an abstract data structure that stores user data and transformations (= translation, rotation, scale) of elements of the 3D scene graph. Spatials can be saved and loaded using the <<jme3/advanced/asset_manager#,Asset Manager>>.
-
-<a|
-a| com.jme3.scene.Geometry
-a| com.jme3.scene.Node
-
-a| Visibility:
-a| A Geometry represents a *visible* 3D object in the scene graph.
-a| A Node is an *invisible “handle* for a group of Spatials in the scene graph.
-
-<a| Purpose:
-a| Use Geometries to represent an object's *look*: Every Geometry contains a polygon mesh and a material, specifying its shape, color, texture, and opacity/transparency. +
-You attach Geometries to Nodes.
-a| Use Nodes to *structure and group* Geometries and other Nodes. Every Node is attached to one parent node, and each node can have zero or more children (Nodes or Geometries) attached to itself. +
-*When you transform (move, rotate, etc) a parent node, all its children are transformed (moved, rotated, etc).*
-
-<a| Content:
-<a| Transformations; custom user data; +
-mesh and material;
-a| Transformations; custom user data; +
-no mesh, no material.
-
-<a| Examples:
-a| Box, sphere, player, building, terrain, vehicle, missiles, NPCs, etc…
-a| rootNode, guiNode, audioNode, a custom grouping node such as vehicleNode or shipNode with passengers attached, etc.
-
-|===
-
-
-[IMPORTANT]
-====
-You never create a Spatial with `+++<strike>Spatial s = new Spatial();</strike>+++`! A Spatial is an abstract concept, like a mammal (there is no actual creature called “mammal walking around here). You create either a com.jme3.scene.Node or com.jme3.scene.Geometry instance. Some methods, however, require a `Spatial` type as argument: This is because they are able to accept both Nodes and Geometries as arguments. In this case, you simply _cast_ a Node or Geometry to Spatial.
-====
-
-
-
-=== Mesh
-
-The polygon <<jme3/advanced/mesh#,Mesh>> inside a Geometry can be one of three things:
-
-*  *Shapes:* The simplest type of Meshes are jME's default <<jme3/advanced/shape#,Shape>>s such as cubes and spheres. You can use several Shapes to build complex Geometries. Shapes are built-in and can be created without using the AssetManager.
-*  *3D Models:* <<jme3/advanced/3d_models#,3D models and scenes>> are also made up of meshes, but are more complex than Shapes. You create Models and Scenes in external 3D Mesh Editors and export them as Ogre XML or Wavefront OBJ. Use the <<jme3/advanced/asset_manager#,Asset Manager>> to load models into a your jME3 game.
-*  *Custom Meshes:* Advanced users can create <<jme3/advanced/custom_meshes#,Custom Meshes>> programmatically.
-
-
-== What is a Clone?
-
-Cloned spatials share the same mesh, while each cloned spatial can have its own local transformation (translation, rotation, and scale) in the scene. This means you only use `clone()` on spatials whose meshes never change. The most common use case for cloning is when you use several Spatials that are based on the same <<jme3/advanced/shape#,Shape>>s (e.g. trees, crates).
-
-The second use case is: When you load a model using `loadModel()` from the AssetManager, you may automatically get a `clone()`ed object. In particular:
-
-*  If the model is not animated (it has no `<<jme3/advanced/animation#,AnimControl>>`), jME loads a clone. All clones share one mesh object in order to use less memory.
-*  If the model is animated (it has a `<<jme3/advanced/animation#,AnimControl>>`), then `loadModel()` duplicates the mesh for each loaded instance. (Uses more memory, but can animate.)
-
-Usually there is no need to manually use any of the `clone()` methods on models. Using the <<jme3/advanced/asset_manager#,Asset Manager>>'s `loadModel()` method will automatically do the right thing for your models.
-
-
-[NOTE]
-====
-“Box worlds are not made up of statically cloned `Box()` shapes, this would still be too slow for large worlds. To learn how to make real fast box worlds, search the web for _voxelization_ techniques.
-====
-
-
-
-== How to Add Fields and Methods to a Spatial
-
-You can include custom user data –that is, custom Java objects and methods– in Nodes and Geometries. This is very useful for maintaining information about a game element, such as health, budget, ammunition, inventory, equipment, etc for players, or landmark locations for terrains, and much more.
-
-
-[IMPORTANT]
-====
-You want to add custom accessor methods to a spatial? Do not extend `Node` or `Geometry`, use <<jme3/advanced/custom_controls#,Custom Controls>> instead. You want to add custom fields to a spatial? Do not extend `Node` or `Geometry`, use the built-in `setUserData()` method instead. Where ever the Spatial is accessible, you can easily access the object's class fields (user data) and accessors (control methods) this way.
-====
-
-
-This first example adds an integer field named `health` to the Spatial `playerNode`, and initializes it to 100.
-
-[source,java]
-----
-playerNode.setUserData("health", 100);
-----
-
-The second example adds a set of custom accessor methods to the player object. You create a <<jme3/advanced/custom_controls#,custom PlayerControl() class>> and you add this control to the Spatial:
-
-[source,java]
-----
-playerNode.addControl(new PlayerControl());
-----
-
-In your PlayerControl() class, you define custom methods that set and get your user data in the `spatial` object. For example, the control could add accessors that set and get the player's health:
-
-[source,java]
-----
-
-public int getHealth() {
-  return (Integer)spatial.getUserData("health");
-}
-public void setHealth(int h) {
-  spatial.setUserData("health",h);
-}
-
-----
-
-Elsewhere in your code, you can access this data wherever you have access to the Spatial `playerNode`.
-
-[source,java]
-----
-
-health = playerNode.getControl(PlayerControl.class).getHealth();
-...
-playerNode.getControl(PlayerControl.class).setHealth(99);
-
-----
-
-*  You can add as many data objects (of String, Boolean, Integer, Float, Array types) to a Spatial as you want. Just make sure to label them with unique case-sensitive strings (`health`, `Inventory`, `equipment`, etc).
-*  The saved data can even be a custom Java object if you make the custom Java class <<jme3/advanced/save_and_load#custom_savable_class,implement the Savable interface>>!
-*  When you save a Spatial as a .j3o file, the custom data is saved, too, and all Savables are restored the next time you load the .j3o!
-
-This is how you list all data keys that are already defined for one Spatial:
-
-[source,java]
-----
-for(String key : spatial.getUserDataKeys()){
-    System.out.println(spatial.getName()+"'s keys: "+key);
-}
-----
-
-
-== How to Access a Named Sub-Mesh
-
-Often after you load a scene or model, you need to access a part of it as an individual Geometry in the scene graph. Maybe you want to swap a character's weapon, or you want to play a door-opening animation. First you need to know the unique name of the sub-mesh.
-
-.  Open the model in a 3D mesh editor, or in the jMonkeyEngine SDK's Scene Composer.
-.  Find out the existing names of sub-meshes in the model.
-.  Assign unique names to sub-meshes in the model if neccessary.
-
-In the following example, the Node `house` is the loaded model. The sub-meshes in the Node are called its children. The String, here `door 12`, is the name of the mesh that you are searching.
-
-[source,java]
-----
-
-Geometry submesh = (Geometry) houseScene.getChild("door 12");
-
-----
-
-
-== What is Culling?
-
-There are two types of culling: Face culling, and view frustrum culling.
-
-*Face culling* means not drawing certain polygons of a mesh. Face culling behaviour is a property of the material.
-
-Usage: The “inside of a mesh (the so called backface) is typically never visible to the player, and as an optimization, the `Back` mode skips calculating all backfaces by default. Activating the `Off` or `Front` modes can be useful when you are debugging <<jme3/advanced/custom_meshes#,custom meshes>> and try to identify accidental inside-out faces.
-
-You can switch the com.jme3.material.RenderState.FaceCullMode to either:
-
-*  `FaceCullMode.Back` (default) – Only the frontsides of a mesh are drawn. Backface culling is the default behaviour.
-*  `FaceCullMode.Front` – Only the backsides of a mesh are drawn. A mesh with frontface culling will most likely be invisible. Used for debugging “inside-out custom meshes.
-*  `FaceCullMode.FrontAndBack` – Use this to make a mesh temporarily invisible.
-*  `FaceCullMode.Off` – Every side of the mesh is drawn. Looks normal, but slows down large scenes.
-
-Example:
-
-[source,java]
-----
-material.getAdditionalRenderState().setFaceCullMode(FaceCullMode.FrontAndBack);
-----
-
-*View frustum culling* refers to not drawing (and not even calculating) certain whole models in the scene. At any given moment, half of the scene is behind the player and out of sight anyway. View frustum culling is an optimization to not calculate scene elements that are not visible – elements that are “outside the view frustrum.
-
-The decision what is visible and what not, is done automatically by the engine (`CullHint.Dynamic`). Optionally, you can manually control whether the engine culls individual spatials (and children) from the scene graph:
-
-*  `CullHint.Dynamic` – Default, faster because it doesn't waste time with objects that are out of view.
-*  `CullHint.Never` – Calculate and draw everything always (even if it does not end up on the user's screen because it's out of sight). Slower, but can be used while debugging custom meshes.
-*  `CullHint.Always` – The whole spatial is culled and is not visible. A fast way to hide a Spatial temporarily. Culling a Spatial is faster then detaching it, but it uses more memory.
-*  `CullHint.Inherit` – Inherit culling behaviour from parent node.
-
-Example:
-
-[source,java]
-----
-spatial.setCullHint(CullHint.Never); // always drawn
-----
-
-
-== See also
-
-*  <<jme3/intermediate/optimization#,Optimization>> – The GeometryBatchFactory class batches several Geometries into meshes with each their own texture.
-*  <<jme3/advanced/traverse_scenegraph#,Traverse SceneGraph>> – Find any Node or Geometry in the scenegraph.

+ 0 - 71
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/scenegraph/traverse_scenegraph.adoc

@@ -1,71 +0,0 @@
-= Traverse the SceneGraph
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:keywords: spatial, node, mesh, geometry, scenegraph
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-You can run a search across the whole scene graph and search for individual Spatials (`Nodes` and `Geometry`s) by custom criteria, such as the Spatial's name, or the Spatial's class, or the Spatial's user data, or Spatial's Controls. You do this when you want modify  the found nodes (move them, call a method, etc) but you don't have a local variable for them.
-
-
-== Example Use Cases
-
-*Example 1:*
-
-.  You have created a procedural scene with lots of dynamically generated elements.
-.  You want to find individual Spatials under ever-changing conditions and modify their state. 
-
-*Example 2:*
-
-.  You created a mostly static scene in the jMonkeyEngine SDK and exported it as .j3o file. +
-The scene also contains interactive objects, for example a particle emitter, spatials with user data, or spatials with custom controls. 
-.  You load the .j3o scene using the assetManager. 
-.  You want to interact with one of the loaded interactive scene elements in your Java code. +
-For example, you want to call `emitAllParticles()` on the particle emitter. Or you want to find all NPC's Geometries with a custom CivilianControl, and call the CivilianControl method that makes them start acting their role.
-
-In this case, you can use a SceneGraphVisitorAdapter to identify and access the Spatials in question.
-
-
-== Code Sample
-
-For each search, you create a `com.jme3.scene.SceneGraphVisitorAdapter` that defines your search criteria and what you want to do with the found Spatials. Then you call the `depthFirstTraversal(visitor)` or `breadthFirstTraversal(visitor)` method of the Spatial (e.g. the rootNode, or better, a subnode) to start the search.
-
-[source,java]
-----
-
-SceneGraphVisitor visitor = new SceneGraphVisitor() {
-
-  @Override
-  public void visit(Spatial spat) {
-    // search criterion can be control class:
-    MyControl control = spatial.getControl(MyControl.class);
-    if (control != null) {
-      // you have access to any method, e.g. name.
-      System.out.println("Instance of " + control.getClass().getName() 
-                       + " found for " + spatial.getName());
-    }
-  }
-
-};
-  
-// Now scan the tree either depth first...
-rootNode.depthFirstTraversal(visitor);
-// ... or scan it breadth first.
-rootNode.breadthFirstTraversal(visitor);
-
-----
-
-Which of the two methods is faster depends on how you designed the scengraph, and what tree element you are looking for. If you are searching for one single Geometry that is a “leaf of the tree, and then stop searching, depth-first may be faster. If you search for a high-level grouping Node, breadth-first may be faster. 
-
-The choice of depth- vs breadth-first also influences the order in which found elements are returned (children first or parents first). If you want to modify user data that is inherited from the parent node (e.g. transformations), the order of application is important, because the side-effects add up.
-
-You can use the SceneGraphVisitorAdapter class to scan separately for Geometry and Nodes.
-
-
-== See Also
-
-*  <<jme3/the_scene_graph#,The Scene Graph>>
-*  <<jme3/advanced/spatial#,Spatial>>

+ 0 - 24
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/screenshots.adoc

@@ -1,24 +0,0 @@
-= Taking Screenshots
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-The com.jme3.app.state.ScreenshotAppState enables your users to take screenshots of the running game.
-
-You activate this feature as follows in your simpleInitApp() method:
-
-[source,java]
-----
-
-ScreenshotAppState screenShotState = new ScreenshotAppState();
-this.stateManager.attach(screenShotState);
-
-----
-
-The default screenshot key is KeyInput.KEY_SYSRQ, alos known as “System Request / Print Screen key. On Mac keyboards, this key does not exist, so on Mac +++<abbr title="Operating System">OS</abbr>+++ you take screenshots using Command+Shift+3 (fullscreen) or Command+Shift+4 (windowed: press space to select a window and then click).
-
-The screenshot is saved to the user directory.

+ 0 - 82
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/script/groovy/ai.adoc

@@ -1,82 +0,0 @@
-= ai
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../../
-:imagesdir: ../../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== Finite State Machine
-
-What is the most simple but affective techique to make AI. It's FSM
-emoji:
-
-[source,java]
-----
-code
-----
-
-
-== Decision Tree
-
-Builder emoji:
-
-[source,java]
-----
-code
-----
-
-
-== Pattern Matching
-
-Regexp emoji:
-
-[source,java]
-----
-code
-----
-
-
-== Simple Chatbot
-
-Builder + Closure 
-emoji:
-
-[source,java]
-----
-code
-----
-
-
-== Simple Goalbase Agent
-
-emoji:
-
-[source,java]
-----
-code
-----
-
-
-== Simple Path finding
-
-Use Groovy extension 
-
-emoji:
-
-[source,java]
-----
-code
-----
-
-
-== Simple Steering behavior
-
-emoji:
-
-[source,java]
-----
-code
-----

+ 0 - 53
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/script/groovy_basicscripts.adoc

@@ -1,53 +0,0 @@
-= groovy_basicscripts
-:author: 
-:revnumber: 
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-Rotate the wheel
-
-[source,java]
-----
-code
-----
-
-+++<u>Explain:</u>+++
-
-Travel a tree
-
-[source,java]
-----
-code
-----
-
-+++<u>Explain:</u>+++
-
-Queue a task
-
-[source,java]
-----
-code
-----
-
-+++<u>Explain:</u>+++
-
-GroovyAppState
-
-[source,java]
-----
-code
-----
-
-+++<u>Explain:</u>+++
-
-ClosureCondition
-
-[source,java]
-----
-code
-----
-
-+++<u>Explain:</u>+++

+ 0 - 129
src/docs/asciidoc/zh-Hans-CN/jme3/advanced/script/groovy_event.adoc

@@ -1,129 +0,0 @@
-= groovy_event
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-
-== Event - Trigger - Manager
-
-Event , Trigger , Manager are the 3 most important terms in game programming and scripting that worth to mention in the first place!
-
-
-=== Event
-
-Event is the core element (concept) and the unit of the Messaging System. When components in the game world communicate with each other through pipelines, Messages from one object need to be sent to other objects should also aware of it (to nofity) when some thing happen that. It's called an event; and inside of the event contain piece of imformations that describe the Message.
-
-If Scripting, Event play important role too. It's almost shown up in EventHook to the cycle as: onInit, onUpdate, onClick.. It also provide ad-hoc communicate which in turn enable additional complex and flexible usage to existed systems. We will go deep into its usages later.
-
-
-==== EventBus
-
-Event paradigm is implemented differently in every software that require it, to fit with the specific requirements. Recently we (Java world) have something quite generic that suite for wide range of cases and use intuitive methods to program. It's called EventBus. And fortunately , EventBus fit very well with Groovy scripting solution (kudos!)
-
-…and few Event concepts Explained!
-
-link:http://code.google.com/p/guava-libraries/wiki/EventBusExplained[http://code.google.com/p/guava-libraries/wiki/EventBusExplained]
-
-link:http://codingjunkie.net/guava-eventbus/[http://codingjunkie.net/guava-eventbus/]
-
-
-==== Groovy Eventbus HelloWorld
-
-[source,java]
-----
-
-import com.google.common.eventbus.EventBus
-import com.google.common.eventbus.Subscribe
-
-EventBus eventBus = new EventBus();
-
-class EventHandler{
-    @Subscribe
-    public void hello(CustomEvent event){
-        println "Hello world"
-    }
-}
-
-class CustomEvent{
-
-}
-handler = new EventHandler();
-eventBus.register(handler);
-
-eventBus.post(new CustomEvent());
-
-----
-
-In this example,
-
-Here, EventBus will play the communicate media in our Groovy scripting solution.
-
-
-==== Hooks
-
-
-=== Trigger
-
-If you build up your game world's activites from Action, Trigger is the brick to build Gameplay. It's the combination of : Event + Condition → Action
-
-The concept of trigger can be describle like this: When an Event happen, if it's passed a Condition check, the Action is taken. A more detailed description envolve: the Enviroment - a specific Context of those 3 (E - C - A), Durations , Threaded or not, Executor … But here we concern the most simple form, the Context is the single specific that procedure the Event and its Global awareness.
-
-In Groovy,
-
-*  Event is Class based, mentioned in the chapter above.
-*  Condition can be modeled with a Closure
-*  Action also very suitable with a Closure representation.
-
-
-==== Example1:
-
-[source,java]
-----
-
-Example1:
-
-----
-
-
-===== Example2:
-
-[source,java]
-----
-
-Example2:
-
-----
-
-
-=== Manager
-
-Manager is the concept of who have responsibities and power over others (as its children or employee in the real world), essentially it is a list of its children, and have basic opertions like add,remove to manage that list… You can also think about it as the Control of the MVC paradigm where it is the mediator between Model and View. In JME3, you see Manager every where such as AssetManager, StateManager as the wraper of underlying functions. So, event mixed up quite a lot concepts at once, Manager in Scripting is extremely useful and fullfill the missing piece of the picture we are painting for a while here.
-
-To clean the mist of confusion about mixed of concepts a little bit, there are some practical wisdoms about Manager implementation:
-
-*  Manager acts globally, handy: usually a Singleton, or really easy to reference in script
-**  Manager wrap underlying details in intuitive way
-**  Manager share common informations
-**  Manager executions are frequently : like in an default update cycle
-**  Manager have power over its children : its handle it children; in almost scenarios child has left its Manager's list come hollow (as null)
-
-All the concepts and wisdoms is describes much more detail in Atom framework Design <<jme3/advanced/atom_framework/design#, Game architecture &amp; Design>>
-
-
-=== GQuery
-
-GQuery stand for “JQuery like in Groovy. JQuery is a famous framework in the JavaScript and Web world. GQuery try to provide some of its features, immtimate its syntax and sugars, leverage by Groovy:
-
-*  Query, select a Node Tree (like +++<abbr title="HyperText Markup Language">HTML</abbr>+++, Nifty elements,…) with a minimal Path syntax , same as XPath
-*  Hooks to Node's (components, elements..) events with Eventbus
-
-GQuery is a part of my additions for NiftyGUI, others are:
-
-*  a Groovy builder
-*  a +++<abbr title="Cascading Style Sheets">CSS</abbr>+++ (Cascaded Style Sheet) implementation (for NiftyGUI), even a LESS
-*  a simplier Localization framework
-*  a lot of scripting and functional sugar for NiftyGUI

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott