Beispiel #1
0
bool isRayPlaneIntersection(const MVector3 & origin, const MVector3 & direction, const MVector3 & planePoint, const MVector3 & planeNormal, MVector3 * point)
{
	float constant = - planeNormal.dotProduct(planePoint);

	float normalDotDir = planeNormal.dotProduct(direction);
	float planeDistance = planeNormal.dotProduct(origin) + constant;

	float t = - planeDistance / normalDotDir;

	point->x = (origin.x + (t * direction.x));
	point->y = (origin.y + (t * direction.y));
	point->z = (origin.z + (t * direction.z));

	return true;
}
Beispiel #2
0
bool isPointInTriangle(const MVector3 & point, const MVector3 & a, const MVector3 & b, const MVector3 & c, const MVector3 & normal)
{
	MVector3 nrm = getTriangleNormal(point, a, b);

	if(nrm.dotProduct(normal) < 0)
		return false;

	nrm = getTriangleNormal(point, b, c);
	if(nrm.dotProduct(normal) < 0)
		return false;

	nrm = getTriangleNormal(point, c, a);
	if(nrm.dotProduct(normal) < 0)
		return false;

	return true;
}
Beispiel #3
0
bool isRaySphereIntersection(const MVector3 & origin, const MVector3 & direction, const MVector3 & sphereCenter, float sphereRadius, MVector3 * point)
{
	MVector3 vec = origin - sphereCenter;
	float b = direction.dotProduct(vec);
	float c = vec.getSquaredLength() - (sphereRadius * sphereRadius);
	float d = (b * b) - c;

	if(d < 0)
		return false;

	float distance = -b - sqrtf(d);

	point->x = (origin.x + (distance * direction.x));
	point->y = (origin.y + (distance * direction.y));
	point->z = (origin.z + (distance * direction.z));

	return true;
}
Beispiel #4
0
void generateTangents(MSubMesh * subMesh)
{
	MVector3 * vertices = subMesh->getVertices();
	MVector3 * normals = subMesh->getNormals();
	MVector2 * texCoords = subMesh->getTexCoords();

	if(! (vertices && normals && texCoords))
		return;


	bool generate = false;
	unsigned int mapChannel;

	// find normal mapChannel
	unsigned int d;
	unsigned int dSize = subMesh->getDisplaysNumber();
	for(d=0; d<dSize; d++)
	{
		MDisplay * display = subMesh->getDisplay(d);
		MMaterial * material = display->getMaterial();
		if(material)
		{
			if(material->getType() == 1) // standard
			{
				if(material->getTexturesPassNumber() > 2)
				{
					MTexturePass * texturePass = material->getTexturePass(2); // Normal map pass
					if(texturePass)
					{
						mapChannel = texturePass->getMapChannel();
						generate = true;
					}
				}
			}
			else
			{
				unsigned tSize = material->getTexturesPassNumber();
				unsigned int t;
				for(t=0; t<tSize; t++)
				{
					MTexturePass * texturePass = material->getTexturePass(t);
					if(texturePass)
					{
						if(texturePass->getCombineMode() == M_TEX_COMBINE_DOT)
						{
							mapChannel = texturePass->getMapChannel();
							generate = true;
						}
					}
				}
			}
		}
	}

	// generate
	if(generate)
	{
		M_TYPES indicesType = subMesh->getIndicesType();
		void * indices = subMesh->getIndices();
		MVector3 * tangents = subMesh->allocTangents(subMesh->getNormalsSize());

		// texCoord offset
		unsigned int offset = 0;
		if(subMesh->isMapChannelExist(mapChannel))
			offset = subMesh->getMapChannelOffset(mapChannel);

		texCoords = texCoords + offset;

		// scan triangles to generate tangents from vertices and texCoords
		for(d=0; d<dSize; d++)
		{
			MDisplay * display = subMesh->getDisplay(d);

			if(display->getPrimitiveType() == M_PRIMITIVE_TRIANGLES)
			{
				unsigned int begin = display->getBegin();
				unsigned int size = display->getSize();

				if(! indices)
				{
					for(unsigned int i=begin; i<(begin+size); i+=3)
					{
						MVector3 * P1 = &vertices[i];
						MVector3 * P2 = &vertices[i+1];
						MVector3 * P3 = &vertices[i+2];

						MVector3 * N1 = &normals[i];
						MVector3 * N2 = &normals[i+1];
						MVector3 * N3 = &normals[i+2];

						MVector2 * UV1 = &texCoords[i];
						MVector2 * UV2 = &texCoords[i+1];
						MVector2 * UV3 = &texCoords[i+2];

						MVector3 tangent = computeTangent(*P1, *P2, *P3, *UV1, *UV2, *UV3);

						tangents[i]   = (tangent - ((*N1) * tangent.dotProduct(*N1))).getNormalized();
						tangents[i+1] = (tangent - ((*N2) * tangent.dotProduct(*N2))).getNormalized();
						tangents[i+2] = (tangent - ((*N3) * tangent.dotProduct(*N3))).getNormalized();
					}
				}
				else if(indicesType == M_USHORT)
				{
					unsigned short * _indices = (unsigned short *)indices;
					for(unsigned int i=begin; i<(begin+size); i+=3)
					{
						unsigned short A = _indices[i];
						unsigned short B = _indices[i+1];
						unsigned short C = _indices[i+2];

						MVector3 * P1 = &vertices[A];
						MVector3 * P2 = &vertices[B];
						MVector3 * P3 = &vertices[C];

						MVector3 * N1 = &normals[A];
						MVector3 * N2 = &normals[B];
						MVector3 * N3 = &normals[C];

						MVector2 * UV1 = &texCoords[A];
						MVector2 * UV2 = &texCoords[B];
						MVector2 * UV3 = &texCoords[C];

						MVector3 tangent = computeTangent(*P1, *P2, *P3, *UV1, *UV2, *UV3);

						tangents[A] = (tangent - ((*N1) * tangent.dotProduct(*N1))).getNormalized();
						tangents[B] = (tangent - ((*N2) * tangent.dotProduct(*N2))).getNormalized();
						tangents[C] = (tangent - ((*N3) * tangent.dotProduct(*N3))).getNormalized();
					}
				}
				else if(indicesType == M_UINT)
				{
					unsigned int * _indices = (unsigned int *)indices;
					for(unsigned int i=begin; i<(begin+size); i+=3)
					{
						unsigned int A = _indices[i];
						unsigned int B = _indices[i+1];
						unsigned int C = _indices[i+2];

						MVector3 * P1 = &vertices[A];
						MVector3 * P2 = &vertices[B];
						MVector3 * P3 = &vertices[C];

						MVector3 * N1 = &normals[A];
						MVector3 * N2 = &normals[B];
						MVector3 * N3 = &normals[C];

						MVector2 * UV1 = &texCoords[A];
						MVector2 * UV2 = &texCoords[B];
						MVector2 * UV3 = &texCoords[C];

						MVector3 tangent = computeTangent(*P1, *P2, *P3, *UV1, *UV2, *UV3);

						tangents[A] = (tangent - ((*N1) * tangent.dotProduct(*N1))).getNormalized();
						tangents[B] = (tangent - ((*N2) * tangent.dotProduct(*N2))).getNormalized();
						tangents[C] = (tangent - ((*N3) * tangent.dotProduct(*N3))).getNormalized();
					}
				}
			}
		}
	}
}
Beispiel #5
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));
	}

}