Exemplo n.º 1
0
bool MFCollision_SphereSphereTest(const MFVector &pos1, float radius1, const MFVector &pos2, float radius2, MFCollisionResult *pResult)
{
	MFVector diff = pos2 - pos1;

	if(!pResult)
	{
		return diff.MagSquared3() < radius1*radius1 + radius2*radius2;
	}
	else
	{
		float length = diff.Magnitude3();
		float totalRadius = radius1 + radius2;

		pResult->bCollide = length < totalRadius;

		if(pResult->bCollide)
		{
			pResult->depth = totalRadius - length;
			pResult->normal = -diff.Normalise3();
			pResult->intersectionPoint = diff * ((length / totalRadius) * (radius1 / radius2));
		}

		return pResult->bCollide;
	}
}
Exemplo n.º 2
0
void MFCollision_CalculateDynamicBoundingVolume(MFCollisionItem *pItem)
{
	switch(pItem->pTemplate->type)
	{
		case MFCT_Mesh:
		{
			MFCollisionMesh *pMesh = (MFCollisionMesh*)pItem->pTemplate->pCollisionTemplateData;
			MFBoundingVolume &vol = pItem->pTemplate->boundingVolume;

			vol.min = vol.max = vol.boundingSphere = MakeVector(pMesh->pTriangles[0].verts[0], 0.0f);

			for(int a=0; a<pMesh->numTris; a++)
			{
				MFCollisionTriangle &tri = pMesh->pTriangles[a];

				for(int b=0; b<3; b++)
				{
					vol.min = MFMin(vol.min, tri.verts[b]);
					vol.max = MFMin(vol.max, tri.verts[b]);
					vol.min.w = vol.max.w = 0.0f;

					// if point is outside bounding sphere
					MFVector diff = tri.verts[b] - vol.boundingSphere;
					float mag = diff.MagSquared3();

					if(mag > vol.boundingSphere.w*vol.boundingSphere.w)
					{
						// fit sphere to include point
						mag = MFSqrt(mag) - vol.boundingSphere.w;
						mag *= 0.5f;
						diff.Normalise3();
						vol.boundingSphere.Mad3(diff, mag, vol.boundingSphere);
						vol.boundingSphere.w += mag;
					}
				}
			}
			break;
		}

		default:
			MFDebug_Assert(false, "Invalid item type");
	}
}
Exemplo n.º 3
0
MF_API void MFParticleSystem_AddParticle(MFParticleEmitter *pEmitter)
{
	MFParticleEmitterParameters *pE = &pEmitter->params;
	MFParticleSystem *pParticleSystem = pE->pParticleSystem;

	MFParticle *pNew = NULL;
	if(pParticleSystem->particles.GetLength() < pParticleSystem->params.maxActiveParticles)
		pNew = pParticleSystem->particles.Create();

	if(pNew)
	{
		MFParticleParameters *pP = &pParticleSystem->params;

		pNew->colour = pP->colour;
		pNew->life = pP->life;
		pNew->rot = 0.0f;
		pNew->size = pP->size;

		switch(pE->type)
		{
			case MFET_Point:
				pNew->pos = pE->position.GetTrans();
				break;

			case MFET_Sphere:
			case MFET_Disc:
			{
				MFVector offset;

				do
				{
					offset = MakeVector(MFRand_Range(-pE->radius, pE->radius), MFRand_Range(-pE->radius, pE->radius), MFRand_Range(-pE->radius, pE->radius));
				}
				while(offset.MagSquared3() > pE->radius*pE->radius);

				if(pE->type == MFET_Disc)
				{
					// flatten it on to the disc
					float dist = offset.Dot3(pE->position.GetYAxis());
					offset -= pE->position.GetYAxis()*dist;
				}

				pNew->pos = pE->position.GetTrans() + offset;

				break;
			}
		}

		switch(pE->behaviour)
		{
			case MFEB_Direction:
				pNew->velocity.Normalise3(pE->startVector);
				break;
			case MFEB_TargetAttract:
				pNew->velocity.Normalise3(pE->startVector - pE->position.GetTrans());
				break;
			case MFEB_TargetRepel:
				pNew->velocity.Normalise3(pE->position.GetTrans() - pE->startVector);
				break;
		}

		pNew->velocity *= pE->velocity + MFRand_Range(-pE->velocityScatter, pE->velocityScatter);

		if(pE->directionScatter)
		{
			MFVector scatter;

			do
			{
				scatter = MakeVector(MFRand_Range(-1, 1), MFRand_Range(-1, 1), MFRand_Range(-1, 1));

				float dist = scatter.Dot3(pE->position.GetYAxis());
				scatter -= pE->position.GetYAxis()*dist;
			}
			while(scatter.MagSquared3() < 0.000001f);

			scatter.Normalise3();

			MFMatrix scatterMat;
			scatterMat.SetRotation(scatter, MFRand_Unit()*pE->directionScatter);

			pNew->velocity = ApplyMatrixH(pNew->velocity, scatterMat);
		}
	}
}