void RigidBody::postUnserialization()
	{
		Link *link = entity.getLinkPtr();
		if (isKinematic())
		{
			auto p = posFromMat4(link->getGlobalTransform());
			setPosition(posFromMat4(link->getGlobalTransform()));
			setRotation(link->getOrientation());
		}
	}
	void updateStatic(Entity &e)
	{
		btTransform transform;
		glm::vec3 position = posFromMat4(e->getGlobalTransform());
		glm::vec3 scale = scaleFromMat4(e->getGlobalTransform());
		glm::vec3 rot = rotFromMat4(e->getGlobalTransform(), true);
		transform.setIdentity();
		transform.setOrigin(convertGLMVectorToBullet(position));
		transform.setRotation(btQuaternion(rot.x, rot.y, rot.z));

		auto c = e->getComponent<Component::RigidBody>();
		c->getBody().setWorldTransform(transform);
		c->getShape().setLocalScaling(convertGLMVectorToBullet(scale));
	}
	void RigidBody::_copyFrom(const ComponentBase *model)
	{
		init();
		auto m = (RigidBody*)model;
#ifdef EDITOR_ENABLED
		editorUpdate();
		if (editorStruct)
		{
			editorStruct->copyDatas(m);
			editorStruct->refreshDatas(this);
			Link *link = entity.getLinkPtr();
			if (isKinematic())
			{
				auto p = posFromMat4(link->getGlobalTransform());
				setPosition(posFromMat4(link->getGlobalTransform()));
				setRotation(link->getOrientation());
				// global orientation not supported
			}
		}
#else
		setAngularDrag(m->getAngularDrag());
		setAngularVelocity(m->getAngularVelocity());
		setCenterOfMass(m->getCenterOfMass());
		setLinearDrag(m->getLinearDrag());
		setLinearVelocity(m->getLinearVelocity());
		setMass(m->getMass());
		setDiagonalInertiaTensor(m->getDiagonalInertiaTensor());
		setMaxAngularVelocity(m->getMaxAngularVelocity());
		setMaxDepenetrationVelocity(m->getMaxDepenetrationVelocity());
		affectByGravity(m->isAffectedByGravity());
		setPosition(m->getPosition());
		setRotation(m->getRotation());
		setAsKinematic(m->isKinematic());
		setCollisionDetectionMode(m->getCollisionDetectionMode());
#endif
	}
	void updateDynamic(Entity &e)
	{
		btMotionState &state = e->getComponent<Component::RigidBody>()->getMotionState();
		glm::mat4 m;
		btTransform trans;
		state.getWorldTransform(trans);
		glm::mat4 t = convertBulletTransformToGLM(trans);
		m = glm::translate(m, posFromMat4(t));
		glm::vec3 rot = rotFromMat4(t, false);
		m = glm::rotate(m, rot.x, glm::vec3(1, 0, 0));
		m = glm::rotate(m, rot.y, glm::vec3(0, 1, 0));
		m = glm::rotate(m, rot.z, glm::vec3(0, 0, 1));
		glm::vec3 scale = scaleFromMat4(e->getLocalTransform());
		m = glm::scale(m, scale);
		e->setLocalTransform() = m;
	}
		void setCollisionShape(CollisionShape c, const std::string &meshName = "")
		{
			if (c == UNDEFINED)
				return;
			_meshName = meshName;
			_reset();
			_shapeType = c;
			btTransform transform;
			glm::vec3 position = posFromMat4(_entity->getLocalTransform());
			glm::vec3 scale = scaleFromMat4(_entity->getLocalTransform());
			std::cout << scale.x << " " << scale.y << " " << scale.z << std::endl;
			glm::vec3 rot = rotFromMat4(_entity->getLocalTransform(), true);
			transform.setIdentity();
			transform.setOrigin(convertGLMVectorToBullet(position));
			transform.setRotation(btQuaternion(rot.x, rot.y, rot.z));
			_motionState = new btDefaultMotionState(transform);
			if (c == BOX)
			{
				_collisionShape = new btBoxShape(btVector3(0.5, 0.5, 0.5));//new btBoxShape(halfScale);
			}
			else if (c == SPHERE)
			{
				_collisionShape = new btSphereShape(0.5);//new btSphereShape(scale.x);
			}
			else if (c == MESH)
			{
				// THERE IS SOME LEAKS BECAUSE THAT'S TEMPORARY
				SmartPointer<Resources::SharedMesh> mesh = _scene->getEngine().getInstance<Resources::ResourceManager>().getResource(meshName);
				auto group = new btCompoundShape();

				auto &geos = mesh->getGeometry();

				for (unsigned int i = 0; i < geos.size(); ++i)
				{
					const Resources::Geometry &geo = geos[i]; // DIRTY HACK TEMPORARY
					// NEED TO REPLACE MESH BY MESH GROUP !
					btScalar *t = new btScalar[geo.vertices.size() * 3]();
					for (unsigned int it = 0; it < geo.vertices.size(); ++it)
					{
						t[it * 3] = geo.vertices[it].x;
						t[it * 3 + 1] = geo.vertices[it].y;
						t[it * 3 + 2] = geo.vertices[it].z;
					}
					btConvexHullShape *tmp = new btConvexHullShape(t, geo.vertices.size(), 3 * sizeof(btScalar));
					btShapeHull *hull = new btShapeHull(tmp);
					btScalar margin = tmp->getMargin();
					hull->buildHull(margin);
					tmp->setUserPointer(hull);
					btConvexHullShape *s = new btConvexHullShape();
					for (int it = 0; it < hull->numVertices(); ++it)
					{
						s->addPoint(hull->getVertexPointer()[it], false);
					}
					s->recalcLocalAabb();
					btTransform localTrans;
					localTrans.setIdentity();
					_collisionShape = s;
					group->addChildShape(localTrans,s);
					delete[] t;
					delete hull;
					delete tmp;
				}
				_collisionShape = group;
			}
			else if (c == CONCAVE_STATIC_MESH) // dont work
			{
				SmartPointer<Resources::SharedMesh> mesh = _scene->getEngine().getInstance<Resources::ResourceManager>().getResource(meshName);
				auto trimesh = new btTriangleMesh();
				auto &geos = mesh->getGeometry();

				for (unsigned int j = 0; j < geos.size(); ++j)
				{
					const Resources::Geometry &geo = geos[j];
					for (unsigned int i = 2; i < geo.vertices.size(); i += 3)
					{
						trimesh->addTriangle(btVector3(geo.vertices[i - 2].x, geo.vertices[i - 2].y, geo.vertices[i - 2].z)
							, btVector3(geo.vertices[i - 1].x, geo.vertices[i - 1].y, geo.vertices[i - 1].z)
							, btVector3(geo.vertices[i].x, geo.vertices[i].y, geo.vertices[i].z));
					}
				}

				auto bvh = new btBvhTriangleMeshShape(trimesh, true);
				bvh->buildOptimizedBvh();
				bool isit = bvh->isConcave();
				_collisionShape = bvh;
			}
			if (_mass != 0)
				_collisionShape->calculateLocalInertia(_mass, _inertia);
			_collisionShape->setLocalScaling(convertGLMVectorToBullet(scale));
			_rigidBody = new btRigidBody(_mass, _motionState, _collisionShape, _inertia);
			_rigidBody->setUserPointer(&_entity);
			_rigidBody->setAngularFactor(convertGLMVectorToBullet(_rotationConstraint));
			_rigidBody->setLinearFactor(convertGLMVectorToBullet(_transformConstraint));
			if (_rigidBody->isStaticObject())
			{
				_rigidBody->setActivationState(DISABLE_SIMULATION);
			}
			_manager->getWorld()->addRigidBody(_rigidBody);
		}