Ejemplo n.º 1
0
void Quad::ResetShape(size_t w, size_t h)
{
	size_t base = (w<h) ? w : h;
	float a = FloatRand(base / MinRadiusDelim, base / MaxRadiusDelim);
	float left = FloatRand(0, (float) w);
	_left = point(left, -a);
	_right = point(left + a, 0);
	init();
}
Ejemplo n.º 2
0
void Circle::ResetShape(size_t w, size_t h)
{
	size_t base = (w<h) ? w : h;
	float r = FloatRand(base / MinRadiusDelim, base / MaxRadiusDelim);
	_r = r;
	center.first = FloatRand(r, w - r);
	center.second = -r;
	init();
}
Ejemplo n.º 3
0
	////////////////////////////////////////////////////////////////////////////////////
	// Update - Changes wind when current target velocity expires
	////////////////////////////////////////////////////////////////////////////////////
	void		Update()
	{
		if (mTargetVelocityTimeRemaining==0)
		{
			if (FloatRand()<mChanceOfDeadTime)
			{
				mRDeadTime.Pick(mTargetVelocityTimeRemaining);
				mTargetVelocity.Clear();
			}
			else
			{
				mRDuration.Pick(mTargetVelocityTimeRemaining);
				mRVelocity.Pick(mTargetVelocity);
			}
		}
		else if (mTargetVelocityTimeRemaining!=-1)
		{
			mTargetVelocityTimeRemaining--;

			CVec3	DeltaVelocity(mTargetVelocity - mCurrentVelocity);
			float	DeltaVelocityLen = VectorNormalize(DeltaVelocity.v);
			if (DeltaVelocityLen > mMaxDeltaVelocityPerUpdate)
			{
				DeltaVelocityLen = mMaxDeltaVelocityPerUpdate;
			}
			DeltaVelocity *= (DeltaVelocityLen);
			mCurrentVelocity += DeltaVelocity;
		}
	}
