Exemplo n.º 1
0
void MQuaternion::setFromVectors(const MVector3 & source, const MVector3 & destination)
{
	MVector3 axis=source.crossProduct(destination);
	
	float angle = acosf(source.getNormalized().dotProduct(destination.getNormalized()));

	setFromAngleAxis((float)(angle*RAD_TO_DEG), axis);
}
Exemplo n.º 2
0
void MBLookAt::update(void)
{
	MEngine * engine = MEngine::getInstance();
	MLevel * level = engine->getLevel();
	MScene * scene = level->getCurrentScene();

	MObject3d * parent = getParentObject();

	const char * targetName = m_targetName.getData();
	if(strcmp(targetName, "none") == 0)
		return;

	// target object
	MObject3d * object = scene->getObjectByName(targetName);
	if(! object)
		return;

	// direction
	MVector3 direction = object->getTransformedPosition() - parent->getTransformedPosition();
	if(direction.x == 0 && direction.y == 0 && direction.z == 0)
		return;

	float angle;
	float roll;

	MVector3 axis;

	// compute initial roll
	MVector3 ZAxis = parent->getInverseRotatedVector(MVector3(0, 0, 1)).getNormalized();
	ZAxis.z = 0;
	ZAxis.normalize();

	if(ZAxis.x == 0 && ZAxis.y == 0)
	{
		MVector3 YAxis = parent->getInverseRotatedVector(MVector3(0, 1, 0)).getNormalized();
		YAxis.z = 0;
		YAxis.normalize();

		axis = MVector3(0, 1, 0).crossProduct(YAxis);
		roll = acosf(MVector3(0, 1, 0).dotProduct(YAxis));

		if(MVector3(0, 0, 1).dotProduct(axis) < 0)
			roll = -roll;
	}
	else
	{
		axis = MVector3(0, 1, 0).crossProduct(ZAxis);
		roll = acosf(MVector3(0, 1, 0).dotProduct(ZAxis));

		if(MVector3(0, 0, 1).dotProduct(axis) < 0)
			roll = -roll;
	}

	if(roll < 0.001f && roll > -0.001f) roll = 0;

	// look-at
	MVector3 cameraAxis = MVector3(0, 0, -1);

	axis = cameraAxis.crossProduct(direction);
	angle = acosf(cameraAxis.dotProduct(direction.getNormalized()));

	parent->setAxisAngleRotation(axis, (float)(angle * RAD_TO_DEG));
	parent->updateMatrix();

	// set roll
	ZAxis = parent->getInverseRotatedVector(MVector3(0, 0, 1)).getNormalized();;
	ZAxis.z = 0;
	ZAxis.normalize();

	if(ZAxis.x == 0 && ZAxis.y == 0)
	{
		parent->addAxisAngleRotation(MVector3(0, 0, 1), (float)(-roll*RAD_TO_DEG));
	}
	else
	{
		axis = MVector3(0, 1, 0).crossProduct(ZAxis);
		angle = acosf(MVector3(0, 1, 0).dotProduct(ZAxis));
		if(angle < 0.001f && angle > -0.001f) angle = 0;

		if(MVector3(0, 0, 1).dotProduct(axis) < 0)
			angle = -angle;

		parent->addAxisAngleRotation(MVector3(0, 0, 1), (float)((angle-roll)*RAD_TO_DEG));
	}

}