Matrix PhysicsGeom::getTransformation(void) const
{
    Matrix Transformation;
    
    Vec3f Translation;
    const dReal* t = dGeomGetOffsetPosition(_GeomID);
    Translation.setValues( t[0],t[1],t[2] );

    dQuaternion q;
    dGeomGetOffsetQuaternion(_GeomID, q);
    Quaternion Rotation;
    Rotation.setValueAsQuat(q[1], q[2], q[3], q[0]);

    Transformation.setTransform(Translation,Rotation);

    if(isPlaceable())
    {

        t = dGeomGetPosition(_GeomID);
        Translation.setValues( t[0],t[1],t[2] );

        dGeomGetQuaternion(_GeomID, q);
        Rotation.setValueAsQuat(q[1], q[2], q[3], q[0]);

        Matrix NonBodyTransformation;
        NonBodyTransformation.setTransform(Translation,Rotation);
        Transformation.mult(NonBodyTransformation);
    }

    return Transformation;
}
void PhysicsObject::attachObject(boost::shared_ptr<PhysicsObject> po,
                                 const v3& position,
                                 const qv4& orientation)
{
	po->mBodyOffset = position;

	GeomMapT::const_iterator it = po->mGeometry.begin();
	for (; it != po->mGeometry.end(); ++it)
	{
		// Calculate new relative position
		dGeomID geom = it->second.geomId;
		const dReal* offset = dGeomGetOffsetPosition(geom);
		
		v3 newPos(offset);
		newPos += position;

		// Attach
		dGeomSetBody(geom, mOdeBody);
		dGeomSetOffsetPosition(geom, newPos.x, newPos.y, newPos.z);
		dSpaceRemove(po->mSpaceId, geom);
		dSpaceAdd(mSpaceId, geom);
	}
	
	// add the two masses
	dMass otherMass; 
	dBodyGetMass(po->mOdeBody, &otherMass);

// 	dbglog << "OtherMass: " << otherMass.mass;
// 	dbglog << "OtherCenter: " << odeVectorOut(otherMass.c);
// 	dbglog << "OtherInertia: " << odeMatrixOut(otherMass.I);

	dBodyGetMass(mOdeBody, &mOriginalMass);

// 	dbglog << "OwnMass: " << mOriginalMass.mass;
// 	dbglog << "OwnCenter: " << odeVectorOut(mOriginalMass.c);
// 	dbglog << "OwnInertia: " << odeMatrixOut(mOriginalMass.I);

	dMassAdd(&mOriginalMass, &otherMass);

	dMassTranslate(&mOriginalMass, -mOriginalMass.c[0], -mOriginalMass.c[1], -mOriginalMass.c[2]);
	dBodySetMass(mOdeBody, &mOriginalMass);

// 	dbglog << "NewMass: " << mOriginalMass.mass;
// 	dbglog << "NewCenter: " << odeVectorOut(mOriginalMass.c);
// 	dbglog << "NewInertia: " << odeMatrixOut(mOriginalMass.I);

	// Disable old body
	dBodyDisable(po->mOdeBody);
	
	notifyControlAboutChangeInMass();
}
	// Disable old body
	dBodyDisable(po->mOdeBody);
	
	notifyControlAboutChangeInMass();
}

void PhysicsObject::detachObject(boost::shared_ptr<PhysicsObject> po,
                                 const v3& position,
                                 const qv4& orientation)
{
	// Restore geoms to body
	BOOST_FOREACH(GeomMapT::value_type& vt, po->mGeometry)
	{
		// Calculate new relative position
		dGeomID geom = vt.second.geomId;
		const dReal* offset = dGeomGetOffsetPosition(geom);

		v3 newPos(offset);
		newPos -= po->mBodyOffset;

		// Attach (and detach from this)
		dGeomSetBody(geom, po->mOdeBody);
		dGeomSetOffsetPosition(geom, newPos.x, newPos.y, newPos.z);
		dSpaceRemove(mSpaceId, geom);
		dSpaceAdd(po->mSpaceId, geom);
		
		// Restore individual CollisionModes
		po->setCollisionModeGeom(vt.first, vt.second.collisionMode);
	}
	
	po->mBodyOffset = v3::ZERO;