Index: /trunk/nv/bullet/bullet_world.hh
===================================================================
--- /trunk/nv/bullet/bullet_world.hh	(revision 526)
+++ /trunk/nv/bullet/bullet_world.hh	(revision 527)
@@ -27,4 +27,5 @@
 		virtual collision_shape create_sphere( float radius );
 		virtual collision_shape create_capsule( float radius, float height );
+		virtual collision_shape create_cylinder( const vec3& half_extents );
 		virtual collision_shape create_box( const vec3& half_extens );
 		virtual collision_shape create_static_plane( const vec3& norm, float cst );
Index: /trunk/nv/engine/model_manager.hh
===================================================================
--- /trunk/nv/engine/model_manager.hh	(revision 526)
+++ /trunk/nv/engine/model_manager.hh	(revision 527)
@@ -39,4 +39,11 @@
 		MNF_STATIC,
 	};
+
+	enum class phx_shape
+	{
+		BOX,
+		CYLINDER,
+	};
+
 
 	struct model;
@@ -57,4 +64,8 @@
 		float                        chance    = 1.0f;
 		flags<16,uint16>             nflags;
+		vec3                         phx_hextents;
+		vec3                         phx_offset;
+		float                        phx_mass  = 0.0f;
+		phx_shape                    phx_shape = phx_shape::BOX;
 		model_node_choice            choice    = model_node_choice::ALL;
 
@@ -68,4 +79,8 @@
 			target->position  = position;
 
+			target->phx_hextents = phx_hextents;
+			target->phx_offset   = phx_offset;
+			target->phx_mass     = phx_mass;
+			target->phx_shape    = phx_shape;
 			target->attach_id = attach_id;
 			target->weight    = weight;
@@ -101,4 +116,8 @@
 		sint16                       parent_id;
 		transform					 local;
+		vec3                         phx_hextents;
+		vec3                         phx_offset;
+		float                        phx_mass;
+		phx_shape                    phx_shape;
 		uint32                       gflags;
 	};
@@ -117,4 +136,5 @@
 	NV_RTTI_DECLARE_NAME( model_node_flags, "model_node_flags" )
 	NV_RTTI_DECLARE_NAME( model, "model" )
+	NV_RTTI_DECLARE_NAME( phx_shape, "phx_shape" )
 
 	enum flat_model_flags
@@ -163,5 +183,5 @@
 			result.count = 0;
 			result.phx_mesh = m->phx_mesh;
-			flatten( result, m, rng, control, transform(), -1, map, gen_flags, 0, select );
+			flatten( result, m, rng, control, transform(), transform(), -1, map, gen_flags, 0, select );
 			return result;
 		}
@@ -173,5 +193,6 @@
 			ivec2 control,
 			const transform& ptr, 
-			sint16 parent_id, 
+			const transform& fptr,
+			sint16 parent_id,
 			vector< const model_node* >* map,
 			uint32 gen_flags,
@@ -188,7 +209,13 @@
 						return;
 				}
-			transform tr = m->local;
+
+			bool skip_static = ( gen_flags & FF_GENERATE_NSTATIC ) && m->nflags[MNF_STATIC];
+			bool parse_mesh = ( ( m->mesh || !m->tag.empty() ) && !skip_static ) || ( m->nflags[MNF_FORCE] );
+
+			transform tr = fptr * m->local;
 			if ( !(gen_flags & FF_GENERATE_NLOCAL) )
 				tr = ptr * tr;
+
+
 			vec3 position = rng.eval( m->position );
 			vec3 rotation = rng.eval( m->rotation );
@@ -202,7 +229,12 @@
 					return;
 
-			bool skip_static = ( gen_flags & FF_GENERATE_NSTATIC ) && m->nflags[MNF_STATIC];
-
-			if ( ( ( m->mesh || !m->tag.empty() ) && !skip_static ) || ( m->nflags[MNF_FORCE] ) )
+			transform ftr;
+			if ( !parse_mesh && ( gen_flags & FF_GENERATE_NLOCAL ) )
+			{
+				ftr = tr;
+			}
+
+
+			if ( parse_mesh )
 			{
 				uint32 id = result.count++;
@@ -215,4 +247,9 @@
 				re.attach_id = m->attach_id;
 				re.gflags = parent_flags;
+				re.phx_hextents = m->phx_hextents;
+				re.phx_offset   = m->phx_offset;
+				re.phx_mass     = m->phx_mass;
+				re.phx_shape    = m->phx_shape;
+
 				if ( map ) map->push_back( m );
 				parent_id = sint16(id);
@@ -273,13 +310,13 @@
 						uint32 flags = parent_flags;
 						if ( c != pick ) flags |= FMF_FAIL_CHOICE;
-						flatten( result, c, rng, control, tr, parent_id, map, gen_flags, flags, selected );
+						flatten( result, c, rng, control, tr, ftr, parent_id, map, gen_flags, flags, selected );
 					}
 				else
-					flatten( result, pick, rng, control, tr, parent_id, map, gen_flags, parent_flags, selected );
+					flatten( result, pick, rng, control, tr, ftr, parent_id, map, gen_flags, parent_flags, selected );
 			}
 			else
 				for ( auto c : m->children )
 				{
-					flatten( result, c, rng, control, tr, parent_id, map, gen_flags, parent_flags, selected );
+					flatten( result, c, rng, control, tr, ftr, parent_id, map, gen_flags, parent_flags, selected );
 				}
 		}
Index: /trunk/nv/interface/physics_world.hh
===================================================================
--- /trunk/nv/interface/physics_world.hh	(revision 526)
+++ /trunk/nv/interface/physics_world.hh	(revision 527)
@@ -71,4 +71,5 @@
 		virtual collision_shape create_sphere( float radius ) = 0;
 		virtual collision_shape create_capsule( float radius, float height ) = 0;
+		virtual collision_shape create_cylinder( const vec3& half_extens ) = 0;
 		virtual collision_shape create_box( const vec3& half_extens ) = 0;
 		virtual collision_shape create_static_plane( const vec3& norm, float cst ) = 0;
Index: /trunk/src/bullet/bullet_world.cc
===================================================================
--- /trunk/src/bullet/bullet_world.cc	(revision 526)
+++ /trunk/src/bullet/bullet_world.cc	(revision 527)
@@ -88,4 +88,9 @@
 {
 	return collision_shape{ ( void* )new btCapsuleShape( radius, height ) };
+}
+
+nv::collision_shape nv::bullet_world::create_cylinder( const vec3& half_extents )
+{
+	return collision_shape{ ( void* )new btCylinderShape( n2b( half_extents ) ) };
 }
 
Index: /trunk/src/engine/model_manager.cc
===================================================================
--- /trunk/src/engine/model_manager.cc	(revision 526)
+++ /trunk/src/engine/model_manager.cc	(revision 527)
@@ -85,4 +85,13 @@
 	}
 
+	if ( table.has_field( "phx_hextents" ) )
+		node->phx_hextents = table.get<vec3>( "phx_hextents", vec3() );
+	if ( table.has_field( "phx_offset" ) )
+		node->phx_offset = table.get<vec3>( "phx_offset", vec3() );
+	if ( table.has_field( "phx_mass" ) )
+		node->phx_mass = table.get<float>( "phx_mass", 0.0f);
+	if ( table.has_field( "phx_mass" ) )
+		node->phx_shape = nv::phx_shape( table.get<int>( "phx_shape", 0 ) );
+
 	if ( table.has_field( "local_position" ) )
 		node->local.set_position( table.get<vec3>( "local_position", vec3() ) );
