<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://opensimulator.org/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://opensimulator.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Nlin</id>
		<title>OpenSimulator - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://opensimulator.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Nlin"/>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/Special:Contributions/Nlin"/>
		<updated>2026-05-11T06:48:54Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.19.9</generator>

	<entry>
		<id>http://opensimulator.org/wiki/Related_Software</id>
		<title>Related Software</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/Related_Software"/>
				<updated>2009-12-25T00:48:22Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: Updating information about Rei&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Template:Quicklinks}}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Technical Reference | Technical Reference]] -&amp;gt; [[Technical Reference/terms | Terms]] -&amp;gt; [[Related_Software | Related Software]]&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{content}}&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This is a page which lists software packages that are related to OpenSimulator but are not part of the core project. Opensimulator is not responsible for the content referenced by these links.&lt;br /&gt;
&lt;br /&gt;
== Dependent Software ==&lt;br /&gt;
OpenSim depends on many other libraries to function.  You get these with your default distribution of OpenSim, but for more information on each project you should see it's home page&lt;br /&gt;
* [http://libsecondlife.org libopenmetaverse]&lt;br /&gt;
* [http://www.ode.org ODE] ODE is an open source, high performance library for simulating rigid body dynamics.&lt;br /&gt;
* [http://www.codeplex.com/Json json.net] JSON (JavaScript Object Notation) is a lightweight data-interchange format.&lt;br /&gt;
* [http://www.mono-project.com mono] Mono is a cross platform, open source .NET development framework.&lt;br /&gt;
* [http://nant.sourceforge.net nant] NAnt is a free .NET build tool.&lt;br /&gt;
* [http://www.realxtend.org realXtend] realXtend viewer and server working with OGRE and support MESH.&lt;br /&gt;
* [http://subversion.tigris.org Subversion] Subversion is an open source version control system.&lt;br /&gt;
* [http://www.python.org Python] Python is a dynamic object-oriented programming language that can be used for many kinds of software development.&lt;br /&gt;
* [http://xmlrpccs.sf.net XmlRpcCS]&lt;br /&gt;
* [http://www.nunit.org NUnit]&lt;br /&gt;
* [http://sourceforge.net/projects/dnpb Prebuild]&lt;br /&gt;
* [http://dotnetopenmail.sourceforge.net DotNetOpenMail]&lt;br /&gt;
* [http://www.prototypejs.org Prototype JavaScript Framework ajax]&lt;br /&gt;
* [http://nini.sourceforge.net Nini]&lt;br /&gt;
* [http://logging.apache.org/log4net log4net]&lt;br /&gt;
* [http://gtcache.sourceforge.net GlynnTucker.Cache]&lt;br /&gt;
* '''todo:''' list the rest of the contents of bin here&lt;br /&gt;
&lt;br /&gt;
== OpenSim Viewers ==&lt;br /&gt;
The following 3D Viewers are known to work with OpenSim.  We take no responsibility for their bugs, features, or lack there of.&lt;br /&gt;
* [http://get.secondlife.com Official Second Life (tm) Viewer]&lt;br /&gt;
* [http://opensim-viewer.sourceforge.net Hippo Viewer]&lt;br /&gt;
* [http://imprudenceviewer.org Imprudence Viewer]&lt;br /&gt;
* [http://www.realxtend.org realXtend Viewer]&lt;br /&gt;
* [http://www.meerkatviewer.org Meerkat Viewer]&lt;br /&gt;
* [http://forge.opensimulator.org/gf/project/idealistviewer/ IdealistViewer]&lt;br /&gt;
* [http://3di-rei.org/ 3Di Viewer Rei] - Web Browser based Viewer in C#, JavaScript integration, BSD.&lt;br /&gt;
&lt;br /&gt;
== OpenSim Forge Projects ==&lt;br /&gt;
OpenSimulator now has a [http://forge.opensimulator.org/gf/ forge] for related software. &lt;br /&gt;
* [http://forge.opensimulator.org/gf/project/osinstaller OpenSim Installers]&lt;br /&gt;
* [http://forge.opensimulator.org/gf/project/opensim-viewer Hippo OpenSim Viewer]&lt;br /&gt;
* [http://forge.opensimulator.org/gf/project/opensimwi/ OpenSimWi(Redux)]&lt;br /&gt;
* [http://forge.opensimulator.org/gf/project/openterrains/ Open Source Terrain Textures]&lt;br /&gt;
* [http://forge.opensimulator.org/gf/project/ogp/ OGP Patches]&lt;br /&gt;
* [http://forge.opensimulator.org/gf/project/xenki/ Xenki Viewer]&lt;br /&gt;
* [http://forge.opensimulator.org/gf/project/ostray/ OSTray]&lt;br /&gt;
* [http://forge.opensimulator.org/gf/project/sllauncher/ SL Launcher]&lt;br /&gt;
* [http://forge.opensimulator.org/gf/project/openusermanual/ Open User Manual]&lt;br /&gt;
* [http://forge.opensimulator.org/gf/project/deepservers/ DeepServer (ASP.NET Grid Server)]&lt;br /&gt;
* [http://forge.opensimulator.org/gf/project/modrex/ realXtend Modules]&lt;br /&gt;
'''todo''' list some of the top opensim forge projects.&lt;br /&gt;
&lt;br /&gt;
==Modules==&lt;br /&gt;
&lt;br /&gt;
These are either application or region modules which can be added to the OpenSim core distribution to provide extra functionality.&lt;br /&gt;
&lt;br /&gt;
None are listed yet! &lt;br /&gt;
&lt;br /&gt;
==Other related software==&lt;br /&gt;
These are independent implementations of OpenSimulator services, such as the user server or the inventory server (also known as UGAI).&lt;br /&gt;
&lt;br /&gt;
* [http://openugai.sourceforge.net/ OpenUGAI] - A Perl implementation of the UGAI services which runs within Apache.&lt;br /&gt;
* [http://www.ics.uci.edu/~lopes/terraingen/ Terraingen] - Tool for producing OpenSim terrains from USGS DEM files.&lt;br /&gt;
* [[RegionGenerator]] - Generates Region XML Files&lt;br /&gt;
* [http://www.secondinventory.com/ Second Inventory] - A Windows based client that can be used to back up and restore objects from Second Life™ as well as from various OpenSimulator based grids.  It allows you to back up objects from the Second Life™ main grid, and restore them into OpenSimulator grids.  It is still a bit primitive and sometimes can be flaky.  This software is in no way supported by the OpenSIM team, please contact its creator for support.&lt;br /&gt;
* [http://www.metabolt.net/ METAbolt] - METAbolt is a non-graphical (text based) viewer. It's light weight and cross grid, which means it will work in Second Life™ as well as other grids that are based on OpenSIM. The viewer is Open Source so it's free. Currently METAbolt is only available for Windows platforms.&lt;br /&gt;
* [http://3di-opensim.com/en/ 3Di OpenSim Enterpise] - Business service based on OpenSim.&lt;br /&gt;
* [http://3di-rei.org/ 3Di Viewer Rei] - Web Browser based Viewer.&lt;br /&gt;
* [http://www.nsl.tuis.ac.jp/xoops/modules/xpwiki/?sl_proxy%20%28E%29 sl_proxy] - sl_proxy is a Proxy System for Second Life™ and OpenSim to beyond firewall.&lt;br /&gt;
* [http://www.nsl.tuis.ac.jp/xoops/modules/xpwiki/?XoopenSim XoopenSim] - OpenSim WEB Interface for Xoops Cube. This module was made by remodeling [http://forge.opensimulator.org/gf/project/opensimwi/ OpenSimWi(Redux)]. (Sorry. This page is Japanese only.) &lt;br /&gt;
* [http://www.nsl.tuis.ac.jp/xoops/modules/xpwiki/?OpenSim%2FMoneyServer Money Server (NSL Version)] - This Money Server is modified version of [http://forge.opensimulator.org/gf/project/currency/ DTL Currency Processing] for Linux/Unix.&lt;br /&gt;
* [http://www.nsl.tuis.ac.jp/xoops/modules/d3downloads/index.php?page=singlefile&amp;amp;cid=8&amp;amp;lid=8 Unofficial NSL Patch for OpenSim 0.6.7] - The phenomenon of avatar's falling to the hell is corrected at the boundary of SIM and empty region. etc.etc.&lt;br /&gt;
&lt;br /&gt;
==Addons==&lt;br /&gt;
&lt;br /&gt;
*** PLEASE DO NOT ASK THE OPENSIMULATOR TEAM FOR SUPPPORT ABOUT THESE ADD-ON PACKAGES&lt;br /&gt;
&lt;br /&gt;
==Concepts==&lt;br /&gt;
* [http://www.cs.cmu.edu/~johnny/projects/wii/ 3D Head Tracking Software] - The idea here is that Johnny has written an application that will allow real3d perspective using a WiiMote &amp;amp; a modified set of safety glasses. Johnny includes all of the source and several sample applications to get this moving forward. Would someone like to pick this up and build us a real3D interface for the SL browser? It's not as hard as you think.&lt;br /&gt;
&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Edusim Edusim on Opensim] - Edusim is a [http://en.wikipedia.org/wiki/Cave_Automatic_Virtual_Environment Cave Automatic Virtual Environment] based concept of lesson driven 3D virtual worlds on the ''classroom interactive whiteboard or classroom interactive surface''.  Currently Edusim on Opencobalt Cobalt exists but tweaking a client and making Opensim &amp;quot;finger friendly&amp;quot; would seem to be a relatively straight forward task.&lt;br /&gt;
&lt;br /&gt;
= See Also =&lt;br /&gt;
&lt;br /&gt;
* [[:Category:Getting Started|Getting Started]]&lt;br /&gt;
* [[:Category:Tech Reference|Technical Reference Pages]]&lt;br /&gt;
* [[:Category:Development|Development]]&lt;br /&gt;
* [[Status|Main Status Page]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Users]]&lt;br /&gt;
[[Category:Support]]&lt;br /&gt;
[[Category:Tech Reference]] &lt;br /&gt;
[[Category:Help]]&lt;br /&gt;
[[Category:Configuration]]&lt;br /&gt;
[[Category:Getting_Started]]&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Todo]]&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/Talk:NINJA_Physics</id>
		<title>Talk:NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/Talk:NINJA_Physics"/>
				<updated>2009-01-14T05:39:42Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There used to be functionality like this in Second Life (at least the sources seems to indicate this).&lt;br /&gt;
&lt;br /&gt;
What happened to it? Are there lessons to be learned?&lt;br /&gt;
&lt;br /&gt;
* This is a good question and I unfortunately don't know the answer. All I know, from second hand accounts, is that SL used to support it, but it was buggy and unstable, so it was removed. I'd love to hear more about it and why they abandoned it. (The protocol still contains references to joint information fields, so maybe we can use those fields in the future.) [[User:Nlin|Nlin]] 05:39, 14 January 2009 (UTC)&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2009-01-13T04:38:43Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Editing and Naming limitations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Separate from NINJA Physics, other activity has recently accelerated on LSL script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs.&lt;br /&gt;
&lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available. &amp;lt;b&amp;gt;Important note if NINJA Physics is not working for you:&amp;lt;/b&amp;gt; The NINJA Physics in SVN r7875 should work but requires C# 3.0. The NINJA Physics in r7878 does &amp;lt;b&amp;gt;not work&amp;lt;/b&amp;gt;. If you use SVN r7878 or above, please apply the additional patch in Mantis #2928 at http://opensimulator.org/mantis/view.php?id=2928&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt;, also called a &amp;lt;i&amp;gt;joint prim&amp;lt;/i&amp;gt;, is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the affected prims' movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate. A joint prim only affects the physics simulation if the joint prim's &amp;quot;[x] Physical&amp;quot; property is activated.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint prim.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors. If, for example, you create a hinge joint (by naming a prim &amp;quot;hingejoint-uniquename&amp;quot;) but specify non-existent or non-physical body names in the Description field, the joint will not be able to be created and a warning icon appears in-world on top of the joint. Click on the warning icon to see the error message. Deactivate, correct, and re-activate the joint.&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object. You should only change the name when the joint is deactivated. &lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected. You should only change the name when the prim is deactivated.&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no geometric representation in the physics scene. Technically, joints are implemented in the physics engine as mathematical (equality or inequality) constraints on the position and/or velocity of rigid bodies, so they constrain the admissible region of the rigid body simulator solution space but do not occupy space themselves.&lt;br /&gt;
* While the joint proxy is active (physical), you cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction, collision bounce, and collision filtering settings in OpenSim.ini can be tweaked for different effects.&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has been re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of prim taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Editing and Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name, where such names are unique for the entire region.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims (Mantis #2966).&lt;br /&gt;
* Connecting a joint to the environment requires specifying one of the connected prims as &amp;quot;NULL&amp;quot;, in capital letters and without quotes. &amp;quot;null&amp;quot; won't work.&lt;br /&gt;
* Editing one or several joints or prims in an actively simulating assembly should freeze the entire assembly, but it doesn't. (The assembly keeps simulating and moving even if a part of the assembly is selected for editing.)&lt;br /&gt;
* If velocity interpolate on the client is on, deactivated joint prims will sometimes fly away due to incorrectly continuation of the velocity interpolation. The server should always stop movement of joint prims when they are deactivated or renamed. Code is in place to do this, but apparently some corner cases remain unfixed.&lt;br /&gt;
&lt;br /&gt;
== Linked or attached prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
* Don't try to attach (to your avatar) prims that are part of a jointed assembly. This would however be a very cool feature in the future (allowing things like physical ponytails that swing properly), but needs more research about how to implement it.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/Development_Team</id>
		<title>Development Team</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/Development_Team"/>
				<updated>2009-01-13T04:00:57Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Active OpenSim Core Developers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Active OpenSim Core Developers ==&lt;br /&gt;
These people have commit access to our central SVN server and are [http://www.ohloh.net/projects/4753/contributors regular contributors] to the codebase.&lt;br /&gt;
&lt;br /&gt;
(please add in as much info as you like for your name)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; class=&amp;quot;sortable&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Photo &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;IRC Nick &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;SL Avatar&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Other Grid&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Time Zone&amp;lt;br&amp;gt;(UTC)&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Org&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Areas of Interest&amp;lt;/th&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:MW |MW ]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Darren&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;OSG:Wright Juran&amp;lt;br/&amp;gt;TN:Darren Guard&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;0&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[http://tribalmedia.se/ Tribal Media AB]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Everything&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:lbsa71|lbsa71]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Stefan Andersson&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Tribal Skytower&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;OSG:Stefan Andersson&amp;lt;br/&amp;gt;TN:Stefan Andersson&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+1&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[http://tribalmedia.se/ Tribal Media AB]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Web Integration&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Adam Frisby|Adam Frisby]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Adam Frisby&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Adam Zaius&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+8&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;DeepThink Pty Ltd&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Terrain, Performance&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:MingChen|MingChen]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Mike/Michael Ortman&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Ming Chen&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-6 (-5 in Summer)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;DeepThink Pty Ltd&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Estate/Parcel Support/Modules/Keeping things all neat and tidy.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt; &lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:SeanDague|sdague]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Sean Dague&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Neas Bade&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-5&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;IBM&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Database, Linux, Testing, Misc&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Tedd|Tedd]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Tedd Hansen&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Tedd Maa&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+1&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Tedd Hansen&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Programming/Scripting/Architecture&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:dalien|dalien]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Dalien Talbot&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Dalien Talbot&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+1&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Mostly TCP-based&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Small fixes; rev.eng./prototyping; nightlies; git-keeper &amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;ckrinke&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Charles&amp;amp;nbsp;Krinke&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Charlesk&amp;amp;nbsp;Bing&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-8&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Reliability/Grid servers/ll-functions&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:chi11ken|chi11ken]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Jeff Ames&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Chillken Proto&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+9&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[http://www.3di.jp/en/ 3Di Inc, Japan]&amp;lt;br/&amp;gt;/ Genkii&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:adjohn|adjohn]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Adam Johnson&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Zeuz Zenovka&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+9&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[http://www.3di.jp/en/ 3Di Inc, Japan]&amp;lt;br/&amp;gt;/ Genkii&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:joha1|joha1]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Johan Berntsson&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Joppi Brandenburg&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+9&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[http://www.3di.jp/en/ 3Di Inc, Japan]&amp;lt;br/&amp;gt;http://www.3di.jp/en/&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Performance, packet handling/libSL&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Teravus|Teravus]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Teravus&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Teravus Ousley&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-5&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;W3z&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Physics &amp;amp; Admin tools, A working sim.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:justincc|justincc]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Justin Clark-Casey&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Lulworth Beaumont&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Justin Clark-Casey (osgrid)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;0&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Black Dress Technology&amp;lt;br/&amp;gt;[http://justincc.wordpress.com justincc's OpenSim blog]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Grid, performance &amp;amp; reliability, inventory (avatar and object), assets, scenes, etc.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[Alondria]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Alondria LeFay&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Alondria LeFay (OSGrid)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-8&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Independent&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Implementation of LSL functions and other scripting tidbits.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:DrScofield|drscofld]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Dirk Husemann&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Dr Scofield&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+1&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;IBM&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;reliability, networking protocols, voice, inventory, assets, remote control, and pretty much everything else :-)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:dahlia|dahlia]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;T. Hoff&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Dahlia Trimble&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-8 / -7&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;independent&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;prim collision geometry, more later :)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Mikem|mikem]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Mike&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+9&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[http://www.3di.jp/en/ 3Di Inc, Japan]&amp;lt;br/&amp;gt;http://www.3di.jp/en/&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;patches, scripting improvements, LSL compiler&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Melanie_T|Melanie_T]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Melanie&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Melanie Milland&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;0&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Xumeo Inc.&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Scripting, Prims/Scene, Life, The Universe, and Everything&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Homer Horwitz|Homer_Horwitz]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Homer Horwitz&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Homer Horwitz&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+2&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Independent&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;map/TP, rev. engineering, &amp;quot;now, that's funny&amp;quot; problems, but still interested in all parts of it&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Diva|Diva]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Crista Lopes&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Diva Canto&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Crista Lopes / Diva Canto&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-8&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;University of California, Irvine&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Everything, except databases&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:nlin|nlin]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;N Lin&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Standard Drucker&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+9&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[http://www.3di.jp/en/ 3Di Inc, Japan]&amp;lt;br/&amp;gt;http://www.3di.jp/en/&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Physics, scripting, more to come&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Retired OpenSim core developers ==&lt;br /&gt;
&lt;br /&gt;
These people are core developers who have transcended our mortal plane (i.e. they are no longer active).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; class=&amp;quot;sortable&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Photo &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;IRC Nick &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;SL Avatar&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Other Grid&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Time Zone&amp;lt;br&amp;gt;(UTC)&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Org&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Areas of Interest&amp;lt;/th&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:babblefrog|babblefrog]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Brian McBee&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Dogen Coldstream&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Babblefrog Ballistic (osgrid)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-8&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Disorganized&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:danx0r|danx0r]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Dan Miller&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Albert Pascal&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-8&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;squiggle.com&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;PHEEZIKS; everything&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Tleiades&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Tleiades&amp;amp;nbsp;Hax&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+1&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Grid servers/Database&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Darok|Darok]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Darok Kaminski&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+1&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Physics engines (especially BulletX)&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td /&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Gareth / Gwen&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Gareth Nelson&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Gareth Ellison&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Gareth Nelson (on everywhere but SL)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;BST (UTC+1)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Litesim Ltd&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Grid servers, sim border crossing, avatar animations&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Additional Developers/Testers/Contributors ==&lt;br /&gt;
These people have contributed bug reports, patches or other contributions to OpenSim.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; class=&amp;quot;wikitable sortable&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;IRC Nick &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;SL Avatar&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Other Grid&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Time Zone&amp;lt;br&amp;gt;(UTC)&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Org&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;th&amp;gt;Areas of Interest&amp;lt;/th&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Nebadon|Nebadon]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Michael Cerquoni&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Nebadon Izumi&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Nebadon Izumi&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-7 Arizona&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Oni Kenkon Creations&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Building, Scripting, Testing&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:jtclark48|jclark4]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Jay Clark&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Jay Clarke&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-5&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;IBM&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Physics, Grid Host, AI, Scripting, Testing&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:AdamStevenson|BigFootAg]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Adam Stevenson&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Adamus Petrov&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-6&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Texas A&amp;amp;M University&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;AI, Skynet, Evolving Systems, Biology&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:jeff1564|Jeff1564]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Jeff&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Potter Taurog&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-8&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Building, Scripting, Testing&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Rock_Vacirca&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Colin Withers&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Rock Vacirca&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+1&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;http://rock-vacirca.blogspot.com&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Testing, building, scripting, maintaining an opensim blog.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;simsim&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;caocao&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+9&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Testing whole functions of OpenSim system,working with OpenSim-Engine,reporting on OpenSim&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Vicero Lambert|Vicero Lambert]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Ldvoipeng&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;idoru&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Magi|Magi]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Andy Agnew&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Magi Merlin&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+10&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Spun Pty Ltd&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;3D Web Integration, Database stuff and playing with the odds and ends box.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;john_&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;John&amp;amp;nbsp;Moyer&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;VAJohn&amp;amp;nbsp;GeekSquad or&amp;amp;nbsp;Matthew&amp;amp;nbsp;Kendal&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-5&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Best&amp;amp;nbsp;Buy/Geek&amp;amp;nbsp;Squad&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Tester&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:ClarkZone|ClarkZone]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Troy Admin(@ClarkZone)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Troy Childs&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Troy Admin (ClarkZone)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-5&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Http://clarkzone.dyndns.org&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Tester and Grid Host&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:aiaustin|aiaustin]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Ai Austin&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Ai&amp;amp;nbsp;Austin&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Ai&amp;amp;nbsp;AIAI&amp;amp;nbsp;(AIAI Grid)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+0&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;AIAI,&amp;amp;nbsp;University&amp;amp;nbsp;of&amp;amp;nbsp;Edinburgh&amp;lt;br&amp;gt;http://www.aiai.ed.ac.uk/~ai/&amp;lt;br&amp;gt;http://vue.ed.ac.uk/openvue/&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Windows Vista tests&amp;lt;br&amp;gt;Content testing&amp;lt;br&amp;gt;Use of multiple VWs&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Marc Manders&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Marc Manders&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+6&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;marcmanders@gmail.com&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;creative features&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:balthazar|balthazar]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Trevor Brooks&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Balthazar Sin&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-5&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;None&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Terrains, testing and some small coding tasks&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:jimbo2120|jimbo2120]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Michael Osias&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Illuminous Beltran&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-5&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;IBM&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Grid, AI, Skynet, coding and testing&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Sakai|Sakai]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Steve S&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Sakai Openlife (OpenlifeGrid)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+10&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;http://www.openlifegrid.com&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Grid, Hardware, Testing, Contribution&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;ZeroPoint&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Guilderoy&amp;amp;nbsp;Dench&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-5&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Programming/Database&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;MaltosSosa&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Maltos Sosa&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Maltos Sosa&amp;lt;br&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Maltos Sosa (Central Grid)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Central Grid&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Grid Operator, Central Grid Project Manager. Anything we can offer, just ask.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:DerekTang|DerekTang]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Derek Tang&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Derek Timeless&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Derek Tang (ChineseGrid)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+8&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;http://ChineseGrid.net&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Running a public WINDOWS sim for testing, Docs, Helping Chinese users to enjoy OpenSim; building Chinese OpenSim communities. In construction...&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:TayB|TayB]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Earl B&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Taylor Boyau&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-10&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;ViziGrid&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Grid Host,Networking,Contributions &amp;amp; Testing.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:JamieDav|JamieDav]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Jamie David&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Jamie David&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+7&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Forum&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Grid, Sim, Avitar, Functionality&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Krtaylor|Krtaylor]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Kurt Taylor&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Kurt Stringer &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-6&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;IBM&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Grid, Networking, Monitoring, Scripting, Inventory, Testing&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Nink|Nink]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Peter Finn&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Nink Noonan&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-5&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;IBM&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Disruptive Influence.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Bruce|Bruce]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Bruce Meerson&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Bruce Meerson&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+8&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;HiPiHi&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Watching.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Darb|DarbD]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Brian B. Quinn&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Darb Dabney&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;regions&amp;lt;br /&amp;gt;near Berkeley&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-7&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;City of Berkeley, CA&amp;lt;br /&amp;gt; http://blog.simgis.org&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;LiDAR-based sculpties, real-world terrain, &amp;lt;br /&amp;gt;pursuit of civic paraverses &amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[CharlieO]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Dan&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Charlie Omega&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Mild coding/tweaking/simple feature adds, Stress testing/break stuff, Testing limits of existing code. Making sure [[LSL Status]] is up to date&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;oobscure&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Opensource Obscure&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+1&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;http://www.opensim.it&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Running a public Linux sim for testing, Docs, Helping italian users, Building opensim communities, Watching&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;pitman&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Mike Pitman&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Rez Tone&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;IBM&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Scientific visualization schemes, virt world product design, persistant workspaces, virt world based big biz&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;cmu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Christopher Mumme&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Snook Destiny&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+1&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;http://www.cmu-develop.de/ and research group &amp;quot;Collaboration Systems and CSCW&amp;quot; at Clausthal University of Technology&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Testing OpenSim, working with OpenSim-Engine, reporting on OpenSim&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[Silpol]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Andriy Tymchenko&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Andy Tir&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;EET (+2/3)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt; http://silpol.blogspot.com/ (also visible at Nokia)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;highly uncoordinated mess with elements of palace games, under-table diplomacy, rebellion, coup d'état and mutiny. optionally pirate&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Grumly|Grumly]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Forest Klaar&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Grumly TheBear&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;GMT+1&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;.NET MCAD Dev/Arch/Trainer http://www.devoteam.com&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Trying to get into OpenSim code for now. Particularly interrested in data persistence. blog (Hello, Avatar!): http://lslblog.free.fr&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[daTwitch]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;James G. Stallings II&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br&amp;gt;Lazarus Longstaff&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hiro Protagonist (OSGrid)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-5&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;House Husband&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;OSGrid Region owner, OSGrid Operator,&amp;lt;BR&amp;gt;Forum Admin, sometime wiki editor&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;gryc&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Gryc Ueusp&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Gryc Uriza&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Gryc Uriza(OSGrid)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-6&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;PHP scripting, web interfaces, interconnectivity, cross-platformedness&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Phrearch|Phrearch]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Jeroen van Veen&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Phrearch Miles&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Phrearch Miles(OSGrid)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Amsterdam/Paris&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;WiXTD, Wikidoc and Moo&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Burnman|Burnman]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Allen Wilkins&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Burnman Bedlam&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Sid Green (United Grid)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Boston, USA&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;United Grid&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Testing, testing, and more testing! Getting familiar with the source, interested in all aspects of the project.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:krisbfunk|krisbfunk]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Kris Bulman&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;krisbfunk Vought&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Krisbfunk Nocturnal(OSGrid)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;PE, Canada (-4)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Edactive Technologies&amp;lt;br /&amp;gt;NocturnalEye Productions&amp;lt;br /&amp;gt;UPEI&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Currently: Testing, bug reports, wiki updating, building on OSGrid&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;[[User:HashBox|HashBox]]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Sibariel Darkstone&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Sibariel Darkstone (OSGrid)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;New Zealand (+12)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Testing, bug reports, and updating the wiki.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Kinoc|Kinoc]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Kino Coursey&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Daxxon Jaxxon&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Daxxon Kinoc (OSgrid)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-6&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Daxtron Laboratories &amp;lt;br /&amp;gt; http://www.daxtron.com&amp;lt;br /&amp;gt; University of North Texas&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;AI, Semantic web, Ontologies, Natural Laanguage Processing, Cyc, Bots, NPC &amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:trapuh|trapuh]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Pedro Ribeiro&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Vaiten Forder&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;GMT&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;University Student, Escola Superior de Educação de Viseu, Portugal &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Testing, eventual bug reports and wiki. Music, web/digital arts and php+sql.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:SonicViz|SonicViz]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Paul Cohen&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Komuso Tokugawa&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+9&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Http://sonicviz.com&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Audio/Music, Interactive Music, Control Protocols, Interfaces, VisualFX, Procedural animation/Generative systems + testing and general dev&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Mokele|mokele]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Scott Norman&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Mokelembembe Mokeev&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-8 (Southern California)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Web Developer (PHP and MySQL)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Interested in seeing running on PowerPC Macs which it is. So, when I can, I'll compile and test on PowerPC Mac (PowerBook G4) and submit reports and then update the wiki if need on installing on Mac. Also have a Ubuntu 7.10 server that  I can do testing on too.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:devalnor|devalnor]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Devalnor&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;M. Watkin&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+1 (Belgium)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Small Patch code, bug reports, and updating the wiki.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Ezekiel|Ezekiel]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Ezekiel&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Ezekiel Zabelin&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+1 &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;http://www.yosims.com &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Concepts, business aspects of virtual worlds - web developer (PHP, MySQL, Javascript, LSL) &amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Buggmaster|Buggmaster]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Mike D&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Bug Master&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;None&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-8 &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;http://www.adultmetaverse.com&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Grid, Data/Web PHP/PERL/MySQL&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Nixnerd|nixnerd]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Richmund&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Dangerously Moody&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;None&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;GMT &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;http://www.integratedtechnologies.eu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Cross Platform Testing, Feedback, Bug Reporting&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:MoHax|mohax]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Mo Hax&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Mo Hax&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-5 Eastern&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;IBM&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Testing, Feedback, Content Contributions, Bug Reporting, Documenting, Development&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Webmage|webmage]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;webmage&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Leyla Masala&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Web Mage&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+1&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;IBM&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Testing, terrain&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:NLStitch|NLStitch]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Marijn Oosterveld&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Stitch Seale&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;NYA&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;GMT +1 Amsterdam&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Twingate Systems (http://www.twingate.nl)&amp;lt;br&amp;gt;HanzeHogeschool Groningen, Netherlands&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Programming, Photography, AI&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Ideia Boa|Ideia Boa]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Joao Lopes&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Ideia Boa&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Ideia Boa or Boa Ideia in some grids&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;GTM+1 Stockholm/Sweden&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Cub SL Portugues - Portugueses Virtual World Site &amp;lt;br /&amp;gt;http://www.clubslportugues.com&amp;lt;br /&amp;gt;OpenSimPT the Grid for Portuguese language too&amp;lt;br/&amp;gt;http://www.opensimpt.com&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Testing and more testing! Trying to get into OpenSim code for now. Updating the original wiki and translating the OpenSim Wiki into Portuguese and reporting on OpenSim&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Lulurun|lulurun]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;liu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+9&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;3Di Inc, Japan &amp;lt;br /&amp;gt;http://www.3di.jp&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;patches, openid, server performance, UGAI&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Carlosroundel|Carlosrounde]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Carlosroundel&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Carlos Roundel&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+1&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Cyberlandia Italy&amp;lt;br /&amp;gt;http://www.cyberlandia.net&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;grid, programmer, database, tester&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Mikebert|Mikebert]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Michael Strunck&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Mikebert Miles&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+1&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;OpenSIM Wiki, Germany&amp;lt;br /&amp;gt;http://www.opensim.de&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;German Wiki, Translater, Server Performance (Linux/Windows), Tester, Feedback, Bug Reporting, Server-Hosting&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Fly-man-|Fly-Man-]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Laurence&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Fly Man&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+1&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Testing, OpenSimSearch, OpenSimProfile, OpenWiredux&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Taoki&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Mircea Kitsune / Taoki Vixen&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Mircea Kitsune (OSGrid) / Mircea Lobo (LL grid)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;GMT +2&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Usually testing and bug reporting but I also make smaller patches where I know what to do.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Patnad|Patnad]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Patrick&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Patnad Babii&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Patnad Babii (OSGrid)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;GMT -5&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Bug testing and reporting, I code C# but haven't touched OpenSim Project.. Yet!&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:Hallow Palmer|Hallow Palmer]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Markus&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hallow Palmer&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;+1&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Grid4Us&amp;lt;br /&amp;gt;http://www.grid4us.net&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Server Performance (Windows), Tester, Feedback, Business concepts,Bug Reporting, Server-Hosting&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[User:^DarkMan|^DarkMan]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Brian Adair&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Patrick Ouachita&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Brian Adair | Patrick Meta&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;-6 CST&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;RealMetaLife | B&amp;amp;H Networking&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Building, Scripting, Testing, etc.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
[[Category:Main]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2009-01-13T03:42:24Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Tips for effectively using joints */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Separate from NINJA Physics, other activity has recently accelerated on LSL script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs.&lt;br /&gt;
&lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available. &amp;lt;b&amp;gt;Important note if NINJA Physics is not working for you:&amp;lt;/b&amp;gt; The NINJA Physics in SVN r7875 should work but requires C# 3.0. The NINJA Physics in r7878 does &amp;lt;b&amp;gt;not work&amp;lt;/b&amp;gt;. If you use SVN r7878 or above, please apply the additional patch in Mantis #2928 at http://opensimulator.org/mantis/view.php?id=2928&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt;, also called a &amp;lt;i&amp;gt;joint prim&amp;lt;/i&amp;gt;, is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the affected prims' movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate. A joint prim only affects the physics simulation if the joint prim's &amp;quot;[x] Physical&amp;quot; property is activated.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint prim.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors. If, for example, you create a hinge joint (by naming a prim &amp;quot;hingejoint-uniquename&amp;quot;) but specify non-existent or non-physical body names in the Description field, the joint will not be able to be created and a warning icon appears in-world on top of the joint. Click on the warning icon to see the error message. Deactivate, correct, and re-activate the joint.&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object. You should only change the name when the joint is deactivated. &lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected. You should only change the name when the prim is deactivated.&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no geometric representation in the physics scene. Technically, joints are implemented in the physics engine as mathematical (equality or inequality) constraints on the position and/or velocity of rigid bodies, so they constrain the admissible region of the rigid body simulator solution space but do not occupy space themselves.&lt;br /&gt;
* While the joint proxy is active (physical), you cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction, collision bounce, and collision filtering settings in OpenSim.ini can be tweaked for different effects.&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has been re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of prim taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Editing and Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name, where such names are unique for the entire region.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims (Mantis #2966).&lt;br /&gt;
* Connecting a joint to the environment requires specifying one of the connected prims as &amp;quot;NULL&amp;quot;, in capital letters and without quotes. &amp;quot;null&amp;quot; won't work.&lt;br /&gt;
* Editing one or several joints or prims in an actively simulating assembly should freeze the entire assembly, but it doesn't. (The assembly keeps simulating and moving even if a part of the assembly is selected for editing.)&lt;br /&gt;
&lt;br /&gt;
== Linked or attached prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
* Don't try to attach (to your avatar) prims that are part of a jointed assembly. This would however be a very cool feature in the future (allowing things like physical ponytails that swing properly), but needs more research about how to implement it.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2009-01-13T03:19:57Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Editing and Naming limitations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Separate from NINJA Physics, other activity has recently accelerated on LSL script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs.&lt;br /&gt;
&lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available. &amp;lt;b&amp;gt;Important note if NINJA Physics is not working for you:&amp;lt;/b&amp;gt; The NINJA Physics in SVN r7875 should work but requires C# 3.0. The NINJA Physics in r7878 does &amp;lt;b&amp;gt;not work&amp;lt;/b&amp;gt;. If you use SVN r7878 or above, please apply the additional patch in Mantis #2928 at http://opensimulator.org/mantis/view.php?id=2928&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt;, also called a &amp;lt;i&amp;gt;joint prim&amp;lt;/i&amp;gt;, is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the affected prims' movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate. A joint prim only affects the physics simulation if the joint prim's &amp;quot;[x] Physical&amp;quot; property is activated.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint prim.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors. If, for example, you create a hinge joint (by naming a prim &amp;quot;hingejoint-uniquename&amp;quot;) but specify non-existent or non-physical body names in the Description field, the joint will not be able to be created and a warning icon appears in-world on top of the joint. Click on the warning icon to see the error message. Deactivate, correct, and re-activate the joint.&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object. You should only change the name when the joint is deactivated. &lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected. You should only change the name when the prim is deactivated.&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no geometric representation in the physics scene. While the joint proxy is active (physical), you cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction, collision bounce, and collision filtering settings in OpenSim.ini can be tweaked for different effects.&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has been re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of prim taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Editing and Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name, where such names are unique for the entire region.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims (Mantis #2966).&lt;br /&gt;
* Connecting a joint to the environment requires specifying one of the connected prims as &amp;quot;NULL&amp;quot;, in capital letters and without quotes. &amp;quot;null&amp;quot; won't work.&lt;br /&gt;
* Editing one or several joints or prims in an actively simulating assembly should freeze the entire assembly, but it doesn't. (The assembly keeps simulating and moving even if a part of the assembly is selected for editing.)&lt;br /&gt;
&lt;br /&gt;
== Linked or attached prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
* Don't try to attach (to your avatar) prims that are part of a jointed assembly. This would however be a very cool feature in the future (allowing things like physical ponytails that swing properly), but needs more research about how to implement it.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2009-01-12T12:05:54Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Definitions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Separate from NINJA Physics, other activity has recently accelerated on LSL script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs.&lt;br /&gt;
&lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available. &amp;lt;b&amp;gt;Important note if NINJA Physics is not working for you:&amp;lt;/b&amp;gt; The NINJA Physics in SVN r7875 should work but requires C# 3.0. The NINJA Physics in r7878 does &amp;lt;b&amp;gt;not work&amp;lt;/b&amp;gt;. If you use SVN r7878 or above, please apply the additional patch in Mantis #2928 at http://opensimulator.org/mantis/view.php?id=2928&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt;, also called a &amp;lt;i&amp;gt;joint prim&amp;lt;/i&amp;gt;, is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the affected prims' movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate. A joint prim only affects the physics simulation if the joint prim's &amp;quot;[x] Physical&amp;quot; property is activated.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint prim.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors. If, for example, you create a hinge joint (by naming a prim &amp;quot;hingejoint-uniquename&amp;quot;) but specify non-existent or non-physical body names in the Description field, the joint will not be able to be created and a warning icon appears in-world on top of the joint. Click on the warning icon to see the error message. Deactivate, correct, and re-activate the joint.&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object. You should only change the name when the joint is deactivated. &lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected. You should only change the name when the prim is deactivated.&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no geometric representation in the physics scene. While the joint proxy is active (physical), you cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction, collision bounce, and collision filtering settings in OpenSim.ini can be tweaked for different effects.&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has been re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of prim taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Editing and Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name, where such names are unique for the entire region.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims (Mantis #2966).&lt;br /&gt;
* Editing one or several joints or prims in an actively simulating assembly should freeze the entire assembly, but it doesn't. (The assembly keeps simulating and moving even if a part of the assembly is selected for editing.)&lt;br /&gt;
&lt;br /&gt;
== Linked or attached prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
* Don't try to attach (to your avatar) prims that are part of a jointed assembly. This would however be a very cool feature in the future (allowing things like physical ponytails that swing properly), but needs more research about how to implement it.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2009-01-12T11:55:50Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Editing and Naming limitations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Separate from NINJA Physics, other activity has recently accelerated on LSL script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs.&lt;br /&gt;
&lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available. &amp;lt;b&amp;gt;Important note if NINJA Physics is not working for you:&amp;lt;/b&amp;gt; The NINJA Physics in SVN r7875 should work but requires C# 3.0. The NINJA Physics in r7878 does &amp;lt;b&amp;gt;not work&amp;lt;/b&amp;gt;. If you use SVN r7878 or above, please apply the additional patch in Mantis #2928 at http://opensimulator.org/mantis/view.php?id=2928&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors. If, for example, you create a hinge joint (by naming a prim &amp;quot;hingejoint-uniquename&amp;quot;) but specify non-existent or non-physical body names in the Description field, the joint will not be able to be created and a warning icon appears in-world on top of the joint. Click on the warning icon to see the error message. Deactivate, correct, and re-activate the joint.&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object. You should only change the name when the joint is deactivated. &lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected. You should only change the name when the prim is deactivated.&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no geometric representation in the physics scene. While the joint proxy is active (physical), you cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction, collision bounce, and collision filtering settings in OpenSim.ini can be tweaked for different effects.&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has been re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of prim taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Editing and Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name, where such names are unique for the entire region.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims (Mantis #2966).&lt;br /&gt;
* Editing one or several joints or prims in an actively simulating assembly should freeze the entire assembly, but it doesn't. (The assembly keeps simulating and moving even if a part of the assembly is selected for editing.)&lt;br /&gt;
&lt;br /&gt;
== Linked or attached prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
* Don't try to attach (to your avatar) prims that are part of a jointed assembly. This would however be a very cool feature in the future (allowing things like physical ponytails that swing properly), but needs more research about how to implement it.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2009-01-12T11:54:13Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Naming limitations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Separate from NINJA Physics, other activity has recently accelerated on LSL script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs.&lt;br /&gt;
&lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available. &amp;lt;b&amp;gt;Important note if NINJA Physics is not working for you:&amp;lt;/b&amp;gt; The NINJA Physics in SVN r7875 should work but requires C# 3.0. The NINJA Physics in r7878 does &amp;lt;b&amp;gt;not work&amp;lt;/b&amp;gt;. If you use SVN r7878 or above, please apply the additional patch in Mantis #2928 at http://opensimulator.org/mantis/view.php?id=2928&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors. If, for example, you create a hinge joint (by naming a prim &amp;quot;hingejoint-uniquename&amp;quot;) but specify non-existent or non-physical body names in the Description field, the joint will not be able to be created and a warning icon appears in-world on top of the joint. Click on the warning icon to see the error message. Deactivate, correct, and re-activate the joint.&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object. You should only change the name when the joint is deactivated. &lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected. You should only change the name when the prim is deactivated.&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no geometric representation in the physics scene. While the joint proxy is active (physical), you cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction, collision bounce, and collision filtering settings in OpenSim.ini can be tweaked for different effects.&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has been re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of prim taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Editing and Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name, where such names are unique for the entire region.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims (Mantis #).&lt;br /&gt;
* Editing one or several joints or prims in an actively simulating assembly should freeze the entire assembly, but it doesn't. (The assembly keeps simulating and moving even if a part of the assembly is selected for editing.)&lt;br /&gt;
&lt;br /&gt;
== Linked or attached prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
* Don't try to attach (to your avatar) prims that are part of a jointed assembly. This would however be a very cool feature in the future (allowing things like physical ponytails that swing properly), but needs more research about how to implement it.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2009-01-08T08:25:04Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Linked or attached prims */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Separate from NINJA Physics, other activity has recently accelerated on LSL script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs.&lt;br /&gt;
&lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available. &amp;lt;b&amp;gt;Important note if NINJA Physics is not working for you:&amp;lt;/b&amp;gt; The NINJA Physics in SVN r7875 should work but requires C# 3.0. The NINJA Physics in r7878 does &amp;lt;b&amp;gt;not work&amp;lt;/b&amp;gt;. If you use SVN r7878 or above, please apply the additional patch in Mantis #2928 at http://opensimulator.org/mantis/view.php?id=2928&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors. If, for example, you create a hinge joint (by naming a prim &amp;quot;hingejoint-uniquename&amp;quot;) but specify non-existent or non-physical body names in the Description field, the joint will not be able to be created and a warning icon appears in-world on top of the joint. Click on the warning icon to see the error message. Deactivate, correct, and re-activate the joint.&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object. You should only change the name when the joint is deactivated. &lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected. You should only change the name when the prim is deactivated.&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no geometric representation in the physics scene. While the joint proxy is active (physical), you cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction, collision bounce, and collision filtering settings in OpenSim.ini can be tweaked for different effects.&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has been re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of prim taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked or attached prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
* Don't try to attach (to your avatar) prims that are part of a jointed assembly. This would however be a very cool feature in the future (allowing things like physical ponytails that swing properly), but needs more research about how to implement it.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2009-01-08T08:24:18Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: attached jointed assemblies&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Separate from NINJA Physics, other activity has recently accelerated on LSL script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs.&lt;br /&gt;
&lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available. &amp;lt;b&amp;gt;Important note if NINJA Physics is not working for you:&amp;lt;/b&amp;gt; The NINJA Physics in SVN r7875 should work but requires C# 3.0. The NINJA Physics in r7878 does &amp;lt;b&amp;gt;not work&amp;lt;/b&amp;gt;. If you use SVN r7878 or above, please apply the additional patch in Mantis #2928 at http://opensimulator.org/mantis/view.php?id=2928&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors. If, for example, you create a hinge joint (by naming a prim &amp;quot;hingejoint-uniquename&amp;quot;) but specify non-existent or non-physical body names in the Description field, the joint will not be able to be created and a warning icon appears in-world on top of the joint. Click on the warning icon to see the error message. Deactivate, correct, and re-activate the joint.&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object. You should only change the name when the joint is deactivated. &lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected. You should only change the name when the prim is deactivated.&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no geometric representation in the physics scene. While the joint proxy is active (physical), you cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction, collision bounce, and collision filtering settings in OpenSim.ini can be tweaked for different effects.&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has been re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of prim taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked or attached prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
* Don't try to attach (to your avatar) prims that are part of a jointed assembly. This would however be a very cool feature in the future, but needs more research about how to implement it.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-29T13:10:10Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Troubleshooting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Separate from NINJA Physics, other activity has recently accelerated on LSL script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs.&lt;br /&gt;
&lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available. &amp;lt;b&amp;gt;Important note if NINJA Physics is not working for you:&amp;lt;/b&amp;gt; The NINJA Physics in SVN r7875 should work but requires C# 3.0. The NINJA Physics in r7878 does &amp;lt;b&amp;gt;not work&amp;lt;/b&amp;gt;. If you use SVN r7878 or above, please apply the additional patch in Mantis #2928 at http://opensimulator.org/mantis/view.php?id=2928&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors. If, for example, you create a hinge joint (by naming a prim &amp;quot;hingejoint-uniquename&amp;quot;) but specify non-existent or non-physical body names in the Description field, the joint will not be able to be created and a warning icon appears in-world on top of the joint. Click on the warning icon to see the error message. Deactivate, correct, and re-activate the joint.&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object. You should only change the name when the joint is deactivated. &lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected. You should only change the name when the prim is deactivated.&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no geometric representation in the physics scene. While the joint proxy is active (physical), you cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction, collision bounce, and collision filtering settings in OpenSim.ini can be tweaked for different effects.&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has been re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of prim taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-29T00:58:48Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Separate from NINJA Physics, other activity has recently accelerated on LSL script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs.&lt;br /&gt;
&lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available. &amp;lt;b&amp;gt;Important note if NINJA Physics is not working for you:&amp;lt;/b&amp;gt; The NINJA Physics in SVN r7875 should work but requires C# 3.0. The NINJA Physics in r7878 does &amp;lt;b&amp;gt;not work&amp;lt;/b&amp;gt;. If you use SVN r7878 or above, please apply the additional patch in Mantis #2928 at http://opensimulator.org/mantis/view.php?id=2928&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors. If, for example, you create a hinge joint (by naming a prim &amp;quot;hingejoiint-uniquename&amp;quot;) but specify non-existent or non-physical body names in the Description field, the joint will not be able to be created and a warning icon appears in-world on top of the joint. Click on the warning icon to see the error message. Deactivate, correct, and re-activate the joint.&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object. You should only change the name when the joint is deactivated. &lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected. You should only change the name when the prim is deactivated.&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no geometric representation in the physics scene. While the joint proxy is active (physical), you cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction, collision bounce, and collision filtering settings in OpenSim.ini can be tweaked for different effects.&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has been re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of prim taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-28T17:17:42Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs.&lt;br /&gt;
&lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available. &amp;lt;b&amp;gt;Important note if NINJA Physics is not working for you:&amp;lt;/b&amp;gt; The NINJA Physics in SVN r7875 should work but requires C# 3.0. The NINJA Physics in r7878 does &amp;lt;b&amp;gt;not work&amp;lt;/b&amp;gt;. If you use SVN r7878 or above, please apply the additional patch in Mantis #2928 at http://opensimulator.org/mantis/view.php?id=2928&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors. If, for example, you create a hinge joint (by naming a prim &amp;quot;hingejoiint-uniquename&amp;quot;) but specify non-existent or non-physical body names in the Description field, the joint will not be able to be created and a warning icon appears in-world on top of the joint. Click on the warning icon to see the error message. Deactivate, correct, and re-activate the joint.&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object. You should only change the name when the joint is deactivated. &lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected. You should only change the name when the prim is deactivated.&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no geometric representation in the physics scene. While the joint proxy is active (physical), you cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction, collision bounce, and collision filtering settings in OpenSim.ini can be tweaked for different effects.&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has been re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of prim taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-28T14:13:26Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Quick start */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available. &amp;lt;b&amp;gt;Important note if NINJA Physics is not working for you:&amp;lt;/b&amp;gt; The NINJA Physics in SVN r7875 should work but requires C# 3.0. The NINJA Physics in r7878 does &amp;lt;b&amp;gt;not work&amp;lt;/b&amp;gt;. If you use SVN r7878 or above, please apply the additional patch in Mantis #2928 at http://opensimulator.org/mantis/view.php?id=2928&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors. If, for example, you create a hinge joint (by naming a prim &amp;quot;hingejoiint-uniquename&amp;quot;) but specify non-existent or non-physical body names in the Description field, the joint will not be able to be created and a warning icon appears in-world on top of the joint. Click on the warning icon to see the error message. Deactivate, correct, and re-activate the joint.&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object. You should only change the name when the joint is deactivated. &lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected. You should only change the name when the prim is deactivated.&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no geometric representation in the physics scene. While the joint proxy is active (physical), you cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction, collision bounce, and collision filtering settings in OpenSim.ini can be tweaked for different effects.&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has been re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of prim taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-28T03:59:34Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Tips for effectively using joints */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available.&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors. If, for example, you create a hinge joint (by naming a prim &amp;quot;hingejoiint-uniquename&amp;quot;) but specify non-existent or non-physical body names in the Description field, the joint will not be able to be created and a warning icon appears in-world on top of the joint. Click on the warning icon to see the error message. Deactivate, correct, and re-activate the joint.&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object. You should only change the name when the joint is deactivated. &lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected. You should only change the name when the prim is deactivated.&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no geometric representation in the physics scene. While the joint proxy is active (physical), you cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction, collision bounce, and collision filtering settings in OpenSim.ini can be tweaked for different effects.&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has been re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of prim taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T18:17:51Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Tips for effectively using joints */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available.&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors. If, for example, you create a hinge joint (by naming a prim &amp;quot;hingejoiint-uniquename&amp;quot;) but specify non-existent or non-physical body names in the Description field, the joint will not be able to be created and a warning icon appears in-world on top of the joint. Click on the warning icon to see the error message. Deactivate, correct, and re-activate the joint.&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object. You should only change the name when the joint is deactivated. &lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected. You should only change the name when the prim is deactivated.&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no geometric representation in the physics scene. You cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction, collision bounce, and collision filtering settings in OpenSim.ini can be tweaked for different effects.&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has been re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of prim taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T18:14:06Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Tips for effectively using joints */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available.&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors. If, for example, you create a hinge joint (by naming a prim &amp;quot;hingejoiint-uniquename&amp;quot;) but specify non-existent or non-physical body names in the Description field, the joint will not be able to be created and a warning icon appears in-world on top of the joint. Click on the warning icon to see the error message. Deactivate, correct, and re-activate the joint.&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object. You should only change the name when the joint is deactivated. &lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected. You should only change the name when the prim is deactivated.&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no geometric representation in the physics scene. You cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has been re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of prim taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T18:12:12Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Troubleshooting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available.&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors. If, for example, you create a hinge joint (by naming a prim &amp;quot;hingejoiint-uniquename&amp;quot;) but specify non-existent or non-physical body names in the Description field, the joint will not be able to be created and a warning icon appears in-world on top of the joint. Click on the warning icon to see the error message. Deactivate, correct, and re-activate the joint.&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object. You should only change the name when the joint is deactivated. &lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected. You should only change the name when the prim is deactivated.&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has been re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of prim taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T14:25:55Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Part 5: ODE joints implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available.&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object.&lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected.&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has been re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of prim taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T14:22:46Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Part 5: ODE joints implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available.&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object.&lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected.&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has been re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T14:17:03Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Activating and deactivating bodies and joints */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available.&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object causes deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object.&lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected.&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has bee re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T13:24:11Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Tips for effectively using joints */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available.&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object.&lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected.&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has bee re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T11:48:38Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Tips for effectively using joints */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available.&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object.&lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected.&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joiints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joints don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has bee re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T11:31:24Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Activating and deactivating bodies and joints */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available.&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object.&lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected.&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joiints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joint's don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has bee re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T11:29:02Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Multi-user testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available.&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
, especially == Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object.&lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected.&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joiints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joint's don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has bee re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Client-side issues ==&lt;br /&gt;
The client has no knowledge of joints and renders each prim separately. It is possible that network lags will lead to temporary visual breakage of the joints on the client because the jointed prims' positions/orientations/velocities are updated separately without consideration of the joints.&lt;br /&gt;
&lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T11:20:12Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Part 5: ODE joints implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available.&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
, especially == Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object.&lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected.&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joiints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joint's don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge. In v2 of the patch (included in trunk) the optimization - which is actually a throttle that is necessary - has bee re-instated, additionally adding a check for rotational-only motion to allow rotation updates to be transmitted even in the absence of translational motion.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T11:17:34Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Part 3: scene */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available.&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
, especially == Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object.&lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected.&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joiints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joint's don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach.&lt;br /&gt;
&lt;br /&gt;
In v2 of this patch (now included in trunk), the joint callback handlers have been moved into Scene.cs.&lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T11:12:20Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Quick start */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# &amp;lt;s&amp;gt;Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&amp;lt;/s&amp;gt; I am happy to report that NINJA Physics is included in trunk SVN as of r7875, so update your repository and it should be available.&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
, especially == Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object.&lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected.&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joiints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joint's don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T11:02:02Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Tips for effectively using joints */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
, especially == Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object.&lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected.&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joiints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joint's don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T11:01:12Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Troubleshooting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
, especially == Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems. If you keep getting errors with a joint, it is possible that some other prim somewhere in the region has the same name. Try changing the name of the joint proxy object.&lt;br /&gt;
* Duplicate prim names cause problems. If you are repeatedly unable to connect a prim with a joint, it is possible that some other prim somewhere in the region has the same name, and that the joint is connecting to that prim instead of the one you want. Try changing the name of the prim being connected.&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joiints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joint's don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T10:56:35Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Tips for effectively using joints */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems&lt;br /&gt;
* Duplicate prim names cause problems&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joiints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez. Do not rez the same jointed assembly more than once or you will have prims and joints with duplicate names, which causes unexpected behavior as the joint's don't know which of the duplicated prims they are supposed to connect.&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T10:54:26Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Persistence of joints */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems&lt;br /&gt;
* Duplicate prim names cause problems&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joiints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* All jointed assemblies in the region should be deactivated before shutting down the region. Upon region restart, select and re-activate the jointed assemblies. However, this leads to gradual accumulation of joint error (see below). &lt;br /&gt;
* &amp;quot;Live&amp;quot; jointed assemblies are not properly restored on region shutdown/startup. In other words, if you activate a jointed assembly then, while the jointed assembly is still simulating, shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup. This is a bug and will hopefully soon be fixed. Additionally, accumulation of joint error still occurs (see below).&lt;br /&gt;
* A region with deactivated jointed assemblies can be saved/loaded with save-oar/load-oar. However, trying to use save-oar/load-oar with live jointed assemblies that are actively simulating doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
&lt;br /&gt;
To summarize:&lt;br /&gt;
* Deactivate jointed assemblies before persisting them. &lt;br /&gt;
* Expect gradual accumulation of joint error over time (see below).&lt;br /&gt;
* Periodically delete and re-rez the jointed assembly from inventory to correct joint error.&lt;br /&gt;
&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T10:44:04Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Tips for effectively using joints */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems&lt;br /&gt;
* Duplicate prim names cause problems&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint proxy (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* Prims connected by joiints should probably be simple shapes like boxes or spheres for simpler collision. Complex shapes with twists or cuts cause creation of concave meshes with sharp corners which may not collide smoothly (leading to jitter) or quickly. Unfortunately, it doesn't seem possible to use ODE capsules (often used for ragdoll limbs) for collision detection because there is no way to specify a &amp;quot;capsule&amp;quot; geometry for a prim in the viewer.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* Region shutdown/startup persistence doesn't yet work. In other words, if you activate a jointed assembly then shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup.&lt;br /&gt;
* load-oar persistence doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T10:23:12Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Naming limitations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems&lt;br /&gt;
* Duplicate prim names cause problems&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
== Linked prims ==&lt;br /&gt;
* A linked prim cannot currently be part of a jointed assembly.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* Region shutdown/startup persistence doesn't yet work. In other words, if you activate a jointed assembly then shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup.&lt;br /&gt;
* load-oar persistence doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T03:46:16Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Tips for effectively using joints */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems&lt;br /&gt;
* Duplicate prim names cause problems&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top each other and on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* Region shutdown/startup persistence doesn't yet work. In other words, if you activate a jointed assembly then shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup.&lt;br /&gt;
* load-oar persistence doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T03:43:26Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Troubleshooting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems&lt;br /&gt;
* Duplicate prim names cause problems&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
== Tips for effectively using joints ==&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* The joint proxy object itself does not collide with anything and has no representation in the physics scene. You cannot directly physically manipulate the joint (by dragging it in the viewer or through script physics). When active, its position always automatically follows the position of the jointed bodies.&lt;br /&gt;
* Prims connected by a joint do not collide with each other.&lt;br /&gt;
* Prims connected by a joint can overlap on top of the joint proxy object, effectively hiding the joint proxy object.&lt;br /&gt;
* You can also make the joint proxy object very small or transparent to hide it.&lt;br /&gt;
* If you hide the joint proxy, it can be difficult to debug when things go wrong. Hide joints only after you've verified that the joints are created properly.&lt;br /&gt;
* To take a jointed assembly into inventory:&lt;br /&gt;
** Select all&lt;br /&gt;
** Deactivate&lt;br /&gt;
** Link&lt;br /&gt;
** Take&lt;br /&gt;
* To rez a jointed assembly from inventory:&lt;br /&gt;
** Rez&lt;br /&gt;
** Move to desired location&lt;br /&gt;
** Unlink&lt;br /&gt;
** Select all&lt;br /&gt;
** Activate&lt;br /&gt;
* Friction settings in OpenSim.ini can be tweaked for different effects&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* Region shutdown/startup persistence doesn't yet work. In other words, if you activate a jointed assembly then shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup.&lt;br /&gt;
* load-oar persistence doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T03:33:15Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Things that can go wrong */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems&lt;br /&gt;
* Duplicate prim names cause problems&lt;br /&gt;
* Joint error messages displayed in-world like script compiler errors&lt;br /&gt;
* Workflow for creating a complex jointed assembly&lt;br /&gt;
** Create a few prims&lt;br /&gt;
** Create a few joints&lt;br /&gt;
** Select them all&lt;br /&gt;
** Keeping the selection, click &amp;quot;[x] Physical&amp;quot; to turn on physics&lt;br /&gt;
** Keeping the selection, observe if joint error message icons appear&lt;br /&gt;
** Keeping the selection, cllick &amp;quot;[ ] Physical&amp;quot; to turn off physics&lt;br /&gt;
** Fix any joint error messages that occured (e.g. mistyped or duplicate prim names)&lt;br /&gt;
** Repeat&lt;br /&gt;
** When all joint error messages are fixed for the group of prims under consideration, continue to construct more of the assembly&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* Region shutdown/startup persistence doesn't yet work. In other words, if you activate a jointed assembly then shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup.&lt;br /&gt;
* load-oar persistence doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T03:26:04Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Noisy logging */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Things that can go wrong ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems&lt;br /&gt;
* Duplicate prim names cause problems&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* Region shutdown/startup persistence doesn't yet work. In other words, if you activate a jointed assembly then shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup.&lt;br /&gt;
* load-oar persistence doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-27T03:22:59Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Activating and deactivating bodies and joints */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
== Things that can go wrong ==&lt;br /&gt;
&lt;br /&gt;
(work in progress...)&lt;br /&gt;
&lt;br /&gt;
* Duplicate joint names cause problems&lt;br /&gt;
* Duplicate prim names cause problems&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
== Noisy logging ==&lt;br /&gt;
The current logging output contains too many debugging messages and should be reduced.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* Region shutdown/startup persistence doesn't yet work. In other words, if you activate a jointed assembly then shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup.&lt;br /&gt;
* load-oar persistence doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-19T15:01:28Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Quick start */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/download/frsrelease/142/304/demo-playground.tgz&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
== Noisy logging ==&lt;br /&gt;
The current logging output contains too many debugging messages and should be reduced.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* Region shutdown/startup persistence doesn't yet work. In other words, if you activate a jointed assembly then shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup.&lt;br /&gt;
* load-oar persistence doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-19T11:38:24Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/project/ninjaphysics/scmsvn/?action=browse&amp;amp;path=%2F%2Acheckout%2A%2Ftrunk%2Fdata%2Fdemo-playground.tgz&amp;amp;revision=2&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
== Noisy logging ==&lt;br /&gt;
The current logging output contains too many debugging messages and should be reduced.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* Region shutdown/startup persistence doesn't yet work. In other words, if you activate a jointed assembly then shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup.&lt;br /&gt;
* load-oar persistence doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;br /&gt;
= Links =&lt;br /&gt;
* GForge project homepage http://forge.opensimulator.org/gf/project/ninjaphysics/&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-19T11:32:36Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Philosophy */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/project/ninjaphysics/scmsvn/?action=browse&amp;amp;path=%2F%2Acheckout%2A%2Ftrunk%2Fdata%2Fdemo-playground.tgz&amp;amp;revision=2&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
== Noisy logging ==&lt;br /&gt;
The current logging output contains too many debugging messages and should be reduced.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* Region shutdown/startup persistence doesn't yet work. In other words, if you activate a jointed assembly then shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup.&lt;br /&gt;
* load-oar persistence doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-19T11:31:32Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Definitions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by using repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/project/ninjaphysics/scmsvn/?action=browse&amp;amp;path=%2F%2Acheckout%2A%2Ftrunk%2Fdata%2Fdemo-playground.tgz&amp;amp;revision=2&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is initially specified by and later visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
== Noisy logging ==&lt;br /&gt;
The current logging output contains too many debugging messages and should be reduced.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* Region shutdown/startup persistence doesn't yet work. In other words, if you activate a jointed assembly then shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup.&lt;br /&gt;
* load-oar persistence doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-19T11:25:55Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by using repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts.patch to your OpenSim source tree and compile. Available at http://opensimulator.org/mantis/view.php?id=2874&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory. Available at http://forge.opensimulator.org/gf/project/ninjaphysics/scmsvn/?action=browse&amp;amp;path=%2F%2Acheckout%2A%2Ftrunk%2Fdata%2Fdemo-playground.tgz&amp;amp;revision=2&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select all prims in the swing object (Ctrl+3, mouse drag). If you have a powerful CPU, you can also select everything in the region, but note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on the jointed assembly and drag it around. Also, the following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
== Noisy logging ==&lt;br /&gt;
The current logging output contains too many debugging messages and should be reduced.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* Region shutdown/startup persistence doesn't yet work. In other words, if you activate a jointed assembly then shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup.&lt;br /&gt;
* load-oar persistence doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-19T11:10:53Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Quick start */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by using repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts to your OpenSim source tree and compile.&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select everything in the region (Ctrl+3, mouse drag). Note that processing joints takes some CPU power, so you may want to select a smaller group of objects to start.&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on any jointed assembly and drag it around. The following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
== Noisy logging ==&lt;br /&gt;
The current logging output contains too many debugging messages and should be reduced.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* Region shutdown/startup persistence doesn't yet work. In other words, if you activate a jointed assembly then shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup.&lt;br /&gt;
* load-oar persistence doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-19T11:05:47Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Part 6 - OpenSim.ini.example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by using repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts to your OpenSim source tree and compile.&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select everything in the region (Ctrl+3, mouse drag). (You can also select a smaller group of objects.)&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on any jointed assembly and drag it around. The following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6: OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
== Noisy logging ==&lt;br /&gt;
The current logging output contains too many debugging messages and should be reduced.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* Region shutdown/startup persistence doesn't yet work. In other words, if you activate a jointed assembly then shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup.&lt;br /&gt;
* load-oar persistence doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-19T11:05:14Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* Naming limitations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by using repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts to your OpenSim source tree and compile.&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select everything in the region (Ctrl+3, mouse drag). (You can also select a smaller group of objects.)&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on any jointed assembly and drag it around. The following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6 - OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
== Noisy logging ==&lt;br /&gt;
The current logging output contains too many debugging messages and should be reduced.&lt;br /&gt;
&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* Region shutdown/startup persistence doesn't yet work. In other words, if you activate a jointed assembly then shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup.&lt;br /&gt;
* load-oar persistence doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-19T10:48:07Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: /* NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
This project proposes a new physics extension called NINJA Physics. The NINJA Physics extension enhances the ODE physics in OpenSim with joints: movable linkages between prims. This will allow wheeled vehicles, ragdolls, and mechanical/robotic assemblies to be interactively built within the standard viewer and controllable through scripting. This kind of physics is not currently available in OpenSim or Second Life.&lt;br /&gt;
&lt;br /&gt;
A demonstration of the idea can be seen here: http://jp.youtube.com/watch?v=nirTXPO-opE&lt;br /&gt;
&lt;br /&gt;
NINJA stands for a Networked INteractive Jointed Assembly. &amp;quot;Jointed Assembly&amp;quot; refers to an articulated rigid body. The &amp;quot;INteractive&amp;quot; aspect refers to interactive editing in 3D space of jointed assemblies using the viewer and intuitive 3D placement of joint objects as normal prims.  The &amp;quot;Networked&amp;quot; aspect refers to many users simultaneously interacting with jointed assemblies in a networked virtual world. &lt;br /&gt;
&lt;br /&gt;
The core ODE physics engine already provides support for joints; it is OpenSim and the viewer that lack support. This project therefore aims to extend the OpenSim physics interface to access the ODE joint functionality. Furthermore, this project must also provide a means of creating and editing joints within the standard viewer, which has no native support for joints. In the future, viewer changes and protocol changes can be considered for native joint support.&lt;br /&gt;
&lt;br /&gt;
This new kind of physics, jointed physics, is separate from and complementary to the existing LSL script-based vehicles. Activity has recently accelerated on script-based vehicles, with some water-based vehicles already working (e.g. sailboats). The new jointed/NINJA physics will allow more new kinds of vehicles not currently possible with scripting. Two example of new kinds of vehicles are cars with wheels that actually turn and rotate, and robots that walk by moving limbs. &lt;br /&gt;
= Philosophy =&lt;br /&gt;
The development of NINJA Physics follows these principles.&lt;br /&gt;
&lt;br /&gt;
# Break nothing. When turned off, NINJA Physics should have no observable effect on simulator behavior. When turned on, existing physics behavior without joints should be exactly the same as before. Additionally, new physics behavior with joints should be available to the user.&lt;br /&gt;
# Standard viewer compatibility. Editing of joints must be possible using only the affordances of the standard viewer. This means we must enter new information (joint information) in an existing GUI not designed for that purpose. We do this by using repurposing existing prim editor fields (Name and Description) and using a special naming convention to specify joints. The requirment of standard viewer compatibility conflicts slightly with the requirement of breaking nothing; by using a special naming convention, it is possible that existing regions might already use that naming convention, which would lead to altered behavior. In practice, this will likely not be a great concern.&lt;br /&gt;
# Code readability. The first version of the NINJA Physics patch is implemented in as straightforward a way as possible to allow understanding and critique of the basic approach. At this stage, no overly-clever optimizations and only necessary abstractions have been applied.&lt;br /&gt;
# Generalizability. The first version of NINJA Physics is implemented using ODE Physics, but the same implementation should be usable for any physics engine that supports joints.&lt;br /&gt;
&lt;br /&gt;
= User documentation =&lt;br /&gt;
== Quick start ==&lt;br /&gt;
To try out NINJA Physics, follow these steps.&lt;br /&gt;
# Apply the patch ninja-allparts to your OpenSim source tree and compile.&lt;br /&gt;
# Copy demo-playground.tgz to your opensim/bin directory&lt;br /&gt;
# Edit OpenSim.ini to run in standalone mode with ODE physics. Set use_NINJA_physics_joints=true.&lt;br /&gt;
# Start OpenSim.exe. In the region console type load-oar demo-playground.tgz to load demo data.&lt;br /&gt;
# Login to the region and navigate to (128,128). Select everything in the region (Ctrl+3, mouse drag). (You can also select a smaller group of objects.)&lt;br /&gt;
# In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab to turn the selection physical, then press ESC to exit selection mode. The prims and the joints go &amp;quot;live&amp;quot;.&lt;br /&gt;
# Click on any jointed assembly and drag it around. The following commands spoken in chat can control the ragdoll: &amp;quot;arise&amp;quot;, &amp;quot;kneel&amp;quot;, &amp;quot;die&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Definitions ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint&amp;lt;/i&amp;gt; is a constraint on the motion of rigid bodies. Currently we consider two types of joints: a ball-and-socket joint and a hinge joint. A ball-and-socket joint is similar to the joint connecting your upper arm to your shoulder; the joint constrains the position of the two bodies, but allows free rotation. A hinge joint is similar to a door hinge: it constrains the position of two bodies but allows rotation about only one axis, the hinge axis. By using joints, we can create complex assemblies of prims in OpenSim that move with realistically-constrained motion.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;joint proxy object&amp;lt;/i&amp;gt; is a prim created in the viewer and existing within the region to represent a joint. Its position, relative to the prims it affects, defines the position around which the prims movement will be constrained. For hinge joints, the orientation of the joint proxy object defines the hinge axis; specifically, the x-axis of the proxy object is defined as the axis about which the connected prims will be allowed to rotate.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;i&amp;gt;physics engine joint&amp;lt;/i&amp;gt; is the data structure within the physics engine that actually constrains the behavior of the rigid bodies as simulated in the simulator. The physics engine joint is visualized by the joint proxy object.&lt;br /&gt;
&lt;br /&gt;
== Enabling NINJA Physics in OpenSim.ini ==&lt;br /&gt;
&lt;br /&gt;
In OpenSim.ini, set &amp;quot;physics = OpenDynamicsEngine&amp;quot; and &amp;quot;use_NINJA_physics_joints = true&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Creating a ball-and-socket joint == &lt;br /&gt;
&lt;br /&gt;
Create two box prims side-by-side with space in between them.  Leave them non-physical for now. Give each one a unique name  (right click, edit, General tab, Name). Example names are  &amp;quot;box1&amp;quot; and &amp;quot;box2&amp;quot;. Leave the dimensions at (0.5, 0.5, 0.5).  These 2 prims will be connected by a ball joint.&lt;br /&gt;
&lt;br /&gt;
Create a small sphere. Make its dimensions something like  (0.1, 0.1, 0.1). This prim represents a ball-and-socket joint.  Position the sphere between the 2 boxes. Assign the small sphere the name of &amp;quot;balljoint-uniquename&amp;quot;, where &amp;quot;uniquename&amp;quot; is a unique name not used by any other prim. Give the sphere a Description of &amp;quot;box1 box2&amp;quot;, which are the names of the 2 prims to be connected, separated by a space.&lt;br /&gt;
&lt;br /&gt;
Close all windows in the viewer. Press Ctrl+3 to enter edit mode. Drag the mouse to highlight the 2 boxes to be connected and the small sphere.&lt;br /&gt;
&lt;br /&gt;
In the object editing window, click on the &amp;quot;Physical&amp;quot; checkbox in the &amp;quot;Object&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Drag the boxes around and notice they remain connected by a joint. &lt;br /&gt;
&lt;br /&gt;
== Creating a hinge joint == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A similar procedure is used for creating bodies connected with hinge joints, with the following differces:&lt;br /&gt;
&lt;br /&gt;
The joint object should be named &amp;quot;hingejoint-uniquename&amp;quot;, where uniquename is a unique name not used elsewhere in the region.&lt;br /&gt;
&lt;br /&gt;
The joint object's position determines the anchor of the hinge.&lt;br /&gt;
&lt;br /&gt;
The joint object's X axis orientation determines the axis of rotation of the hinge. The easiest way to visualize this is to create a prim whose size is elongated along its x axis; set the object size directly in the object editor to something like (1.0, 0.1, 0.1).&lt;br /&gt;
&lt;br /&gt;
Hinges can be used for simulating wheels. Connected bodies can rotate freely around the hinge, like a wheel around an axle.&lt;br /&gt;
&lt;br /&gt;
== Activating and deactivating bodies and joints ==&lt;br /&gt;
&lt;br /&gt;
Setting a joint proxy object to &amp;quot;physical&amp;quot; causes creation of that joint in the physics engine. Setting the joint proxy object to non-physical, or deleting the joint proxy object, or taking the joint proxy object caused deletion of the corresponding joint in the physics engine. (This is why each joint must have a unique name, so that the physics engine knows which joint is being referred to.) Deleting joints in an active jointed assembly will cause the connected bodies to disconnect. Deleting, deactivating, or taking a prim in an active jointed assembly will cause all joints connected to that prim to deactivate.&lt;br /&gt;
&lt;br /&gt;
= Developer documentation =&lt;br /&gt;
&lt;br /&gt;
== Patch structure ==&lt;br /&gt;
&lt;br /&gt;
The patch for NINJA Physics is divided into 6 parts for better readability.&lt;br /&gt;
&lt;br /&gt;
=== Part 1: data structures ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part1-joint_data_structures.patch declares the PhysicsJoint class and its subclass OdePhysicsJoint for storing joint information.&lt;br /&gt;
&lt;br /&gt;
=== Part 2: abstract physics interface ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part2-physics_interfaces.patch alters PhysicsScene.cs with new methods for manipulating joints. The main idea is that a user of the physics engine can make joint requests or be notified of joint activity. Joint requests include requesting the physics engine to create or delete joints. Joint activity notification takes place through events that are fired whenever a joint is moved or a joint is deleted. These events allow the external scene to update scene information (position and orientation of joint proxy objects) to accurately reflect the state of the joints.&lt;br /&gt;
&lt;br /&gt;
This part of the patch also modifies PhysicsActor.cs to contain the scene object part name and description. The physics engine links bodies together based by looking for physics actors whose names match the joint description.&lt;br /&gt;
&lt;br /&gt;
=== Part 3: scene ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part3-scene.patch alters Scene.cs to allow NINJA Physics to be turned on/off. It also extends the behavior of DeleteSceneObject to delete the joint in the physics engine if the scene object corresponding to the joint (i.e. the joint proxy object) is deleted.&lt;br /&gt;
&lt;br /&gt;
Also, this part of the patch alters SceneGraph.cs with callback handlers to respond to joint movement or joint deletion notifications from the physics engine. When a joint in the physics engine is moved/deactivated, its representation in the scene (the joint proxy object) is correspondingly moved/stopped from moving. Note that the joint has no direct representation (i.e. no body or geom) in the physics engine, so the physics engine has no knowledge of the scene graph's joint proxy object, necessitating this callback approach. &lt;br /&gt;
&lt;br /&gt;
=== Part 4: SceneObjectPart ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part4-sceneobjectpart patches SceneObjectPart.cs to detect if the SceneObjectPart is a joint (based on its name of &amp;quot;balljoint-*&amp;quot; or &amp;quot;hingejoint-*&amp;quot;). If it is a joint, then requests to make this SceneObjectPart physical/non-physical are translated into calls to the physics scene to request creation/deletion of joints.&lt;br /&gt;
&lt;br /&gt;
=== Part 5: ODE joints implementation ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part5-ode.patch is the ODE implementation of NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
ODEPrim.cs is patched to remove an optimization that prevents updates from being sent when the object position is almost stationary. This prevents rotational-only motion from being sent to the client, such as a fan blade rotating on a hinge.&lt;br /&gt;
&lt;br /&gt;
OdePlugin.cs implements the creation and deletion of joints within ODE. Internal data structures keep track of associations between joints and bodies. Unprocessed joint requests (creation or deletion) are processed in the Simulate loop. &lt;br /&gt;
&lt;br /&gt;
Joint deletion requests are handled immediately and the joint deleted callback is invoked to nofity the external scene of the joint change. &lt;br /&gt;
&lt;br /&gt;
Joint creation requests are not handled immediately, because a joint can only be created if the bodies it is connecting already exist in the physics scene. Therefore, a joint creation request adds the new joint into a pending list. After processing of joint taints, a check is performed to see if any pending joints are still waiting for their respective bodies to appear in the physics engine. If such pending joints exist, and all of their bodies also exist, the joint is removed from the pending list and is actually created in ODE. Internal data structures also keep track of the association between bodies and the joints connected to that body.&lt;br /&gt;
&lt;br /&gt;
Finally, whenever an physics actor (body) moves, it is checked if that body is connected by joints. If so, movement of the body implies movement of the joints connected to that body. Therefore, a joint moved callback is invoked to notify the external scene of the joint motion.&lt;br /&gt;
&lt;br /&gt;
The DumpJointInfo function is useful for debugging.&lt;br /&gt;
&lt;br /&gt;
=== Part 6 - OpenSim.ini.example ===&lt;br /&gt;
&lt;br /&gt;
Patch ninja-part6-ini.patch shows the OpenSim.ini option to control NINJA Physics.&lt;br /&gt;
&lt;br /&gt;
== Joint states ==&lt;br /&gt;
Joints pass through the following states during their lifetime:&lt;br /&gt;
&lt;br /&gt;
* Requested creation. In this state, the joint is not yet processed by main physics simulation loop.&lt;br /&gt;
* Pending. In this state, the joint is processed by main physics loop but does not yet exist in the physics engine. It is waiting for its constituent bodies to exist in the physics engine.&lt;br /&gt;
* Active. In this state, the joint exists in ODE and affects the ODE simulation. Furthermore, motion of the joint generates a joint moved event that can be subscribed to and acted upon.&lt;br /&gt;
* Requesting deletion. In this state, the joint has requested to be deleted from the main physics simulation loop, but that request has not been processed by the main simulate loop. Therefore the joint is still being simulated.&lt;br /&gt;
* About to delete. In this state, the joint is about to be deleted and a joint deactivated event is sent to notify subscribers of the joint's impending death.&lt;br /&gt;
* Deleted. The joint no longer exists in ODE, does not affect the physical simulation, and generates no further events.&lt;br /&gt;
&lt;br /&gt;
= Limitations =&lt;br /&gt;
&lt;br /&gt;
This section describes some current limitations and shortcomings of the current implementation and areas of continuing and future work.&lt;br /&gt;
&lt;br /&gt;
== Naming limitations ==&lt;br /&gt;
* Each joint and each prim connected by a joint must have a unique name.&lt;br /&gt;
* Changes of joint names or prim names while the prim/joint is physical are not handled.&lt;br /&gt;
* When creating a joint, in the description field, use exactly one space between the names of the connected prims.&lt;br /&gt;
== Timing issues ==&lt;br /&gt;
* Extremely rapid toggling between physical and non-physical states, with the final state being &amp;quot;physical&amp;quot;, can sometimes incorrectly lead to the joint's last state being &amp;quot;non-physical&amp;quot;.&lt;br /&gt;
== Persistence of joints ==&lt;br /&gt;
* Region shutdown/startup persistence doesn't yet work. In other words, if you activate a jointed assembly then shutdown the region, upon region startup the recreated joints are not all perfectly reconstructed. It almost works, but some joint orientations are incorrect on region startup.&lt;br /&gt;
* load-oar persistence doesn't work due to threading/atomicity issues (see below).&lt;br /&gt;
== Atomicity issues ==&lt;br /&gt;
* Non-atomicity of viewer selection processing. If you select a group of non-physical prims and joints, and turn them all physical by clicking &amp;quot;physical&amp;quot; in the viewer, it is not guaranteed that the entire selected group will be turned physical in one tick of the simulation. It is therefore possible that part of the assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed. This will lead to joint positions different than the original static specification of the joints.&lt;br /&gt;
* Non-atomicity of load-oar. Due to multi-threading, physics simulation continues while a load-oar is executing. This again means that parts of an assembly will go &amp;quot;live&amp;quot; and start moving before all of the joints in the assembly have been constructed.&lt;br /&gt;
== Accumulation of joint error ==&lt;br /&gt;
Repeatedly deactivating and reactivating a jointed assembly will lead to non-reversible accumulation of error in the joints. The joint proxy object saves the &amp;quot;position&amp;quot; of the joint but this information is not complete information about the joint. In particular, it does not contain any information about the joint error. For instance, imagine a ball and socket joint where, due to extreme forces acting on the parts, the ball and socket have been forced apart, leading to joint error. Currently, the joint proxy object only saves the joint position relative to one body, which is analagous to saving only the position of the ball but not the position of the socket. Upon deactivating and reactivating a joint with joint error, the current body positions are assumed to be 0% error, which means that the original joint error has been permanently &amp;quot;forgotten&amp;quot;. &lt;br /&gt;
== Multi-user testing ==&lt;br /&gt;
This hasn't been tested in a multi-user environment. Single-user testing revealed occasional deadlocks which should hopefully now all be solved, but multi-user testing may expose more corner cases. My hope is that interested users of the OpenSim community can help test various multi-user scenarios. It will also be interesting to see how network latency and server load affect the user experience.&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/NINJA_Physics</id>
		<title>NINJA Physics</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/NINJA_Physics"/>
				<updated>2008-12-19T05:07:45Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: New page: = NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =  Documentation in progress&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= NINJA Physics: Networked INteractive Jointed Assemblies for OpenSim =&lt;br /&gt;
&lt;br /&gt;
Documentation in progress&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/User:Nlin</id>
		<title>User:Nlin</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/User:Nlin"/>
				<updated>2008-12-19T05:06:44Z</updated>
		
		<summary type="html">&lt;p&gt;Nlin: New page: Some projects of mine:  NINJA Physics&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Some projects of mine:&lt;br /&gt;
&lt;br /&gt;
[[NINJA Physics]]&lt;/div&gt;</summary>
		<author><name>Nlin</name></author>	</entry>

	</feed>