Beispiel #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);
}
Beispiel #2
0
void MQuaternion::setFromAngleAxis(float angle, const MVector3 & axis)
{
	const MVector3 normAxis = axis.getNormalized();
	
	float sinHalfAngle = (float)sin((angle * DEG_TO_RAD) / 2.0);
	float cosHalfAngle = (float)cos((angle * DEG_TO_RAD) / 2.0);

	values[0] = sinHalfAngle * normAxis.x;
	values[1] = sinHalfAngle * normAxis.y;
	values[2] = sinHalfAngle * normAxis.z;
	values[3] = cosHalfAngle;

	normalize();
}
Beispiel #3
0
MVector3 computeTangent(
	const MVector3 & P1,  const MVector3 & P2,  const MVector3 & P3,
	const MVector2 & UV1, const MVector2 & UV2, const MVector2 & UV3)
{
	MVector3 Edge1 = P2 - P1;
	MVector3 Edge2 = P3 - P1;
	MVector2 Edge1uv = UV2 - UV1;
	MVector2 Edge2uv = UV3 - UV1;

	float cp = Edge1uv.y * Edge2uv.x - Edge1uv.x * Edge2uv.y;

	if(cp != 0.0f)
	{
		float mul = 1.0f / cp;
		MVector3 tangent = (Edge1 * -Edge2uv.y + Edge2 * Edge1uv.y) * mul;

		return tangent.getNormalized();
	}

	return MVector3(0.0f, 0.0f, 0.0f);
}
Beispiel #4
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));
	}

}