Ejemplo n.º 1
0
void fxRenderImage::findCameraAxis(TSRenderContext &rc)
{
	TMat3F wCamMat = rc.getCamera()->getTCW();

	camAxis = transform.p;
	camAxis -= wCamMat.p;
	camDist = m_dot(camAxis,camAxis);
	if (IsEqual(camDist,0.0f))
		camAxis.set(0,1,0); // camAxis.len()==0, just use standard axes
	else
	{
		camDist = m_sqrtf(camDist);
		camAxis *= 1/camDist;
	}
}
Ejemplo n.º 2
0
/** return square root of a */
template <>	inline float	CMath<float>::sqrt(float a)		{	return m_sqrtf(a);	}
// decide where to place and then add to the manager
void SimExplosionCloud::lightFuse(SimExplosion * explosion, Point3F & cameraPos, bool igniteNow)
{
	// decide when to detonate
	if (!igniteNow)
		explosion->setDetonationTime(g_expRand.getFloat(0,detonationMax));

	Point3F pos;
   Point3F vec(0, 0, 0);
	Point3F worldPos,worldVec;

	switch (form)
	{
		case Sphere :
		{
			// try to make sure explosions no closer together than 1m in z
			int maxZ = (int) radius;
			if (maxZ)
			{
				if (topOnly)
					vec.z = g_expRand.getInt(0,maxZ);
				else
					vec.z = g_expRand.getInt(-maxZ,maxZ);
			}
			// don't break, fall through to circle
		}
		case Circle :
		{
			float angle = g_expRand.getFloat(0,float(M_2PI));
			float circleRad = m_sqrtf(radius*radius - vec.z *vec.z);
			vec.x  = circleRad * m_cos(angle);
			vec.y  = circleRad * m_sin(angle);
			pos = center;
			pos += vec;
			break;
		}
		case Screen:
		{
			if (radius>0.1f) // if radius==0, skip some work
			{
				vec=cameraPos; 
				vec -= center; 
				vec.normalize(); 
				Point3F dirX,dirZ;
				if (fabs(vec.z) < 0.95)
				{
				   // vec is not near vector (0,0,1), so we can
   				// use it as the pivot vector
   				m_cross(vec, Point3F(0,0,1), &dirX);
					dirX.normalize();
   				m_cross(dirX, vec, &dirZ);
				}
				else
				{
				   // dirY is near vector (0,0,1), so use
   				// pivot Point3F(1,0,0) instead
   				m_cross(Point3F(1,0,0), vec, &dirZ);
   				dirZ.normalize();
   				m_cross(vec, dirZ, &dirX);
				}
				dirX *= g_expRand.getFloat(-radius,radius);
				dirZ *= g_expRand.getFloat(-radius,radius);
				vec *= radius;
				vec += dirX;
				vec += dirZ;
			}
			pos = center;
			pos += vec;
			break;
		}
		case Box :
		{
			int side;
			if (topOnly)
				side = g_expRand.getInt(1,5);
			else
				side = g_expRand.getInt(0,5);
			pos = box.fMax;
			switch (side)
			{
				case 0:
					pos.z = box.fMin.z;
				case 1:
					pos.x = g_expRand.getFloat(box.fMin.x,box.fMax.x);
					pos.y = g_expRand.getFloat(box.fMin.y,box.fMax.y);
					break;
				case 2:
					pos.y = box.fMin.y;
				case 3:
					pos.x = g_expRand.getFloat(box.fMin.x,box.fMax.x);
					pos.z = g_expRand.getFloat(box.fMin.z,box.fMax.z);
					break;
				case 4:
					pos.x = box.fMin.x;
				case 5:
					pos.y = g_expRand.getFloat(box.fMin.y,box.fMax.y);
					pos.z = g_expRand.getFloat(box.fMin.z,box.fMax.z);
					break;
			}
			switch (side)
			{
				case 0:
					vec.set(0,0,box.fMin.z-box.fMax.z);
					break;
				case 1:
					vec.set(0,0,box.fMax.z-box.fMin.z);
					break;
				case 2:
					vec.set(0,box.fMin.y-box.fMax.y,0);
					break;
				case 3:
					vec.set(0,box.fMax.y-box.fMin.y,0);
					break;
				case 4:
					vec.set(box.fMin.x-box.fMax.x,0,0);
					break;
				case 5:
					vec.set(box.fMax.x-box.fMin.x,0,0);
					break;
			}
			break;
		}
	}

	// now put into world coords
	if (hasTransform)
	{
		m_mul(pos,transform,&worldPos);
		m_mul(vec,(RMat3F&)transform,&worldVec);
	}
	else
	{
		worldPos=pos;
		worldVec=vec;
	}

	Point3F camAxis = worldPos;
	camAxis -= cameraPos;
	if (m_dot(camAxis,worldVec)>0.0f)
	{
		worldPos -= worldVec;
		worldPos -= worldVec;
	}
	explosion->setPosition(worldPos);
	explosion->setAxis(worldVec); // move away from the building... ;->
	explosion->setSound(false);
	manager->addObject(explosion);
}