Sfoglia il codice sorgente

Joint fixes:
- Reworked joint body transform calculation so it's more intuitive and matches the joint gizmo display
- Fixed joint gizmo display so it doesn't show lines past the joint body limits
- Fixed joint internal data so it's properly serialized
Fixed Gizmo drawing so it properly clears old transform before starting new gizmo drawing
Finished architecture and GUI manuals
Fixed working directories for the OptimizedDebugBuild

BearishSun 9 anni fa
parent
commit
916f246010

+ 8 - 0
Build/VS2015/BansheeEditorExec.vcxproj.user

@@ -24,4 +24,12 @@
     <LocalDebuggerWorkingDirectory>..\..\bin\x86\$(Configuration)\</LocalDebuggerWorkingDirectory>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='OptimizedDebug|Win32'">
+    <LocalDebuggerWorkingDirectory>..\..\bin\x86\$(Configuration)\</LocalDebuggerWorkingDirectory>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='OptimizedDebug|x64'">
+    <LocalDebuggerWorkingDirectory>..\..\bin\x64\$(Configuration)\</LocalDebuggerWorkingDirectory>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
 </Project>

+ 8 - 0
Build/VS2015/Game.vcxproj.user

@@ -24,4 +24,12 @@
     <LocalDebuggerWorkingDirectory>..\..\bin\x64\$(Configuration)\</LocalDebuggerWorkingDirectory>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='OptimizedDebug|Win32'">
+    <LocalDebuggerWorkingDirectory>..\..\bin\x86\$(Configuration)\</LocalDebuggerWorkingDirectory>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='OptimizedDebug|x64'">
+    <LocalDebuggerWorkingDirectory>..\..\bin\x64\$(Configuration)\</LocalDebuggerWorkingDirectory>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
 </Project>

+ 1 - 1
Documentation/Doxygen/Native.doxyconfig

@@ -926,7 +926,7 @@ EXAMPLE_RECURSIVE      = NO
 # that contain images that are to be included in the documentation (see the
 # \image command).
 
-IMAGE_PATH             = 
+IMAGE_PATH             = ../Manuals/Native/Images
 
 # The INPUT_FILTER tag can be used to specify a program that doxygen should
 # invoke to filter for each input file. Doxygen will invoke the filter program

+ 4 - 0
Documentation/Doxygen/doxystyle.css

@@ -24,6 +24,10 @@ h3 {
 	border-bottom: 1px dashed #CD8512;
 }
 
