impl::impl(system_impl_ptr sys,compound_sensor_ptr s,/*compound_shape_proxy& s,*/ params_t const& params, decart_position const& pos)
        : bt_body_user_info_t(rb_aircraft)
		, sys_ (sys)
		, chassis_    (sys->dynamics_world())
		, raycast_veh_(sys->dynamics_world())
        , chassis_shape_(compound_sensor_impl_ptr(s)->cs_)
		, params_(params)
        , elevator_(0)
        , ailerons_(0)
        , rudder_(0)
        , thrust_(0)
        , steer_(0)
        , prev_attack_angle_(0)
        , has_chassis_contact_(false)
        , body_contact_points_(1.5)
    {
		tuning_.m_maxSuspensionTravelCm = 500;

		btTransform  tr;
		tr.setIdentity();
		btVector3 aabbMin,aabbMax;
#if 0
        chassis_shape_.get()->getAabb(tr,aabbMin,aabbMax);
#else
        chassis_shape_->getAabb(tr,aabbMin,aabbMax);
#endif

		btScalar dxx = btScalar(params_.wingspan / 2);
		btScalar dyy = btScalar(params_.length / 2);
		btScalar dzz = btScalar((aabbMax.z() - aabbMin.z()) / 2);
		btScalar m12 = btScalar((params_.mass) /12);
		btVector3 inertia = m12 * btVector3(dyy*dyy + dzz*dzz, dxx*dxx + dzz*dzz, dyy*dyy + dxx*dxx);

        btDefaultMotionState* motionState = new btDefaultMotionState(tr);
		btRigidBody::btRigidBodyConstructionInfo chassis_construction_info(btScalar(params_.mass), NULL/*new custom_ms*//*motionState*/, chassis_shape_/*&*chassis_shape_.get()*/, inertia);
		chassis_.reset(phys::bt_rigid_body_ptr(boost::make_shared<btRigidBody>(chassis_construction_info)));

		// FIXME TODO
		chassis_->setCenterOfMassTransform(to_bullet_transform(pos.pos, pos.orien.cpr()));
FIXME("Off point for bullet")
#if 1
		chassis_->setLinearVelocity(to_bullet_vector3(pos.dpos));
#endif
		//chassis_->setDamping(0.05f, 0.5f);
		chassis_->setRestitution(0.1f);
		//chassis_->setActivationState(DISABLE_DEACTIVATION);
		chassis_->setFriction(0.3f);

		raycast_veh_.reset(boost::make_shared<btRaycastVehicle>(tuning_, &*chassis_.get(), &*sys->vehicle_raycaster()));

		raycast_veh_->setCoordinateSystem(0,2,1);


		sys_->dynamics_world()->addAction(this);

		sys_->register_rigid_body(this);

		chassis_->setUserPointer(this);
    }
    impl::impl(system_impl_ptr sys,compound_sensor_ptr s,params_t const& params, decart_position const& pos)
        : bt_body_user_info_t(rb_simple)
		, sys_                  (sys)
		, chassis_              (sys->dynamics_world())
        , chassis_shape_        (s?compound_sensor_impl_ptr(s)->cs_: create_compound_shape())
		, params_               (params)
        , has_chassis_contact_  (false)
        , body_contact_points_  (1.5)
    {

		btTransform  tr;
		tr.setIdentity();
		btVector3 aabbMin,aabbMax;

#if 1
        FIXME(chassis_shape_)
        chassis_shape_->getAabb(tr,aabbMin,aabbMax);
       
        const float  fake_mass = 20;

		btScalar dxx = btScalar((aabbMax.x() - aabbMin.x()) / 2);
		btScalar dyy = btScalar((aabbMax.y() - aabbMin.y()) / 2);
		btScalar dzz = btScalar((aabbMax.z() - aabbMin.z()) / 2);
		btScalar m12 = btScalar((fake_mass) /12);
		btVector3 inertia = m12 * btVector3(dyy*dyy + dzz*dzz, dxx*dxx + dzz*dzz, dyy*dyy + dxx*dxx);

        btDefaultMotionState* motionState = new btDefaultMotionState(tr);
		btRigidBody::btRigidBodyConstructionInfo chassis_construction_info(btScalar(fake_mass), /*NULL*//*new custom_ms*/motionState,  new btBoxShape(btVector3(.6,.6,.6))/*chassis_shape_*//*&*chassis_shape_.get()*/, inertia);
		chassis_.reset(boost::make_shared<btRigidBody>(chassis_construction_info));

		// FIXME TODO
		chassis_->setCenterOfMassTransform(to_bullet_transform(pos.pos, pos.orien.cpr()));
#if 0
		chassis_->setLinearVelocity(to_bullet_vector3(pos.dpos));
#endif
		//chassis_->setDamping(0.05f, 0.5f);
		chassis_->setRestitution(0.1f);
		//chassis_->setActivationState(DISABLE_DEACTIVATION);
		chassis_->setFriction(0.3f);
#endif

        //sys_->dynamics_world()->addAction(this);

		sys_->register_rigid_body(this);

#if 1
		chassis_->setUserPointer(this);
#endif
    }