Пример #1
0
/* static */
double WeightMatrix::DotProduct(const double* u, const double* v, int n) {
  // Note: because the order of addition is different among the 3 DotProduct
  // functions, the results can (and do) vary slightly (although they agree
  // to within about 4e-15). This produces different results when running
  // training, despite all random inputs being precisely equal.
  // To get consistent results, use just one of these DotProduct functions.
  // On a test multi-layer network, serial is 57% slower than sse, and avx
  // is about 8% faster than sse. This suggests that the time is memory
  // bandwidth constrained and could benefit from holding the reused vector
  // in AVX registers.
  if (SIMDDetect::IsAVXAvailable()) return DotProductAVX(u, v, n);
  if (SIMDDetect::IsSSEAvailable()) return DotProductSSE(u, v, n);
  double total = 0.0;
  for (int k = 0; k < n; ++k) total += u[k] * v[k];
  return total;
}
Пример #2
0
/*
====================
UpdateParticle

====================
*/
bool CParticleEngine::UpdateParticle( cl_particle_t *pParticle ) 
{
	pmtrace_t pmtrace;
	bool bColWater = false;

	float flTime = gEngfuncs.GetClientTime();
	vec3_t vFinalVelocity = pParticle->velocity;
	particle_system_t *pSystem = pParticle->pSystem;

	//
	// Check if the particle is ready to die
	//
	if(pParticle->life != -1)
	{
		if(pParticle->life <= flTime)
		{
			if(pSystem->deathcreate[0] != 0)
				CreateSystem(pSystem->deathcreate, pParticle->origin, pParticle->velocity.Normalize(), 0);

			return false; // remove
		}
	}

	//
	// Damp velocity
	//
	if(pSystem->velocitydamp && (pParticle->spawntime + pSystem->veldampdelay) < flTime)
		VectorScale(vFinalVelocity, (1.0 - pSystem->velocitydamp*m_flFrameTime), vFinalVelocity);

	//
	// Add gravity before collision test
	//
	vFinalVelocity.z -= m_pCvarGravity->value*pSystem->gravity*m_flFrameTime;

	//
	// Add in wind on either axes
	//
	if(pSystem->windtype)
	{
		if(pParticle->windxvel)
		{
			if(pSystem->windtype == PARTICLE_WIND_LINEAR)
				vFinalVelocity.x += pParticle->windxvel*m_flFrameTime;
			else
				vFinalVelocity.x += sin((flTime*pParticle->windmult))*pParticle->windxvel*m_flFrameTime;
		}
		if(pParticle->windyvel)
		{
			if(pSystem->windtype == PARTICLE_WIND_LINEAR)
				vFinalVelocity.y += pParticle->windyvel*m_flFrameTime;
			else
				vFinalVelocity.y += sin((flTime*pParticle->windmult))*pParticle->windyvel*m_flFrameTime;
		}
	}

	//
	// Calculate rotation on all axes
	//
	if(pSystem->rotationvel)
	{
		if(pSystem->rotationdamp && pParticle->rotationvel)
		{
			if((pSystem->rotationdampdelay + pParticle->spawntime) < flTime)
				pParticle->rotationvel = pParticle->rotationvel*(1.0 - pSystem->rotationdamp);
		}

		pParticle->rotation += pParticle->rotationvel*m_flFrameTime;
	
		if(pParticle->rotation < 0)
			pParticle->rotation += 360;
		if(pParticle->rotation > 360)
			pParticle->rotation -= 360;
	}
	if(pSystem->rotxvel)
	{
		if(pSystem->rotxdamp && pParticle->rotxvel)
		{
			if((pSystem->rotxdampdelay + pParticle->spawntime) < flTime)
				pParticle->rotxvel = pParticle->rotxvel*(1.0 - pSystem->rotxdamp);
		}

		pParticle->rotx += pParticle->rotxvel*m_flFrameTime;
	
		if(pParticle->rotx < 0)
			pParticle->rotx += 360;
		if(pParticle->rotx > 360)
			pParticle->rotx -= 360;
	}
	if(pSystem->rotyvel)
	{
		if(pSystem->rotydamp && pParticle->rotyvel)
		{
			if((pSystem->rotydampdelay + pParticle->spawntime) < flTime)
				pParticle->rotyvel = pParticle->rotyvel*(1.0 - pSystem->rotydamp);
		}

		pParticle->roty += pParticle->rotyvel*m_flFrameTime;
	
		if(pParticle->roty < 0)
			pParticle->roty += 360;
		if(pParticle->roty > 360)
			pParticle->roty -= 360;
	}

	//
	// Collision detection
	//
	if(pSystem->collision)
	{
		gEngfuncs.pEventAPI->EV_SetTraceHull(2);
		gEngfuncs.pEventAPI->EV_PlayerTrace(pParticle->origin, (pParticle->origin+vFinalVelocity*m_flFrameTime), PM_WORLD_ONLY, -1, &pmtrace);

		if(pmtrace.allsolid)
			return false; // Probably spawned inside a solid
			
		if(pSystem->colwater)
		{
			if(gEngfuncs.PM_PointContents(pParticle->origin + vFinalVelocity*m_flFrameTime, 0) == CONTENTS_WATER)
			{
				pmtrace.endpos = pParticle->origin + vFinalVelocity*m_flFrameTime;
				int iEntity = gEngfuncs.PM_WaterEntity(pParticle->origin + vFinalVelocity*m_flFrameTime);
				
				if(iEntity)
				{
					cl_entity_t *pEntity = gEngfuncs.GetEntityByIndex(iEntity);
					pmtrace.endpos.z = pEntity->model->maxs.z + 0.001;
				}

				pmtrace.plane.normal = Vector(0, 0, 1);
				pmtrace.fraction = 0;
				bColWater = true;
			}
		}

		if(pmtrace.fraction != 1.0)
		{
			if(pSystem->collision == PARTICLE_COLLISION_STUCK)
			{
				if(gEngfuncs.PM_PointContents(pmtrace.endpos, NULL) == CONTENTS_SKY)
					return false;

				if(pParticle->life == -1 && pSystem->stuckdie)
				{
					pParticle->life = gEngfuncs.GetClientTime() + pSystem->stuckdie;
					pParticle->fadeoutdelay = gEngfuncs.GetClientTime() - pParticle->spawntime;
				}
				VectorMASSE( pParticle->origin, pmtrace.fraction*m_flFrameTime, vFinalVelocity, pParticle->origin );

				pParticle->rotationvel = NULL;
				pParticle->rotxvel = NULL;
				pParticle->rotyvel = NULL;

				VectorClear(pParticle->velocity);
				VectorClear(vFinalVelocity);
			}
			else if(pSystem->collision == PARTICLE_COLLISION_BOUNCE)
			{
				float fProj/* = DotProduct(vFinalVelocity, pmtrace.plane.normal)*/;
				DotProductSSE(&fProj, vFinalVelocity, pmtrace.plane.normal);
			
				VectorMASSE(vFinalVelocity, -fProj*2, pmtrace.plane.normal, pParticle->velocity);
				VectorScale(pParticle->velocity, pSystem->impactdamp, pParticle->velocity);
				VectorScale(vFinalVelocity, pmtrace.fraction, vFinalVelocity);

				if(pParticle->rotationvel)
					pParticle->rotationvel *= -fProj*2*pSystem->impactdamp*m_flFrameTime;

				if(pParticle->rotxvel)
					pParticle->rotxvel *= -fProj*2*pSystem->impactdamp*m_flFrameTime;

				if(pParticle->rotyvel)
					pParticle->rotyvel *= -fProj*2*pSystem->impactdamp*m_flFrameTime;
			}
			else if(pSystem->collision == PARTICLE_COLLISION_DECAL)
			{
				gBSPRenderer.CreateDecal(pmtrace.endpos, pmtrace.plane.normal, pSystem->create);
				return false;
			}
			else if(pSystem->collision == PARTICLE_COLLISION_NEW_SYSTEM)
			{
				if(bColWater && pSystem->watercreate[0] != 0)
				{
					for(int i = 0; i < pSystem->watersystem->startparticles; i++)
						CreateParticle(pSystem->watersystem, pmtrace.endpos, pmtrace.plane.normal);
				}
				if(gEngfuncs.PM_PointContents(pmtrace.endpos, NULL) != CONTENTS_SKY && pSystem->create[0] != 0)
				{
					for(int i = 0; i < pSystem->createsystem->startparticles; i++)
						CreateParticle(pSystem->createsystem, pmtrace.endpos, pmtrace.plane.normal);
				}
				return false;
			}
			else
			{
				// kill it
				return false;
			}
		}
		else
		{
			VectorCopy(vFinalVelocity, pParticle->velocity);
		}
	}
	else
	{
		VectorCopy(vFinalVelocity, pParticle->velocity);
	}

	//
	// Add in the final velocity
	//
	VectorMASSE(pParticle->origin, m_flFrameTime, vFinalVelocity, pParticle->origin);

	//
	// Always reset to 1.0
	//
	pParticle->alpha = 1.0;

	//
	// Fading in
	//
	if(pSystem->fadeintime)
	{
		if((pParticle->spawntime + pSystem->fadeintime) > flTime)
		{
			float flFadeTime = pParticle->spawntime + pSystem->fadeintime;
			float flTimeToFade = flFadeTime - flTime;

			pParticle->alpha = 1.0 - (flTimeToFade/pSystem->fadeintime);
		}
	}

	//
	// Fade out
	//
	if(pParticle->fadeoutdelay)
	{
		if((pParticle->fadeoutdelay + pParticle->spawntime) < flTime)
		{
			float flTimeToDeath = pParticle->life - flTime;
			float flFadeTime = pParticle->fadeoutdelay + pParticle->spawntime;
			float flFadeFrac = pParticle->life - flFadeTime;

			pParticle->alpha = flTimeToDeath/flFadeFrac;
		}
	}

	//
	// Minimum and maximum distance fading
	//
	if(pSystem->fadedistfar && pSystem->fadedistnear)
	{
		float flDist = (pParticle->origin - gBSPRenderer.m_vRenderOrigin).Length();
		float flAlpha = 1.0-((pSystem->fadedistfar - flDist)/(pSystem->fadedistfar-pSystem->fadedistnear));
	
		if( flAlpha < 0 ) flAlpha = 0;
		if( flAlpha > 1 ) flAlpha = 1;

		pParticle->alpha *= flAlpha;
	}

	//
	// Dampen scale
	//
	if(pSystem->scaledampfactor && (pParticle->scaledampdelay < flTime))
		pParticle->scale = pParticle->scale - m_flFrameTime*pSystem->scaledampfactor;

	if(pParticle->scale <= 0)
		return false;

	//
	// Check if lighting is required
	//
	if(pSystem->lightcheck != PARTICLE_LIGHTCHECK_NONE)
	{
		if(pSystem->lightcheck == PARTICLE_LIGHTCHECK_NORMAL)
		{
			pParticle->color = LightForParticle(pParticle);
		}
		else if(pSystem->lightcheck == PARTICLE_LIGHTCHECK_SCOLOR)
		{
			pParticle->scolor = LightForParticle(pParticle);
		}
		else if(pSystem->lightcheck == PARTICLE_LIGHTCHECK_MIXP)
		{
			pParticle->color = LightForParticle(pParticle);
			pParticle->color.x = pParticle->color.x*pSystem->primarycolor.x;
			pParticle->color.y = pParticle->color.y*pSystem->primarycolor.y;
			pParticle->color.z = pParticle->color.z*pSystem->primarycolor.z;
		}
	}

	//
	// See if we need to blend colors
	// 
	if(pSystem->lightcheck != PARTICLE_LIGHTCHECK_NORMAL)
	{
		if((pParticle->secondarydelay < flTime) && (flTime < (pParticle->secondarydelay + pParticle->secondarytime)))
		{
			float flTimeFull = (pParticle->secondarydelay+pParticle->secondarytime) - flTime;
			float flColFrac = flTimeFull/pParticle->secondarytime;

			pParticle->color[0] = pParticle->scolor[0]*(1.0 - flColFrac) + pSystem->primarycolor[0]*flColFrac;
			pParticle->color[1] = pParticle->scolor[1]*(1.0 - flColFrac) + pSystem->primarycolor[1]*flColFrac;
			pParticle->color[2] = pParticle->scolor[2]*(1.0 - flColFrac) + pSystem->primarycolor[2]*flColFrac;
		}
	}

	//
	// Spawn tracer particles
	//
	if(pSystem->tracerdist)
	{
		vec3_t vDistance;
		VectorSubtract(pParticle->origin, pParticle->lastspawn, vDistance);

		if(vDistance.Length() > pSystem->tracerdist)
		{
			vec3_t vDirection = pParticle->origin - pParticle->lastspawn;
			int iNumTraces = vDistance.Length()/pSystem->tracerdist;

			for(int i = 0; i < iNumTraces; i++)
			{
				float flFraction = (i+1)/(float)iNumTraces;
				vec3_t vOrigin = pParticle->lastspawn + vDirection*flFraction;
				CreateParticle(pSystem->createsystem, vOrigin, pParticle->velocity.Normalize());
			}

			VectorCopy(pParticle->origin, pParticle->lastspawn);
		}
	}

	//
	// Calculate texcoords
	//
	if(pSystem->numframes)
	{
		// Get desired frame
		int iFrame = ((int)((flTime - pParticle->spawntime)*pSystem->framerate));
		iFrame = iFrame % pSystem->numframes;

		// Check if we actually have to set the frame
		if(iFrame != pParticle->frame)
		{
			cl_texture_t *pTexture = pSystem->texture;

			int	iNumFramesX = pTexture->iWidth/pSystem->framesizex;
			int	iNumFramesY = pTexture->iHeight/pSystem->framesizey;

			int iColumn = iFrame%iNumFramesX;
			int iRow = (iFrame/iNumFramesX)%iNumFramesY;

			// Calculate these only once
			float flFractionWidth = (float)pSystem->framesizex/(float)pTexture->iWidth;
			float flFractionHeight = (float)pSystem->framesizey/(float)pTexture->iHeight;

			// Calculate top left coordinate
			pParticle->texcoords[0][0] = (iColumn+1)*flFractionWidth;
			pParticle->texcoords[0][1] = iRow*flFractionHeight;

			// Calculate top right coordinate
			pParticle->texcoords[1][0] = iColumn*flFractionWidth;
			pParticle->texcoords[1][1] = iRow*flFractionHeight;

			// Calculate bottom right coordinate
			pParticle->texcoords[2][0] = iColumn*flFractionWidth;
			pParticle->texcoords[2][1] = (iRow+1)*flFractionHeight;

			// Calculate bottom left coordinate
			pParticle->texcoords[3][0] = (iColumn+1)*flFractionWidth;
			pParticle->texcoords[3][1] = (iRow+1)*flFractionHeight;

			// Fill in current frame
			pParticle->frame = iFrame;
		}
	}

	// All went well, particle is still active
	return true;
}
Пример #3
0
/*
====================
LightForParticle

====================
*/
vec3_t CParticleEngine::LightForParticle( cl_particle_t *pParticle ) 
{
	float flRad;
	float flDist;
	float flAtten;
	float flCos;

	vec3_t vDir;
	vec3_t vNorm;
	vec3_t vForward;

	float flTime = gEngfuncs.GetClientTime();
	model_t *pWorld = IEngineStudio.GetModelByIndex(1);
	vec3_t vEndPos = pParticle->origin - Vector(0, 0, 8964);
	vec3_t vColor = Vector(0, 0, 0);

	g_StudioRenderer.StudioRecursiveLightPoint(NULL, pWorld->nodes, pParticle->origin, vEndPos, vColor);
	cl_dlight_t *pLight = gBSPRenderer.m_pDynLights;

	for(int i = 0; i < MAX_DYNLIGHTS; i++, pLight++)
	{
		if(pLight->die < flTime || !pLight->radius)
			continue;

		if(pLight->cone_size)
		{
			if(pLight->frustum.CullBox(pParticle->origin, pParticle->origin))
				continue;

			vec3_t vAngles = pLight->angles;
			FixVectorForSpotlight(vAngles);
			AngleVectors(vAngles, vForward, NULL, NULL);
		}
		else
		{
			if(CheckLightBBox(pParticle, pLight))
				continue;
		}

		flRad = pLight->radius*pLight->radius;
		VectorSubtract(pParticle->origin, pLight->origin, vDir);
		DotProductSSE(&flDist, vDir, vDir);
		flAtten = (flDist/flRad - 1)* -1;
		
		if(pLight->cone_size)
		{
			VectorNormalizeFast(vDir);
			flCos = cos((pLight->cone_size*2)*0.3*(M_PI*2/360));
			DotProductSSE(&flDist, vForward, vDir);

			if(flDist < 0 || flDist < flCos)
				continue;

			flAtten *= (flDist - flCos)/(1.0 - flCos);
		}

		if(flAtten <= 0)
			continue;

		VectorMASSE(vColor, flAtten, pLight->color, vColor);
	}

	return vColor;
}
Пример #4
0
/*
====================
RenderParticle

====================
*/
void CParticleEngine::RenderParticle( cl_particle_t *pParticle, float flUp, float flRight ) 
{
	float flDot;
	vec3_t vTemp;
	vec3_t vPoint;
	vec3_t vDir;
	vec3_t vAngles;

	if(pParticle->alpha == 0)
		return;

	VectorSubtract(pParticle->origin, gBSPRenderer.m_vRenderOrigin, vDir);
	if(gHUD.m_pFogSettings.active)
	{
		if(vDir.Length() > gHUD.m_pFogSettings.end)
			return;
	}

	VectorNormalizeFast(vDir);
	DotProductSSE(&flDot, vDir, m_vForward);

	// z clipped
	if(flDot < 0)
		return;

	cl_texture_t *pTexture = pParticle->pSystem->texture;
	if(pParticle->pSystem->rendermode == SYSTEM_RENDERMODE_ADDITIVE)
	{
		glBlendFunc(GL_SRC_ALPHA, GL_ONE);
		glColor4f(pParticle->color[0], pParticle->color[1], pParticle->color[2], pParticle->alpha*pParticle->pSystem->mainalpha);
		glFogfv(GL_FOG_COLOR, g_vecZero);
	}
	else if(pParticle->pSystem->rendermode == SYSTEM_RENDERMODE_ALPHABLEND)
	{
		glBlendFunc(GL_ONE, GL_ONE);
		glColor3f(pParticle->alpha*pParticle->pSystem->mainalpha, pParticle->alpha*pParticle->pSystem->mainalpha, pParticle->alpha*pParticle->pSystem->mainalpha);
		glFogfv(GL_FOG_COLOR, g_vecZero);
	}
	else
	{
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glColor4f(pParticle->color[0], pParticle->color[1], pParticle->color[2], pParticle->alpha*pParticle->pSystem->mainalpha);
		glFogfv(GL_FOG_COLOR, gHUD.m_pFogSettings.color);
	}

	if(pParticle->pSystem->displaytype == SYSTEM_DISPLAY_PLANAR)
	{
		gBSPRenderer.GetUpRight(pParticle->normal, m_vRUp, m_vRRight);
	}
	else if(pParticle->rotation || pParticle->rotx || pParticle->roty)
	{
		VectorCopy(gBSPRenderer.m_vViewAngles, vAngles);

		if(pParticle->rotx) vAngles[0] = pParticle->rotx;
		if(pParticle->roty) vAngles[1] = pParticle->roty;
		if(pParticle->rotation) vAngles[2] = pParticle->rotation;

		AngleVectors(vAngles, NULL, m_vRRight, m_vRUp);
	}

	if(pParticle->pSystem->displaytype == SYSTEM_DISPLAY_PARALELL)
	{
		glBegin(GL_TRIANGLE_FAN);
		vPoint = pParticle->origin + m_vRUp * flUp * pParticle->scale * 2;
		vPoint = vPoint + m_vRRight * flRight * (-pParticle->scale);
		glTexCoord2f(pParticle->texcoords[0][0], pParticle->texcoords[0][1]);
		glVertex3fv(vPoint);

		vPoint = pParticle->origin + m_vRUp * flUp * pParticle->scale * 2;
		vPoint = vPoint + m_vRRight * flRight * pParticle->scale;
		glTexCoord2f(pParticle->texcoords[1][0], pParticle->texcoords[1][1]);
		glVertex3fv (vPoint);

		vPoint = pParticle->origin + m_vRRight * flRight * pParticle->scale;
		glTexCoord2f(pParticle->texcoords[2][0], pParticle->texcoords[2][1]);
		glVertex3fv(vPoint);

		vPoint = pParticle->origin + m_vRRight * flRight * (-pParticle->scale);
		glTexCoord2f(pParticle->texcoords[3][0], pParticle->texcoords[3][1]);
		glVertex3fv (vPoint);
		glEnd();
	}
	else
	{
		glBegin(GL_TRIANGLE_FAN);
		vPoint = pParticle->origin + m_vRUp * flUp * pParticle->scale;
		vPoint = vPoint + m_vRRight * flRight * (-pParticle->scale);
		glTexCoord2f(pParticle->texcoords[0][0], pParticle->texcoords[0][1]);
		glVertex3fv(vPoint);

		vPoint = pParticle->origin + m_vRUp * flUp * pParticle->scale;
		vPoint = vPoint + m_vRRight * flRight * pParticle->scale;
		glTexCoord2f(pParticle->texcoords[1][0], pParticle->texcoords[1][1]);
		glVertex3fv (vPoint);

		vPoint = pParticle->origin + m_vRUp * flUp * (-pParticle->scale);
		vPoint = vPoint + m_vRRight * flRight * pParticle->scale;
		glTexCoord2f(pParticle->texcoords[2][0], pParticle->texcoords[2][1]);
		glVertex3fv(vPoint);

		vPoint = pParticle->origin + m_vRUp * flUp * (-pParticle->scale);
		vPoint = vPoint + m_vRRight * flRight * (-pParticle->scale);
		glTexCoord2f(pParticle->texcoords[3][0], pParticle->texcoords[3][1]);
		glVertex3fv (vPoint);
		glEnd();
	}

	if(gBSPRenderer.m_pCvarWireFrame->value > 0)
	{
		glDisable(GL_BLEND);
		glDepthMask(GL_TRUE);
		glDisable(GL_TEXTURE_2D);
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
		glColor3f(1.0, 0.0, 0.0);
		glLineWidth(1);

		if(gBSPRenderer.m_pCvarWireFrame->value > 1)
			glDisable(GL_DEPTH_TEST);

		if(pParticle->pSystem->displaytype == SYSTEM_DISPLAY_PARALELL)
		{
			glBegin(GL_TRIANGLE_FAN);
			vPoint = pParticle->origin + m_vRUp * flUp * pParticle->scale * 2;
			vPoint = vPoint + m_vRRight * flRight * (-pParticle->scale);
			glVertex3fv(vPoint);

			vPoint = pParticle->origin + m_vRUp * flUp * pParticle->scale * 2;
			vPoint = vPoint + m_vRRight * flRight * pParticle->scale;
			glVertex3fv (vPoint);

			vPoint = pParticle->origin + m_vRRight * flRight * pParticle->scale;
			glVertex3fv(vPoint);

			vPoint = pParticle->origin + m_vRRight * flRight * (-pParticle->scale);
			glVertex3fv (vPoint);
			glEnd();
		}
		else
		{
			glBegin(GL_TRIANGLE_FAN);
			vPoint = pParticle->origin + m_vRUp * flUp * pParticle->scale;
			vPoint = vPoint + m_vRRight * flRight * (-pParticle->scale);
			glVertex3fv(vPoint);

			vPoint = pParticle->origin + m_vRUp * flUp * pParticle->scale;
			vPoint = vPoint + m_vRRight * flRight * pParticle->scale;
			glVertex3fv (vPoint);

			vPoint = pParticle->origin + m_vRUp * flUp * (-pParticle->scale);
			vPoint = vPoint + m_vRRight * flRight * pParticle->scale;
			glVertex3fv(vPoint);

			vPoint = pParticle->origin + m_vRUp * flUp * (-pParticle->scale);
			vPoint = vPoint + m_vRRight * flRight * (-pParticle->scale);
			glVertex3fv (vPoint);
			glEnd();
		}

		if(gBSPRenderer.m_pCvarWireFrame->value > 1)
			glEnable(GL_DEPTH_TEST);

		glEnable(GL_BLEND);
		glDepthMask(GL_FALSE);
		glEnable(GL_TEXTURE_2D);
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	}

	m_iNumParticles++;
}