Exemple #1
0
/*
================
RemoveLinearMeshColumsRows
================
*/
mesh_t *RemoveLinearMeshColumnsRows( mesh_t *in ) {
    int                            i, j, k;
    float                        len, maxLength;
    vec3_t                        proj, dir;
    mesh_t                        out;
    
    /* ydnar: static for os x */
    MAC_STATIC bspDrawVert_t    expand[MAX_EXPANDED_AXIS][MAX_EXPANDED_AXIS];
    

    out.width = in->width;
    out.height = in->height;

    for ( i = 0 ; i < in->width ; i++ ) {
        for ( j = 0 ; j < in->height ; j++ ) {
            expand[j][i] = in->verts[j*in->width+i];
        }
    }

    for ( j = 1 ; j < out.width - 1; j++ ) {
        maxLength = 0;
        for ( i = 0 ; i < out.height ; i++ ) {
            ProjectPointOntoVector(expand[i][j].xyz, expand[i][j-1].xyz, expand[i][j+1].xyz, proj);
            VectorSubtract(expand[i][j].xyz, proj, dir);
            len = VectorLength(dir);
            if (len > maxLength) {
                maxLength = len;
            }
        }
        if (maxLength < 0.1)
        {
            out.width--;
            for ( i = 0 ; i < out.height ; i++ ) {
                for (k = j; k < out.width; k++) {
                    expand[i][k] = expand[i][k+1];
                }
            }
            j--;
        }
    }
    for ( j = 1 ; j < out.height - 1; j++ ) {
        maxLength = 0;
        for ( i = 0 ; i < out.width ; i++ ) {
            ProjectPointOntoVector(expand[j][i].xyz, expand[j-1][i].xyz, expand[j+1][i].xyz, proj);
            VectorSubtract(expand[j][i].xyz, proj, dir);
            len = VectorLength(dir);
            if (len > maxLength) {
                maxLength = len;
            }
        }
        if (maxLength < 0.1)
        {
            out.height--;
            for ( i = 0 ; i < out.width ; i++ ) {
                for (k = j; k < out.height; k++) {
                    expand[k][i] = expand[k+1][i];
                }
            }
            j--;
        }
    }
    // collapse the verts
    out.verts = &expand[0][0];
    for ( i = 1 ; i < out.height ; i++ ) {
        memmove( &out.verts[i*out.width], expand[i], out.width * sizeof(bspDrawVert_t) );
    }

    return CopyMesh(&out);
}
Exemple #2
0
void CG_AddTrailToScene(trailJunc_t *trail, int iteration, int numJuncs)
{
#define MAX_TRAIL_VERTS     2048
	polyVert_t verts[MAX_TRAIL_VERTS];
	polyVert_t outVerts[MAX_TRAIL_VERTS * 3];
	int k, i, n, l, numOutVerts;
	polyVert_t mid;
	float mod[4];
	float sInc = 0.0f, s = 0.0f;   // TTimo: init
	trailJunc_t *j, *jNext;
	vec3_t fwd, up, p, v;
	(void)fwd; // Ignore compiler warning -- Justasic
	// clipping vars
#define TRAIL_FADE_CLOSE_DIST   64.0
#define TRAIL_FADE_FAR_SCALE    4.0
	vec3_t viewProj;
	float viewDist, fadeAlpha;

	// add spark shader at head position
	if(trail->flags & TJFL_SPARKHEADFLARE)
	{
		j = trail;
		VectorCopy(j->pos, p);
		VectorMA(p, -j->width * 2, vup, p);
		VectorMA(p, -j->width * 2, vright, p);
		VectorCopy(p, verts[0].xyz);
		verts[0].st[0] = 0;
		verts[0].st[1] = 0;
		verts[0].modulate[0] = 255;
		verts[0].modulate[1] = 255;
		verts[0].modulate[2] = 255;
		verts[0].modulate[3] = (unsigned char)(j->alpha * 255.0);

		VectorCopy(j->pos, p);
		VectorMA(p, -j->width * 2, vup, p);
		VectorMA(p, j->width * 2, vright, p);
		VectorCopy(p, verts[1].xyz);
		verts[1].st[0] = 0;
		verts[1].st[1] = 1;
		verts[1].modulate[0] = 255;
		verts[1].modulate[1] = 255;
		verts[1].modulate[2] = 255;
		verts[1].modulate[3] = (unsigned char)(j->alpha * 255.0);

		VectorCopy(j->pos, p);
		VectorMA(p, j->width * 2, vup, p);
		VectorMA(p, j->width * 2, vright, p);
		VectorCopy(p, verts[2].xyz);
		verts[2].st[0] = 1;
		verts[2].st[1] = 1;
		verts[2].modulate[0] = 255;
		verts[2].modulate[1] = 255;
		verts[2].modulate[2] = 255;
		verts[2].modulate[3] = (unsigned char)(j->alpha * 255.0);

		VectorCopy(j->pos, p);
		VectorMA(p,  j->width * 2, vup, p);
		VectorMA(p, -j->width * 2, vright, p);
		VectorCopy(p, verts[3].xyz);
		verts[3].st[0] = 1;
		verts[3].st[1] = 0;
		verts[3].modulate[0] = 255;
		verts[3].modulate[1] = 255;
		verts[3].modulate[2] = 255;
		verts[3].modulate[3] = (unsigned char)(j->alpha * 255.0);

		trap_R_AddPolyToScene(cgs.media.sparkFlareShader, 4, verts);
	}

//	if (trail->flags & TJFL_CROSSOVER && iteration < 1) {
//		iteration = 1;
//	}

	if(!numJuncs)
	{
		// first count the number of juncs in the trail
		j = trail;
		numJuncs = 0;
		sInc = 0;

		while(j)
		{
			numJuncs++;

			// check for a dead next junc
			if(!j->inuse && j->nextJunc && !j->nextJunc->inuse)
			{
				CG_KillTrail(j);
			}
			else if(j->nextJunc && j->nextJunc->freed)
			{
				// not sure how this can happen, but it does, and causes infinite loops
				j->nextJunc = NULL;
			}

			if(j->nextJunc)
			{
				sInc += VectorDistance(j->nextJunc->pos, j->pos);
			}

			j = j->nextJunc;
		}
	}

	if(numJuncs < 2)
	{
		return;
	}

	if(trail->sType == STYPE_STRETCH)
	{
		//sInc = ((1.0 - 0.1) / (float)(numJuncs)); // hack, the end of funnel shows a bit of the start (looping)
		s = 0.05;
		//s = 0.05;
	}
	else if(trail->sType == STYPE_REPEAT)
	{
		s = trail->sTex;
	}

	// now traverse the list
	j = trail;
	jNext = j->nextJunc;
	i = 0;

	while(jNext)
	{

		// first get the directional vectors to the next junc
		VectorSubtract(jNext->pos, j->pos, fwd);
		GetPerpendicularViewVector(cg.refdef.vieworg, j->pos, jNext->pos, up);

		// if it's a crossover, draw it twice
		if(j->flags & TJFL_CROSSOVER)
		{
			if(iteration > 0)
			{
				ProjectPointOntoVector(cg.refdef.vieworg, j->pos, jNext->pos, viewProj);
				VectorSubtract(cg.refdef.vieworg, viewProj, v);
				VectorNormalize(v);

				if(iteration == 1)
				{
					VectorMA(up, 0.3, v, up);
				}
				else
				{
					VectorMA(up, -0.3, v, up);
				}

				VectorNormalize(up);
			}
		}
		// do fading when moving towards the projection point onto the trail segment vector
		else if(!(j->flags & TJFL_NOCULL) && (j->widthEnd > 4 || jNext->widthEnd > 4))
		{
			ProjectPointOntoVector(cg.refdef.vieworg, j->pos, jNext->pos, viewProj);
			viewDist = Distance(viewProj, cg.refdef.vieworg);

			if(viewDist < (TRAIL_FADE_CLOSE_DIST * TRAIL_FADE_FAR_SCALE))
			{
				if(viewDist < TRAIL_FADE_CLOSE_DIST)
				{
					fadeAlpha = 0.0;
				}
				else
				{
					fadeAlpha = (viewDist - TRAIL_FADE_CLOSE_DIST) / (TRAIL_FADE_CLOSE_DIST * TRAIL_FADE_FAR_SCALE);
				}

				if(fadeAlpha < j->alpha)
				{
					j->alpha = fadeAlpha;
				}

				if(fadeAlpha < jNext->alpha)
				{
					jNext->alpha = fadeAlpha;
				}
			}
		}

		// now output the QUAD for this segment

		// 1 ----
		VectorMA(j->pos, 0.5 * j->width, up, p);
		VectorCopy(p, verts[i].xyz);
		verts[i].st[0] = s;
		verts[i].st[1] = 1.0;

		for(k = 0; k < 3; k++)
			verts[i].modulate[k] = (unsigned char)(j->color[k] * 255.0);

		verts[i].modulate[3] = (unsigned char)(j->alpha * 255.0);

		// blend this with the previous junc
		if(j != trail)
		{
			VectorAdd(verts[i].xyz, verts[i - 1].xyz, verts[i].xyz);
			VectorScale(verts[i].xyz, 0.5, verts[i].xyz);
			VectorCopy(verts[i].xyz, verts[i - 1].xyz);
		}
		else if(j->flags & TJFL_FADEIN)
		{
			verts[i].modulate[3] = 0;   // fade in
		}

		i++;

		// 2 ----
		VectorMA(p, -1 * j->width, up, p);
		VectorCopy(p, verts[i].xyz);
		verts[i].st[0] = s;
		verts[i].st[1] = 0.0;

		for(k = 0; k < 3; k++)
			verts[i].modulate[k] = (unsigned char)(j->color[k] * 255.0);

		verts[i].modulate[3] = (unsigned char)(j->alpha * 255.0);

		// blend this with the previous junc
		if(j != trail)
		{
			VectorAdd(verts[i].xyz, verts[i - 3].xyz, verts[i].xyz);
			VectorScale(verts[i].xyz, 0.5, verts[i].xyz);
			VectorCopy(verts[i].xyz, verts[i - 3].xyz);
		}
		else if(j->flags & TJFL_FADEIN)
		{
			verts[i].modulate[3] = 0;   // fade in
		}

		i++;

		if(trail->sType == STYPE_REPEAT)
		{
			s = jNext->sTex;
		}
		else
		{
			//s += sInc;
			s += VectorDistance(j->pos, jNext->pos) / sInc;

			if(s > 1.0)
			{
				s = 1.0;
			}
		}

		// 3 ----
		VectorMA(jNext->pos, -0.5 * jNext->width, up, p);
		VectorCopy(p, verts[i].xyz);
		verts[i].st[0] = s;
		verts[i].st[1] = 0.0;

		for(k = 0; k < 3; k++)
			verts[i].modulate[k] = (unsigned char)(jNext->color[k] * 255.0);

		verts[i].modulate[3] = (unsigned char)(jNext->alpha * 255.0);
		i++;

		// 4 ----
		VectorMA(p, jNext->width, up, p);
		VectorCopy(p, verts[i].xyz);
		verts[i].st[0] = s;
		verts[i].st[1] = 1.0;

		for(k = 0; k < 3; k++)
			verts[i].modulate[k] = (unsigned char)(jNext->color[k] * 255.0);

		verts[i].modulate[3] = (unsigned char)(jNext->alpha * 255.0);
		i++;

		if(i + 4 > MAX_TRAIL_VERTS)
		{
			break;
		}

		j = jNext;
		jNext = j->nextJunc;
	}

	if(trail->flags & TJFL_FIXDISTORT)
	{
		// build the list of outVerts, by dividing up the QUAD's into 4 Tri's each, so as to allow
		//  any shaped (convex) Quad without bilinear distortion
		for(k = 0, numOutVerts = 0; k < i; k += 4)
		{
			VectorCopy(verts[k].xyz, mid.xyz);
			mid.st[0] = verts[k].st[0];
			mid.st[1] = verts[k].st[1];

			for(l = 0; l < 4; l++)
			{
				mod[l] = (float)verts[k].modulate[l];
			}

			for(n = 1; n < 4; n++)
			{
				VectorAdd(verts[k + n].xyz, mid.xyz, mid.xyz);
				mid.st[0] += verts[k + n].st[0];
				mid.st[1] += verts[k + n].st[1];

				for(l = 0; l < 4; l++)
				{
					mod[l] += (float)verts[k + n].modulate[l];
				}
			}

			VectorScale(mid.xyz, 0.25, mid.xyz);
			mid.st[0] *= 0.25;
			mid.st[1] *= 0.25;

			for(l = 0; l < 4; l++)
			{
				mid.modulate[l] = (unsigned char)(mod[l] / 4.0);
			}

			// now output the tri's
			for(n = 0; n < 4; n++)
			{
				outVerts[numOutVerts++] = verts[k + n];
				outVerts[numOutVerts++] = mid;

				if(n < 3)
				{
					outVerts[numOutVerts++] = verts[k + n + 1];
				}
				else
				{
					outVerts[numOutVerts++] = verts[k];
				}
			}

		}

		if(!(trail->flags & TJFL_NOPOLYMERGE))
		{
			trap_R_AddPolysToScene(trail->shader, 3, &outVerts[0], numOutVerts / 3);
		}
		else
		{
			int k;

			for(k = 0; k < numOutVerts / 3; k++)
			{
				trap_R_AddPolyToScene(trail->shader, 3, &outVerts[k * 3]);
			}
		}
	}
	else
	{
		// send the polygons
		// FIXME: is it possible to send a GL_STRIP here? We are actually sending 2x the verts we really need to
		if(!(trail->flags & TJFL_NOPOLYMERGE))
		{
			trap_R_AddPolysToScene(trail->shader, 4, &verts[0], i / 4);
		}
		else
		{
			int k;

			for(k = 0; k < i / 4; k++)
			{
				trap_R_AddPolyToScene(trail->shader, 4, &verts[k * 4]);
			}
		}
	}

	// do we need to make another pass?
	if(trail->flags & TJFL_CROSSOVER)
	{
		if(iteration < 2)
		{
			CG_AddTrailToScene(trail, iteration + 1, numJuncs);
		}
	}

}
Exemple #3
0
/*
=================
CG_Bleed

This is the spurt of blood when a character gets hit
=================
*/
void CG_Bleed(vec3_t origin, int entityNum)
{
#define BLOOD_SPURT_COUNT   4
	int       i, j;
	centity_t *cent;

	if (!cg_blood.integer)
	{
		return;
	}

#ifdef SAVEGAME_SUPPORT
	if (cg_reloading.integer)
	{
		// to dangerous, since we call playerangles() in here, which calls the animation system, which might not be setup yet
		return;
	}
#endif // SAVEGAME_SUPPORT

	cent = &cg_entities[entityNum];

	// Ridah, blood spurts
	if (entityNum != cg.snap->ps.clientNum)
	{
		vec3_t vhead, vbody, bOrigin, dir, vec, pvec, ndir;

		CG_GetBleedOrigin(vhead, vbody, entityNum);

		// project the impact point onto the vector defined by torso -> head
		ProjectPointOntoVector(origin, vbody, vhead, bOrigin);

		// if it's below the waste, or above the head, clamp
		VectorSubtract(vhead, vbody, vec);
		VectorSubtract(bOrigin, vbody, pvec);
		if (DotProduct(pvec, vec) < 0)
		{
			VectorCopy(vbody, bOrigin);
		}
		else
		{
			VectorSubtract(bOrigin, vhead, pvec);
			if (DotProduct(pvec, vec) > 0)
			{
				VectorCopy(vhead, bOrigin);
			}
		}

		// spawn some blood trails, heading out towards the impact point
		VectorSubtract(origin, bOrigin, dir);
		VectorNormalize(dir);

		{
			float  len;
			vec3_t vec;

			VectorSubtract(bOrigin, vhead, vec);
			len = VectorLength(vec);

			if (len > 8)
			{
				VectorMA(bOrigin, 8, dir, bOrigin);
			}
		}

		// DHM - Nerve :: Made minor adjustments
		for (i = 0; i < BLOOD_SPURT_COUNT; i++)
		{
			VectorCopy(dir, ndir);
			for (j = 0; j < 3; j++)
				ndir[j] += crandom() * 0.3;
			VectorNormalize(ndir);
			CG_AddBloodTrails(bOrigin, ndir,
			                  100,  // speed
			                  450 + (int)(crandom() * 50),       // duration
			                  2 + rand() % 2,     // count
			                  0.1);     // rand scale
		}
	}
}
Exemple #4
0
/*
=================
CG_Bleed

This is the spurt of blood when a character gets hit
=================
*/
void CG_Bleed(vec3_t origin, int entityNum)
{
	if (!cg_blood.integer)
	{
		return;
	}

	// blood spurts
	if (entityNum != cg.snap->ps.clientNum)
	{
		vec3_t vhead, vbody, bOrigin, dir, vec, pvec, ndir;
		int    i, j;

		CG_GetBleedOrigin(vhead, vbody, entityNum);

		// project the impact point onto the vector defined by torso -> head
		ProjectPointOntoVector(origin, vbody, vhead, bOrigin);

		// if it's below the waste, or above the head, clamp
		VectorSubtract(vhead, vbody, vec);
		VectorSubtract(bOrigin, vbody, pvec);
		if (DotProduct(pvec, vec) < 0)
		{
			VectorCopy(vbody, bOrigin);
		}
		else
		{
			VectorSubtract(bOrigin, vhead, pvec);
			if (DotProduct(pvec, vec) > 0)
			{
				VectorCopy(vhead, bOrigin);
			}
		}

		// spawn some blood trails, heading out towards the impact point
		VectorSubtract(origin, bOrigin, dir);
		VectorNormalize(dir);

		{
			float  len;
			vec3_t vec;

			VectorSubtract(bOrigin, vhead, vec);
			len = VectorLength(vec);

			if (len > 8)
			{
				VectorMA(bOrigin, 8, dir, bOrigin);
			}
		}

		for (i = 0; i < BLOOD_SPURT_COUNT; i++)
		{
			VectorCopy(dir, ndir);
			for (j = 0; j < 3; j++)
			{
				ndir[j] += crandom() * 0.3;
			}
			VectorNormalize(ndir);
			CG_AddBloodTrails(bOrigin, ndir,
			                  100,  // speed
			                  450 + (int)(crandom() * 50),       // duration
			                  2 + rand() % 2,     // count
			                  0.1);     // rand scale
		}
	}
}
Exemple #5
0
/*
==============
AICast_PredictMovement

  Simulates movement over a number of frames, returning the end position
==============
*/
void AICast_PredictMovement( cast_state_t *cs, int numframes, float frametime, aicast_predictmove_t *move, usercmd_t *ucmd, int checkHitEnt ) {
	int frame, i;
	playerState_t ps;
	pmove_t pm;
	trace_t tr;
	vec3_t end, startHitVec, thisHitVec, lastOrg, projPoint;
	qboolean checkReachMarker;

//int pretime = Sys_MilliSeconds();
//G_Printf("PredictMovement: %f duration, %i frames\n", frametime, numframes );
	VectorCopy( vec3_origin, startHitVec );

	if ( cs->bs ) {
		ps = cs->bs->cur_ps;
	} else {
		ps = g_entities[cs->entityNum].client->ps;
	}

	ps.eFlags |= EF_DUMMY_PMOVE;

	move->stopevent = PREDICTSTOP_NONE;

	if ( checkHitEnt >= 0 && !Q_stricmp( g_entities[checkHitEnt].classname, "ai_marker" ) ) {
		checkReachMarker = qtrue;
		VectorSubtract( g_entities[checkHitEnt].r.currentOrigin, ps.origin, startHitVec );
		VectorCopy( ps.origin, lastOrg );
	} else {
		checkReachMarker = qfalse;
	}

	// don't let the frametime be too high
//	while (frametime > 0.2) {
//		numframes *= 2;
//		frametime /= 2;
//	}

	for ( frame = 0; frame < numframes; frame++ )
	{
		memset( &pm, 0, sizeof( pm ) );
		pm.ps = &ps;
		pm.cmd = *ucmd;
		pm.oldcmd = *ucmd;
		pm.ps->commandTime = 0;
		pm.cmd.serverTime = (int)( 1000.0 * frametime );
		pm.tracemask = g_entities[cs->entityNum].clipmask; //MASK_PLAYERSOLID;

		pm.trace = trap_TraceCapsule; //trap_Trace;
		pm.pointcontents = trap_PointContents;
		pm.debugLevel = qfalse;
		pm.noFootsteps = qtrue;
		// RF, not needed for prediction
		//pm.noWeapClips = qtrue;	// (SA) AI's ignore weapon clips

		// perform a pmove
		Pmove( &pm );

		if ( checkHitEnt >= 0 ) {
			// if we've hit the checkent, abort
			if ( checkReachMarker ) {
				VectorSubtract( g_entities[checkHitEnt].r.currentOrigin, pm.ps->origin, thisHitVec );
				if ( DotProduct( startHitVec, thisHitVec ) < 0 ) {
					// project the marker onto the movement vec, and check distance
					ProjectPointOntoVector( g_entities[checkHitEnt].r.currentOrigin, lastOrg, pm.ps->origin, projPoint );
					if ( VectorDistance( g_entities[checkHitEnt].r.currentOrigin, projPoint ) < 8 ) {
						move->stopevent = PREDICTSTOP_HITENT;
						goto done;
					}
				}
				// use this position as the base for the next test
				//VectorCopy( thisHitVec, startHitVec );
				VectorCopy( pm.ps->origin, lastOrg );
			}
			// if we didnt reach the marker, then check for something that blocked us
			for ( i = 0; i < pm.numtouch; i++ ) {
				if ( pm.touchents[i] == pm.ps->groundEntityNum ) {
					continue;
				}
				if ( pm.touchents[i] == checkHitEnt ) {
					move->stopevent = PREDICTSTOP_HITENT;
					goto done;
				} else if ( pm.touchents[i] < MAX_CLIENTS ||
							( pm.touchents[i] != ENTITYNUM_WORLD && ( g_entities[pm.touchents[i]].s.eType != ET_MOVER || g_entities[pm.touchents[i]].moverState != MOVER_POS1 ) ) ) {
					// we have hit another entity, so abort
					move->stopevent = PREDICTSTOP_HITCLIENT;
					goto done;
				} else if ( !Q_stricmp( g_entities[pm.touchents[i]].classname, "script_mover" ) ) {
					// avoid script_mover's
					move->stopevent = PREDICTSTOP_HITCLIENT;
					goto done;
				}
			}
		}
	}

done:

	// hack, if we are above ground, chances are it's because we only did one frame, and gravity isn't applied until
	// after the frame, so try and drop us down some
	if ( move->groundEntityNum == ENTITYNUM_NONE ) {
		VectorCopy( move->endpos, end );
		end[2] -= 32;
		trap_Trace( &tr, move->endpos, pm.mins, pm.maxs, end, pm.ps->clientNum, pm.tracemask );
		if ( !tr.startsolid && !tr.allsolid && tr.fraction < 1 ) {
			VectorCopy( tr.endpos, pm.ps->origin );
			pm.ps->groundEntityNum = tr.entityNum;
		}
	}

	// copy off the results
	VectorCopy( pm.ps->origin, move->endpos );
	move->frames = numframes;
	//move->presencetype = cs->bs->presencetype;
	VectorCopy( pm.ps->velocity, move->velocity );
	move->numtouch = pm.numtouch;
	memcpy( move->touchents, pm.touchents, sizeof( pm.touchents ) );
	move->groundEntityNum = pm.ps->groundEntityNum;

//G_Printf("PredictMovement: %i ms\n", -pretime + Sys_MilliSeconds() );
}
Exemple #6
0
/*
=================
CG_Bleed

This is the spurt of blood when a character gets hit
=================
*/
void CG_Bleed( vec3_t origin, int entityNum ) {
#define BLOOD_SPURT_COUNT   4
	int i,j;
//	localEntity_t *ex;
	centity_t *cent;
//	vec3_t	dir;

	if ( !cg_blood.integer ) {
		return;
	}

	cent = &cg_entities[entityNum];

	if ( cent->currentState.aiChar == AICHAR_ZOMBIE ) {
		CG_ParticleBloodCloudZombie( cent, origin, vec3_origin );
		return;
	}

	// Ridah, blood spurts
	if ( entityNum != cg.snap->ps.clientNum ) {
		vec3_t vhead, vlegs, vtorso, bOrigin, dir, vec, pvec, ndir;

		CG_GetBleedOrigin( vhead, vtorso, vlegs, entityNum );

		// project the impact point onto the vector defined by torso -> head
		ProjectPointOntoVector( origin, vtorso, vhead, bOrigin );

		// if it's below the waste, or above the head, clamp
		VectorSubtract( vhead, vtorso, vec );
		VectorSubtract( bOrigin, vtorso, pvec );
		if ( DotProduct( pvec, vec ) < 0 ) {
			VectorCopy( vtorso, bOrigin );
		} else {
			VectorSubtract( bOrigin, vhead, pvec );
			if ( DotProduct( pvec, vec ) > 0 ) {
				VectorCopy( vhead, bOrigin );
			}
		}

		// spawn some blood trails, heading out towards the impact point
		VectorSubtract( origin, bOrigin, dir );
		VectorNormalize( dir );

		{
			float len;
			vec3_t vec;

			VectorSubtract( bOrigin, vhead, vec );
			len = VectorLength( vec );

			if ( len > 8 ) {
				VectorMA( bOrigin, 8, dir, bOrigin );
			}
		}

		// DHM - Nerve :: Made minor adjustments
		for ( i = 0; i < BLOOD_SPURT_COUNT; i++ ) {
			VectorCopy( dir, ndir );
			for ( j = 0; j < 3; j++ ) ndir[j] += crandom() * 0.3;
			VectorNormalize( ndir );
			CG_AddBloodTrails( bOrigin, ndir,
							   100,     // speed
							   450 + (int)( crandom() * 50 ),   // duration
							   2 + rand() % 2,  // count
							   0.1 );   // rand scale
		}

	}
	// done.
}
Exemple #7
0
/*
* Patch_RemoveLinearColumnsRows
*/
void Patch_RemoveLinearColumnsRows( vec_t *verts, int comp, int *pwidth, int *pheight,
	int numattribs, uint8_t * const *attribs, const int *attribsizes )
{
	int i, j, k, l;
	const vec_t *v0, *v1, *v2;
	float len, maxLength;
	int maxWidth = *pwidth;
	int src, dst;
	int width = *pwidth, height = *pheight;
	vec3_t dir, proj;

	for( j = 1; j < width - 1; j++ )
	{
		maxLength = 0;
		for( i = 0; i < height; i++ )
		{
			v0 = &verts[(i * maxWidth + j - 1) * comp];
			v1 = &verts[(i * maxWidth + j + 1) * comp];
			v2 = &verts[(i * maxWidth + j) * comp];
			VectorSubtract( v1, v0, dir );
			VectorNormalize( dir );
			ProjectPointOntoVector( v2, v0, dir, proj );
			VectorSubtract( v2, proj, dir );
			len = VectorLengthSquared( dir );
			if ( len > maxLength )
				maxLength = len;
		}
		if( maxLength < 0.01f )
		{
			width--;
			for ( i = 0; i < height; i++ )
			{
				dst = i * maxWidth + j;
				src = dst + 1;
				memmove( &verts[dst * comp], &verts[src * comp], ( width - j ) * sizeof( vec_t ) * comp );
				for( k = 0; k < numattribs; k++ )
					memmove( &attribs[k][dst * attribsizes[k]], &attribs[k][src * attribsizes[k]], ( width - j ) * attribsizes[k] );
			}
			j--;
		}
	}

	for( j = 1; j < height - 1; j++ )
	{
		maxLength = 0;
		for ( i = 0; i < width; i++ )
		{
			v0 = &verts[((j - 1) * maxWidth + i) * comp];
			v1 = &verts[((j + 1) * maxWidth + i) * comp];
			v2 = &verts[(j * maxWidth + i) * comp];
			VectorSubtract( v1, v0, dir );
			VectorNormalize( dir );
			ProjectPointOntoVector( v2, v0, dir, proj );
			VectorSubtract( v2, proj, dir );
			len = VectorLengthSquared( dir );
			if ( len > maxLength )
				maxLength = len;
		}
		if( maxLength < 0.01f ) {
			height--;
			for( i = 0; i < width; i++ )
			{
				for ( k = j; k < height; k++ )
				{
					src = ( k + 1 ) * maxWidth + i;
					dst = k * maxWidth + i;
					memcpy( &verts[dst * comp], &verts[src * comp], sizeof( vec_t ) * comp );
					for( l = 0; l < numattribs; l++ )
						memcpy( &attribs[l][dst * attribsizes[l]], &attribs[l][src * attribsizes[l]], attribsizes[l] );
				}
			}
			j--;
		}
	}

	if ( maxWidth != width )
	{
		for ( i = 0; i < height; i++ )
		{
			src = i * maxWidth;
			dst = i * width;
			memmove( &verts[dst * comp], &verts[src * comp], width * sizeof( vec_t ) * comp );
			for( j = 0; j < numattribs; j++ )
				memmove( &attribs[j][dst * attribsizes[j]], &attribs[j][src * attribsizes[j]], width * attribsizes[j] );
		}
	}

	*pwidth = width;
	*pheight = height;
}