CMistyFog::CMistyFog(int index, CWorldEffect *owner, bool buddy) :
	CWorldEffect(owner),
		
	mSize(0.05f*2.0f),
	mMinSize(0.05f*3.0f),
	mMaxSize(0.15f*2.0f),
	mAlpha(1.0f),
	mAlphaFade(false),
	mBuddy(buddy)
{
	char			name[1024];
	unsigned char	*pos;
	int				x, y;

	if (mBuddy)
	{
		mRendering = false;

//		mImage = ((CMistyFog *)owner)->GetImage();
		mData = ((CMistyFog *)owner)->GetData();
		mWidth = ((CMistyFog *)owner)->GetWidth();
		mHeight = ((CMistyFog *)owner)->GetHeight();
	}
	else
	{
		sprintf(name, "gfx/world/fog%d.tga", index);

		R_LoadImage( name, &mData, &mWidth, &mHeight );
		if (!mData)
		{
			ri.Error (ERR_DROP, "Could not load %s", name);
		}

		pos = mData;
		for(y=0;y<mHeight;y++)
		{
			for(x=0;x<mWidth;x++)
			{
				pos[3] = pos[0];
				pos += 4;
			}
		}

//		mImage = R_CreateImage(name, mData, mWidth, mHeight, false, true, false, GL_REPEAT);

		mRendering = true;
		AddSlave(new CMistyFog(index, this, true));
	}

	mSpeed = 90.0 + FloatRand() * 20.0;

	CreateTextureCoords();
}
void CMistyFog::CreateTextureCoords(void)
{
	float	xStart, yStart;
	float	forwardWind, rightWind;

	mSpeed = 800.0 + FloatRand() * 2000.0;
	mSpeed /= 4.0;

	forwardWind = DotProduct(mWindTransform, backEnd.viewParms.or.axis[0]);
	rightWind = DotProduct(mWindTransform, backEnd.viewParms.or.axis[1]);

	if (forwardWind > 0.5)
	{	// moving away, so make the size smaller
		mCurrentSize = mMinSize + (FloatRand() * mMinSize * 0.01);
//		mCurrentSize = mMinSize / 3.0;
	}
	else if (forwardWind < -0.5)
	{	// moving towards, so make bigger
//		mCurrentSize = (mSize * 0.8) + (FloatRand() * mSize * 0.8);
		mCurrentSize = mMaxSize - (FloatRand() * mMinSize);
	}
	else
	{	// normal range
		mCurrentSize = mMinSize * 1.5 + (FloatRand() * mSize);
	}

	mCurrentSize /= 2.0;

	xStart = (1.0 - mCurrentSize - 0.40) * FloatRand() + 0.20;
	yStart = (1.0 - mCurrentSize - 0.40) * FloatRand() + 0.20;

	mTextureCoords[0][0] = xStart - mCurrentSize;
	mTextureCoords[0][1] = yStart - mCurrentSize;
	mTextureCoords[1][0] = xStart + mCurrentSize;
	mTextureCoords[1][1] = yStart + mCurrentSize;
}
void CRainSystem::Update(float elapseTime)
{
	int			i;
	SParticle	*item;
	vec3_t		windDifference;

	if ( elapseTime < 0.0f )
	{
		// sanity check
		elapseTime = 0.0f;
	}

	mWindChange--;

	if (mWindChange < 0)
	{
		mNewWindDirection[0] = 1.0 - (FloatRand() * 2.0);
		mNewWindDirection[1] = 1.0 - (FloatRand() * 2.0);
		mNewWindDirection[2] = 0.0;
		VectorNormalize(mNewWindDirection);
		VectorScale(mNewWindDirection, 0.025f, mWindSpeed);

		mWindChange = 200 + rand() % 250;
//		mWindChange = 10;

		ParmUpdate(CRainSystem::RAINSYSTEM_WIND_DIRECTION);
	}

	VectorSubtract(mNewWindDirection, mWindDirection, windDifference);
	VectorMA(mWindDirection, elapseTime, windDifference);

	CWorldEffectsSystem::Update(elapseTime);

	if (originContents & CONTENTS_OUTSIDE && !(originContents & CONTENTS_WATER))
	{
		mIsRaining = true;
		if (mFadeAlpha < 1.0)
		{
			mFadeAlpha += elapseTime / 2.0;
		}
		if (mFadeAlpha > 1.0)
		{
			mFadeAlpha = 1.0;
		}
	}
	else
	{
		mIsRaining = false;
		if (mFadeAlpha > 0.0)
		{
			mFadeAlpha -= elapseTime / 2.0;
		}

		if (mFadeAlpha <= 0.0)
		{
			return;
		}
	}

	item = mRainList;
	for(i=mMaxRain;i;i--)
	{
		VectorMA(item->pos, elapseTime, item->velocity);

		if (item->pos[2] < -mSpread[2] )
		{
			item->pos[0] = ri.flrand(0.0, mSpread[0]);
			item->pos[1] = ri.flrand(0.0, mSpread[1]);
			item->pos[2] = 40;

			item->velocity[0] = ri.flrand(mMinVelocity[0], mMaxVelocity[0]);
			item->velocity[1] = ri.flrand(mMinVelocity[1], mMaxVelocity[1]);
			item->velocity[2] = ri.flrand(mMinVelocity[2], mMaxVelocity[2]);
		}

		item++;
	}
}
void CSnowSystem::Update(float elapseTime)
{
	int			i;
	SParticle	*item;
	vec3_t		origin, newMins, newMaxs;
	vec3_t		difference, start;
	bool		resetFlake;
	int			x, y, z;
	int			contents;

	mWindChange--;
	if (mWindChange < 0)
	{
		mWindDirection[0] = 1.0 - (FloatRand() * 2.0);
		mWindDirection[1] = 1.0 - (FloatRand() * 2.0);
		mWindDirection[2] = 0.0;
		VectorNormalize(mWindDirection);
		VectorScale(mWindDirection, 0.025f, mWindSpeed);

		mWindChange = 200 + rand() % 250;
//		mWindChange = 10;

		ParmUpdate(CRainSystem::RAINSYSTEM_WIND_DIRECTION);
	}

	if ((mOverallContents & CONTENTS_OUTSIDE))
	{
		CWorldEffectsSystem::Update(elapseTime);
	}

	VectorCopy(backEnd.viewParms.or.origin, origin);

	mNextWindGust -= elapseTime;
	if (mNextWindGust < 0.0)
	{
		mWindGust->SetVariable(CWorldEffect::WORLDEFFECT_ENABLED, false);
	}

	if (mNextWindGust < mWindLowSize)
	{
		vec3_t		windPos;
		vec3_t		windDirection;

		windDirection[0] = ri.flrand(-1.0, 1.0);
		windDirection[1] = ri.flrand(-1.0, 1.0);
		windDirection[2] = 0.0;//ri.flrand(-0.1, 0.1);
		VectorNormalize(windDirection);
		VectorScale(windDirection, ri.flrand(mWindMin, mWindMax), windDirection);

		VectorCopy(origin, windPos);

		mWindGust->SetVariable(CWorldEffect::WORLDEFFECT_ENABLED, true);
		mWindGust->UpdateParms(windPos, windDirection, mWindSize, 0);

		mNextWindGust = ri.flrand(mWindDuration, mWindDuration*2.0);
		mWindLowSize = -ri.flrand(mWindLow, mWindLow*3.0);
	}

	newMins[0] = mMinSpread[0] + origin[0];
	newMaxs[0] = mMaxSpread[0] + origin[0];

	newMins[1] = mMinSpread[1] + origin[1];
	newMaxs[1] = mMaxSpread[1] + origin[1];

	newMins[2] = mMinSpread[2] + origin[2];
	newMaxs[2] = mMaxSpread[2] + origin[2];

	for(i=0;i<3;i++)
	{
		difference[i] = newMaxs[i] - mMaxs[i];
		if (difference[i] >= 0.0)
		{
			if (difference[i] > newMaxs[i]-newMins[i])
			{
				difference[i] = newMaxs[i]-newMins[i];
			}
			start[i] = newMaxs[i] - difference[i];
		}
		else
		{ 
			if (difference[i] < newMins[i]-newMaxs[i])
			{
				difference[i] = newMins[i]-newMaxs[i];
			}
			start[i] = newMins[i] - difference[i];
		}
	}

//	contentsStart[0] = (((origin[0] + mMinSpread[0]) / mContentsSize[0])) * mContentsSize[0];
//	contentsStart[1] = (((origin[1] + mMinSpread[1]) / mContentsSize[1])) * mContentsSize[1];
//	contentsStart[2] = (((origin[2] + mMinSpread[2]) / mContentsSize[2])) * mContentsSize[2];

	if (fabs(difference[0]) > 25.0 || fabs(difference[1]) > 25.0 || fabs(difference[2]) > 25.0)
	{
		vec3_t		pos;
		int			*store;

		mContentsStart[0] = ((int)((origin[0] + mMinSpread[0]) / mContentsSize[0])) * mContentsSize[0];
		mContentsStart[1] = ((int)((origin[1] + mMinSpread[1]) / mContentsSize[1])) * mContentsSize[1];
		mContentsStart[2] = ((int)((origin[2] + mMinSpread[2]) / mContentsSize[2])) * mContentsSize[2];

		mOverallContents = 0;
		store = (int *)mContents;
		for(z=0,pos[2]=mContentsStart[2];z<CONTENTS_Z_SIZE;z++,pos[2]+=mContentsSize[2])
		{
			for(y=0,pos[1]=mContentsStart[1];y<CONTENTS_Y_SIZE;y++,pos[1]+=mContentsSize[1])
			{
				for(x=0,pos[0]=mContentsStart[0];x<CONTENTS_X_SIZE;x++,pos[0]+=mContentsSize[0])
				{
					contents = ri.CM_PointContents(pos, 0);
					mOverallContents |= contents;
					*store++ = contents;
				}
			}
		}

		item = mSnowList;
		for(i=mMaxSnowflakes;i;i--)
		{
			resetFlake = false;

			if (item->pos[0] < newMins[0] || item->pos[0] > newMaxs[0])
			{
				item->pos[0] = ri.flrand(0.0, difference[0]) + start[0];
				resetFlake = true;
			}
			if (item->pos[1] < newMins[1] || item->pos[1] > newMaxs[1])
			{
				item->pos[1] = ri.flrand(0.0, difference[1]) + start[1];
				resetFlake = true;
			}
			if (item->pos[2] < newMins[2] || item->pos[2] > newMaxs[2])
			{
				item->pos[2] = ri.flrand(0.0, difference[2]) + start[2];
				resetFlake = true;
			}

			if (resetFlake)
			{
				item->velocity[0] = 0.0;
				item->velocity[1] = 0.0;
				item->velocity[2] = ri.flrand(mMaxVelocity[2], mMinVelocity[2]);
			}
			item++;
		}

		VectorCopy(newMins, mMins);
		VectorCopy(newMaxs, mMaxs);
	}

	if (!(mOverallContents & CONTENTS_OUTSIDE))
	{
		mIsSnowing = false;
		return;
	}

	mIsSnowing = true;

	mUpdateCount = (mUpdateCount + 1) % mUpdateMax;

	x = y = z = 0;
	item = mSnowList;
	for(i=mMaxSnowflakes;i;i--)
	{
		resetFlake = false;

//		if ((i & mUpdateCount) == 0)   wrong check
		{
			if (item->velocity[0] < mMinVelocity[0])
			{
				item->velocity[0] += mVelocityStabilize * elapseTime;
			}
			else if (item->velocity[0] > mMaxVelocity[0])
			{
				item->velocity[0] -= mVelocityStabilize * elapseTime;
			}
			else
			{
				item->velocity[0] += ri.flrand(-1.4f, 1.4f);
			}
			if (item->velocity[1] < mMinVelocity[1])
			{
				item->velocity[1] += mVelocityStabilize * elapseTime;
			}
			else if (item->velocity[1] > mMaxVelocity[1])
			{
				item->velocity[1] -= mVelocityStabilize * elapseTime;
			}
			else
			{
				item->velocity[1] += ri.flrand(-1.4f, 1.4f);
			}
			if (item->velocity[2] > mMinVelocity[2])
			{
				item->velocity[2] -= mVelocityStabilize*2.0;
			}
		}
		VectorMA(item->pos, elapseTime, item->velocity);

		if (item->pos[2] < newMins[2])
		{
			resetFlake = true;
		}
		else
		{
//			if ((i & mUpdateCount) == 0)
			{
				x = (item->pos[0] - mContentsStart[0]) / mContentsSize[0];
				y = (item->pos[1] - mContentsStart[1]) / mContentsSize[1];
				z = (item->pos[2] - mContentsStart[2]) / mContentsSize[2];
				if (x < 0 || x >= CONTENTS_X_SIZE ||
					y < 0 || y >= CONTENTS_Y_SIZE ||
					z < 0 || z >= CONTENTS_Z_SIZE)
				{
					resetFlake = true;
				}
			}
		}

		if (resetFlake)
		{
			item->pos[2] = newMaxs[2] - (newMins[2] - item->pos[2]);
			if (item->pos[2] < newMins[2] || item->pos[2] > newMaxs[2])
			{	// way out of range
				item->pos[2] = ri.flrand(newMins[2], newMaxs[2]);
			}

			item->pos[0] = ri.flrand(newMins[0], newMaxs[0]);
			item->pos[1] = ri.flrand(newMins[1], newMaxs[1]);

			item->velocity[0] = 0.0;
			item->velocity[1] = 0.0;
			item->velocity[2] = ri.flrand(mMaxVelocity[2], mMinVelocity[2]);
			item->flags &= ~PARTICLE_FLAG_RENDER;
		}
		else if (mContents[z][y][x] & CONTENTS_OUTSIDE)
		{
			item->flags |= PARTICLE_FLAG_RENDER;
		}
		else
		{
			item->flags &= ~PARTICLE_FLAG_RENDER;
		}

		item++;
	}
}