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(); }
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(); }
//////////////////////////////////////////////////////////////////////////////////// // 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++; } }