// Camera is less than size of CPlayerData away from void SetCameraPos (CFixVector *vCameraPos, CObject *objP) { CFixVector vPlayerCameraOffs = *vCameraPos - objP->info.position.vPos; int count = 0; fix xCameraPlayerDist; fix xFarScale; xCameraPlayerDist = vPlayerCameraOffs.Mag(); if (xCameraPlayerDist < xCameraToPlayerDistGoal) { // 2*objP->info.xSize) { // Camera is too close to CPlayerData CObject, so move it away. tFVIQuery fq; tFVIData hit_data; CFixVector local_p1; if (vPlayerCameraOffs.IsZero()) vPlayerCameraOffs[X] += I2X (1)/16; hit_data.hit.nType = HIT_WALL; xFarScale = I2X (1); while ((hit_data.hit.nType != HIT_NONE) && (count++ < 6)) { CFixVector closer_p1; CFixVector::Normalize(vPlayerCameraOffs); vPlayerCameraOffs *= xCameraToPlayerDistGoal; fq.p0 = &objP->info.position.vPos; closer_p1 = objP->info.position.vPos + vPlayerCameraOffs; // This is the actual point we want to put the camera at. vPlayerCameraOffs *= xFarScale; // ...but find a point 50% further away... local_p1 = objP->info.position.vPos + vPlayerCameraOffs; // ...so we won't have to do as many cuts. fq.p1 = &local_p1; fq.startSeg = objP->info.nSegment; fq.radP0 = fq.radP1 = 0; fq.thisObjNum = objP->Index (); fq.ignoreObjList = NULL; fq.flags = 0; fq.bCheckVisibility = false; FindVectorIntersection (&fq, &hit_data); if (hit_data.hit.nType == HIT_NONE) *vCameraPos = closer_p1; else { vPlayerCameraOffs = CFixVector::Random(); xFarScale = I2X (3) / 2; } } } }
CFixVector *TransformGunPoint (CObject *objP, CFixVector *vGunPoints, int nGun, fix xDelay, ubyte nLaserType, CFixVector *vMuzzle, CFixMatrix *mP) { int bSpectate = SPECTATOR (objP); tObjTransformation* posP = bSpectate ? &gameStates.app.playerPos : &objP->info.position; CFixMatrix m, *viewP; CFixVector v [2]; #if FULL_COCKPIT_OFFS int bLaserOffs = ((gameStates.render.cockpit.nType == CM_FULL_COCKPIT) && (objP->Index () == LOCALPLAYER.nObject)); #else int bLaserOffs = 0; #endif if (nGun < 0) { // use center between gunPoints nGun and nGun + 1 *v = vGunPoints [-nGun] + vGunPoints [-nGun - 1]; // VmVecScale (VmVecAdd (v, vGunPoints - nGun, vGunPoints - nGun - 1), I2X (1) / 2); *v *= (I2X (1) / 2); } else { v [0] = vGunPoints [nGun]; if (bLaserOffs) v [0] += posP->mOrient.UVec () * LASER_OFFS; } if (!mP) mP = &m; if (bSpectate) { viewP = mP; *viewP = posP->mOrient.Transpose (); } else viewP = objP->View (); v[1] = *viewP * v [0]; memcpy (mP, &posP->mOrient, sizeof (CFixMatrix)); if (nGun < 0) v[1] += (*mP).UVec () * (-2 * v->Mag ()); (*vMuzzle) = posP->vPos + v [1]; // If supposed to fire at a delayed time (xDelay), then move this point backwards. if (xDelay) *vMuzzle += mP->FVec () * (-FixMul (xDelay, WI_speed (nLaserType, gameStates.app.nDifficultyLevel))); return vMuzzle; }
int CParticle::Create (CFixVector *vPos, CFixVector *vDir, CFixMatrix *mOrient, short nSegment, int nLife, int nSpeed, char nParticleSystemType, char nClass, float nScale, tRgbaColorf *colorP, int nCurTime, int bBlowUp, float fBrightness, CFixVector *vEmittingFace) { static tRgbaColorf defaultColor = {1,1,1,1}; tRgbaColorf color; CFixVector vDrift; int nRad, nFrames, nType = particleImageManager.GetType (nParticleSystemType); if (nScale < 0) nRad = (int) -nScale; else if (gameOpts->render.particles.bSyncSizes) nRad = (int) PARTICLE_SIZE (gameOpts->render.particles.nSize [0], nScale); else nRad = (int) nScale; if (!nRad) nRad = I2X (1); m_nType = nType; m_bEmissive = (nParticleSystemType == LIGHT_PARTICLES); m_nClass = nClass; m_nSegment = nSegment; m_nBounce = 0; color = colorP ? *colorP : defaultColor; m_color [0] = m_color [1] = color; if ((nType == BULLET_PARTICLES) || (nType == BUBBLE_PARTICLES)) { m_bBright = 0; m_nFade = -1; } else { m_bBright = (nType == SMOKE_PARTICLES) ? (rand () % 50) == 0 : 0; if (colorP) { if (nType != LIGHT_PARTICLES) { m_color [0].red *= RANDOM_FADE; m_color [0].green *= RANDOM_FADE; m_color [0].blue *= RANDOM_FADE; } m_nFade = 0; } else { m_color [0].red = 1.0f; m_color [0].green = 0.5f; m_color [0].blue = 0.0f; m_nFade = 2; } if (m_bEmissive) m_color [0].alpha = (float) (SMOKE_START_ALPHA + 64) / 255.0f; else if (nParticleSystemType != GATLING_PARTICLES) { if (!colorP) m_color [0].alpha = (float) (SMOKE_START_ALPHA + randN (64)) / 255.0f; else { if (colorP->alpha < 0) m_color [0].alpha = -colorP->alpha; else { if (2 == (m_nFade = (char) colorP->alpha)) { m_color [0].red = 1.0f; m_color [0].green = 0.5f; m_color [0].blue = 0.0f; } m_color [0].alpha = (float) (SMOKE_START_ALPHA + randN (64)) / 255.0f; } } } #if 1 if (gameOpts->render.particles.bDisperse && !m_bBright) { fBrightness = 1.0f - fBrightness; m_color [0].alpha += fBrightness * fBrightness / 8.0f; } #endif } //nSpeed = (int) (sqrt (nSpeed) * (float) I2X (1)); nSpeed *= I2X (1); if (vDir) { CAngleVector a; CFixMatrix m; float d; a [PA] = randN (I2X (1) / 4) - I2X (1) / 8; a [BA] = randN (I2X (1) / 4) - I2X (1) / 8; a [HA] = randN (I2X (1) / 4) - I2X (1) / 8; m = CFixMatrix::Create (a); vDrift = m * (*vDir); CFixVector::Normalize (vDrift); d = (float) CFixVector::DeltaAngle (vDrift, *vDir, NULL); if (d) { d = (float) exp ((I2X (1) / 8) / d); nSpeed = (fix) ((float) nSpeed / d); } #if 0 if (!colorP) // hack for static particleSystem w/o user defined color m_color [0].green = m_color [0].blue = 1.0f; #endif vDrift *= nSpeed; if ((nType == SMOKE_PARTICLES) || (nType == BUBBLE_PARTICLES)) m_vDir = *vDir * (I2X (3) / 4 + I2X (randN (16)) / 64); else m_vDir = *vDir; m_bHaveDir = 1; } else { CFixVector vOffs; vDrift [X] = nSpeed - randN (2 * nSpeed); vDrift [Y] = nSpeed - randN (2 * nSpeed); vDrift [Z] = nSpeed - randN (2 * nSpeed); vOffs = vDrift; m_vDir.SetZero (); m_bHaveDir = 1; } m_vDrift = vDrift; if (vEmittingFace) m_vPos = *RandomPointOnQuad (vEmittingFace, vPos); else if (nType != BUBBLE_PARTICLES) m_vPos = *vPos + vDrift * (I2X (1) / 64); else { //m_vPos = *vPos + vDrift * (I2X (1) / 32); nSpeed = vDrift.Mag () / 16; vDrift = CFixVector::Avg ((*mOrient).RVec () * (nSpeed - randN (2 * nSpeed)), (*mOrient).UVec () * (nSpeed - randN (2 * nSpeed))); m_vPos = *vPos + vDrift + (*mOrient).FVec () * (I2X (1) / 2 - randN (I2X (1))); #if 1 m_vDrift.SetZero (); #else CFixVector::Normalize (m_vDrift); m_vDrift *= I2X (32); #endif } if ((nType != BUBBLE_PARTICLES) && mOrient) { CAngleVector vRot; CFixMatrix mRot; vRot [BA] = 0; vRot [PA] = 2048 - ((d_rand () % 9) * 512); vRot [HA] = 2048 - ((d_rand () % 9) * 512); mRot = CFixMatrix::Create (vRot); m_mOrient = *mOrient * mRot; } if (nLife < 0) nLife = -nLife; if (nType == SMOKE_PARTICLES) { if (gameOpts->render.particles.bDisperse) nLife = (nLife * 2) / 3; nLife = nLife / 2 + randN (nLife / 2); } m_nLife = m_nTTL = nLife; m_nMoved = nCurTime; m_nDelay = 0; //bStart ? randN (nLife) : 0; if (nType == SMOKE_PARTICLES) nRad += randN (nRad); else if (nType == BUBBLE_PARTICLES) nRad = nRad / 10 + randN (9 * nRad / 10); else nRad *= 2; if ((m_bBlowUp = bBlowUp)) { m_nRad = nRad / 2; m_nWidth = m_nHeight = m_nRad; m_nRad += m_nRad / bBlowUp; } else { m_nWidth = m_nHeight = nRad; m_nRad = nRad / 2; } nFrames = nParticleFrames [0][nType]; if (nType == BULLET_PARTICLES) { m_nFrame = 0; m_nRotFrame = 0; m_nOrient = 3; } else if (nType == BUBBLE_PARTICLES) { m_nFrame = rand () % (nFrames * nFrames); m_nRotFrame = 0; m_nOrient = 0; } else if (nType == LIGHT_PARTICLES) { m_nFrame = 0; m_nRotFrame = 0; m_nOrient = 0; } else { m_nFrame = rand () % (nFrames * nFrames); m_nRotFrame = m_nFrame / 2; m_nOrient = rand () % 4; } #if 1 if (m_bEmissive) m_color [0].alpha *= ParticleBrightness (colorP); else if (nParticleSystemType == SMOKE_PARTICLES) m_color [0].alpha /= colorP ? color.red + color.green + color.blue + 2 : 2; else if (nParticleSystemType == BUBBLE_PARTICLES) m_color [0].alpha /= 2; else if (nParticleSystemType == LIGHT_PARTICLES) m_color [0].alpha /= 5; # if 0 else if (nParticleSystemType == GATLING_PARTICLES) ;//m_color [0].alpha /= 6; # endif #endif return 1; }