+.textblock {
+	padding-bottom: 25px;
+}
+
 /* Nav bar */
 .tabs, .tabs2, .tabs3 {
 	background-color: #ffb750;

BIN
Documentation/Manuals/Native/Images/Architecture.png


BIN
Documentation/Manuals/Native/Images/ArchitectureSimple.png


+ 54 - 62
Documentation/Manuals/Native/architecture.md

@@ -2,7 +2,7 @@ Architecture									{#architecture}
 ===============
 [TOC]
 
-This manual will show you the general architecture of Banshee, to give you a better idea of how everything is structured and where to locate particular systems.
+This manual will explain the architecture of Banshee, to give you a better idea of how everything is structured and where to locate particular systems.
 
 Banshee is implemented throughout many separate libraries. Spreading the engine implementation over different libraries ensures multiple things:
  - Portions of the engine can be easily modified or replaced
@@ -12,97 +12,89 @@ Banshee is implemented throughout many separate libraries. Spreading the engine
  
 All the libraries can be separated into four main categories:
  - Layers - These are the core libraries of the engine. Each layer is built on top of the previous layer and provides higher level and more specific functionality than the other.
- - Plugins - These are separate, independant, and in most cases optional libraries containing various high level systems. They always depend on a specific layer, depending how high level the system they implement is. You will be able to design your own plugins that completely replace certain portion of the engine functionality without having to modify the engine itself (e.g. use OpenGL instead of DirectX)
+ - Plugins - These are separate, independant, and in most cases optional libraries containing various high level systems. They always depend on a specific layer, depending how high level the system they implement is. You are able to design your own plugins that completely replace certain portion of the engine functionality without having to modify the engine itself (e.g. use OpenGL instead of DirectX)
  - Scripting - These are libraries used for interop between the C++ core and the scripting language, as well as the managed scripting libraries themselves. Generally these can also be counted as plugins, but they are a bit more tightly coupled with the engine core.
  - Executable - These are small pieces of code meant to initialize and start up the engine/editor.
  
+To give you a better idea here is a diagram showing how all the libraries connect:
+![Banshee's libraries](ArchitectureSimple.png)  
+ 
 # Layers #										{#arch_layers}
 The layers contain the core of the engine. All the essentials and all the abstract interfaces for plugins belong here. The engine core was split into multiple layers for two reasons:
- - To give developers a chance to pick the level of functionality they need. Some people will want just core and utility and start working on their own engine while others might be just interested in game development and will stick with the editor layer.
- - To decouple code. Lower layers do not know about higher levels and low level code never caters to specialized high level code. This makes the design cleaner and forces a certain direction for dependencies.
+ - To give developers a chance to pick the level of functionality they need. Some people will want just core and utility and start working on their own engine or low level technologies, while others might be just interested in game development and will stick with the editor layer.
+ - To decouple code. Lower layers do not know about higher layers and low level code never caters to specialized high level code. This makes the design cleaner and forces a certain direction for dependencies.
 
-Lower levels were designed to be more general purpose than higher levels. They provide very general techniques usually usable in various situations, and they attempt to cater to everyone. On the other hand higher levels provide a lot more focused and specialized techniques. This might mean relying on very specific rendering APIs, platforms or plugins but it also means using newer, fancier and maybe not as widely accepted techniques (e.g. some new rendering algorithm or a shader).
+Lower layers were designed to be more general purpose than higher layers. They provide very general techniques usually usable in various situations, and they attempt to cater to everyone. On the other hand higher layers provide a lot more focused and specialized techniques. This might mean relying on very specific rendering APIs, platforms or plugins but it also means using newer, fancier and maybe not as widely accepted techniques (e.g. some new rendering algorithm or a shader).
 
 Going from the lowest to highest the layers are:
-## BansheeUtility ##							{#arch_utility}
-This is the lowest layer of the engine. It is a collection of very decoupled and separate systems that are likely to be used throughout all of the higher layers. Essentially a collection of tools that are in no way tied into a larger whole. Most of the functionality isn't even game engine specific, like providing file-system access, file path parsing or events. Other things that belong here are the math library, object serialization and RTTI system, threading primitives and managers, among various others.
+## BansheeUtility ##					
+This is the lowest layer of the engine. It is a collection of very decoupled and separate systems that are likely to be used throughout all of the higher layers. Essentially a collection of tools that are in no way tied into a larger whole. Most of the functionality isn't even game engine specific, like providing [file-system access](@ref BansheeEngine::FileSystem), [file path parsing](@ref BansheeEngine::Path), [events](@ref BansheeEngine::Event), [math library](@ref BansheeEngine::Math), [RTTI system](@ref BansheeEngine::RTTITypeBase), [threading primitives and managers](@ref BansheeEngine::ThreadPool), among various others.
+
+See the [utilities](@ref utilities) manual for an overview of all the most important systems in this layer. 
 
-## BansheeCore ##								{#arch_core}
-It is the second lowest layer and the first layer that starts to take shape of an actual engine. This layer provides some very game-specific modules tied into a coherent whole, but it tries to be very generic and offer something that every engine might need instead of focusing on very specialized techniques. Render API wrappers exist here, but actual render APIs are implemented as plugins so you are not constrained by specific subset. Scene manager, renderer, resource management, audio, animation, physics, importers and others all belong here, and all are implemented in an abstract way that they can be implemented/extended by higher layers or plugins.
+## BansheeCore ##		
+This layer builds upon the utility layer by providing abstract interfaces for most of the engine systems. The interfaces themselves are implemented in the form of plugins, and are not part of the layer itself (for the most part). This layer glues all the engine's systems together and provides a foundation that the engine is built on. The layer tries to be generic and include only functionality that is common, while leaving more specialized functionality for higher layers. Some systems provided by this layer are @ref BansheeEngine::RenderAPI "render API wrapper", @ref BansheeEngine::Resources "resource management", @ref BansheeEngine::Importer "asset import", @ref BansheeEngine::Input "input", @ref BansheeEngine::Physics "physics" and more.
 
-## BansheeEngine ##								{#arch_engine}
-Second highest layer and first layer with a more focused goal. It is built upon BansheeCore but relies on a specific sub-set of plugins and implements systems like scene manager and renderer in a specific way. For example DirectX 11 and OpenGL render systems are referenced by name, as well as Mono scripting system among others. Renderer that follows a specific set of techniques and algorithms that determines how are all objects rendered also belongs here.
+## %BansheeEngine ##				
+This layer builds upon the abstraction provided by the core layer and provides actual implementations of the core layer interfaces. Since most of the interfaces are implemented as plugins this layer doesn't contain too much of its own code, but is rather in charge of linking everything together. Aside from linking plugins together it also contains some specialized code, like the @ref BansheeEngine::GUIManager "GUI" and @ref BansheeEngine::ScriptManager "script" managers, as well as various other functionality that was not considered generic enough to be included in the core layer.
 
-## BansheeEditor ##								{#arch_editor}
-And finally the top layer is the editor. It provides various editor specific features like the project library, built systems, editor window systems, scene view tools and similar. Large portions of the editor are implemented in the scripting code, and this layer provides more of a set of helper tools used by the scripting system. If you are going to work with this layer you will also be working closely with the scripting interop code and the scripting code.
+## BansheeEditor ##					
+And finally the top layer is the editor. It builts upon everything else so far and provides various editor specific features like the project library, build system, editor window management, scene view tools and similar. Large portions of the editor are implemented in the scripting code, and this layer provides more of a set of helper tools used by the scripting system. If you are going to work with this layer you will also be working closely with the scripting interop code and the scripting code (see below).
 
 # Plugins #										{#arch_plugins}
-Banshee provides a wide variety of plugins out of the box. Some of these are fully optional, but all can be replaced with your own implementations. Each plugin is based on an abstract interface implemented in one of the layers (for the most part, BansheeCore and BansheeEngine layers).
+Banshee provides a wide variety of plugins out of the box. The plugins are loaded dynamically and allow you to change engine functionality completely transparently to other systems (e.g. you can choose to load an OpenGL renderer instead of a DirectX one). Some plugins are completely optional and you can choose to ignore them (e.g. importer plugins can usually be ignored for game builds). Most importantly the plugins segregate the code, ensuring the design of the engine is decoupled and clean. Each plugin is based on an abstract interface implemented in one of the layers (for the most part, BansheeCore and %BansheeEngine layers).
 
 ## Render API ##								{#arch_rapi}		
-Render API plugins allow you to use a different backend for performing hardware accelerated rendering. Render API handles low level rendering, including features like vertex/index buffers, creating rasterizer/depth/blend states, shader programs, render targets, textures, draw calls and similar. Render API interface is defined in the BansheeCore layer.
-
-A few out of the box implementations are provided, the user can choose which one to use upon application startup. At least one must be present during start-up (can be a null renderer (i.e. one that does nothing, like for server purposes) if you choose to add one).
-
-### BansheeD3D11RenderAPI ###					{#arch_dx11rapi}
-Provides implementation of the Render API interface for DirectX 11. 
+Render API plugins allow you to use a different backend for performing hardware accelerated rendering. @ref BansheeEngine::RenderAPI "RenderAPI" handles low level rendering, including features like vertex/index buffers, creating rasterizer/depth/blend states, shader programs, render targets, textures, draw calls and similar. See the [render API](@ref renderAPI) manual to learn more about it.
 
-### BansheeD3D9RenderAPI ###					{#arch_dx9rapi}
-Provides implementation of the RenderAPI interface for DirectX 9. 
-
-### BansheeGLRenderAPI ###						{#arch_GLrapi}
-Provides implementation of the RenderAPI interface for OpenGL 4.3.
+The following plugins all have their own implementations of the @ref BansheeEngine::RenderAPI "RenderAPI" interface, as well as any related types (e.g. @ref BansheeEngine::VertexBuffer "VertexBuffer", @ref BansheeEngine::IndexBuffer "IndexBuffer"):
+ - **BansheeD3D11RenderAPI** - Provides implementation of the @ref BansheeEngine::RenderAPI "RenderAPI" interface for DirectX 11. 
+ - **BansheeD3D9RenderAPI**	- Provides implementation of the @ref BansheeEngine::RenderAPI "RenderAPI" interface for DirectX 9. 
+ - **BansheeGLRenderAPI** - Provides implementation of the @ref BansheeEngine::RenderAPI "RenderAPI" interface for OpenGL 4.3.
 
 ## Importers ##									{#arch_importers}		
-Importers allow you to convert various types of files into formats easily readable by the engine. Normally importers are only used during development (e.g. in the editor), but the game itself will only use previously imported assets (although ultimately that's up to the user).
-
-All importers implement a relatively simple interface represented by a single SpecificImporter class. The engine can start with zero importers, or with as many as you need.
-
-See [this link](TODOLINK) on a guide how to add your own importer. Some important importers are provided out of the box:
+Importers allow you to convert various types of files into formats easily readable by the engine. Normally importers are only used during development (e.g. in the editor), and the game itself will only use previously imported assets (although ultimately that's up to the user).
 
-### BansheeFreeImgImporter ###					{#arch_freeimg}	
-Handles import of most popular image formats, like .png, .psd, .jpg, .bmp and similar. It uses the FreeImage library for reading the image files and converting them into engine Texture format.
-
-### BansheeFBXImporter ###						{#arch_fbx}
-Handles import of FBX mesh files. Uses Autodesk FBX SDK for reading the files and converting them into engine Mesh format.
-
-### BansheeFontImporter ###						{#arch_font}
-Handles import of TTF and OTF font files. Uses FreeType for reading the font files and converting them into engine Font format.
-
-### BansheeSL ###								{#arch_bsl}	
-Provides an implementation of the Banshee's shader language that allows you to easily define an entire pipeline state in a single file.
+All importers implement a relatively simple interface represented by the @ref BansheeEngine::SpecificImporter "SpecificImporter" class. The engine can start with zero importers, or with as many as you need. See the [importer](@ref customImporters) manual to learn more about importers and how to create your own. Some important importers are provided out of the box:
+ - **BansheeFreeImgImporter** - Handles import of most popular image formats, like .png, .psd, .jpg, .bmp and similar. It uses the FreeImage library for reading the image files and converting them into engine's @ref BansheeEngine::Texture "Texture" format.
+ - **BansheeFBXImporter** - Handles import of FBX mesh files. Uses Autodesk FBX SDK for reading the files and converting them into engine's @ref BansheeEngine::Mesh "Mesh" format.
+ - **BansheeFontImporter** - Handles import of TTF and OTF font files. Uses FreeType for reading the font files and converting them into engine's @ref BansheeEngine::Font "Font" format.
+ - **BansheeSL** - Provides an implementation of the Banshee's shader language that allows you to easily define an entire pipeline state in a single file. Imports .bsl files into engine's @ref BansheeEngine::Shader "Shader" format.
 
 ## Others ##									{#arch_others}
 
-### BansheeOISInput ###							{#arch_ois}		
-Handles raw mouse/keyboard/gamepad input for multiple platforms. Implements the RawInputHandler interface. Uses the OIS library specifically modified for Banshee (source code available with Banshee's dependencies). Be aware that there is also an OSInputHandler that is used for non-game specific purposes (e.g. tracking cursor, text input), but that is part of the engine core instead of a plugin.
+### BansheeOISInput ###							{#arch_ois}
+Handles raw mouse/keyboard/gamepad input for multiple platforms. All input plugins implement the @ref BansheeEngine::RawInputHandler "RawInputHandler" interface. Uses the OIS library specifically modified for Banshee (source code available with Banshee's dependencies). 
 
-### BansheePhysX ###							{#arch_physx}
-Handles physics: rigidbodies, colliders, triggers, joints, character controller and similar. Implements the Physics interface (and all related classes). Uses NVIDIA PhysX as the backend.
+Be aware that there is also an @ref BansheeEngine::OSInputHandler "OSInputHandler" that is used for non-game specific purposes (e.g. tracking cursor, text input), but that is part of the engine core instead of a plugin.
 
-### BansheeMono ###								{#arch_mono}
-Provides access to the C# scripting language using the Mono runtime. All the script interop libraries (listed below) depend on this plugin, as well as a specific engine layer.
+### BansheePhysX ###				
+Handles physics: rigidbodies, colliders, triggers, joints, character controller and similar. Implements the @ref BansheeEngine::Physics "Physics" interface and any related classes (e.g. @ref BansheeEngine::Rigidbody "Rigidbody", @ref BansheeEngine::Collider "Collider"). Uses NVIDIA PhysX as the backend.
 
-### RenderBeast ###								{#arch_rbeast}	
-Banshee's default renderer. Implements the Renderer interface. This plugin might seem similar to the Render API plugins mentioned above but it is a higher level system. While Render API plugins provide low level access to rendering functionality the renderer handles rendering of all scene objects in a specific manner without having to issue draw calls manually. A specific set of options can be configured, both globally and per object that control how an object is rendered, as well as specifying completely custom materials. e.g. the renderer will handle physically based rendering, HDR, shadows, global illumination and similar features.
+### BansheeMono ###					
+Provides access to the C# scripting language using the Mono runtime. This allows the C++ code to call into C# code, and vice versa, as well as providing various meta-data about the managed code, and other functionality. All the script interop libraries (listed below) depend on this plugin. See the [scripting](@ref scripting) manual to learn more about this layer.
 
-See [this link](TODOLINK) for more information on how the renderer works and how to potentially implement your own.
+### RenderBeast ###					
+Banshee's default renderer. Implements the @ref BansheeEngine::Renderer "Renderer" interface. This plugin might seem similar to the render API plugins mentioned above but it is a higher level system. While render API plugins provide low level access to rendering functionality the renderer handles rendering of all scene objects in a specific manner without requiring the developer to issue draw calls manually. A specific set of options can be configured, both globally and per object that control how an object is rendered, as well as specifying completely custom materials. e.g. the renderer will handle physically based rendering, HDR, shadows, global illumination and similar features.
+
+See the [renderer](@ref renderer) manual to learn more about how the renderer works and how to implement your own.
 
 # Scripting #									{#arch_scripting}
 Scripting libraries can be placed into two different categories: 
- - Interop libraries written in C++. These provide glue code between C++ and C# (e.g. converting types, managing objects and similar). These are prefixed with the letter S.
- - Managed libraries containing actual managed code. These are prefixed with the letter M.
- 
-Whenever adding a new type that exists in both script and managed code you will need to access both of these library categories. Read [this guide](TODOLINK) to learn more about adding your own scripting types.
+ - Interop libraries written in C++. These provide glue code between C++ and C# (e.g. converting types, managing objects and similar). These are prefixed with the letter *S*.
+ - Managed libraries containing actual managed code. These are prefixed with the letter *M*.
  
-## SBansheeEngine ##							{#arch_sengine}
-Interop library that provides glue code between BansheeEngine layer and the scripting code in MBansheeEngine.
+Whenever adding a new type that exists in both script and managed code you will need to access both of these library categories. Read the [scripting](@ref scripting) manual to learn about exposing C++ code to scripts.
 
-## SBansheeEditor ##							{#arch_seditor}	
-Interop library that provides glue code between BansheeEditor layer and the scripting code in MBansheeEditor.
+Interop libraries:
+ - **SBansheeEngine** - Provides glue code between %BansheeEngine layer and the scripting code in MBansheeEngine.
+ - **SBansheeEditor** - Provides glue code between BansheeEditor layer and the scripting code in MBansheeEditor.
 
-## MBansheeEngine ##							{#arch_mengine}
-Provides most of the high-level C++ engine API available in BansheeEngine layer (e.g. scene object model, resources, GUI, materials, etc.) as a high-level C# scripting API. Certain portions of the API are provided in pure C# (like the math library).
+Managed assemblies:
+ - **MBansheeEngine**	- Provides most of the high-level C++ engine API available in %BansheeEngine layer (e.g. scene object model, resources, GUI, materials, etc.) as a high-level C# scripting API. Certain portions of the API are provided in pure C# (like the math library) while most just wrap their C++ counterparts.
+ - **MBansheeEditor** - Provides all editor specific functionality from the BansheeEditor layer as a C# scripting API (e.g. project library, building, scene view, etc.). Also implements a large number of editor features in pure C# on top of the provided engine and editor APIs (e.g. specific editor windows and tools).
+ 
+# Complete architecture #			{#arch_complete}
+See the diagram below to give you a better idea of the full architecture of Banshee. The diagram is not complete, but rather meant as a way to qive you a rough idea of where everything is, to make it easier to navigate the engine.
 
-## MBansheeEditor ##							{#arch_meditor}
-Provides all editor specific functionality from the BansheeEditor layer as a C# scripting API (e.g. project library, building, scene view, etc.). Also implements a large number of editor features in pure C# on top of the provided engine and editor APIs (e.g. specific editor windows and tools).
+![Architecture](@ref Architecture.png) 

+ 7 - 7
Documentation/Manuals/Native/gui.md

@@ -4,7 +4,7 @@ Creating custom GUI elements						{#customGUI}
 
 Sometimes the built-in GUI elements are just not enough, for example when you need a very specific GUI element for your game (e.g. for displaying graphs, charts), want to use a special material or in general just need some more customization options. While in some cases you could construct such elements from the provided GUI elements, it is often more efficient to create a brand new customized type. New GUI elements can be created relatively easily and allow you to fully customize the look and interaction with your element.
 
-Before staring you should familiarize yourself how Banshee's GUI works from the users perspective. Make sure to read the scripting GUI manual to understand the basics (although the manual is for scripting, the C++ versions of these methods are essentially equivalent and the same concepts apply).
+Before starting you should familiarize yourself how Banshee's GUI works from the users perspective. Make sure to read the scripting GUI manual to understand the basics (although the manual is for scripting, the C++ versions of these methods are essentially equivalent and the same concepts apply).
 
 All GUI elements derive from the base @ref BansheeEngine::GUIElementBase "GUIElementBase" type. The elements can be categorized into two major groups:
  - GUILayout: They derive from @ref BansheeEngine::GUILayout "GUILayout" and do not have any graphics, but instead they control the placement of all elements attached to them.
@@ -18,7 +18,7 @@ When creating a custom GUI element you will need to override the @ref BansheeEng
  - @ref BansheeEngine::GUIElement::_getNumRenderElements() "_getNumRenderElements()" - Return the number of separate elements that your GUIElement consists of. Each element has its own mesh, material and texture. In most cases there is only one element.
  - @ref BansheeEngine::GUIElement::_getNumQuads() "_getNumQuads()" - Returns the number of quads for the mesh of the render element at the specified index (e.g. one quad if the GUI element displays just one texture). This allows external systems to know how big of a buffer to allocate for the element's mesh.
  - @ref BansheeEngine::GUIElement::_fillBuffer() "_fillBuffer()" - This is the meat of the `GUIElement` override. It allows you to fill a buffer with vertices, uv coordinates and indices for a mesh for the specified render element. This allows you to fully control the look of your GUI element by providing customized geometry.
- - @ref BansheeEngine::GUIElement::_getMaterial() "_getMaterial()" - Here you should return a material that will be applied to the mesh output in the previous method. You can choose from a few pre-built material types and provide a texture and a color. If you wish to add a new custom material, check later in this guide.
+ - @ref BansheeEngine::GUIElement::_getMaterial() "_getMaterial()" - Here you should return a material that will be applied to the mesh output in the previous method. You can choose from a few pre-built material types and provide a texture and a color. 
  - @ref BansheeEngine::GUIElement::updateRenderElementsInternal() "updateRenderElementsInternal()" - Called whenever the element's size or style changes. In this method you should rebuild the element's mesh. (While you could build the mesh in `_fillBuffer` it is inefficient as `_fillBuffer` will get called much more often than `updateRenderElementsInternal` due to mesh batching).
  
 In order to help you with creating GUI meshes and materials make sure to take a look at @ref BansheeEngine::ImageSprite "ImageSprite" and @ref BansheeEngine::TextSprite "TextSprite" classes. `ImageSprite` can easily generate image geometry of specified size, whether a simple quad or a scale-9-grid image. And `TextSprite` will take a text string, font and additional options as input, and output a set of quads required for text rendering.
@@ -40,19 +40,19 @@ You should also provide a style-name for your element. This is a string that wil
 If you implemented everything so far you should have a functional GUIElement that has a custom look, but it still doesn't accept any input. In order to accept input you must override some or all of the following methods:
  - @ref BansheeEngine::GUIElement::_mouseEvent "GUIElement::_mouseEvent" - Triggered when the mouse moves and/or is clicked
  - @ref BansheeEngine::GUIElement::_textInputEvent "GUIElement::_textInputEvent" - Triggered when the user inputs some text on the keyboard
- - @ref BansheeEngine::GUIElement::_virtualButtonEvent "GUIElement::_virtualButtonEvent" - Triggered when a certain virtual button is pressed (see [Input guide](@ref input) if you wish to know about virtual buttons)
- - @ref BansheeEngine::GUIElement::_commandEvent "GUIElement::_commandEvent" - Triggers when some kind of a specialized event happens, like losing/gainging focus, deleting text, selecting text, forcing redraw and similar. See @ref BansheeEngine::GUICommandEventType "GUICommandEventType" for an explanation of what each does.
+ - @ref BansheeEngine::GUIElement::_virtualButtonEvent "GUIElement::_virtualButtonEvent" - Triggered when a certain virtual button is pressed.
+ - @ref BansheeEngine::GUIElement::_commandEvent "GUIElement::_commandEvent" - Triggers when some kind of a specialized event happens, like losing/gaining focus, deleting text, selecting text, forcing redraw and similar. See @ref BansheeEngine::GUICommandEventType "GUICommandEventType" for an explanation of what each event type does.
  
 Check out `_mouseEvent` implementation in @ref BansheeEngine::GUIButtonBase "GUIButtonBase" for a simple implementation of a mouse hover on/off and click functionality. Check @ref BansheeEngine::GUIInputBox "GUIInputBox" for a more complex implementation of input.
 
-If working with text input also take a look at @ref BansheeEngine::GUIInputCaret "GUIInputCaret" and @ref BansheeEngine::GUIInputSelection "GUIInputSelection", as they help with input caret movement, and text selection. Instances of these classes can be accessed from @ref BansheeEngine::GUIManager "GUIManager" with @ref BansheeEngine::GUIManager::getInputCaretTool() "getInputCaretTool()" and @ref BansheeEngine::GUIManager::getInputSelectionTool() "getInputSelectionTool()". This is completely optional and you may choose to handle these manually. See @ref BansheeEngine::GUIInputBox "GUIInputBox" for example usage.
+If working with text input also take a look at @ref BansheeEngine::GUIInputCaret "GUIInputCaret" and @ref BansheeEngine::GUIInputSelection "GUIInputSelection", as they help with input caret movement and text selection. Instances of these classes can be accessed from @ref BansheeEngine::GUIManager "GUIManager" with @ref BansheeEngine::GUIManager::getInputCaretTool() "getInputCaretTool()" and @ref BansheeEngine::GUIManager::getInputSelectionTool() "getInputSelectionTool()". This is completely optional and you may choose to handle these manually. See @ref BansheeEngine::GUIInputBox "GUIInputBox" for example usage.
 
 # Updating # {#customGUI_d}
 
-If your element allows the user to update certain contents of it after creation (i.e. it's not static), you need to notify the GUI system so it knows when to rebuild the element. For example if your GUI element displays a text string you might provide a `setText` method that allows the user to change what is displayed. When that is done the GUI system will need to update the batched GUI mesh, update the GUI elements mesh and/or update the layout position/size of the element.
+If your element allows the user to update certain contents of it after creation (i.e. it's not static), you need to notify the GUI system so it knows when to rebuild the element. For example if your GUI element displays a text string you might provide a `setText` method that allows the user to change what is displayed. When that is done the GUI system will need to update the batched GUI mesh, update the GUI element's mesh and/or update the layout position/size of the element.
 
 There are three ways to notify the GUI system the element is dirty, each more expensive in performance than the previous:
- - @ref BansheeEngine::GUIElement::_markMeshAsDirty() "_markMeshAsDirty()" - Causes the batched GUI mesh to be re-assembled, will cause a call to `_fillBuffer`. Call this if element's size didn't change (e.g. when its position, or depth changes). Batched GUI mesh is a mesh managed by the GUI system that consists of multiple GUI elements sharing the same material properties.
+ - @ref BansheeEngine::GUIElement::_markMeshAsDirty() "_markMeshAsDirty()" - Causes the batched GUI mesh to be re-assembled, will cause a call to `_fillBuffer`. Call this if element's size didn't change (e.g. when its position, or depth changes). Batched GUI mesh is a mesh managed by the GUI system that consists of multiple GUI elements sharing the same material properties (used to improve rendering performance).
  - @ref BansheeEngine::GUIElement::_markContentAsDirty() "_markContentAsDirty()" - Has the same effect as `_markMeshDirty()`, but will also trigger an `updateRenderElementsInternal` call so the GUI element mesh will be fully rebuilt. Call this when contents of the GUI element change, but not its size (e.g. changing a texture but it is the same dimensions as the old one.)
  - @ref BansheeEngine::GUIElement::_markLayoutAsDirty() "_markLayoutAsDirty()" - Has the same effect as `_markContentDirty()`, but will also cause the layout system to recalculate the element's position and size. This can be very expensive as this will generally trigger layout updates for all siblings and children, potentially even parent GUI elements. Call this when element changes and no other dirty calls are appropriate. Normally you have to call this whenever the element's size changes.
 

+ 2 - 1
Source/BansheeCore/Include/BsFJoint.h

@@ -15,7 +15,8 @@ namespace BansheeEngine
 	/** Specifies first or second body referenced by a Joint. */
 	enum class JointBody
 	{
-		A, B
+		Target, /**< Body the joint is influencing. */
+		Anchor /**< Body the joint is attached to (if any). */
 	};
 
 	/** @} */

+ 14 - 17
Source/BansheeCore/Source/BsCJoint.cpp

@@ -178,8 +178,8 @@ namespace BansheeEngine
 		if (gPhysics()._isUpdateInProgress())
 			return;
 
-		updateTransform(JointBody::A);
-		updateTransform(JointBody::B);
+		updateTransform(JointBody::Target);
+		updateTransform(JointBody::Anchor);
 	}
 
 	void CJoint::restoreInternal()
@@ -194,8 +194,8 @@ namespace BansheeEngine
 		else
 			mDesc.bodies[1].body = nullptr;
 
-		getLocalTransform(JointBody::A, mDesc.bodies[0].position, mDesc.bodies[0].rotation);
-		getLocalTransform(JointBody::B, mDesc.bodies[1].position, mDesc.bodies[1].rotation);
+		getLocalTransform(JointBody::Target, mDesc.bodies[0].position, mDesc.bodies[0].rotation);
+		getLocalTransform(JointBody::Anchor, mDesc.bodies[1].position, mDesc.bodies[1].rotation);
 
 		mInternal = createInternal();
 
@@ -219,9 +219,9 @@ namespace BansheeEngine
 			return;
 
 		if (mBodies[0] == body)
-			updateTransform(JointBody::A);
+			updateTransform(JointBody::Target);
 		else if (mBodies[1] == body)
-			updateTransform(JointBody::B);
+			updateTransform(JointBody::Anchor);
 		else
 			assert(false); // Not allowed to happen
 	}
@@ -252,20 +252,17 @@ namespace BansheeEngine
 		position = mPositions[(int)body];
 		rotation = mRotations[(int)body];
 
-		// Transform to world space of the related body
 		HRigidbody rigidbody = mBodies[(int)body];
-		if (rigidbody != nullptr)
+		if (rigidbody == nullptr) // Get world space transform if no relative to any body
 		{
-			Quaternion worldRot = rigidbody->SO()->getWorldRotation();
+			Quaternion worldRot = SO()->getWorldRotation();
 
-			rotation = worldRot * rotation;
-			position = worldRot.rotate(position) + rigidbody->SO()->getWorldPosition();
-
-			// Transform to space local to the joint
-			Quaternion invRotation = SO()->getWorldRotation().inverse();
-
-			position = invRotation.rotate(position - SO()->getWorldPosition());
-			rotation = invRotation * rotation;
+			rotation = worldRot*rotation;
+			position = worldRot.rotate(position) + SO()->getWorldPosition();
+		}
+		else
+		{
+			position = rotation.rotate(position);
 		}
 	}
 	

+ 1 - 0
Source/BansheeEditor/Source/BsGizmoManager.cpp

@@ -103,6 +103,7 @@ namespace BansheeEngine
 		if(mTransformDirty)
 		{
 			mTransform = Matrix4::IDENTITY;
+			mDrawHelper->setTransform(Matrix4::IDENTITY);
 			mTransformDirty = false;
 		}
 

+ 3 - 3
Source/BansheePhysX/Source/BsFPhysXJoint.cpp

@@ -11,7 +11,7 @@ namespace BansheeEngine
 {
 	PxJointActorIndex::Enum toJointActor(JointBody body)
 	{
-		if (body == JointBody::A)
+		if (body == JointBody::Target)
 			return PxJointActorIndex::eACTOR0;
 
 		return PxJointActorIndex::eACTOR1;
@@ -37,7 +37,7 @@ namespace BansheeEngine
 
 		mJoint->getActors(actorA, actorB);
 
-		PxRigidActor* wantedActor = body == JointBody::A ? actorA : actorB;
+		PxRigidActor* wantedActor = body == JointBody::Target ? actorA : actorB;
 		if (wantedActor == nullptr)
 			return nullptr;
 
@@ -55,7 +55,7 @@ namespace BansheeEngine
 		if (value != nullptr)
 			actor = static_cast<PhysXRigidbody*>(value)->_getInternal();
 
-		if (body == JointBody::A)
+		if (body == JointBody::Target)
 			actorA = actor;
 		else
 			actorB = actor;

+ 1 - 1
Source/BansheeSL/Include/BsLexerFX.h

@@ -349,7 +349,7 @@ extern int yylex \
 #undef YY_DECL
 #endif
 
-#line 390 "../../../Source/BansheeSL/BsLexerFX.l"
+#line 390 "..\\..\\Source\\BansheeSL\\BsLexerFX.l"
 
 
 #line 356 "BsLexerFX.h"

+ 2 - 2
Source/BansheeSL/Include/BsParserFX.h

@@ -41,7 +41,7 @@ extern int yydebug;
 #endif
 /* "%code requires" blocks.  */
 /* Line 2579 of glr.c  */
-#line 9 "../../../Source/BansheeSL/BsParserFX.y"
+#line 9 "..\\..\\Source\\BansheeSL\\BsParserFX.y"
 
 #include "BsMMAlloc.h"
 #include "BsASTFX.h"
@@ -226,7 +226,7 @@ typedef struct YYLTYPE {
 typedef union YYSTYPE
 {
 /* Line 2579 of glr.c  */
-#line 73 "../../../Source/BansheeSL/BsParserFX.y"
+#line 73 "..\\..\\Source\\BansheeSL\\BsParserFX.y"
 
 	int intValue;
 	float floatValue;

File diff suppressed because it is too large
+ 172 - 172
Source/BansheeSL/Source/BsLexerFX.c


File diff suppressed because it is too large
+ 167 - 167
Source/BansheeSL/Source/BsParserFX.c


+ 1 - 1
Source/MBansheeEditor/Inspectors/DistanceJointInspector.cs

@@ -17,7 +17,7 @@ namespace BansheeEditor
         private GUIToggleField enableMinLimitField = new GUIToggleField(new LocEdString("Enable minimum limit"));
         private GUIFloatField minLimitField = new GUIFloatField(new LocEdString("Minimum distance"));
         private GUIToggleField enableMaxLimitField = new GUIToggleField(new LocEdString("Enable maximum limit"));
-        private GUIFloatField maxLimitField = new GUIFloatField(new LocEdString("Maximum maximum"));
+        private GUIFloatField maxLimitField = new GUIFloatField(new LocEdString("Maximum distance"));
         private GUIFloatField toleranceField = new GUIFloatField(new LocEdString("Tolerance"));
         private GUIToggleField enableSpringField = new GUIToggleField(new LocEdString("Enable spring"));
         private SpringGUI springGUI;

+ 20 - 20
Source/MBansheeEditor/Inspectors/JointInspector.cs

@@ -13,11 +13,11 @@ namespace BansheeEditor
     /// </summary>
     internal abstract class JointInspector : Inspector
     {
-        private GUIGameObjectField bodyAField = new GUIGameObjectField(typeof(Rigidbody), new LocEdString("Body A"));
-        private GUIVector3Field bodyAOffsetField = new GUIVector3Field(new LocEdString("Body A offset"));
+        private GUIGameObjectField targetField = new GUIGameObjectField(typeof(Rigidbody), new LocEdString("Target"));
+        private GUIVector3Field targetOffsetField = new GUIVector3Field(new LocEdString("Target offset"));
 
-        private GUIGameObjectField bodyBField = new GUIGameObjectField(typeof(Rigidbody), new LocEdString("Body B"));
-        private GUIVector3Field bodyBOffsetField = new GUIVector3Field(new LocEdString("Body B offset"));
+        private GUIGameObjectField anchorField = new GUIGameObjectField(typeof(Rigidbody), new LocEdString("Anchor"));
+        private GUIVector3Field anchorOffsetField = new GUIVector3Field(new LocEdString("Anchor offset"));
 
         private GUIFloatField breakForceField = new GUIFloatField(new LocEdString("Break force"));
         private GUIFloatField breakTorqueField = new GUIFloatField(new LocEdString("Break torque"));
@@ -31,11 +31,11 @@ namespace BansheeEditor
         /// <param name="joint">Joint to update the GUI from.</param>
         protected virtual void Refresh(Joint joint)
         {
-            bodyAField.Value = joint.GetRigidbody(JointBody.A);
-            bodyAOffsetField.Value = joint.GetPosition(JointBody.A);
+            targetField.Value = joint.GetRigidbody(JointBody.Target);
+            targetOffsetField.Value = joint.GetPosition(JointBody.Target);
 
-            bodyBField.Value = joint.GetRigidbody(JointBody.B);
-            bodyBOffsetField.Value = joint.GetPosition(JointBody.B);
+            anchorField.Value = joint.GetRigidbody(JointBody.Anchor);
+            anchorOffsetField.Value = joint.GetPosition(JointBody.Anchor);
 
             breakForceField.Value = joint.BreakForce;
             breakTorqueField.Value = joint.BreakTorque;
@@ -47,15 +47,15 @@ namespace BansheeEditor
         /// </summary>
         protected virtual void BuildGUI(Joint joint)
         {
-            bodyAField.OnChanged += x => { joint.SetRigidbody(JointBody.A, (Rigidbody)x); MarkAsModified(); ConfirmModify(); };
-            bodyAOffsetField.OnChanged += x => { joint.SetPosition(JointBody.A, x); MarkAsModified(); };
-            bodyAOffsetField.OnFocusLost += ConfirmModify;
-            bodyAOffsetField.OnConfirmed += ConfirmModify;
+            targetField.OnChanged += x => { joint.SetRigidbody(JointBody.Target, (Rigidbody)x); MarkAsModified(); ConfirmModify(); };
+            targetOffsetField.OnChanged += x => { joint.SetPosition(JointBody.Target, x); MarkAsModified(); };
+            targetOffsetField.OnFocusLost += ConfirmModify;
+            targetOffsetField.OnConfirmed += ConfirmModify;
 
-            bodyBField.OnChanged += x => { joint.SetRigidbody(JointBody.B, (Rigidbody)x); MarkAsModified(); ConfirmModify(); };
-            bodyBOffsetField.OnChanged += x => { joint.SetPosition(JointBody.B, x); MarkAsModified(); };
-            bodyBOffsetField.OnFocusLost += ConfirmModify;
-            bodyBOffsetField.OnConfirmed += ConfirmModify;
+            anchorField.OnChanged += x => { joint.SetRigidbody(JointBody.Anchor, (Rigidbody)x); MarkAsModified(); ConfirmModify(); };
+            anchorOffsetField.OnChanged += x => { joint.SetPosition(JointBody.Anchor, x); MarkAsModified(); };
+            anchorOffsetField.OnFocusLost += ConfirmModify;
+            anchorOffsetField.OnConfirmed += ConfirmModify;
 
             breakForceField.OnChanged += x => { joint.BreakForce = x; MarkAsModified(); };
             breakForceField.OnFocusLost += ConfirmModify;
@@ -67,10 +67,10 @@ namespace BansheeEditor
 
             collisionField.OnChanged += x => { joint.EnableCollision = x; MarkAsModified(); ConfirmModify(); };
             
-            Layout.AddElement(bodyAField);
-            Layout.AddElement(bodyAOffsetField);
-            Layout.AddElement(bodyBField);
-            Layout.AddElement(bodyBOffsetField);
+            Layout.AddElement(targetField);
+            Layout.AddElement(targetOffsetField);
+            Layout.AddElement(anchorField);
+            Layout.AddElement(anchorOffsetField);
             Layout.AddElement(breakForceField);
             Layout.AddElement(breakTorqueField);
             Layout.AddElement(collisionField);

+ 14 - 14
Source/MBansheeEditor/Windows/Scene/Gizmos/JointGizmos.cs

@@ -47,8 +47,8 @@ namespace BansheeEditor
         [DrawGizmo(DrawGizmoFlags.Selected | DrawGizmoFlags.ParentSelected)]
         private static void DrawFixedJoint(FixedJoint joint)
         {
-            Vector3 anchorA = GetAnchor(joint, JointBody.A);
-            Vector3 anchorB = GetAnchor(joint, JointBody.B);
+            Vector3 anchorA = GetAnchor(joint, JointBody.Target);
+            Vector3 anchorB = GetAnchor(joint, JointBody.Anchor);
 
             Gizmos.Color = Color.White;
             Gizmos.DrawSphere(anchorA, 0.05f);
@@ -65,8 +65,8 @@ namespace BansheeEditor
         [DrawGizmo(DrawGizmoFlags.Selected | DrawGizmoFlags.ParentSelected)]
         private static void DrawDistanceJoint(DistanceJoint joint)
         {
-            Vector3 anchorA = GetAnchor(joint, JointBody.A);
-            Vector3 anchorB = GetAnchor(joint, JointBody.B);
+            Vector3 anchorA = GetAnchor(joint, JointBody.Target);
+            Vector3 anchorB = GetAnchor(joint, JointBody.Anchor);
 
             Gizmos.Color = Color.White;
             Gizmos.DrawSphere(anchorA, 0.05f);
@@ -101,7 +101,7 @@ namespace BansheeEditor
             }
 
             Gizmos.Color = Color.Green;
-            Gizmos.DrawLine(anchorA + normal * min, anchorA + normal * max);
+            Gizmos.DrawLine(anchorA + normal * min, anchorA + normal * MathEx.Min(max, length));
         }
 
         /// <summary>
@@ -111,8 +111,8 @@ namespace BansheeEditor
         [DrawGizmo(DrawGizmoFlags.Selected | DrawGizmoFlags.ParentSelected)]
         private static void DrawSliderJoint(SliderJoint joint)
         {
-            Vector3 anchorA = GetAnchor(joint, JointBody.A);
-            Vector3 anchorB = GetAnchor(joint, JointBody.B);
+            Vector3 anchorA = GetAnchor(joint, JointBody.Target);
+            Vector3 anchorB = GetAnchor(joint, JointBody.Anchor);
 
             Gizmos.Color = Color.White;
             Gizmos.DrawSphere(anchorA, 0.05f);
@@ -142,7 +142,7 @@ namespace BansheeEditor
             }
 
             Gizmos.Color = Color.Green;
-            Gizmos.DrawLine(anchorA + normal * min, anchorA + normal * max);
+            Gizmos.DrawLine(anchorA + normal * min, anchorA + normal * MathEx.Min(max, length));
         }
 
         /// <summary>
@@ -152,8 +152,8 @@ namespace BansheeEditor
         [DrawGizmo(DrawGizmoFlags.Selected | DrawGizmoFlags.ParentSelected)]
         private static void DrawSphericalJoint(SphericalJoint joint)
         {
-            Vector3 anchorA = GetAnchor(joint, JointBody.A);
-            Vector3 anchorB = GetAnchor(joint, JointBody.B);
+            Vector3 anchorA = GetAnchor(joint, JointBody.Target);
+            Vector3 anchorB = GetAnchor(joint, JointBody.Anchor);
 
             Gizmos.Color = Color.White;
             Gizmos.DrawSphere(anchorA, 0.05f);
@@ -195,8 +195,8 @@ namespace BansheeEditor
         [DrawGizmo(DrawGizmoFlags.Selected | DrawGizmoFlags.ParentSelected)]
         private static void DrawHingeJoint(HingeJoint joint)
         {
-            Vector3 anchorA = GetAnchor(joint, JointBody.A);
-            Vector3 anchorB = GetAnchor(joint, JointBody.B);
+            Vector3 anchorA = GetAnchor(joint, JointBody.Target);
+            Vector3 anchorB = GetAnchor(joint, JointBody.Anchor);
 
             Gizmos.Color = Color.White;
             Gizmos.DrawSphere(anchorA, 0.05f);
@@ -272,8 +272,8 @@ namespace BansheeEditor
         [DrawGizmo(DrawGizmoFlags.Selected | DrawGizmoFlags.ParentSelected)]
         private static void DrawD6Joint(D6Joint joint)
         {
-            Vector3 anchorA = GetAnchor(joint, JointBody.A);
-            Vector3 anchorB = GetAnchor(joint, JointBody.B);
+            Vector3 anchorA = GetAnchor(joint, JointBody.Target);
+            Vector3 anchorB = GetAnchor(joint, JointBody.Anchor);
 
             Gizmos.Color = Color.White;
             Gizmos.DrawSphere(anchorA, 0.05f);

+ 1 - 1
Source/MBansheeEngine/Physics/Interop/NativeD6Joint.cs

@@ -125,7 +125,7 @@ namespace BansheeEngine
     /// <summary>
     /// Used for passing D6Joint initialization data between native and managed code.
     /// </summary>
-    [StructLayout(LayoutKind.Sequential)]
+    [StructLayout(LayoutKind.Sequential), SerializeObject]
     internal struct ScriptD6JointData // Note: Must match C++ struct ScriptD6JointData
     {
         public LimitLinear linearLimit;

+ 1 - 1
Source/MBansheeEngine/Physics/Interop/NativeDistanceJoint.cs

@@ -93,7 +93,7 @@ namespace BansheeEngine
     /// <summary>
     /// Used for passing DistanceJoint initialization data between native and managed code.
     /// </summary>
-    [StructLayout(LayoutKind.Sequential)]
+    [StructLayout(LayoutKind.Sequential), SerializeObject]
     internal struct ScriptDistanceJointData // Note: Must match C++ struct ScriptDistanceJointData
     {
         public float minDistance;

+ 1 - 1
Source/MBansheeEngine/Physics/Interop/NativeHingeJoint.cs

@@ -77,7 +77,7 @@ namespace BansheeEngine
     /// <summary>
     /// Used for passing HingeJoint initialization data between native and managed code.
     /// </summary>
-    [StructLayout(LayoutKind.Sequential)]
+    [StructLayout(LayoutKind.Sequential), SerializeObject]
     internal struct ScriptHingeJointData // Note: Must match C++ struct ScriptHingeJointData
     {
         public LimitAngularRange limit;

+ 1 - 1
Source/MBansheeEngine/Physics/Interop/NativeSliderJoint.cs

@@ -61,7 +61,7 @@ namespace BansheeEngine
     /// <summary>
     /// Used for passing SliderJoint initialization data between native and managed code.
     /// </summary>
-    [StructLayout(LayoutKind.Sequential)]
+    [StructLayout(LayoutKind.Sequential), SerializeObject]
     internal struct ScriptSliderJointData // Note: Must match C++ struct ScriptSliderJointData
     {
         public LimitLinearRange limit;

+ 1 - 1
Source/MBansheeEngine/Physics/Interop/NativeSphericalJoint.cs

@@ -45,7 +45,7 @@ namespace BansheeEngine
     /// <summary>
     /// Used for passing SphericalJoint initialization data between native and managed code.
     /// </summary>
-    [StructLayout(LayoutKind.Sequential)]
+    [StructLayout(LayoutKind.Sequential), SerializeObject]
     internal struct ScriptSphericalJointData // Note: Must match C++ struct ScriptSphericalJointData
     {
         public LimitConeRange limit;

+ 23 - 19
Source/MBansheeEngine/Physics/Joint.cs

@@ -206,9 +206,9 @@ namespace BansheeEngine
 			    return;
 
 		    if (commonData.bodies[0] == body)
-			    UpdateTransform(JointBody.A);
+			    UpdateTransform(JointBody.Target);
 		    else if (commonData.bodies[1] == body)
-			    UpdateTransform(JointBody.B);
+			    UpdateTransform(JointBody.Anchor);
 	    }
 
         /// <summary>
@@ -258,8 +258,8 @@ namespace BansheeEngine
             if (Physics.IsUpdateInProgress)
                 return;
 
-            UpdateTransform(JointBody.A);
-            UpdateTransform(JointBody.B);
+            UpdateTransform(JointBody.Target);
+            UpdateTransform(JointBody.Anchor);
         }
 
         /// <summary>
@@ -284,8 +284,8 @@ namespace BansheeEngine
                     [email protected][1] = nativeBody.GetCachedPtr();
             }
 
-            GetLocalTransform(JointBody.A, out [email protected][0], out [email protected][0]);
-            GetLocalTransform(JointBody.B, out [email protected][1], out [email protected][1]);
+            GetLocalTransform(JointBody.Target, out [email protected][0], out [email protected][0]);
+            GetLocalTransform(JointBody.Anchor, out [email protected][1], out [email protected][1]);
 
             native = CreateNative();
             native.Component = this;
@@ -324,26 +324,23 @@ namespace BansheeEngine
         /// </summary>
         /// <param name="body">Body to calculate the transform for.</param>
         /// <param name="position">Output position for the body.</param>
-        /// <param name="rotation">Output rotation for the body</param>
+        /// <param name="rotation">Output rotation for the body.</param>
         private void GetLocalTransform(JointBody body, out Vector3 position, out Quaternion rotation)
         {
             position = commonData.positions[(int)body];
             rotation = commonData.rotations[(int)body];
 
-            // Transform to world space of the related body
             Rigidbody rigidbody = commonData.bodies[(int)body];
-            if (rigidbody != null)
+            if (rigidbody == null) // Get world space transform if no relative to any body
             {
-                Quaternion worldRot = rigidbody.SceneObject.Rotation;
-
-                rotation = worldRot * rotation;
-                position = worldRot.Rotate(position) + rigidbody.SceneObject.Position;
-
-                // Transform to space local to the joint
-                Quaternion invRotation = SceneObject.Rotation.Inverse;
+                Quaternion worldRot = SceneObject.Rotation;
 
-                position = invRotation.Rotate(position - SceneObject.Position);
-                rotation = invRotation * rotation;
+                rotation = worldRot*rotation;
+                position = worldRot.Rotate(position) + SceneObject.Position;
+            }
+            else
+            {
+                position = rotation.Rotate(position);
             }
         }
 
@@ -448,7 +445,14 @@ namespace BansheeEngine
     /// </summary>
     public enum JointBody
     {
-        A, B
+        /// <summary>
+        /// Body the joint is influencing.
+        /// </summary>
+        Target,
+        /// <summary>
+        /// Body to which the joint is attached to (if any).
+        /// </summary>
+        Anchor
     };
 
     /// <summary>

Some files were not shown because too many files changed in this diff