Exemplo n.º 1
0
static inline int findIntersectionInternal(struct OBJ_Model * obj,Face triangle, Vertex p1, Vertex p2, Vector * new_normal, Vector * intersection_point)
{
	Vector e1, e2, p, s, q;
	Vector bcoords;
	float t,u,v, tmp, e=0.000001;
	double l, new_normal_length;
	Vector v0,v1,v2,dir;
	Vector origin, end;
	origin.n1 = p1.x;
	origin.n2 = p1.y;
	origin.n3 = p1.z;

	end.n1 = p2.x;
	end.n2 = p2.y;
	end.n3 = p2.z;


	Subtraction(dir,end,origin);
	l = VectorLength(dir);
	dir.n1/=(float)l;
	dir.n2/=(float)l;
	dir.n3/=(float)l;
	v0.n1 = obj->vertexList[ triangle.v[0]].x;
	v0.n2 = obj->vertexList[ triangle.v[0]].y;
	v0.n3 = obj->vertexList[ triangle.v[0]].z;
	v1.n1 = obj->vertexList[ triangle.v[1]].x;
	v1.n2 = obj->vertexList[ triangle.v[1]].y;
	v1.n3 = obj->vertexList[ triangle.v[1]].z;
	v2.n1 = obj->vertexList[ triangle.v[2]].x;
	v2.n2 = obj->vertexList[ triangle.v[2]].y;
	v2.n3 = obj->vertexList[ triangle.v[2]].z;

	Subtraction(e1, v1, v0);
	Subtraction(e2, v2, v0);
	CrossProduct(p, dir, e2);
	tmp = DotProduct(p, e1);

	if (tmp > -e && tmp < e)
		return 0;

	tmp = 1.0/tmp;
	Subtraction(s, origin, v0);
	u = tmp * DotProduct(s, p);
	if (u<0 || u>1)
		return 0;

	CrossProduct(q, s, e1);
	v = tmp * DotProduct(dir, q);
	if (v<0 || v>1)
		return 0;

	if ( u+v >1)
		return 0;

	t = tmp * DotProduct(e2, q);

	bcoords.n2 = u;
	bcoords.n3 = v;
	bcoords.n1 = 1 - u - v;

	new_normal->n1 = bcoords.n1 * obj->normalList[ triangle.n[0]].n1 +
					bcoords.n2 * obj->normalList[ triangle.n[1]].n1 +
					bcoords.n3 * obj->normalList[ triangle.n[2]].n1;

	new_normal->n2 = bcoords.n1 * obj->normalList[ triangle.n[0]].n2 +
					bcoords.n2 * obj->normalList[ triangle.n[1]].n2 +
					bcoords.n3 * obj->normalList[ triangle.n[2]].n2;

	new_normal->n3 = bcoords.n1 * obj->normalList[ triangle.n[0]].n3 +
					bcoords.n2 * obj->normalList[ triangle.n[1]].n3 +
					bcoords.n3 * obj->normalList[ triangle.n[2]].n3;

    Vector tmpVec = *new_normal;
	new_normal_length = VectorLength(tmpVec);
	new_normal->n1 /=new_normal_length;
	new_normal->n2 /=new_normal_length;
	new_normal->n3 /=new_normal_length;

	intersection_point->n1 = dir.n1 * t + origin.n1;
	intersection_point->n2 = dir.n2 * t + origin.n2;
	intersection_point->n3 = dir.n3 * t + origin.n3;
	return 1;
}
Exemplo n.º 2
0
void CG_ImpactMark( qhandle_t markShader, const vec3_t origin, const vec3_t dir, 
				   float orientation, float red, float green, float blue, float alpha,
				   qboolean alphaFade, float radius, qboolean temporary ) {
	vec3_t			axis[3];
	float			texCoordScale;
	vec3_t			originalPoints[4];
	byte			colors[4];
	int				i, j;
	int				numFragments;
	markFragment_t	markFragments[MAX_MARK_FRAGMENTS], *mf;
	vec3_t			markPoints[MAX_MARK_POINTS];
	vec3_t			projection;

	if(markShader == 0) return;
	assert(markShader);

	if ( !cg_addMarks.integer ) {
		return;
	}
	else if (cg_addMarks.integer == 2)
	{
		trap_R_AddDecalToScene(markShader, origin, dir, orientation, red, green, blue, alpha,
			alphaFade, radius, temporary);
		return;
	}

	if ( radius <= 0 ) {
		CG_Error( "CG_ImpactMark called with <= 0 radius" );
	}

	//if ( markTotal >= MAX_MARK_POLYS ) {
	//	return;
	//}

	// create the texture axis
	VectorNormalize2( dir, axis[0] );
	PerpendicularVector( axis[1], axis[0] );
	RotatePointAroundVector( axis[2], axis[0], axis[1], orientation );
	CrossProduct( axis[0], axis[2], axis[1] );

	texCoordScale = 0.5 * 1.0 / radius;

	// create the full polygon
	for ( i = 0 ; i < 3 ; i++ ) {
		originalPoints[0][i] = origin[i] - radius * axis[1][i] - radius * axis[2][i];
		originalPoints[1][i] = origin[i] + radius * axis[1][i] - radius * axis[2][i];
		originalPoints[2][i] = origin[i] + radius * axis[1][i] + radius * axis[2][i];
		originalPoints[3][i] = origin[i] - radius * axis[1][i] + radius * axis[2][i];
	}

	// get the fragments
	VectorScale( dir, -20, projection );
	numFragments = trap_CM_MarkFragments( 4, (const vec3_t *) originalPoints,
					projection, MAX_MARK_POINTS, markPoints[0],
					MAX_MARK_FRAGMENTS, markFragments );

	colors[0] = red * 255;
	colors[1] = green * 255;
	colors[2] = blue * 255;
	colors[3] = alpha * 255;

	for ( i = 0, mf = markFragments ; i < numFragments ; i++, mf++ ) {
		polyVert_t	*v;
		polyVert_t	verts[MAX_VERTS_ON_POLY];
		markPoly_t	*mark;

		// we have an upper limit on the complexity of polygons
		// that we store persistantly
		if ( mf->numPoints > MAX_VERTS_ON_POLY ) {
			mf->numPoints = MAX_VERTS_ON_POLY;
		}
		for ( j = 0, v = verts ; j < mf->numPoints ; j++, v++ ) {
			vec3_t		delta;

			VectorCopy( markPoints[mf->firstPoint + j], v->xyz );

			VectorSubtract( v->xyz, origin, delta );
			v->st[0] = 0.5 + DotProduct( delta, axis[1] ) * texCoordScale;
			v->st[1] = 0.5 + DotProduct( delta, axis[2] ) * texCoordScale;
			*(int *)v->modulate = *(int *)colors;
		}

		// if it is a temporary (shadow) mark, add it immediately and forget about it
		if ( temporary ) {
			trap_R_AddPolyToScene( markShader, mf->numPoints, verts );
			continue;
		}

		// otherwise save it persistantly
		mark = CG_AllocMark();
		mark->time = cg.time;
		mark->alphaFade = alphaFade;
		mark->markShader = markShader;
		mark->poly.numVerts = mf->numPoints;
		mark->color[0] = red;
		mark->color[1] = green;
		mark->color[2] = blue;
		mark->color[3] = alpha;
		memcpy( mark->verts, verts, mf->numPoints * sizeof( verts[0] ) );
		markTotal++;
	}
}
Exemplo n.º 3
0
void CM_AddFacetBevels( facet_t *facet ) {

	int i, j, k, l;
	int axis, dir, order, flipped;
	float plane[4], d, newplane[4];
	winding_t *w, *w2;
	vec3_t mins, maxs, vec, vec2;

#ifndef ADDBEVELS
	return;
#endif

	Vector4Copy( planes[ facet->surfacePlane ].plane, plane );

	w = BaseWindingForPlane( plane,  plane[3] );
	for ( j = 0 ; j < facet->numBorders && w ; j++ ) {
		if (facet->borderPlanes[j] == facet->surfacePlane) continue;
		Vector4Copy( planes[ facet->borderPlanes[j] ].plane, plane );

		if ( !facet->borderInward[j] ) {
			VectorSubtract( vec3_origin, plane, plane );
			plane[3] = -plane[3];
		}

		ChopWindingInPlace( &w, plane, plane[3], 0.1f );
	}
	if ( !w ) {
		return;
	}

	WindingBounds(w, mins, maxs);

	// add the axial planes
	order = 0;
	for ( axis = 0 ; axis < 3 ; axis++ )
	{
		for ( dir = -1 ; dir <= 1 ; dir += 2, order++ )
		{
			VectorClear(plane);
			plane[axis] = dir;
			if (dir == 1) {
				plane[3] = maxs[axis];
			}
			else {
				plane[3] = -mins[axis];
			}
			//if it's the surface plane
			if (CM_PlaneEqual(&planes[facet->surfacePlane], plane, &flipped)) {
				continue;
			}
			// see if the plane is allready present
			for ( i = 0 ; i < facet->numBorders ; i++ ) {
				if (CM_PlaneEqual(&planes[facet->borderPlanes[i]], plane, &flipped))
					break;
			}

			if ( i == facet->numBorders ) {
				if (facet->numBorders > 4 + 6 + 16) {
					Com_Printf("ERROR: too many bevels\n");
					continue;
				}
				facet->borderPlanes[facet->numBorders] = CM_FindPlane2(plane, &flipped);
				facet->borderNoAdjust[facet->numBorders] = qfalse;
				facet->borderInward[facet->numBorders] = flipped;
				facet->numBorders++;
			}
		}
	}
	//
	// add the edge bevels
	//
	// test the non-axial plane edges
	for ( j = 0 ; j < w->numpoints ; j++ )
	{
		k = (j+1)%w->numpoints;
		VectorSubtract (w->p[j], w->p[k], vec);
		//if it's a degenerate edge
		if (VectorNormalize (vec) < 0.5f)
			continue;
		CM_SnapVector(vec);
		for ( k = 0; k < 3 ; k++ )
			if ( vec[k] == -1 || vec[k] == 1 )
				break;	// axial
		if ( k < 3 )
			continue;	// only test non-axial edges

		// try the six possible slanted axials from this edge
		for ( axis = 0 ; axis < 3 ; axis++ )
		{
			for ( dir = -1 ; dir <= 1 ; dir += 2 )
			{
				// construct a plane
				VectorClear (vec2);
				vec2[axis] = dir;
				CrossProduct (vec, vec2, plane);
				if (VectorNormalize (plane) < 0.5f)
					continue;
				plane[3] = DotProduct (w->p[j], plane);

				// if all the points of the facet winding are
				// behind this plane, it is a proper edge bevel
				for ( l = 0 ; l < w->numpoints ; l++ )
				{
					d = DotProduct (w->p[l], plane) - plane[3];
					if (d > 0.1f)
						break;	// point in front
				}
				if ( l < w->numpoints )
					continue;

				//if it's the surface plane
				if (CM_PlaneEqual(&planes[facet->surfacePlane], plane, &flipped)) {
					continue;
				}
				// see if the plane is allready present
				for ( i = 0 ; i < facet->numBorders ; i++ ) {
					if (CM_PlaneEqual(&planes[facet->borderPlanes[i]], plane, &flipped)) {
							break;
					}
				}

				if ( i == facet->numBorders ) {
					if (facet->numBorders > 4 + 6 + 16) {
						Com_Printf("ERROR: too many bevels\n");
						continue;
					}
					facet->borderPlanes[facet->numBorders] = CM_FindPlane2(plane, &flipped);

					for ( k = 0 ; k < facet->numBorders ; k++ ) {
						if (facet->borderPlanes[facet->numBorders] ==
							facet->borderPlanes[k]) Com_Printf("WARNING: bevel plane already used\n");
					}

					facet->borderNoAdjust[facet->numBorders] = qfalse;
					facet->borderInward[facet->numBorders] = flipped;
					//
					w2 = CopyWinding(w);
					Vector4Copy(planes[facet->borderPlanes[facet->numBorders]].plane, newplane);
					if (!facet->borderInward[facet->numBorders])
					{
						VectorNegate(newplane, newplane);
						newplane[3] = -newplane[3];
					} //end if
					ChopWindingInPlace( &w2, newplane, newplane[3], 0.1f );
					if (!w2) {
						Com_DPrintf("WARNING: CM_AddFacetBevels... invalid bevel\n");
						continue;
					}
					else {
						FreeWinding(w2);
					}
					//
					facet->numBorders++;
					//already got a bevel
//					break;
				}
			}
		}
	}
	FreeWinding( w );

#ifndef BSPC
	//add opposite plane
	if (facet->numBorders > 4 + 6 + 16) {
		Com_Printf("ERROR: too many bevels\n");
		return;
	}
	facet->borderPlanes[facet->numBorders] = facet->surfacePlane;
	facet->borderNoAdjust[facet->numBorders] = qfalse;
	facet->borderInward[facet->numBorders] = qtrue;
	facet->numBorders++;
#endif //BSPC

}
Exemplo n.º 4
0
qboolean	PM_SlideMove( qboolean gravity ) {
	int			bumpcount, numbumps;
	vec3_t		dir;
	float		d;
	int			numplanes;
	vec3_t		planes[MAX_CLIP_PLANES];
	vec3_t		primal_velocity;
	vec3_t		clipVelocity;
	int			i, j, k;
	trace_t	trace;
	vec3_t		end;
	float		time_left;
	float		into;
	vec3_t		endVelocity;
	vec3_t		endClipVelocity;

	numbumps = 4;

	VectorCopy (pm->ps->velocity, primal_velocity);

	if ( gravity ) {
		VectorCopy( pm->ps->velocity, endVelocity );
		endVelocity[2] -= pm->ps->gravity * pml.frametime;
		pm->ps->velocity[2] = ( pm->ps->velocity[2] + endVelocity[2] ) * 0.5;
		primal_velocity[2] = endVelocity[2];
		if ( pml.groundPlane ) {
			// slide along the ground plane
			PM_ClipVelocity (pm->ps->velocity, pml.groundTrace.plane.normal,
				pm->ps->velocity, OVERCLIP );
		}
	}

	time_left = pml.frametime;

	// never turn against the ground plane
	if ( pml.groundPlane ) {
		numplanes = 1;
		VectorCopy( pml.groundTrace.plane.normal, planes[0] );
	} else {
		numplanes = 0;
	}

	// never turn against original velocity
	VectorNormalize2( pm->ps->velocity, planes[numplanes] );
	numplanes++;

	for ( bumpcount=0 ; bumpcount < numbumps ; bumpcount++ ) {

		// calculate position we are trying to move to
		VectorMA( pm->ps->origin, time_left, pm->ps->velocity, end );

		// see if we can make it there
		pm->trace ( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, pm->tracemask);

		if (trace.allsolid) {
			// entity is completely trapped in another solid
			pm->ps->velocity[2] = 0;	// don't build up falling damage, but allow sideways acceleration
			return qtrue;
		}

		if (trace.fraction > 0) {
			// actually covered some distance
			VectorCopy (trace.endpos, pm->ps->origin);
		}

		if (trace.fraction == 1) {
			 break;		// moved the entire distance
		}

		// save entity for contact
		PM_AddTouchEnt( trace.entityNum );

		time_left -= time_left * trace.fraction;

		if (numplanes >= MAX_CLIP_PLANES) {
			// this shouldn't really happen
			VectorClear( pm->ps->velocity );
			return qtrue;
		}

		//
		// if this is the same plane we hit before, nudge velocity
		// out along it, which fixes some epsilon issues with
		// non-axial planes
		//
		for ( i = 0 ; i < numplanes ; i++ ) {
			if ( DotProduct( trace.plane.normal, planes[i] ) > 0.99 ) {
				VectorAdd( trace.plane.normal, pm->ps->velocity, pm->ps->velocity );
				break;
			}
		}
		if ( i < numplanes ) {
			continue;
		}
		VectorCopy (trace.plane.normal, planes[numplanes]);
		numplanes++;

		//
		// modify velocity so it parallels all of the clip planes
		//

		// find a plane that it enters
		for ( i = 0 ; i < numplanes ; i++ ) {
			into = DotProduct( pm->ps->velocity, planes[i] );
			if ( into >= 0.1 ) {
				continue;		// move doesn't interact with the plane
			}

			// see how hard we are hitting things
			if ( -into > pml.impactSpeed ) {
				pml.impactSpeed = -into;
			}

			// slide along the plane
			PM_ClipVelocity (pm->ps->velocity, planes[i], clipVelocity, OVERCLIP );

			// slide along the plane
			PM_ClipVelocity (endVelocity, planes[i], endClipVelocity, OVERCLIP );

			// see if there is a second plane that the new move enters
			for ( j = 0 ; j < numplanes ; j++ ) {
				if ( j == i ) {
					continue;
				}
				if ( DotProduct( clipVelocity, planes[j] ) >= 0.1 ) {
					continue;		// move doesn't interact with the plane
				}

				// try clipping the move to the plane
				PM_ClipVelocity( clipVelocity, planes[j], clipVelocity, OVERCLIP );
				PM_ClipVelocity( endClipVelocity, planes[j], endClipVelocity, OVERCLIP );

				// see if it goes back into the first clip plane
				if ( DotProduct( clipVelocity, planes[i] ) >= 0 ) {
					continue;
				}

				// slide the original velocity along the crease
				CrossProduct (planes[i], planes[j], dir);
				VectorNormalize( dir );
				d = DotProduct( dir, pm->ps->velocity );
				VectorScale( dir, d, clipVelocity );

				CrossProduct (planes[i], planes[j], dir);
				VectorNormalize( dir );
				d = DotProduct( dir, endVelocity );
				VectorScale( dir, d, endClipVelocity );

				// see if there is a third plane the the new move enters
				for ( k = 0 ; k < numplanes ; k++ ) {
					if ( k == i || k == j ) {
						continue;
					}
					if ( DotProduct( clipVelocity, planes[k] ) >= 0.1 ) {
						continue;		// move doesn't interact with the plane
					}

					// stop dead at a tripple plane interaction
					VectorClear( pm->ps->velocity );
					return qtrue;
				}
			}

			// if we have fixed all interactions, try another move
			VectorCopy( clipVelocity, pm->ps->velocity );
			VectorCopy( endClipVelocity, endVelocity );
			break;
		}
	}

	if ( gravity ) {
		VectorCopy( endVelocity, pm->ps->velocity );
	}

	// don't change velocity if in a timer (FIXME: is this correct?)
	if ( pm->ps->pm_time ) {
		VectorCopy( primal_velocity, pm->ps->velocity );
	}

	return ( bumpcount != 0 );
}
Exemplo n.º 5
0
/*
=================
R_GetPortalOrientation

entityNum is the entity that the portal surface is a part of, which may
be moving and rotating.

Returns qtrue if it should be mirrored
=================
*/
qboolean R_GetPortalOrientations( drawSurf_t *drawSurf, int entityNum, 
							 orientation_t *surface, orientation_t *camera,
							 vec3_t pvsOrigin, qboolean *mirror ) {
	int			i;
	cplane_t	originalPlane, plane;
	trRefEntity_t	*e;
	float		d;
	vec3_t		transformed;

	// create plane axis for the portal we are seeing
	R_PlaneForSurface( drawSurf->surface, &originalPlane );

	// rotate the plane if necessary
	if ( entityNum != REFENTITYNUM_WORLD ) {
		tr.currentEntityNum = entityNum;
		tr.currentEntity = &tr.refdef.entities[entityNum];

		// get the orientation of the entity
		R_RotateForEntity( tr.currentEntity, &tr.viewParms, &tr.or );

		// rotate the plane, but keep the non-rotated version for matching
		// against the portalSurface entities
		R_LocalNormalToWorld( originalPlane.normal, plane.normal );
		plane.dist = originalPlane.dist + DotProduct( plane.normal, tr.or.origin );

		// translate the original plane
		originalPlane.dist = originalPlane.dist + DotProduct( originalPlane.normal, tr.or.origin );
	} else {
		plane = originalPlane;
	}

	VectorCopy( plane.normal, surface->axis[0] );
	PerpendicularVector( surface->axis[1], surface->axis[0] );
	CrossProduct( surface->axis[0], surface->axis[1], surface->axis[2] );

	// locate the portal entity closest to this plane.
	// origin will be the origin of the portal, origin2 will be
	// the origin of the camera
	for ( i = 0 ; i < tr.refdef.num_entities ; i++ ) {
		e = &tr.refdef.entities[i];
		if ( e->e.reType != RT_PORTALSURFACE ) {
			continue;
		}

		d = DotProduct( e->e.origin, originalPlane.normal ) - originalPlane.dist;
		if ( d > 64 || d < -64) {
			continue;
		}

		// get the pvsOrigin from the entity
		VectorCopy( e->e.oldorigin, pvsOrigin );

		// if the entity is just a mirror, don't use as a camera point
		if ( e->e.oldorigin[0] == e->e.origin[0] && 
			e->e.oldorigin[1] == e->e.origin[1] && 
			e->e.oldorigin[2] == e->e.origin[2] ) {
			VectorScale( plane.normal, plane.dist, surface->origin );
			VectorCopy( surface->origin, camera->origin );
			VectorSubtract( vec3_origin, surface->axis[0], camera->axis[0] );
			VectorCopy( surface->axis[1], camera->axis[1] );
			VectorCopy( surface->axis[2], camera->axis[2] );

			*mirror = qtrue;
			return qtrue;
		}

		// project the origin onto the surface plane to get
		// an origin point we can rotate around
		d = DotProduct( e->e.origin, plane.normal ) - plane.dist;
		VectorMA( e->e.origin, -d, surface->axis[0], surface->origin );
			
		// now get the camera origin and orientation
		VectorCopy( e->e.oldorigin, camera->origin );
		AxisCopy( e->e.axis, camera->axis );
		VectorSubtract( vec3_origin, camera->axis[0], camera->axis[0] );
		VectorSubtract( vec3_origin, camera->axis[1], camera->axis[1] );

		// optionally rotate
		if ( e->e.oldframe ) {
			// if a speed is specified
			if ( e->e.frame ) {
				// continuous rotate
				d = (tr.refdef.time/1000.0f) * e->e.frame;
				VectorCopy( camera->axis[1], transformed );
				RotatePointAroundVector( camera->axis[1], camera->axis[0], transformed, d );
				CrossProduct( camera->axis[0], camera->axis[1], camera->axis[2] );
			} else {
				// bobbing rotate, with skinNum being the rotation offset
				d = sin( tr.refdef.time * 0.003f );
				d = e->e.skinNum + d * 4;
				VectorCopy( camera->axis[1], transformed );
				RotatePointAroundVector( camera->axis[1], camera->axis[0], transformed, d );
				CrossProduct( camera->axis[0], camera->axis[1], camera->axis[2] );
			}
		}
		else if ( e->e.skinNum ) {
			d = e->e.skinNum;
			VectorCopy( camera->axis[1], transformed );
			RotatePointAroundVector( camera->axis[1], camera->axis[0], transformed, d );
			CrossProduct( camera->axis[0], camera->axis[1], camera->axis[2] );
		}
		*mirror = qfalse;
		return qtrue;
	}

	// if we didn't locate a portal entity, don't render anything.
	// We don't want to just treat it as a mirror, because without a
	// portal entity the server won't have communicated a proper entity set
	// in the snapshot

	// unfortunately, with local movement prediction it is easily possible
	// to see a surface before the server has communicated the matching
	// portal surface entity, so we don't want to print anything here...

	//ri.Printf( PRINT_ALL, "Portal surface without a portal entity\n" );

	return qfalse;
}
Exemplo n.º 6
0
Model* GenerateTerrain(TextureData *tex)
{	
	int vertexCount = tex->width * tex->height;
	int triangleCount = (tex->width-1) * (tex->height-1) * 2;
	int x, z;
	
	GLfloat *vertexArray = malloc(sizeof(GLfloat) * 3 * vertexCount);
	GLfloat *normalArray = malloc(sizeof(GLfloat) * 3 * vertexCount);
	GLfloat *texCoordArray = malloc(sizeof(GLfloat) * 2 * vertexCount);
	GLuint *indexArray = malloc(sizeof(GLuint) * triangleCount*3);
	vec3 u, v;
	printf("bpp %d\n", tex->bpp);
	for (x = 0; x < tex->width; x++)
		for (z = 0; z < tex->height; z++)
		{
// Vertex array. You need to scale this properly
			vertexArray[(x + z * tex->width)*3 + 0] = x / 5.0;
			vertexArray[(x + z * tex->width)*3 + 1] = tex->imageData[(x + z * tex->width) * (tex->bpp/8)] / 100.0;
			vertexArray[(x + z * tex->width)*3 + 2] = z / 5.0;
// Normal vectors. You need to calculate these.
			normalArray[(x + z * tex->width)*3 + 0] = 0.0;
			normalArray[(x + z * tex->width)*3 + 1] = 1.0;
			normalArray[(x + z * tex->width)*3 + 2] = 0.0;
// Texture coordinates. You may want to scale them.
			texCoordArray[(x + z * tex->width)*2 + 0] = x; // (float)x / tex->width;
			texCoordArray[(x + z * tex->width)*2 + 1] = z; // (float)z / tex->height;
		}

	for (x = 0; x < tex->width-1; x++)
		for (z = 0; z < tex->height-1; z++)
		{
		// Triangle 1
			indexArray[(x + z * (tex->width-1))*6 + 0] = x + z * tex->width;
			indexArray[(x + z * (tex->width-1))*6 + 1] = x + (z+1) * tex->width;
			indexArray[(x + z * (tex->width-1))*6 + 2] = x+1 + z * tex->width;
		// Triangle 2
			indexArray[(x + z * (tex->width-1))*6 + 3] = x+1 + z * tex->width;
			indexArray[(x + z * (tex->width-1))*6 + 4] = x + (z+1) * tex->width;
			indexArray[(x + z * (tex->width-1))*6 + 5] = x+1 + (z+1) * tex->width;

			// beräkna normalvectorer
			if(x>=1 && z>= 1){
				u.x =vertexArray[(x+1 + z * tex->width)*3+0] - vertexArray[(x-1 + (z-1) * tex->width)*3+0];
				u.y = vertexArray[(x+1 + z * tex->width)*3+1] - vertexArray[(x-1 + (z-1) * tex->width)*3+1];
				u.z =vertexArray[(x+1 + z * tex->width)*3+2] - vertexArray[(x-1 + (z-1) * tex->width)*3+2];
	
				v.x= vertexArray[(x + (z+1) * tex->width)*3+0] - vertexArray[(x-1 + (z-1) * tex->width)*3+0];
				v.y=vertexArray[(x + (z+1) * tex->width)*3+1] - vertexArray[(x-1 + (z-1) * tex->width)*3+1];
				v.z=vertexArray[(x + (z+1) * tex->width)*3+2] - vertexArray[(x-1 + (z-1) * tex->width)*3+2];

				vec3 normal= CrossProduct(v,u);

				normalArray[(x + z * tex->width)*3+ 0] = normal.x;
				normalArray[(x + z * tex->width)*3+ 1] = normal.y;
				normalArray[(x + z * tex->width)*3+ 2] = normal.z;
			}
		}

	
	// End of terrain generation
	
	// Create Model and upload to GPU:

	Model* model = LoadDataToModel(
			vertexArray,
			normalArray,
			texCoordArray,
			NULL,
			indexArray,
			vertexCount,
			triangleCount*3);

	return model;
}
Exemplo n.º 7
0
/*
=================
RB_ShadowTessEnd

triangleFromEdge[ v1 ][ v2 ]


  set triangle from edge( v1, v2, tri )
  if ( facing[ triangleFromEdge[ v1 ][ v2 ] ] && !facing[ triangleFromEdge[ v2 ][ v1 ] ) {
  }
=================
*/
void RB_ShadowTessEnd( void ) {
	int		i;
	int		numTris;
	vec3_t	lightDir;
	GLboolean rgba[4];

	// we can only do this if we have enough space in the vertex buffers
	if ( tess.numVertexes >= SHADER_MAX_VERTEXES / 2 ) {
		return;
	}

	if ( glConfig.stencilBits < 4 ) {
		return;
	}

	VectorCopy( backEnd.currentEntity->lightDir, lightDir );

	// project vertexes away from light direction
	for ( i = 0 ; i < tess.numVertexes ; i++ ) {
		VectorMA( tess.xyz[i], -512, lightDir, tess.xyz[i+tess.numVertexes] );
	}

	// decide which triangles face the light
	Com_Memset( numEdgeDefs, 0, 4 * tess.numVertexes );

	numTris = tess.numIndexes / 3;
	for ( i = 0 ; i < numTris ; i++ ) {
		int		i1, i2, i3;
		vec3_t	d1, d2, normal;
		float	*v1, *v2, *v3;
		float	d;

		i1 = tess.indexes[ i*3 + 0 ];
		i2 = tess.indexes[ i*3 + 1 ];
		i3 = tess.indexes[ i*3 + 2 ];

		v1 = tess.xyz[ i1 ];
		v2 = tess.xyz[ i2 ];
		v3 = tess.xyz[ i3 ];

		VectorSubtract( v2, v1, d1 );
		VectorSubtract( v3, v1, d2 );
		CrossProduct( d1, d2, normal );

		d = DotProduct( normal, lightDir );
		if ( d > 0 ) {
			facing[ i ] = 1;
		} else {
			facing[ i ] = 0;
		}

		// create the edges
		R_AddEdgeDef( i1, i2, facing[ i ] );
		R_AddEdgeDef( i2, i3, facing[ i ] );
		R_AddEdgeDef( i3, i1, facing[ i ] );
	}

	// draw the silhouette edges

	GL_Bind( tr.whiteImage );
	qglEnable( GL_CULL_FACE );
	GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
	qglColor3f( 0.2f, 0.2f, 0.2f );

	// don't write to the color buffer
	qglGetBooleanv(GL_COLOR_WRITEMASK, rgba);
	qglColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );

	qglEnable( GL_STENCIL_TEST );
	qglStencilFunc( GL_ALWAYS, 1, 255 );

	// mirrors have the culling order reversed
	if ( backEnd.viewParms.isMirror ) {
		qglCullFace( GL_FRONT );
		qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR );

		R_RenderShadowEdges();

		qglCullFace( GL_BACK );
		qglStencilOp( GL_KEEP, GL_KEEP, GL_DECR );

		R_RenderShadowEdges();
	} else {
		qglCullFace( GL_BACK );
		qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR );

		R_RenderShadowEdges();

		qglCullFace( GL_FRONT );
		qglStencilOp( GL_KEEP, GL_KEEP, GL_DECR );

		R_RenderShadowEdges();
	}


	// reenable writing to the color buffer
	qglColorMask(rgba[0], rgba[1], rgba[2], rgba[3]);
}
Exemplo n.º 8
0
void AbsoluteToLocal(plane_t normal2, face_t* f, vec3_t& p1, vec3_t& p2, vec3_t& p3)
{
	vec3_t ex,ey,ez;

#ifdef _DEBUG
	if (g_qeglobals.m_bBrushPrimitMode)
		Sys_Printf("Warning : illegal call of AbsoluteToLocal in brush primitive mode\n");
#endif

	// computing new local axis base
	TextureAxisFromPlane(&normal2, ex, ey);
	CrossProduct(ex, ey, ez);

	// projecting back on (ex,ey)
	Back(ez,p1);
	Back(ez,p2);
	Back(ez,p3);

	vec3_t aux;
	// rotation
	VectorCopy(p2, aux);
	VectorSubtract(aux, p1,aux);

	float x = DotProduct(aux,ex);
	float y = DotProduct(aux,ey);
	f->texdef.rotate = 180 * atan2(y,x) / Q_PI;

	vec3_t rex,rey;
	// computing rotated local axis base
	VectorCopy(ez, aux);
	VectorScale(aux, f->texdef.rotate, aux);
	VectorCopy(ex, rex);
	VectorRotate(rex, aux, rex);
	VectorCopy(ey, rey);
	VectorRotate(rey, aux, rey);

	// scale
	VectorCopy(p2, aux);
	VectorSubtract(aux, p1, aux);
	f->texdef.scale[0] = DotProduct(aux, rex);
	VectorCopy(p3, aux);
	VectorSubtract(aux, p1, aux);
	f->texdef.scale[1] = DotProduct(aux, rey);

	// shift
	// only using p1
	x = DotProduct(rex,p1);
	y = DotProduct(rey,p1);                 
	x /= f->texdef.scale[0];
	y /= f->texdef.scale[1];

	VectorCopy(rex, p1);
	VectorScale(p1, x, p1);
	VectorCopy(rey, aux);
	VectorScale(aux, y, aux);
	VectorAdd(p1, aux, p1);
	VectorCopy(ez, aux);
	VectorScale(aux, -f->texdef.rotate, aux);
	VectorRotate(p1, aux, p1);
	f->texdef.shift[0] = -DotProduct(p1, ex);
	f->texdef.shift[1] = -DotProduct(p1, ey);

	// stored rot is good considering local axis base
	// change it if necessary
	f->texdef.rotate = -f->texdef.rotate;

	Clamp(f->texdef.shift[0], f->d_texture->width);
	Clamp(f->texdef.shift[1], f->d_texture->height);
	Clamp(f->texdef.rotate, 360);

}
Exemplo n.º 9
0
void FVMesh3D::complete_data()
{

// initialize the list of cell for each vertex    
for(size_t i=0;i<_nb_vertex;i++)
    {
    _vertex[i].nb_cell=0;
    }  
// we have to determine the list of neighbor cell for each vertex further
// compute the centroid and length of edge
for(size_t i=0;i<_nb_edge;i++)
    {
    _edge[i].centroid=(_edge[i].firstVertex->coord+_edge[i].secondVertex->coord)*(double)0.5;
    FVPoint3D<double> u;
    u=_edge[i].firstVertex->coord-_edge[i].secondVertex->coord;
    _edge[i].length=Norm(u);
    }
// We have completly finish with the edge

// compute geometric stuff for the face
for(size_t i=0;i<_nb_face;i++)
    {
    _face[i].perimeter=0.;
    _face[i].area=0.;
    _face[i].centroid=0.;
    // conpute  perimeter or the face 
    for(size_t j=0;j<_face[i].nb_edge;j++)
        {
        _face[i].perimeter+=_face[i].edge[j]->length; 
        _face[i].centroid+=_face[i].edge[j]->centroid*_face[i].edge[j]->length; 
        }
    // compute the centroid of the face
    _face[i].centroid/=_face[i].perimeter;  
    // compute the area of the face
    for(size_t j=0;j<_face[i].nb_edge;j++)
        {    
        FVPoint3D<double> u,v,w;  
        u=_face[i].edge[j]->firstVertex->coord-_face[i].centroid; 
        v=_face[i].edge[j]->secondVertex->coord-_face[i].centroid;
        w=CrossProduct(u,v);
        _face[i].area+=Norm(w)*0.5;
        }  
   // build the list of vertex pointer for the face  
    pos_v=0;
    for(size_t j=0;j<_face[i].nb_edge;j++)
        {
        bool _still_exist;   
        _still_exist=false; 
        for(size_t k=0;k<pos_v;k++)
             if(_face[i].edge[j]->firstVertex==_face[i].vertex[k])  _still_exist=true;
        if(!_still_exist) {_face[i].vertex[pos_v]=_face[i].edge[j]->firstVertex;pos_v++;}
        _still_exist=false;  
        for(size_t k=0;k<pos_v;k++)
             if(_face[i].edge[j]->secondVertex==_face[i].vertex[k])  _still_exist=true;
        if(!_still_exist) {_face[i].vertex[pos_v]=_face[i].edge[j]->secondVertex;pos_v++;}    
        }
    _face[i].nb_vertex=pos_v;         
    }
    //  left and right cell, normal vector will be determined after the loop on cells
// end loop on the faces  
for(size_t i=0;i<_nb_cell;i++)
    {
    _cell[i].surface=0.;
    _cell[i].volume=0.;
    _cell[i].centroid=0.;
    // conpute surface of the cell 
    // determine the left and right cell for the face
    for(size_t j=0;j<_cell[i].nb_face;j++)
        {
        size_t pos;    
        _cell[i].surface+=_cell[i].face[j]->area; 
        _cell[i].centroid+=_cell[i].face[j]->centroid*_cell[i].face[j]->area; 
        pos=_cell[i].face[j]->label-1;
        if(!(_face[pos].leftCell)  )  
             _face[pos].leftCell=&(_cell[i]);
        else
             _face[pos].rightCell=&(_cell[i]); 
        }
    // compute the centroid of the cell
    _cell[i].centroid/=_cell[i].surface;  
    // compute the cell2face vector
    // compute the volume of the cell
    for(size_t j=0;j<_cell[i].nb_face;j++)
        {
        _cell[i].cell2face[j]= _cell[i].face[j]->centroid-_cell[i].centroid;   
        for(size_t k=0;k<_cell[i].face[j]->nb_edge;k++)
            {
            FVPoint3D<double> u,v,w;
            u=_cell[i].cell2face[j];
            v=_cell[i].face[j]->edge[k]->firstVertex->coord-_cell[i].centroid;
            w=_cell[i].face[j]->edge[k]->secondVertex->coord-_cell[i].centroid;   
            _cell[i].volume+=fabs(Det(u,v,w))/6;
            }
        }   
    // build the list of the vertex pointer for a cell     
    pos_v=0;
    for(size_t j=0;j<_cell[i].nb_face;j++)
        for(size_t k=0;k<_cell[i].face[j]->nb_edge;k++)
            {
            bool _still_exist;   
            _still_exist=false;  
            for(size_t m=0;m<pos_v;m++)
                 if(_cell[i].face[j]->edge[k]->firstVertex==_cell[i].vertex[m])  _still_exist=true;
            if(!_still_exist) {_cell[i].vertex[pos_v]=_cell[i].face[j]->edge[k]->firstVertex;pos_v++;}
            _still_exist=false;  
            for(size_t m=0;m<pos_v;m++)
                 if(_cell[i].face[j]->edge[k]->secondVertex==_cell[i].vertex[m])  _still_exist=true;
            if(!_still_exist) {_cell[i].vertex[pos_v]=_cell[i].face[j]->edge[k]->secondVertex;pos_v++;}  
            }
     _cell[i].nb_vertex=pos_v;  
    // build the list of the cell pointer for a vertex        
     for(size_t j=0;j<_cell[i].nb_vertex;j++)
        {
        size_t pos;
        pos=_cell[i].vertex[j]->label-1;
        _vertex[pos].cell[_vertex[pos].nb_cell]=&(_cell[i]); 
        _vertex[pos].nb_cell++;
       if(_vertex[pos].nb_cell>=NB_CELL_PER_VERTEX_3D)
         cout<<"Warning, overflow in class FVVertex3D, too many Cells, found "<<_vertex[pos].nb_cell<<endl; 
        }
    }   
//  we compute the normal from left to rigth for each sub-triangle   
_boundary_face.resize(0);
_nb_boundary_face=0;
for(size_t i=0;i<_nb_face;i++)
    {
    for(size_t j=0;j<_face[i].nb_edge;j++)
        {
         FVPoint3D<double> u,v,w;  
         double no;
         u=_face[i].edge[j]->firstVertex->coord-_face[i].centroid;
         v=_face[i].edge[j]->secondVertex->coord-_face[i].centroid;       
         w=CrossProduct(u,v);
         no=Norm(w);
         w/=no;
         _face[i].normal[j]=w;
         u=_face[i].centroid-_face[i].leftCell->centroid;
         if(w*u<0) _face[i].normal[j]*=-1.; 
         }     // build the list of boundary face
    if(! (_face[i].rightCell)) {_boundary_face.push_back(&(_face[i]));_nb_boundary_face++;} 
    }
}
void displayRollerCoaster()
{
    //DISPLAY THE ROLLER COASTER
    float a=0.01,f=0.1;
    texture = LoadTexture("wood.jpg",256, 256);
    glEnable(GL_TEXTURE_2D);
    for(float r=0;r<2;r++){
        glBegin(GL_QUADS);
        for (int j = 0; j < g_iNumOfSplines; j++) {
            for(int i=-2;i<g_Splines[j].numControlPoints-1;i++)
            {
                for(float u=0.0;u<1.0;u+=0.02){
                    //Point
                    p.x= CatmullRom(u, g_Splines[j].points[i].x, g_Splines[j].points[i+1].x, g_Splines[j].points[i+2].x, g_Splines[j].points[i+3].x);
                    p.y= CatmullRom(u, g_Splines[j].points[i].y, g_Splines[j].points[i+1].y, g_Splines[j].points[i+2].y, g_Splines[j].points[i+3].y);
                    p.z= CatmullRom(u, g_Splines[j].points[i].z, g_Splines[j].points[i+1].z, g_Splines[j].points[i+2].z, g_Splines[j].points[i+3].z);
                    //Tangent
                    t.x= CatmullRomTangent(u, g_Splines[j].points[i].x, g_Splines[j].points[i+1].x, g_Splines[j].points[i+2].x, g_Splines[j].points[i+3].x);
                    t.y= CatmullRomTangent(u, g_Splines[j].points[i].y, g_Splines[j].points[i+1].y, g_Splines[j].points[i+2].y, g_Splines[j].points[i+3].y);
                    t.z= CatmullRomTangent(u, g_Splines[j].points[i].z, g_Splines[j].points[i+1].z, g_Splines[j].points[i+2].z, g_Splines[j].points[i+3].z);
                    t = normalize(t);
                    //Normal
                    n = CrossProduct(t, v);
                    n = normalize(n);
                    //Binormal
                    b = CrossProduct(t, n);
                    b = normalize(b);
                    
                    p1.x= CatmullRom(u+0.02, g_Splines[j].points[i].x, g_Splines[j].points[i+1].x, g_Splines[j].points[i+2].x, g_Splines[j].points[i+3].x);
                    p1.y= CatmullRom(u+0.02, g_Splines[j].points[i].y, g_Splines[j].points[i+1].y, g_Splines[j].points[i+2].y, g_Splines[j].points[i+3].y);
                    p1.z= CatmullRom(u+0.02, g_Splines[j].points[i].z, g_Splines[j].points[i+1].z, g_Splines[j].points[i+2].z, g_Splines[j].points[i+3].z);
                    
                    t1.x= CatmullRomTangent(u+0.02, g_Splines[j].points[i].x, g_Splines[j].points[i+1].x, g_Splines[j].points[i+2].x, g_Splines[j].points[i+3].x);
                    t1.y= CatmullRomTangent(u+0.02, g_Splines[j].points[i].y, g_Splines[j].points[i+1].y, g_Splines[j].points[i+2].y, g_Splines[j].points[i+3].y);
                    t1.z= CatmullRomTangent(u+0.02, g_Splines[j].points[i].z, g_Splines[j].points[i+1].z, g_Splines[j].points[i+2].z, g_Splines[j].points[i+3].z);
                    t1 = normalize(t1);
                    
                    n1 = CrossProduct(t1, v);
                    n1 = normalize(n1);
                    b1 = CrossProduct(t1, n1);
                    b1 = normalize(b1);
                    
                    if(r==1)
                    {
                        p.x+=f*n.x;
                        p.y+=f*n.y;
                        p.z+=f*n.z;
                        
                        p1.x+=f*n1.x;
                        p1.y+=f*n1.y;
                        p1.z+=f*n1.z;
                        
                    }
                    
                    glColor3f(1.0, 0.0, 0.0);
                    //V1
                    glTexCoord2d(0.0,0.0);glVertex3f(p.x+a*(n.x-b.x),p.y+a*(n.y-b.y),p.z+a*(n.z-b.z));
                    //V2
                    glTexCoord2d(1.0,0.0);glVertex3f(p.x+a*(n.x+b.x),p.y+a*(n.y+b.y),p.z+a*(n.z+b.z));
                    //V3
                    glTexCoord2d(1.0,1.0);glVertex3f(p.x+a*(-n.x+b.x),p.y+a*(-n.y+b.y),p.z+a*(-n.z+b.z));
                    //V4
                    glTexCoord2d(0.0,1.0);glVertex3f(p.x+a*(-n.x-b.x),p.y+a*(-n.y-b.y),p.z+a*(-n.z-b.z));
                    
                    //V5
                    glTexCoord2d(0.0,0.0);glVertex3f(p1.x+a*(n1.x-b1.x),p1.y+a*(n1.y-b1.y),p1.z+a*(n1.z-b1.z));
                    //V6
                    glTexCoord2d(1.0,0.0);glVertex3f(p1.x+a*(n1.x+b1.x),p1.y+a*(n1.y+b1.y),p1.z+a*(n1.z+b1.z));
                    //V7
                    glTexCoord2d(1.0,1.0);glVertex3f(p1.x+a*(-n1.x+b1.x),p1.y+a*(-n1.y+b1.y),p1.z+a*(-n1.z+b1.z));
                    //V8
                    glTexCoord2d(0.0,1.0);glVertex3f(p1.x+a*(-n1.x-b1.x),p1.y+a*(-n1.y-b1.y),p1.z+a*(-n1.z-b1.z));
                    
                    //V1
                    glTexCoord2d(0.0,0.0);glVertex3f(p.x+a*(n.x-b.x),p.y+a*(n.y-b.y),p.z+a*(n.z-b.z));
                    //V4
                    glTexCoord2d(0.0,1.0);glVertex3f(p.x+a*(-n.x-b.x),p.y+a*(-n.y-b.y),p.z+a*(-n.z-b.z));
                    //V8
                    glTexCoord2d(0.0,1.0);glVertex3f(p1.x+a*(-n1.x-b1.x),p1.y+a*(-n1.y-b1.y),p1.z+a*(-n1.z-b1.z));
                    //V5
                    glTexCoord2d(0.0,0.0);glVertex3f(p1.x+a*(n1.x-b1.x),p1.y+a*(n1.y-b1.y),p1.z+a*(n1.z-b1.z));
                    
                    //V3
                    glTexCoord2d(1.0,1.0);glVertex3f(p.x+a*(-n.x+b.x),p.y+a*(-n.y+b.y),p.z+a*(-n.z+b.z));
                    //V4
                    glTexCoord2d(0.0,1.0);glVertex3f(p.x+a*(-n.x-b.x),p.y+a*(-n.y-b.y),p.z+a*(-n.z-b.z));
                    //V8
                    glTexCoord2d(0.0,1.0);glVertex3f(p1.x+a*(-n1.x-b1.x),p1.y+a*(-n1.y-b1.y),p1.z+a*(-n1.z-b1.z));
                    //V7
                    glTexCoord2d(1.0,1.0);glVertex3f(p1.x+a*(-n1.x+b1.x),p1.y+a*(-n1.y+b1.y),p1.z+a*(-n1.z+b1.z));
                    
                    //V2
                    glTexCoord2d(1.0,0.0);glVertex3f(p.x+a*(n.x+b.x),p.y+a*(n.y+b.y),p.z+a*(n.z+b.z));
                    //V3
                    glTexCoord2d(1.0,1.0);glVertex3f(p.x+a*(-n.x+b.x),p.y+a*(-n.y+b.y),p.z+a*(-n.z+b.z));
                    //V7
                    glTexCoord2d(1.0,1.0);glVertex3f(p1.x+a*(-n1.x+b1.x),p1.y+a*(-n1.y+b1.y),p1.z+a*(-n1.z+b1.z));
                    //V6
                    glTexCoord2d(1.0,0.0);glVertex3f(p1.x+a*(n1.x+b1.x),p1.y+a*(n1.y+b1.y),p1.z+a*(n1.z+b1.z));
                    
                    //V1
                    glTexCoord2d(0.0,0.0);glVertex3f(p.x+a*(n.x-b.x),p.y+a*(n.y-b.y),p.z+a*(n.z-b.z));
                    //V2
                    glTexCoord2d(1.0,0.0);glVertex3f(p.x+a*(n.x+b.x),p.y+a*(n.y+b.y),p.z+a*(n.z+b.z));
                    //V6
                    glTexCoord2d(1.0,0.0);glVertex3f(p1.x+a*(n1.x+b1.x),p1.y+a*(n1.y+b1.y),p1.z+a*(n1.z+b1.z));
                    //V5
                    glTexCoord2d(0.0,0.0);glVertex3f(p1.x+a*(n1.x-b1.x),p1.y+a*(n1.y-b1.y),p1.z+a*(n1.z-b1.z));
                }
            }
        }
        glEnd();
    }
    glDisable(GL_TEXTURE_2D);
}
void displayRails()
{
    //DISPLAY RAILS ON ROLLER COASTER
    glColor3f(1.0, 1.0, 1.0);
    texture = LoadTexture("wood.jpg",256, 256);
    glEnable(GL_TEXTURE_2D);
    glBegin(GL_QUADS);
    for (int j = 0; j < g_iNumOfSplines; j++) {
        for(int i=-2;i<g_Splines[j].numControlPoints-1;i++)
        {
            for(float u=0.0;u<1.0;u+=0.05){
                
                point p,t,n,v,n1,t1,p1;
                v.x=0.0;v.y=0.0;v.z=-1.0;
                
                float f=0.1;
                //Point
                p.x= CatmullRom(u, g_Splines[j].points[i].x, g_Splines[j].points[i+1].x, g_Splines[j].points[i+2].x, g_Splines[j].points[i+3].x);
                p.y= CatmullRom(u, g_Splines[j].points[i].y, g_Splines[j].points[i+1].y, g_Splines[j].points[i+2].y, g_Splines[j].points[i+3].y);
                p.z= CatmullRom(u, g_Splines[j].points[i].z, g_Splines[j].points[i+1].z, g_Splines[j].points[i+2].z, g_Splines[j].points[i+3].z);
                //Tangent
                t.x= CatmullRomTangent(u, g_Splines[j].points[i].x, g_Splines[j].points[i+1].x, g_Splines[j].points[i+2].x, g_Splines[j].points[i+3].x);
                t.y= CatmullRomTangent(u, g_Splines[j].points[i].y, g_Splines[j].points[i+1].y, g_Splines[j].points[i+2].y, g_Splines[j].points[i+3].y);
                t.z= CatmullRomTangent(u, g_Splines[j].points[i].z, g_Splines[j].points[i+1].z, g_Splines[j].points[i+2].z, g_Splines[j].points[i+3].z);
                t = normalize(t);
                //Normal
                n = CrossProduct(t, v);
                n = normalize(n);
                
                p1.x= CatmullRom(u+0.01, g_Splines[j].points[i].x, g_Splines[j].points[i+1].x, g_Splines[j].points[i+2].x, g_Splines[j].points[i+3].x);
                p1.y= CatmullRom(u+0.01, g_Splines[j].points[i].y, g_Splines[j].points[i+1].y, g_Splines[j].points[i+2].y, g_Splines[j].points[i+3].y);
                p1.z= CatmullRom(u+0.01, g_Splines[j].points[i].z, g_Splines[j].points[i+1].z, g_Splines[j].points[i+2].z, g_Splines[j].points[i+3].z);
                
                t1.x= CatmullRomTangent(u+0.01, g_Splines[j].points[i].x, g_Splines[j].points[i+1].x, g_Splines[j].points[i+2].x, g_Splines[j].points[i+3].x);
                t1.y= CatmullRomTangent(u+0.01, g_Splines[j].points[i].y, g_Splines[j].points[i+1].y, g_Splines[j].points[i+2].y, g_Splines[j].points[i+3].y);
                t1.z= CatmullRomTangent(u+0.01, g_Splines[j].points[i].z, g_Splines[j].points[i+1].z, g_Splines[j].points[i+2].z, g_Splines[j].points[i+3].z);
                t1 = normalize(t1);
                
                n1 = CrossProduct(t1, v);
                n1 = normalize(n1);
                
                glColor3f(1.0, 1.0, 1.0);
                glTexCoord2d(0.0,0.0);glVertex3f(p.x,p.y,p.z);
                glTexCoord2d(3,0.0);glVertex3f(p.x+f*(n.x),p.y+f*(n.y),p.z+f*(n.z));
                glTexCoord2d(3,1);glVertex3f(p1.x+f*(n1.x),p1.y+f*(n1.y),p1.z+f*(n1.z));
                glTexCoord2d(0.0,1);glVertex3f(p1.x,p1.y,p1.z);
                
                glColor3f(1.0, 1.0, 1.0);
                glTexCoord2d(0.0,0.0);glVertex3f(p.x,p.y,p.z-0.003);
                glTexCoord2d(3.0,0.0);glVertex3f(p.x+f*(n.x),p.y+f*(n.y),p.z+f*(n.z)-0.003);
                glTexCoord2d(3.0,1.0);glVertex3f(p1.x+f*(n1.x),p1.y+f*(n1.y),p1.z+f*(n1.z)-0.003);
                glTexCoord2d(0.0,1.0);glVertex3f(p1.x,p1.y,p1.z-0.003);
                
                glColor3f(0.8, 0.5, 0.0);
                glTexCoord2d(0.0,0.0);glVertex3f(p.x,p.y,p.z);
                glTexCoord2d(3.0,0.0);glVertex3f(p.x+f*(n.x),p.y+f*(n.y),p.z+f*(n.z));
                glTexCoord2d(3.0,1.0);glVertex3f(p.x+f*(n.x),p.y+f*(n.y),p.z+f*(n.z)-0.003);
                glTexCoord2d(0.0,1.0);glVertex3f(p.x,p.y,p.z-0.003);
                
                glColor3f(1.0, 1.0, 1.0);
                glTexCoord2d(0.0,0.0);glVertex3f(p1.x,p1.y,p1.z);
                glTexCoord2d(3.0,0.0);glVertex3f(p1.x+f*(n1.x),p1.y+f*(n1.y),p1.z+f*(n1.z));
                glTexCoord2d(3.0,1.0);glVertex3f(p1.x+f*(n1.x),p1.y+f*(n1.y),p1.z+f*(n1.z)-0.003);
                glTexCoord2d(0.0,1.0);glVertex3f(p1.x,p1.y,p1.z-0.003);
                
                
            }
        }
    }
    glEnd();
    glDisable(GL_TEXTURE_2D);
}
Exemplo n.º 12
0
/*****************************************************************************
 * Draw a faceted latitude band of the Boing ball.
 *
 * Parms:   long_lo, long_hi
 *          Low and high longitudes of slice, resp.
 *****************************************************************************/
void DrawBoingBallBand( GLfloat long_lo,
                        GLfloat long_hi )
{
   vertex_t vert_ne;            /* "ne" means south-east, so on */
   vertex_t vert_nw;
   vertex_t vert_sw;
   vertex_t vert_se;
   vertex_t vert_norm;
   GLfloat  lat_deg;
   static int colorToggle = 0;

  /*
   * Iterate thru the points of a latitude circle.
   * A latitude circle is a 2D set of X,Z points.
   */
   for ( lat_deg = 0;
         lat_deg <= (360 - STEP_LATITUDE);
         lat_deg += STEP_LATITUDE )
   {
     /*
      * Color this polygon with red or white.
      */
      if ( colorToggle )
         glColor3f( 0.8f, 0.1f, 0.1f );
      else
         glColor3f( 0.95f, 0.95f, 0.95f );
#if 0
      if ( lat_deg >= 180 )
         if ( colorToggle )
            glColor3f( 0.1f, 0.8f, 0.1f );
         else
            glColor3f( 0.5f, 0.5f, 0.95f );
#endif
      colorToggle = ! colorToggle;

     /*
      * Change color if drawing shadow.
      */
      if ( drawBallHow == DRAW_BALL_SHADOW )
         glColor3f( 0.35f, 0.35f, 0.35f );

     /*
      * Assign each Y.
      */
      vert_ne.y = vert_nw.y = (float) cos_deg(long_hi) * RADIUS;
      vert_sw.y = vert_se.y = (float) cos_deg(long_lo) * RADIUS;

     /*
      * Assign each X,Z with sin,cos values scaled by latitude radius indexed by longitude.
      * Eg, long=0 and long=180 are at the poles, so zero scale is sin(longitude),
      * while long=90 (sin(90)=1) is at equator.
      */
      vert_ne.x = (float) cos_deg( lat_deg                 ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE ));
      vert_se.x = (float) cos_deg( lat_deg                 ) * (RADIUS * (float) sin_deg( long_lo                  ));
      vert_nw.x = (float) cos_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE ));
      vert_sw.x = (float) cos_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo                  ));

      vert_ne.z = (float) sin_deg( lat_deg                 ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE ));
      vert_se.z = (float) sin_deg( lat_deg                 ) * (RADIUS * (float) sin_deg( long_lo                  ));
      vert_nw.z = (float) sin_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE ));
      vert_sw.z = (float) sin_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo                  ));

     /*
      * Draw the facet.
      */
      glBegin( GL_POLYGON );

      CrossProduct( vert_ne, vert_nw, vert_sw, &vert_norm );
      glNormal3f( vert_norm.x, vert_norm.y, vert_norm.z );

      glVertex3f( vert_ne.x, vert_ne.y, vert_ne.z );
      glVertex3f( vert_nw.x, vert_nw.y, vert_nw.z );
      glVertex3f( vert_sw.x, vert_sw.y, vert_sw.z );
      glVertex3f( vert_se.x, vert_se.y, vert_se.z );

      glEnd();

#if BOING_DEBUG
      printf( "----------------------------------------------------------- \n" );
      printf( "lat = %f  long_lo = %f  long_hi = %f \n", lat_deg, long_lo, long_hi );
      printf( "vert_ne  x = %.8f  y = %.8f  z = %.8f \n", vert_ne.x, vert_ne.y, vert_ne.z );
      printf( "vert_nw  x = %.8f  y = %.8f  z = %.8f \n", vert_nw.x, vert_nw.y, vert_nw.z );
      printf( "vert_se  x = %.8f  y = %.8f  z = %.8f \n", vert_se.x, vert_se.y, vert_se.z );
      printf( "vert_sw  x = %.8f  y = %.8f  z = %.8f \n", vert_sw.x, vert_sw.y, vert_sw.z );
#endif

   }

  /*
   * Toggle color so that next band will opposite red/white colors than this one.
   */
   colorToggle = ! colorToggle;

  /*
   * This circular band is done.
   */
   return;
}
Exemplo n.º 13
0
/*
==============
RB_DrawSun
    FIXME: sun should render behind clouds, so passing dark areas cover it up
==============
*/
void RB_DrawSun(void)
{
	float  size;
	float  dist;
	vec3_t origin, vec1, vec2;
	byte   color[4];

	if (!tr.sunShader)
	{
		return;
	}

	if (!backEnd.skyRenderedThisView)
	{
		return;
	}
	if (!r_drawSun->integer)
	{
		return;
	}
	qglPushMatrix();
	qglLoadMatrixf(backEnd.viewParms.world.modelMatrix);
	qglTranslatef(backEnd.viewParms.orientation.origin[0], backEnd.viewParms.orientation.origin[1], backEnd.viewParms.orientation.origin[2]);

	dist = backEnd.viewParms.zFar / 1.75;       // div sqrt(3)

	// shrunk the size of the sun
	size = dist * 0.2;

	VectorScale(tr.sunDirection, dist, origin);
	PerpendicularVector(vec1, tr.sunDirection);
	CrossProduct(tr.sunDirection, vec1, vec2);

	VectorScale(vec1, size, vec1);
	VectorScale(vec2, size, vec2);

	// farthest depth range
	qglDepthRange(1.0, 1.0);

	color[0] = color[1] = color[2] = color[3] = 255;

	// simpler sun drawing
	RB_BeginSurface(tr.sunShader, tess.fogNum);

	RB_AddQuadStamp(origin, vec1, vec2, color);
	/*
	        // vec3_t temp; init moved down
	        VectorCopy( origin, temp );
	        VectorSubtract( temp, vec1, temp );
	        VectorSubtract( temp, vec2, temp );
	        VectorCopy( temp, tess.xyz[tess.numVertexes].v );
	        tess.texCoords0[tess.numVertexes].v[0] = 0;
	        tess.texCoords0[tess.numVertexes].v[1] = 0;
	        tess.vertexColors[tess.numVertexes].v[0] = 255;
	        tess.vertexColors[tess.numVertexes].v[1] = 255;
	        tess.vertexColors[tess.numVertexes].v[2] = 255;
	        tess.numVertexes++;

	        VectorCopy( origin, temp );
	        VectorAdd( temp, vec1, temp );
	        VectorSubtract( temp, vec2, temp );
	        VectorCopy( temp, tess.xyz[tess.numVertexes].v );
	        tess.texCoords0[tess.numVertexes].v[0] = 0;
	        tess.texCoords0[tess.numVertexes].v[1] = 1;
	        tess.vertexColors[tess.numVertexes].v[0] = 255;
	        tess.vertexColors[tess.numVertexes].v[1] = 255;
	        tess.vertexColors[tess.numVertexes].v[2] = 255;
	        tess.numVertexes++;

	        VectorCopy( origin, temp );
	        VectorAdd( temp, vec1, temp );
	        VectorAdd( temp, vec2, temp );
	        VectorCopy( temp, tess.xyz[tess.numVertexes].v );
	        tess.texCoords0[tess.numVertexes].v[0] = 1;
	        tess.texCoords0[tess.numVertexes].v[1] = 1;
	        tess.vertexColors[tess.numVertexes].v[0] = 255;
	        tess.vertexColors[tess.numVertexes].v[1] = 255;
	        tess.vertexColors[tess.numVertexes].v[2] = 255;
	        tess.numVertexes++;

	        VectorCopy( origin, temp );
	        VectorSubtract( temp, vec1, temp );
	        VectorAdd( temp, vec2, temp );
	        VectorCopy( temp, tess.xyz[tess.numVertexes].v );
	        tess.texCoords0[tess.numVertexes].v[0] = 1;
	        tess.texCoords0[tess.numVertexes].v[1] = 0;
	        tess.vertexColors[tess.numVertexes].v[0] = 255;
	        tess.vertexColors[tess.numVertexes].v[1] = 255;
	        tess.vertexColors[tess.numVertexes].v[2] = 255;
	        tess.numVertexes++;

	        tess.indexes[tess.numIndexes++] = 0;
	        tess.indexes[tess.numIndexes++] = 1;
	        tess.indexes[tess.numIndexes++] = 2;
	        tess.indexes[tess.numIndexes++] = 0;
	        tess.indexes[tess.numIndexes++] = 2;
	        tess.indexes[tess.numIndexes++] = 3;
	*/
	RB_EndSurface();

	if (r_drawSun->integer > 1)     // draw flare effect
	{
		vec3_t temp;
		// FYI: This is cheezy and was only a test so far.
		//      If we decide to use the flare business I will /definatly/ improve all this

		// get a point a little closer
		dist = dist * 0.7;
		VectorScale(tr.sunDirection, dist, origin);

		// and make the flare a little smaller
		VectorScale(vec1, 0.5f, vec1);
		VectorScale(vec2, 0.5f, vec2);

		// add the vectors to give an 'off angle' result
		VectorAdd(tr.sunDirection, backEnd.viewParms.orientation.axis[0], temp);
		VectorNormalize(temp);

		// amplify the result
		origin[0] += temp[0] * 500.0;
		origin[1] += temp[1] * 500.0;
		origin[2] += temp[2] * 500.0;

		// FIXME: todo: flare effect should render last (on top of everything else) and only when sun is in view (sun moving out of camera past degree n should start to cause flare dimming until view angle to sun is off by angle n + x.

		// draw the flare
		RB_BeginSurface(tr.sunflareShader[0], tess.fogNum);
		RB_AddQuadStamp(origin, vec1, vec2, color);
		RB_EndSurface();
	}

	// back to normal depth range
	qglDepthRange(0.0, 1.0);
	qglPopMatrix();
}
Exemplo n.º 14
0
//-----------------------------------------------------------------------------
// Assumes the material has already been bound
//-----------------------------------------------------------------------------
void DrawSprite( const Vector &vecOrigin, float flWidth, float flHeight, color32 color )
{
	unsigned char pColor[4] = { color.r, color.g, color.b, color.a };

	// Generate half-widths
	flWidth *= 0.5f;
	flHeight *= 0.5f;

	// Compute direction vectors for the sprite
	Vector fwd, right( 1, 0, 0 ), up( 0, 1, 0 );
	VectorSubtract( CurrentViewOrigin(), vecOrigin, fwd );
	float flDist = VectorNormalize( fwd );
	if (flDist >= 1e-3)
	{
		CrossProduct( CurrentViewUp(), fwd, right );
		flDist = VectorNormalize( right );
		if (flDist >= 1e-3)
		{
			CrossProduct( fwd, right, up );
		}
		else
		{
			// In this case, fwd == g_vecVUp, it's right above or 
			// below us in screen space
			CrossProduct( fwd, CurrentViewRight(), up );
			VectorNormalize( up );
			CrossProduct( up, fwd, right );
		}
	}

	CMeshBuilder meshBuilder;
	Vector point;
	CMatRenderContextPtr pRenderContext( materials );
	IMesh* pMesh = pRenderContext->GetDynamicMesh( );

	meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );

	meshBuilder.Color4ubv (pColor);
	meshBuilder.TexCoord2f (0, 0, 1);
	VectorMA (vecOrigin, -flHeight, up, point);
	VectorMA (point, -flWidth, right, point);
	meshBuilder.Position3fv (point.Base());
	meshBuilder.AdvanceVertex();

	meshBuilder.Color4ubv (pColor);
	meshBuilder.TexCoord2f (0, 0, 0);
	VectorMA (vecOrigin, flHeight, up, point);
	VectorMA (point, -flWidth, right, point);
	meshBuilder.Position3fv (point.Base());
	meshBuilder.AdvanceVertex();

	meshBuilder.Color4ubv (pColor);
	meshBuilder.TexCoord2f (0, 1, 0);
	VectorMA (vecOrigin, flHeight, up, point);
	VectorMA (point, flWidth, right, point);
	meshBuilder.Position3fv (point.Base());
	meshBuilder.AdvanceVertex();

	meshBuilder.Color4ubv (pColor);
	meshBuilder.TexCoord2f (0, 1, 1);
	VectorMA (vecOrigin, -flHeight, up, point);
	VectorMA (point, flWidth, right, point);
	meshBuilder.Position3fv (point.Base());
	meshBuilder.AdvanceVertex();
	
	meshBuilder.End();
	pMesh->Draw();
}
Exemplo n.º 15
0
/*
** RB_DrawSun
*/
void RB_DrawSun( void ) {
	float		size;
	float		dist;
	vec3_t		origin, vec1, vec2;
	vec3_t		temp;

	if ( !backEnd.skyRenderedThisView ) {
		return;
	}
	if ( !r_drawSun->integer ) {
		return;
	}
	qglLoadMatrixf( backEnd.viewParms.world.modelMatrix );
	qglTranslatef (backEnd.viewParms.ori.origin[0], backEnd.viewParms.ori.origin[1], backEnd.viewParms.ori.origin[2]);

	dist = 	backEnd.viewParms.zFar / 1.75;		// div sqrt(3)
	size = dist * 0.4;

	VectorScale( tr.sunDirection, dist, origin );
	PerpendicularVector( vec1, tr.sunDirection );
	CrossProduct( tr.sunDirection, vec1, vec2 );

	VectorScale( vec1, size, vec1 );
	VectorScale( vec2, size, vec2 );

	// farthest depth range
	qglDepthRange( 1.0, 1.0 );

	// FIXME: use quad stamp
	RB_BeginSurface( tr.sunShader, tess.fogNum );
		VectorCopy( origin, temp );
		VectorSubtract( temp, vec1, temp );
		VectorSubtract( temp, vec2, temp );
		VectorCopy( temp, tess.xyz[tess.numVertexes] );
		tess.texCoords[tess.numVertexes][0][0] = 0;
		tess.texCoords[tess.numVertexes][0][1] = 0;
		tess.vertexColors[tess.numVertexes][0] = 255;
		tess.vertexColors[tess.numVertexes][1] = 255;
		tess.vertexColors[tess.numVertexes][2] = 255;
		tess.numVertexes++;

		VectorCopy( origin, temp );
		VectorAdd( temp, vec1, temp );
		VectorSubtract( temp, vec2, temp );
		VectorCopy( temp, tess.xyz[tess.numVertexes] );
		tess.texCoords[tess.numVertexes][0][0] = 0;
		tess.texCoords[tess.numVertexes][0][1] = 1;
		tess.vertexColors[tess.numVertexes][0] = 255;
		tess.vertexColors[tess.numVertexes][1] = 255;
		tess.vertexColors[tess.numVertexes][2] = 255;
		tess.numVertexes++;

		VectorCopy( origin, temp );
		VectorAdd( temp, vec1, temp );
		VectorAdd( temp, vec2, temp );
		VectorCopy( temp, tess.xyz[tess.numVertexes] );
		tess.texCoords[tess.numVertexes][0][0] = 1;
		tess.texCoords[tess.numVertexes][0][1] = 1;
		tess.vertexColors[tess.numVertexes][0] = 255;
		tess.vertexColors[tess.numVertexes][1] = 255;
		tess.vertexColors[tess.numVertexes][2] = 255;
		tess.numVertexes++;

		VectorCopy( origin, temp );
		VectorSubtract( temp, vec1, temp );
		VectorAdd( temp, vec2, temp );
		VectorCopy( temp, tess.xyz[tess.numVertexes] );
		tess.texCoords[tess.numVertexes][0][0] = 1;
		tess.texCoords[tess.numVertexes][0][1] = 0;
		tess.vertexColors[tess.numVertexes][0] = 255;
		tess.vertexColors[tess.numVertexes][1] = 255;
		tess.vertexColors[tess.numVertexes][2] = 255;
		tess.numVertexes++;

		tess.indexes[tess.numIndexes++] = 0;
		tess.indexes[tess.numIndexes++] = 1;
		tess.indexes[tess.numIndexes++] = 2;
		tess.indexes[tess.numIndexes++] = 0;
		tess.indexes[tess.numIndexes++] = 2;
		tess.indexes[tess.numIndexes++] = 3;

	RB_EndSurface();

	// back to normal depth range
	qglDepthRange( 0.0, 1.0 );
}
Exemplo n.º 16
0
int SV_FlyMove (edict_t *ent, float time, int mask)
{
	edict_t *hit;
	int bumpcount, numbumps;
	vec3_t dir;
	float d;
	int numplanes;
	vec3_t planes[MAX_CLIP_PLANES];
	vec3_t primal_velocity, original_velocity, new_velocity;
	int i, j;
	trace_t trace;
	vec3_t end;
	float time_left;
	int blocked;

	if (!ent)
	{
		return 0;
	}

	numbumps = 4;

	blocked = 0;
	VectorCopy(ent->velocity, original_velocity);
	VectorCopy(ent->velocity, primal_velocity);
	numplanes = 0;

	time_left = time;

	ent->groundentity = NULL;

	for (bumpcount = 0; bumpcount < numbumps; bumpcount++)
	{
		for (i = 0; i < 3; i++)
		{
			end[i] = ent->s.origin[i] + time_left * ent->velocity[i];
		}

		trace = gi.trace(ent->s.origin, ent->mins, ent->maxs, end, ent, mask);

		if (trace.allsolid)
		{
			/* entity is trapped in another solid */
			VectorCopy(vec3_origin, ent->velocity);
			return 3;
		}

		if (trace.fraction > 0)
		{
			/* actually covered some distance */
			VectorCopy(trace.endpos, ent->s.origin);
			VectorCopy(ent->velocity, original_velocity);
			numplanes = 0;
		}

		if (trace.fraction == 1)
		{
			break; /* moved the entire distance */
		}

		hit = trace.ent;

		if (trace.plane.normal[2] > 0.7)
		{
			blocked |= 1; /* floor */

			if (hit->solid == SOLID_BSP)
			{
				ent->groundentity = hit;
				ent->groundentity_linkcount = hit->linkcount;
			}
		}

		if (!trace.plane.normal[2])
		{
			blocked |= 2; /* step */
		}

		/* run the impact function */
		SV_Impact(ent, &trace);

		if (!ent->inuse)
		{
			break; /* removed by the impact function */
		}

		time_left -= time_left * trace.fraction;

		/* cliped to another plane */
		if (numplanes >= MAX_CLIP_PLANES)
		{
			/* this shouldn't really happen */
			VectorCopy(vec3_origin, ent->velocity);
			return 3;
		}

		VectorCopy(trace.plane.normal, planes[numplanes]);
		numplanes++;

		/* modify original_velocity so it
		   parallels all of the clip planes */
		for (i = 0; i < numplanes; i++)
		{
			ClipVelocity(original_velocity, planes[i], new_velocity, 1);

			for (j = 0; j < numplanes; j++)
			{
				if ((j != i) && !VectorCompare(planes[i], planes[j]))
				{
					if (DotProduct(new_velocity, planes[j]) < 0)
					{
						break; /* not ok */
					}
				}
			}

			if (j == numplanes)
			{
				break;
			}
		}

		if (i != numplanes)
		{
			/* go along this plane */
			VectorCopy(new_velocity, ent->velocity);
		}
		else
		{
			/* go along the crease */
			if (numplanes != 2)
			{
				VectorCopy(vec3_origin, ent->velocity);
				return 7;
			}

			CrossProduct(planes[0], planes[1], dir);
			d = DotProduct(dir, ent->velocity);
			VectorScale(dir, d, ent->velocity);
		}

		/* If original velocity is against the original
		   velocity, stop dead to avoid tiny occilations
		   in sloping corners */
		if (DotProduct(ent->velocity, primal_velocity) <= 0)
		{
			VectorCopy(vec3_origin, ent->velocity);
			return blocked;
		}
	}

	return blocked;
}
Exemplo n.º 17
0
void display(void)
{
	ballXPos = ballXPos + 0.03;
	ballZPos = ballZPos + 0.03;
	int d = floor(ballXPos * 5.0);
	int e = floor(ballZPos * 5.0);

	dx = ballXPos * 5.0 - d;
	dz = ballZPos * 5.0 - e; 
	
	
	if(dx+dz<1){
		dyx = tm->vertexArray[(d+1 + e * texWidth)*3+1] - tm->vertexArray[(d + e * texWidth)*3+1];	
		dyz = tm->vertexArray[(d + (e+1) * texWidth)*3+1] - tm->vertexArray[(d + e * texWidth)*3+1];
		ballYPos = dyx*dx+dyz*dz + tm->vertexArray[(d + e * texWidth)*3+1];
		
	} 
	else{
		dyx = tm->vertexArray[(d+1 + e * texWidth)*3+1] - tm->vertexArray[((d+1) + (e+1) * texWidth)*3+1];	
		dyz = tm->vertexArray[(d + (e+1) * texWidth)*3+1] - tm->vertexArray[((d+1) + (e+1) * texWidth)*3+1];
		dx = (ceil(ballXPos * 5.0)-ballXPos * 5.0);
		dz = (ceil(ballZPos * 5.0)-ballZPos * 5.0);
		ballYPos = dyx*dx+dyz*dz + tm->vertexArray[((d+1) + (e+1) * texWidth)*3+1];
	}
	
	
		

	
	
	//printf("%lf\n",ballYPos);

	
	vec3 lookingDir = Normalize(VectorSub(l, p));
	vec3 walkSideways = Normalize(CrossProduct(lookingDir, v));
	
	if (glutKeyIsDown('a')) { 
	 p = VectorSub(p, walkSideways);
	 l = VectorSub(l, walkSideways);
	}
	
	if (glutKeyIsDown('d')) { 
	  p = VectorAdd(p, walkSideways);
	 l = VectorAdd(l, walkSideways);
	}

	if (glutKeyIsDown('w')) { 	
		p = VectorAdd(p, lookingDir);
		l = VectorAdd(l, lookingDir);
		} 
		
	if (glutKeyIsDown('s')) { 
		p = VectorSub(p, lookingDir);
		l = VectorSub(l, lookingDir);
	 }
		
	if (glutKeyIsDown('l')) { 
		trans = T(-p.x, -p.y, -p.z);
		trans2 = T(p.x, p.y, p.z);
		rot = Ry(-0.05);
		l = MultVec3(trans2, MultVec3(rot, MultVec3(trans, l)));
	}
	
	if (glutKeyIsDown('j')) { 
		trans = T(-p.x, -p.y, -p.z);
		trans2 = T(p.x, p.y, p.z);
		rot = Ry(0.05);
		l = MultVec3(trans2, MultVec3(rot, MultVec3(trans, l)));
	}
	
	if (glutKeyIsDown('i')) { 
	 trans = T(-p.x, -p.y, -p.z);
		trans2 = T(p.x, p.y, p.z);
		rotateUpDown = ArbRotate(walkSideways, 0.05);
		l = MultVec3(trans2, MultVec3(rotateUpDown, MultVec3(trans, l)));
	}
	if (glutKeyIsDown('k')) { 
	 trans = T(-p.x, -p.y, -p.z);
		trans2 = T(p.x, p.y, p.z);
		rotateUpDown = ArbRotate(walkSideways, -0.05);
		l = MultVec3(trans2, MultVec3(rotateUpDown, MultVec3(trans, l)));
	}


	// clear the screen
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		
	printError("pre display");
	
	glUseProgram(program);

	// Build matrix
	camMatrix = lookAtv(p,l,v);
	modelView = IdentityMatrix();
	total = Mult(camMatrix, modelView);
	glUniformMatrix4fv(glGetUniformLocation(program, "mdlMatrix"), 1, GL_TRUE, modelView.m);
	glUniformMatrix4fv(glGetUniformLocation(program, "cameraMatrix"), 1, GL_TRUE, camMatrix.m);
	DrawModel(tm, program, "inPosition", "inNormal", "inTexCoord");

	//Draw sphere
	modelToWorld = T(ballXPos, ballYPos, ballZPos);
	glUniformMatrix4fv(glGetUniformLocation(program, "mdlMatrix"), 1, GL_TRUE, modelToWorld.m);
	DrawModel(sphere, program, "inPosition", "inNormal", NULL);


	printError("display 2");
	
	glutSwapBuffers();
}
Exemplo n.º 18
0
static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm, shaderInfo_t *si,
									  float scale, float subdivide, qboolean original, radWinding_t *rw, clipWork_t *cw ){
	int i, style;
	float dist, area, value;
	vec3_t mins, maxs, normal, d1, d2, cross, color, gradient;
	light_t         *light, *splash;
	winding_t       *w;


	/* dummy check */
	if ( rw == NULL || rw->numVerts < 3 ) {
		return;
	}

	/* get bounds for winding */
	ClearBounds( mins, maxs );
	for ( i = 0; i < rw->numVerts; i++ )
		AddPointToBounds( rw->verts[ i ].xyz, mins, maxs );

	/* subdivide if necessary */
	for ( i = 0; i < 3; i++ )
	{
		if ( maxs[ i ] - mins[ i ] > subdivide ) {
			radWinding_t front, back;


			/* make axial plane */
			VectorClear( normal );
			normal[ i ] = 1;
			dist = ( maxs[ i ] + mins[ i ] ) * 0.5f;

			/* clip the winding */
			RadClipWindingEpsilon( rw, normal, dist, RADIOSITY_CLIP_EPSILON, &front, &back, cw );

			/* recurse */
			RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, qfalse, &front, cw );
			RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, qfalse, &back, cw );
			return;
		}
	}

	/* check area */
	area = 0.0f;
	for ( i = 2; i < rw->numVerts; i++ )
	{
		VectorSubtract( rw->verts[ i - 1 ].xyz, rw->verts[ 0 ].xyz, d1 );
		VectorSubtract( rw->verts[ i ].xyz, rw->verts[ 0 ].xyz, d2 );
		CrossProduct( d1, d2, cross );
		area += 0.5f * VectorLength( cross );
	}
	if ( area < 1.0f || area > 20000000.0f ) {
		return;
	}

	/* more subdivision may be necessary */
	if ( bouncing ) {
		/* get color sample for the surface fragment */
		RadSample( lightmapNum, ds, lm, si, rw, color, gradient, &style );

		/* if color gradient is too high, subdivide again */
		if ( subdivide > minDiffuseSubdivide &&
			 ( gradient[ 0 ] > RADIOSITY_MAX_GRADIENT || gradient[ 1 ] > RADIOSITY_MAX_GRADIENT || gradient[ 2 ] > RADIOSITY_MAX_GRADIENT ) ) {
			RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, ( subdivide / 2.0f ), qfalse, rw, cw );
			return;
		}
	}

	/* create a regular winding and an average normal */
	w = AllocWinding( rw->numVerts );
	w->numpoints = rw->numVerts;
	VectorClear( normal );
	for ( i = 0; i < rw->numVerts; i++ )
	{
		VectorCopy( rw->verts[ i ].xyz, w->p[ i ] );
		VectorAdd( normal, rw->verts[ i ].normal, normal );
	}
	VectorScale( normal, ( 1.0f / rw->numVerts ), normal );
	if ( VectorNormalize( normal, normal ) == 0.0f ) {
		return;
	}

	/* early out? */
	if ( bouncing && VectorLength( color ) < RADIOSITY_MIN ) {
		return;
	}

	/* debug code */
	//%	Sys_Printf( "Size: %d %d %d\n", (int) (maxs[ 0 ] - mins[ 0 ]), (int) (maxs[ 1 ] - mins[ 1 ]), (int) (maxs[ 2 ] - mins[ 2 ]) );
	//%	Sys_Printf( "Grad: %f %f %f\n", gradient[ 0 ], gradient[ 1 ], gradient[ 2 ] );

	/* increment counts */
	numDiffuseLights++;
	switch ( ds->surfaceType )
	{
	case MST_PLANAR:
		numBrushDiffuseLights++;
		break;

	case MST_TRIANGLE_SOUP:
		numTriangleDiffuseLights++;
		break;

	case MST_PATCH:
		numPatchDiffuseLights++;
		break;
	}

	/* create a light */
	light = safe_malloc( sizeof( *light ) );
	memset( light, 0, sizeof( *light ) );

	/* attach it */
	ThreadLock();
	light->next = lights;
	lights = light;
	ThreadUnlock();

	/* initialize the light */
	light->flags = LIGHT_AREA_DEFAULT;
	light->type = EMIT_AREA;
	light->si = si;
	light->fade = 1.0f;
	light->w = w;

	/* set falloff threshold */
	light->falloffTolerance = falloffTolerance;

	/* bouncing light? */
	if ( bouncing == qfalse ) {
		/* handle first-pass lights in normal q3a style */
		value = si->value;
		light->photons = value * area * areaScale;
		light->add = value * formFactorValueScale * areaScale;
		VectorCopy( si->color, light->color );
		VectorScale( light->color, light->add, light->emitColor );
		light->style = si->lightStyle;
		if ( light->style < 0 || light->style >= LS_NONE ) {
			light->style = 0;
		}

		/* set origin */
		VectorAdd( mins, maxs, light->origin );
		VectorScale( light->origin, 0.5f, light->origin );

		/* nudge it off the plane a bit */
		VectorCopy( normal, light->normal );
		VectorMA( light->origin, 1.0f, light->normal, light->origin );
		light->dist = DotProduct( light->origin, normal );

		/* optionally create a point splashsplash light for first pass */
		if ( original && si->backsplashFraction > 0 ) {
			/* allocate a new point light */
			splash = safe_malloc( sizeof( *splash ) );
			memset( splash, 0, sizeof( *splash ) );
			splash->next = lights;
			lights = splash;

			/* set it up */
			splash->flags = LIGHT_Q3A_DEFAULT;
			splash->type = EMIT_POINT;
			splash->photons = light->photons * si->backsplashFraction;
			splash->fade = 1.0f;
			splash->si = si;
			VectorMA( light->origin, si->backsplashDistance, normal, splash->origin );
			VectorCopy( si->color, splash->color );
			splash->falloffTolerance = falloffTolerance;
			splash->style = light->style;

			/* add to counts */
			numPointLights++;
		}
	}
	else
	{
		/* handle bounced light (radiosity) a little differently */
		value = RADIOSITY_VALUE * si->bounceScale * 0.375f;
		light->photons = value * area * bounceScale;
		light->add = value * formFactorValueScale * bounceScale;
		VectorCopy( color, light->color );
		VectorScale( light->color, light->add, light->emitColor );
		light->style = style;
		if ( light->style < 0 || light->style >= LS_NONE ) {
			light->style = 0;
		}

		/* set origin */
		WindingCenter( w, light->origin );

		/* nudge it off the plane a bit */
		VectorCopy( normal, light->normal );
		VectorMA( light->origin, 1.0f, light->normal, light->origin );
		light->dist = DotProduct( light->origin, normal );
	}

	/* emit light from both sides? */
	if ( si->compileFlags & C_FOG || si->twoSided ) {
		light->flags |= LIGHT_TWOSIDED;
	}

	//%	Sys_Printf( "\nAL: C: (%6f, %6f, %6f) [%6f] N: (%6f, %6f, %6f) %s\n",
	//%		light->color[ 0 ], light->color[ 1 ], light->color[ 2 ], light->add,
	//%		light->normal[ 0 ], light->normal[ 1 ], light->normal[ 2 ],
	//%		light->si->shader );
}
Exemplo n.º 19
0
void CGameRules::RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrcIn, float flRadius, int iClassIgnore, CBaseEntity *pEntityIgnore )
{
	const int MASK_RADIUS_DAMAGE = MASK_SHOT&(~CONTENTS_HITBOX);
	CBaseEntity *pEntity = NULL;
	trace_t		tr;
	float		flAdjustedDamage, falloff;
	Vector		vecSpot;

	Vector vecSrc = vecSrcIn;

	if ( flRadius )
		falloff = info.GetDamage() / flRadius;
	else
		falloff = 1.0;

	int bInWater = (UTIL_PointContents ( vecSrc, MASK_WATER ) & MASK_WATER) ? true : false;

#ifdef HL2_DLL
	if( bInWater )
	{
		// Only muffle the explosion if deeper than 2 feet in water.
		if( !(UTIL_PointContents(vecSrc + Vector(0, 0, 24), MASK_WATER) & MASK_WATER) )
		{
			bInWater = false;
		}
	}
#endif // HL2_DLL
	
	vecSrc.z += 1;// in case grenade is lying on the ground

	float flHalfRadiusSqr = Square( flRadius / 2.0f );

	// iterate on all entities in the vicinity.
	for ( CEntitySphereQuery sphere( vecSrc, flRadius ); (pEntity = sphere.GetCurrentEntity()) != NULL; sphere.NextEntity() )
	{
		// This value is used to scale damage when the explosion is blocked by some other object.
		float flBlockedDamagePercent = 0.0f;

		if ( pEntity == pEntityIgnore )
			continue;

		if ( pEntity->m_takedamage == DAMAGE_NO )
			continue;

		// UNDONE: this should check a damage mask, not an ignore
		if ( iClassIgnore != CLASS_NONE && pEntity->Classify() == iClassIgnore )
		{// houndeyes don't hurt other houndeyes with their attack
			continue;
		}

		// blast's don't tavel into or out of water
		if (bInWater && pEntity->GetWaterLevel() == 0)
			continue;

		if (!bInWater && pEntity->GetWaterLevel() == 3)
			continue;

		// Check that the explosion can 'see' this entity.
		vecSpot = pEntity->BodyTarget( vecSrc, false );
		UTIL_TraceLine( vecSrc, vecSpot, MASK_RADIUS_DAMAGE, info.GetInflictor(), COLLISION_GROUP_NONE, &tr );

		if( old_radius_damage.GetBool() )
		{
			if ( tr.fraction != 1.0 && tr.m_pEnt != pEntity )
			continue;
		}
		else
		{
			if ( tr.fraction != 1.0 )
			{
				if ( IsExplosionTraceBlocked(&tr) )
				{
					if( ShouldUseRobustRadiusDamage( pEntity ) )
					{
						if( vecSpot.DistToSqr( vecSrc ) > flHalfRadiusSqr )
						{
							// Only use robust model on a target within one-half of the explosion's radius.
							continue;
						}

						Vector vecToTarget = vecSpot - tr.endpos;
						VectorNormalize( vecToTarget );

						// We're going to deflect the blast along the surface that 
						// interrupted a trace from explosion to this target.
						Vector vecUp, vecDeflect;
						CrossProduct( vecToTarget, tr.plane.normal, vecUp );
						CrossProduct( tr.plane.normal, vecUp, vecDeflect );
						VectorNormalize( vecDeflect );

						// Trace along the surface that intercepted the blast...
						UTIL_TraceLine( tr.endpos, tr.endpos + vecDeflect * ROBUST_RADIUS_PROBE_DIST, MASK_RADIUS_DAMAGE, info.GetInflictor(), COLLISION_GROUP_NONE, &tr );
						//NDebugOverlay::Line( tr.startpos, tr.endpos, 255, 255, 0, false, 10 );

						// ...to see if there's a nearby edge that the explosion would 'spill over' if the blast were fully simulated.
						UTIL_TraceLine( tr.endpos, vecSpot, MASK_RADIUS_DAMAGE, info.GetInflictor(), COLLISION_GROUP_NONE, &tr );
						//NDebugOverlay::Line( tr.startpos, tr.endpos, 255, 0, 0, false, 10 );

						if( tr.fraction != 1.0 && tr.DidHitWorld() )
						{
							// Still can't reach the target.
							continue;
						}
						// else fall through
					}
					else
					{
						continue;
					}
				}

				// UNDONE: Probably shouldn't let children block parents either?  Or maybe those guys should set their owner if they want this behavior?
				// HL2 - Dissolve damage is not reduced by interposing non-world objects
				if( tr.m_pEnt && tr.m_pEnt != pEntity && tr.m_pEnt->GetOwnerEntity() != pEntity )
				{
					// Some entity was hit by the trace, meaning the explosion does not have clear
					// line of sight to the entity that it's trying to hurt. If the world is also
					// blocking, we do no damage.
					CBaseEntity *pBlockingEntity = tr.m_pEnt;
					//Msg( "%s may be blocked by %s...", pEntity->GetClassname(), pBlockingEntity->GetClassname() );

					UTIL_TraceLine( vecSrc, vecSpot, CONTENTS_SOLID, info.GetInflictor(), COLLISION_GROUP_NONE, &tr );

					if( tr.fraction != 1.0 )
					{
						continue;
					}
					
					// Now, if the interposing object is physics, block some explosion force based on its mass.
					if( pBlockingEntity->VPhysicsGetObject() )
					{
						const float MASS_ABSORB_ALL_DAMAGE = 350.0f;
						float flMass = pBlockingEntity->VPhysicsGetObject()->GetMass();
						float scale = flMass / MASS_ABSORB_ALL_DAMAGE;

						// Absorbed all the damage.
						if( scale >= 1.0f )
						{
							continue;
						}

						ASSERT( scale > 0.0f );
						flBlockedDamagePercent = scale;
						//Msg("  Object (%s) weighing %fkg blocked %f percent of explosion damage\n", pBlockingEntity->GetClassname(), flMass, scale * 100.0f);
					}
					else
					{
						// Some object that's not the world and not physics. Generically block 25% damage
						flBlockedDamagePercent = 0.25f;
					}
				}
			}
		}
		// decrease damage for an ent that's farther from the bomb.
		float flDistanceToEnt = ( vecSrc - tr.endpos ).Length();
		flAdjustedDamage = flDistanceToEnt * falloff;
		flAdjustedDamage = info.GetDamage() - flAdjustedDamage;

		if ( flAdjustedDamage <= 0 )
		{
			continue;
		}

		// the explosion can 'see' this entity, so hurt them!
		if (tr.startsolid)
		{
			// if we're stuck inside them, fixup the position and distance
			tr.endpos = vecSrc;
			tr.fraction = 0.0;
		}
		
		CTakeDamageInfo adjustedInfo = info;
		//Msg("%s: Blocked damage: %f percent (in:%f  out:%f)\n", pEntity->GetClassname(), flBlockedDamagePercent * 100, flAdjustedDamage, flAdjustedDamage - (flAdjustedDamage * flBlockedDamagePercent) );
		adjustedInfo.SetRadius( flRadius );
		adjustedInfo.SetDamage( flAdjustedDamage - (flAdjustedDamage * flBlockedDamagePercent) );

		// Now make a consideration for skill level!
		if( info.GetAttacker() && info.GetAttacker()->IsPlayer() && pEntity->IsNPC() )
		{
			// An explosion set off by the player is harming an NPC. Adjust damage accordingly.
			adjustedInfo.AdjustPlayerDamageInflictedForSkillLevel();
		}

		Vector dir = vecSpot - vecSrc;
		VectorNormalize( dir );

		// If we don't have a damage force, manufacture one
		if ( adjustedInfo.GetDamagePosition() == vec3_origin || adjustedInfo.GetDamageForce() == vec3_origin )
		{
			if ( !( adjustedInfo.GetDamageType() & DMG_PREVENT_PHYSICS_FORCE ) )
			{
				CalculateExplosiveDamageForce( &adjustedInfo, dir, vecSrc );
			}
		}
		else
		{
			// Assume the force passed in is the maximum force. Decay it based on falloff.
			float flForce = adjustedInfo.GetDamageForce().Length() * falloff;
			adjustedInfo.SetDamageForce( dir * flForce );
			adjustedInfo.SetDamagePosition( vecSrc );
		}

		if ( tr.fraction != 1.0 && pEntity == tr.m_pEnt )
		{
			ClearMultiDamage( );
			pEntity->DispatchTraceAttack( adjustedInfo, dir, &tr );
			ApplyMultiDamage();
		}
		else
		{
			pEntity->TakeDamage( adjustedInfo );
		}

		// Now hit all triggers along the way that respond to damage... 
		pEntity->TraceAttackToTriggers( adjustedInfo, vecSrc, tr.endpos, dir );

#if defined( GAME_DLL )
		if ( info.GetAttacker() && info.GetAttacker()->IsPlayer() && ToBaseCombatCharacter( tr.m_pEnt ) )
		{

			// This is a total hack!!!
			bool bIsPrimary = true;
			CBasePlayer *player = ToBasePlayer( info.GetAttacker() );
			CBaseCombatWeapon *pWeapon = player->GetActiveWeapon();
			if ( pWeapon && FClassnameIs( pWeapon, "weapon_smg1" ) )
			{
				bIsPrimary = false;
			}

			gamestats->Event_WeaponHit( player, bIsPrimary, (pWeapon != NULL) ? player->GetActiveWeapon()->GetClassname() : "NULL", info );
		}
#endif
	}
}
Exemplo n.º 20
0
/*
=================
BaseWindingForPlane
=================
*/
winding_t *BaseWindingForPlane (plane_t *p)
{
    int		i, x;
    double	max, v;
    vec3_t	org, vright, vup;
    winding_t	*w;

// find the major axis
    max = -BOGUS_RANGE;
    x = -1;
    for (i = 0 ; i < 3; i++)
    {
        v = fabs(p->normal[i]);
        if (v > max)
        {
            x = i;
            max = v;
        }
    }
    if (x == -1)
        Error ("%s: no axis found", __thisfunc__);

    VectorClear (vup);
    switch (x)
    {
    case 0:
    case 1:
        vup[2] = 1;
        break;
    case 2:
        vup[0] = 1;
        break;
    }

    v = DotProduct (vup, p->normal);
    VectorMA (vup, -v, p->normal, vup);
    VectorNormalize (vup);

    VectorScale (p->normal, p->dist, org);

    CrossProduct (vup, p->normal, vright);

    VectorScale (vup, 8192, vup);
    VectorScale (vright, 8192, vright);

// project a really big axis aligned box onto the plane
    w = NewWinding (4);

    VectorSubtract (org, vright, w->points[0]);
    VectorAdd (w->points[0], vup, w->points[0]);

    VectorAdd (org, vright, w->points[1]);
    VectorAdd (w->points[1], vup, w->points[1]);

    VectorAdd (org, vright, w->points[2]);
    VectorSubtract (w->points[2], vup, w->points[2]);

    VectorSubtract (org, vright, w->points[3]);
    VectorSubtract (w->points[3], vup, w->points[3]);

    w->numpoints = 4;

    return w;
}
Exemplo n.º 21
0
int SV_FlyMove (edict_t *ent, float time, int mask)
{
	edict_t		*hit;
	int			bumpcount, numbumps;
	vec3_t		dir;
	float		d;
	int			numplanes;
	vec3_t		planes[MAX_CLIP_PLANES];
	vec3_t		primal_velocity, original_velocity, new_velocity;
	int			i, j;
	trace_t		trace;
	vec3_t		end;
	float		time_left;
	int			blocked;
	
	numbumps = 4;
	
	blocked = 0;
	VectorCopy (ent->velocity, original_velocity);
	VectorCopy (ent->velocity, primal_velocity);
	numplanes = 0;
	
	time_left = time;

	ent->groundentity = NULL;
	for (bumpcount=0 ; bumpcount<numbumps ; bumpcount++)
	{
		for (i=0 ; i<3 ; i++)
			end[i] = ent->s.origin[i] + time_left * ent->velocity[i];

		trace = gi.trace (ent->s.origin, ent->mins, ent->maxs, end, ent, mask);

		if (trace.allsolid)
		{	// entity is trapped in another solid
			VectorCopy (vec3_origin, ent->velocity);
			return 3;
		}

		if (trace.fraction > 0)
		{	// actually covered some distance
			VectorCopy (trace.endpos, ent->s.origin);
			VectorCopy (ent->velocity, original_velocity);
			numplanes = 0;
		}

		if (trace.fraction == 1)
			 break;		// moved the entire distance

		hit = trace.ent;

		if (trace.plane.normal[2] > 0.7)
		{
			blocked |= 1;		// floor
			if ( hit->solid == SOLID_BSP)
			{
				ent->groundentity = hit;
				ent->groundentity_linkcount = hit->linkcount;
			}
		}
		if (!trace.plane.normal[2])
		{
			blocked |= 2;		// step
		}

//
// run the impact function
//
		SV_Impact (ent, &trace);
		if (!ent->inuse)
			break;		// removed by the impact function

		
		time_left -= time_left * trace.fraction;
		
	// cliped to another plane
		if (numplanes >= MAX_CLIP_PLANES)
		{	// this shouldn't really happen
			VectorCopy (vec3_origin, ent->velocity);
			return 3;
		}

		VectorCopy (trace.plane.normal, planes[numplanes]);
		numplanes++;

//
// modify original_velocity so it parallels all of the clip planes
//
//numplanes = 0;
		if (ent->client)//K03 added in a call to make sure it is a client entity
		{
//PON-CTF
		i = false;
		if(!i){if(!ent->groundentity) i = true;}
//PON-CTF
		if(!i)
		{
			numplanes = 0;
			if(ent->waterlevel || (!ent->groundentity && ent->velocity[2] > 10 )) goto VELCX;
			i =0;
			if(/*ent->groundentity ||*/ ent->velocity[2] > 10) goto VELC;

		}
		}//K03 End

		for (i=0 ; i<numplanes ; i++)
		{
			ClipVelocity (original_velocity, planes[i], new_velocity, 1);

			for (j=0 ; j<numplanes ; j++)
				if (j != i)
				{
					if (DotProduct (new_velocity, planes[j]) < 0)
						break;	// not ok
				}
			if (j == numplanes)
				break;
		}
//ponko

//ponko
VELC:
		if (i != numplanes)
		{	// go along this plane
			VectorCopy (new_velocity, ent->velocity);
		}
		else
		{	// go along the crease
			if (numplanes != 2)
			{
//				gi.dprintf ("clip velocity, numplanes == %i\n",numplanes);
				VectorCopy (vec3_origin, ent->velocity);
				return 7;
			}
			CrossProduct (planes[0], planes[1], dir);
			d = DotProduct (dir, ent->velocity);
			VectorScale (dir, d, ent->velocity);
		}
VELCX:
//
// if original velocity is against the original velocity, stop dead
// to avoid tiny occilations in sloping corners
//
		if (DotProduct (ent->velocity, primal_velocity) <= 0)
		{
			VectorCopy (vec3_origin, ent->velocity);
			return blocked;
		}
	}

	return blocked;
}
Exemplo n.º 22
0
//------------------------------------------------------------------------------
// Purpose: Break into panels
// Input  : pBreaker - 
//			vDir - 
//-----------------------------------------------------------------------------
void CBreakableSurface::Die( CBaseEntity *pBreaker, const Vector &vAttackDir )
{
	if ( m_bIsBroken )
		return;

	// Play a break sound
	PhysBreakSound( this, VPhysicsGetObject(), GetAbsOrigin() );

	m_bIsBroken = true;
	m_iHealth = 0.0f;

	if (pBreaker)
	{
		m_OnBreak.FireOutput( pBreaker, this );
	}
	else
	{
		m_OnBreak.FireOutput( this, this );
	}

	float flDir = -1;

	if ( vAttackDir.LengthSqr() > 0.001 )
	{
		float flDot = DotProduct( m_vNormal, vAttackDir );
		if (flDot < 0)
		{
			m_vLLVertex += m_vNormal;
			m_vLRVertex += m_vNormal;
			m_vULVertex += m_vNormal;
			m_vURVertex += m_vNormal;
			m_vNormal	*= -1;
			flDir		=   1;
		}
	}

	// -------------------------------------------------------
	// The surface has two sides, when we are killed pick 
	// the side that the damage came from 
	// -------------------------------------------------------
	Vector vWidth		= m_vLLVertex - m_vLRVertex;
	Vector vHeight		= m_vLLVertex - m_vULVertex;
	CrossProduct( vWidth, vHeight, m_vNormal.GetForModify() );
	VectorNormalize(m_vNormal.GetForModify());

	// ---------------------------------------------------
	//  Make sure width and height are oriented correctly
	// ---------------------------------------------------
	QAngle vAngles;
	VectorAngles(-1*m_vNormal,vAngles);
	Vector vWidthDir,vHeightDir;
	AngleVectors(vAngles,NULL,&vWidthDir,&vHeightDir);

	float flWDist = DotProduct(vWidthDir,vWidth);
	if (fabs(flWDist)<0.5)
	{
		Vector vSaveHeight	= vHeight;
		vHeight				= vWidth * flDir;
		vWidth				= vSaveHeight * flDir;
	}

	// -------------------------------------------------
	// Find which corner to use
	// -------------------------------------------------
	bool bLeft  = (DotProduct(vWidthDir,vWidth)   < 0);
	bool bLower = (DotProduct(vHeightDir,vHeight) < 0);
	if (bLeft)
	{
		m_vCorner = bLower ? m_vLLVertex : m_vULVertex;
	}
	else 
	{
		m_vCorner = bLower ? m_vLRVertex : m_vURVertex;
	}

	// -------------------------------------------------
	//  Calculate the number of panels
	// -------------------------------------------------
	float flWidth		= vWidth.Length();
	float flHeight		= vHeight.Length();
	m_nNumWide			= flWidth  / WINDOW_PANEL_SIZE;
	m_nNumHigh			= flHeight / WINDOW_PANEL_SIZE;

	// If to many panels make panel size bigger
	if (m_nNumWide > MAX_NUM_PANELS) m_nNumWide = MAX_NUM_PANELS;
	if (m_nNumHigh > MAX_NUM_PANELS) m_nNumHigh = MAX_NUM_PANELS;

	m_flPanelWidth	= flWidth  / m_nNumWide;
	m_flPanelHeight	= flHeight / m_nNumHigh;
	
	// Initialize panels
	for (int w=0;w<MAX_NUM_PANELS;w++)
	{ 
		for (int h=0;h<MAX_NUM_PANELS;h++)
		{
			SetSupport( w, h, WINDOW_PANE_HEALTHY );
		}
	}

	// Reset onground flags for any entity that may 
	// have been standing on me
	ResetOnGroundFlags();

	VPhysicsDestroyObject();
	AddSolidFlags( FSOLID_TRIGGER );
	AddSolidFlags( FSOLID_NOT_SOLID );
	SetTouch(&CBreakableSurface::SurfaceTouch);
}
Exemplo n.º 23
0
int R_MarkFragments( int numPoints, const vector3 *points, const vector3 *projection, int maxPoints, vector3 *pointBuffer, int maxFragments, markFragment_t *fragmentBuffer ) {
	int				numsurfaces, numPlanes;
	int				i, j, k, m, n;
	surfaceType_t	*surfaces[64];
	vector3			mins, maxs;
	int				returnedFragments;
	int				returnedPoints;
	vector3			normals[MAX_VERTS_ON_POLY+2];
	float			dists[MAX_VERTS_ON_POLY+2];
	vector3			clipPoints[2][MAX_VERTS_ON_POLY];
	int				numClipPoints;
	vector3			*v;
	srfGridMesh_t	*cv;
	drawVert_t		*dv;
	vector3			normal;
	vector3			projectionDir;
	vector3			v1, v2;
	int				*indexes;

	if (numPoints <= 0) {
		return 0;
	}

	//increment view count for double check prevention
	tr.viewCount++;

	//
	VectorNormalize2( projection, &projectionDir );
	// find all the brushes that are to be considered
	ClearBounds( &mins, &maxs );
	for ( i = 0 ; i < numPoints ; i++ ) {
		vector3	temp;

		AddPointToBounds( &points[i], &mins, &maxs );
		VectorAdd( &points[i], projection, &temp );
		AddPointToBounds( &temp, &mins, &maxs );
		// make sure we get all the leafs (also the one(s) in front of the hit surface)
		VectorMA( &points[i], -20, &projectionDir, &temp );
		AddPointToBounds( &temp, &mins, &maxs );
	}

	if (numPoints > MAX_VERTS_ON_POLY) numPoints = MAX_VERTS_ON_POLY;
	// create the bounding planes for the to be projected polygon
	for ( i = 0 ; i < numPoints ; i++ ) {
		VectorSubtract(&points[(i+1)%numPoints], &points[i], &v1);
		VectorAdd(&points[i], projection, &v2);
		VectorSubtract(&points[i], &v2, &v2);
		CrossProduct(&v1, &v2, &normals[i]);
		VectorNormalizeFast(&normals[i]);
		dists[i] = DotProduct(&normals[i], &points[i]);
	}
	// add near and far clipping planes for projection
	VectorCopy(&projectionDir, &normals[numPoints]);
	dists[numPoints] = DotProduct(&normals[numPoints], &points[0]) - 32;
	VectorCopy(&projectionDir, &normals[numPoints+1]);
	VectorInverse(&normals[numPoints+1]);
	dists[numPoints+1] = DotProduct(&normals[numPoints+1], &points[0]) - 20;
	numPlanes = numPoints + 2;

	numsurfaces = 0;
	R_BoxSurfaces_r(tr.world->nodes, &mins, &maxs, surfaces, 64, &numsurfaces, &projectionDir);
	//assert(numsurfaces <= 64);
	//assert(numsurfaces != 64);

	returnedPoints = 0;
	returnedFragments = 0;

	for ( i = 0 ; i < numsurfaces ; i++ ) {

		if (*surfaces[i] == SF_GRID) {

			cv = (srfGridMesh_t *) surfaces[i];
			for ( m = 0 ; m < cv->height - 1 ; m++ ) {
				for ( n = 0 ; n < cv->width - 1 ; n++ ) {
					// We triangulate the grid and chop all triangles within
					// the bounding planes of the to be projected polygon.
					// LOD is not taken into account, not such a big deal though.
					//
					// It's probably much nicer to chop the grid itself and deal
					// with this grid as a normal SF_GRID surface so LOD will
					// be applied. However the LOD of that chopped grid must
					// be synced with the LOD of the original curve.
					// One way to do this; the chopped grid shares vertices with
					// the original curve. When LOD is applied to the original
					// curve the unused vertices are flagged. Now the chopped curve
					// should skip the flagged vertices. This still leaves the
					// problems with the vertices at the chopped grid edges.
					//
					// To avoid issues when LOD applied to "hollow curves" (like
					// the ones around many jump pads) we now just add a 2 unit
					// offset to the triangle vertices.
					// The offset is added in the vertex normal vector direction
					// so all triangles will still fit together.
					// The 2 unit offset should avoid pretty much all LOD problems.

					numClipPoints = 3;

					dv = cv->verts + m * cv->width + n;

					VectorCopy(&dv[0].xyz, &clipPoints[0][0]);
					VectorMA(&clipPoints[0][0], MARKER_OFFSET, &dv[0].normal, &clipPoints[0][0]);
					VectorCopy(&dv[cv->width].xyz, &clipPoints[0][1]);
					VectorMA(&clipPoints[0][1], MARKER_OFFSET, &dv[cv->width].normal, &clipPoints[0][1]);
					VectorCopy(&dv[1].xyz, &clipPoints[0][2]);
					VectorMA(&clipPoints[0][2], MARKER_OFFSET, &dv[1].normal, &clipPoints[0][2]);
					// check the normal of this triangle
					VectorSubtract(&clipPoints[0][0], &clipPoints[0][1], &v1);
					VectorSubtract(&clipPoints[0][2], &clipPoints[0][1], &v2);
					CrossProduct(&v1, &v2, &normal);
					VectorNormalizeFast(&normal);
					if (DotProduct(&normal, &projectionDir) < -0.1f) {
						// add the fragments of this triangle
						R_AddMarkFragments(numClipPoints, clipPoints,
										   numPlanes, normals, dists,
										   maxPoints, pointBuffer,
										   maxFragments, fragmentBuffer,
										   &returnedPoints, &returnedFragments, &mins, &maxs);

						if ( returnedFragments == maxFragments ) {
							return returnedFragments;	// not enough space for more fragments
						}
					}

					VectorCopy(&dv[1].xyz, &clipPoints[0][0]);
					VectorMA(&clipPoints[0][0], MARKER_OFFSET, &dv[1].normal, &clipPoints[0][0]);
					VectorCopy(&dv[cv->width].xyz, &clipPoints[0][1]);
					VectorMA(&clipPoints[0][1], MARKER_OFFSET, &dv[cv->width].normal, &clipPoints[0][1]);
					VectorCopy(&dv[cv->width+1].xyz, &clipPoints[0][2]);
					VectorMA(&clipPoints[0][2], MARKER_OFFSET, &dv[cv->width+1].normal, &clipPoints[0][2]);
					// check the normal of this triangle
					VectorSubtract(&clipPoints[0][0], &clipPoints[0][1], &v1);
					VectorSubtract(&clipPoints[0][2], &clipPoints[0][1], &v2);
					CrossProduct(&v1, &v2, &normal);
					VectorNormalizeFast(&normal);
					if (DotProduct(&normal, &projectionDir) < -0.05f) {
						// add the fragments of this triangle
						R_AddMarkFragments(numClipPoints, clipPoints,
										   numPlanes, normals, dists,
										   maxPoints, pointBuffer,
										   maxFragments, fragmentBuffer,
										   &returnedPoints, &returnedFragments, &mins, &maxs);

						if ( returnedFragments == maxFragments ) {
							return returnedFragments;	// not enough space for more fragments
						}
					}
				}
			}
		}
		else if (*surfaces[i] == SF_FACE) {

			srfSurfaceFace_t *surf = ( srfSurfaceFace_t * ) surfaces[i];

			// check the normal of this face
			if (DotProduct(&surf->plane.normal, &projectionDir) > -0.5f) {
				continue;
			}

			indexes = (int *)( (byte *)surf + surf->ofsIndices );
			for ( k = 0 ; k < surf->numIndices ; k += 3 ) {
				for ( j = 0 ; j < 3 ; j++ ) {
					v = (vector3 *)(surf->points[0] + VERTEXSIZE * indexes[k+j]);
					VectorMA( v, MARKER_OFFSET, &surf->plane.normal, &clipPoints[0][j] );
				}

				// add the fragments of this face
				R_AddMarkFragments( 3 , clipPoints,
								   numPlanes, normals, dists,
								   maxPoints, pointBuffer,
								   maxFragments, fragmentBuffer,
								   &returnedPoints, &returnedFragments, &mins, &maxs);
				if ( returnedFragments == maxFragments ) {
					return returnedFragments;	// not enough space for more fragments
				}
			}
		}
		else if(*surfaces[i] == SF_TRIANGLES && r_marksOnTriangleMeshes->integer) {

			srfTriangles_t *surf = (srfTriangles_t *) surfaces[i];

			for (k = 0; k < surf->numIndexes; k += 3)
			{
				for(j = 0; j < 3; j++)
				{
					v = &surf->verts[surf->indexes[k + j]].xyz;
					VectorMA(v, MARKER_OFFSET, &surf->verts[surf->indexes[k + j]].normal, &clipPoints[0][j]);
				}

				// add the fragments of this face
				R_AddMarkFragments(3, clipPoints,
								   numPlanes, normals, dists,
								   maxPoints, pointBuffer,
								   maxFragments, fragmentBuffer, &returnedPoints, &returnedFragments, &mins, &maxs);
				if(returnedFragments == maxFragments)
				{
					return returnedFragments;	// not enough space for more fragments
				}
			}
		}
	}
	return returnedFragments;
}
Exemplo n.º 24
0
void C_EnergyWave::ComputePoint( float s, float t, Vector& pt, Vector& normal, float& opacity )
{
	int is = (int)s;
	int it = (int)t;
	if( is >= EWAVE_NUM_HORIZONTAL_POINTS )
		is -= 1;

	if( it >= EWAVE_NUM_VERTICAL_POINTS )
		it -= 1;

	int idx[16];
	ComputeIndices( is, it, idx );

	// The patch equation is:
	// px = S * M * Gx * M^T * T^T 
	// py = S * M * Gy * M^T * T^T 
	// pz = S * M * Gz * M^T * T^T 
	// where S = [s^3 s^2 s 1], T = [t^3 t^2 t 1]
	// M is the patch type matrix, in my case I'm using a catmull-rom
	// G is the array of control points. rows have constant t
	static VMatrix catmullRom( -0.5, 1.5, -1.5, 0.5,
								1, -2.5, 2, -0.5,
								-0.5, 0, 0.5, 0,
								0, 1, 0, 0 );

	VMatrix controlPointsX, controlPointsY, controlPointsZ, controlPointsO;

	Vector pos;
	for (int i = 0; i < 4; ++i)
	{
		for (int j = 0; j < 4; ++j)
		{
			const Vector& v = m_EWaveEffect.GetPoint( idx[i * 4 + j] );

			controlPointsX[j][i] = v.x;
			controlPointsY[j][i] = v.y;
			controlPointsZ[j][i] = v.z;

			controlPointsO[j][i] = m_EWaveEffect.ComputeOpacity( v, GetAbsOrigin() );
		}
	}

	float fs = s - is;
	float ft = t - it;

	VMatrix temp, mgm[4];
	MatrixTranspose( catmullRom, temp );
	MatrixMultiply( controlPointsX, temp, mgm[0] );
	MatrixMultiply( controlPointsY, temp, mgm[1] );
	MatrixMultiply( controlPointsZ, temp, mgm[2] );
	MatrixMultiply( controlPointsO, temp, mgm[3] );

	MatrixMultiply( catmullRom, mgm[0], mgm[0] );
	MatrixMultiply( catmullRom, mgm[1], mgm[1] );
	MatrixMultiply( catmullRom, mgm[2], mgm[2] );
	MatrixMultiply( catmullRom, mgm[3], mgm[3] );

	Vector4D svec, tvec;
	float ft2 = ft * ft;
	tvec[0] = ft2 * ft; tvec[1] = ft2; tvec[2] = ft; tvec[3] = 1.0f;

 	float fs2 = fs * fs;
	svec[0] = fs2 * fs; svec[1] = fs2; svec[2] = fs; svec[3] = 1.0f;

	Vector4D tmp;
	Vector4DMultiply( mgm[0], tvec, tmp );
	pt[0] = DotProduct4D( tmp, svec );
	Vector4DMultiply( mgm[1], tvec, tmp );
	pt[1] = DotProduct4D( tmp, svec );
	Vector4DMultiply( mgm[2], tvec, tmp );
	pt[2] = DotProduct4D( tmp, svec );

	Vector4DMultiply( mgm[3], tvec, tmp );
	opacity = DotProduct4D( tmp, svec );

	if ((s == 0.0f) || (t == 0.0f) ||
		(s == (EWAVE_NUM_HORIZONTAL_POINTS-1.0f)) || (t == (EWAVE_NUM_VERTICAL_POINTS-1.0f)) )
	{
		opacity = 0.0f;
	}

	if ((s <= 0.3) || (t < 0.3))
	{
		opacity *= 0.35f;
	}
	if ((s == (EWAVE_NUM_HORIZONTAL_POINTS-0.7f)) || (t == (EWAVE_NUM_VERTICAL_POINTS-0.7f)) )
	{
		opacity *= 0.35f;
	}

	if (opacity < 0.0f)
		opacity = 0.0f;
	else if (opacity > 255.0f)
		opacity = 255.0f;

	// Normal computation
	Vector4D dsvec, dtvec;
	dsvec[0] = 3.0f * fs2; dsvec[1] = 2.0f * fs; dsvec[2] = 1.0f; dsvec[3] = 0.0f;
	dtvec[0] = 3.0f * ft2; dtvec[1] = 2.0f * ft; dtvec[2] = 1.0f; dtvec[3] = 0.0f;

	Vector ds, dt;
	Vector4DMultiply( mgm[0], tvec, tmp );
	ds[0] = DotProduct4D( tmp, dsvec );
	Vector4DMultiply( mgm[1], tvec, tmp );
	ds[1] = DotProduct4D( tmp, dsvec );
	Vector4DMultiply( mgm[2], tvec, tmp );
	ds[2] = DotProduct4D( tmp, dsvec );

	Vector4DMultiply( mgm[0], dtvec, tmp );
	dt[0] = DotProduct4D( tmp, svec );
	Vector4DMultiply( mgm[1], dtvec, tmp );
	dt[1] = DotProduct4D( tmp, svec );
	Vector4DMultiply( mgm[2], dtvec, tmp );
	dt[2] = DotProduct4D( tmp, svec );

	CrossProduct( ds, dt, normal );
	VectorNormalize( normal );
}
Exemplo n.º 25
0
/*
=============
DeformText

Change a polygon into a bunch of text polygons
=============
*/
void DeformText( const char *text )
{
	int    i;
	vec3_t origin, width, height;
	int    len;
	int    ch;
	byte   color[ 4 ];
	float  bottom, top;
	vec3_t mid;

	height[ 0 ] = 0;
	height[ 1 ] = 0;
	height[ 2 ] = -1;
	CrossProduct( tess.normal[ 0 ].v, height, width );

	// find the midpoint of the box
	VectorClear( mid );
	bottom = 999999;
	top = -999999;

	for ( i = 0; i < 4; i++ )
	{
		VectorAdd( tess.xyz[ i ].v, mid, mid );

		if ( tess.xyz[ i ].v[ 2 ] < bottom )
		{
			bottom = tess.xyz[ i ].v[ 2 ];
		}

		if ( tess.xyz[ i ].v[ 2 ] > top )
		{
			top = tess.xyz[ i ].v[ 2 ];
		}
	}

	VectorScale( mid, 0.25f, origin );

	// determine the individual character size
	height[ 0 ] = 0;
	height[ 1 ] = 0;
	height[ 2 ] = ( top - bottom ) * 0.5f;

	VectorScale( width, height[ 2 ] * -0.75f, width );

	// determine the starting position
	len = strlen( text );
	VectorMA( origin, ( len - 1 ), width, origin );

	// clear the shader indexes
	tess.numIndexes = 0;
	tess.numVertexes = 0;

	color[ 0 ] = color[ 1 ] = color[ 2 ] = color[ 3 ] = 255;

	// draw each character
	for ( i = 0; i < len; i++ )
	{
		ch = text[ i ];
		ch &= 255;

		if ( ch != ' ' )
		{
			int   row, col;
			float frow, fcol, size;

			row = ch >> 4;
			col = ch & 15;

			frow = row * 0.0625f;
			fcol = col * 0.0625f;
			size = 0.0625f;

			RB_AddQuadStampExt( origin, width, height, color, fcol, frow, fcol + size, frow + size );
		}

		VectorMA( origin, -2, width, origin );
	}
Exemplo n.º 26
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pFluid - 
//			*pObject - 
//			*pEntity - 
//-----------------------------------------------------------------------------
void PhysicsSplash( IPhysicsFluidController *pFluid, IPhysicsObject *pObject, CBaseEntity *pEntity )
{
	//FIXME: For now just allow ragdolls for E3 - jdw
	if ( ( pObject->GetGameFlags() & FVPHYSICS_PART_OF_RAGDOLL ) == false )
		return;

	Vector velocity;
	pObject->GetVelocity( &velocity, NULL );
	
	float impactSpeed = velocity.Length();

	if ( impactSpeed < 25.0f )
		return;

	Vector normal;
	float dist;
	pFluid->GetSurfacePlane( &normal, &dist );

	matrix3x4_t &matrix = pEntity->EntityToWorldTransform();
	
	// Find the local axis that best matches the water surface normal
	int bestAxis = BestAxisMatchingNormal( matrix, normal );

	Vector tangent, binormal;
	MatrixGetColumn( matrix, (bestAxis+1)%3, tangent );
	binormal = CrossProduct( normal, tangent );
	VectorNormalize( binormal );
	tangent = CrossProduct( binormal, normal );
	VectorNormalize( tangent );

	// Now we have a basis tangent to the surface that matches the object's local orientation as well as possible
	// compute an OBB using this basis
	
	// Get object extents in basis
	Vector tanPts[2], binPts[2];
	tanPts[0] = physcollision->CollideGetExtent( pObject->GetCollide(), pEntity->GetAbsOrigin(), pEntity->GetAbsAngles(), -tangent );
	tanPts[1] = physcollision->CollideGetExtent( pObject->GetCollide(), pEntity->GetAbsOrigin(), pEntity->GetAbsAngles(), tangent );
	binPts[0] = physcollision->CollideGetExtent( pObject->GetCollide(), pEntity->GetAbsOrigin(), pEntity->GetAbsAngles(), -binormal );
	binPts[1] = physcollision->CollideGetExtent( pObject->GetCollide(), pEntity->GetAbsOrigin(), pEntity->GetAbsAngles(), binormal );

	// now compute the centered bbox
	float mins[2], maxs[2], center[2], extents[2];
	mins[0] = DotProduct( tanPts[0], tangent );
	maxs[0] = DotProduct( tanPts[1], tangent );

	mins[1] = DotProduct( binPts[0], binormal );
	maxs[1] = DotProduct( binPts[1], binormal );

	center[0] = 0.5 * (mins[0] + maxs[0]);
	center[1] = 0.5 * (mins[1] + maxs[1]);

	extents[0] = maxs[0] - center[0];
	extents[1] = maxs[1] - center[1];

	Vector centerPoint = center[0] * tangent + center[1] * binormal + dist * normal;

	Vector axes[2];
	axes[0] = (maxs[0] - center[0]) * tangent;
	axes[1] = (maxs[1] - center[1]) * binormal;

	// visualize OBB hit
	/*
	Vector corner1 = centerPoint - axes[0] - axes[1];
	Vector corner2 = centerPoint + axes[0] - axes[1];
	Vector corner3 = centerPoint + axes[0] + axes[1];
	Vector corner4 = centerPoint - axes[0] + axes[1];
	NDebugOverlay::Line( corner1, corner2, 0, 0, 255, false, 10 );
	NDebugOverlay::Line( corner2, corner3, 0, 0, 255, false, 10 );
	NDebugOverlay::Line( corner3, corner4, 0, 0, 255, false, 10 );
	NDebugOverlay::Line( corner4, corner1, 0, 0, 255, false, 10 );
	*/

	Vector	corner[4];

	corner[0] = centerPoint - axes[0] - axes[1];
	corner[1] = centerPoint + axes[0] - axes[1];
	corner[2] = centerPoint + axes[0] + axes[1];
	corner[3] = centerPoint - axes[0] + axes[1];

	int contents = enginetrace->GetPointContents( centerPoint-Vector(0,0,2) );

	bool bInSlime = ( contents & CONTENTS_SLIME ) ? true : false;

	Vector	color = vec3_origin;
	float	luminosity = 1.0f;
	
	if ( !bInSlime )
	{
		// Get our lighting information
		FX_GetSplashLighting( centerPoint + ( normal * 8.0f ), &color, &luminosity );
	}

	if ( impactSpeed > 150 )
	{
		if ( bInSlime )
		{
			FX_GunshotSlimeSplash( centerPoint, normal, random->RandomFloat( 8, 10 ) );
		}
		else
		{
			FX_GunshotSplash( centerPoint, normal, random->RandomFloat( 8, 10 ) );
		}
	}
	else if ( !bInSlime )
	{
		FX_WaterRipple( centerPoint, 1.5f, &color, 1.5f, luminosity );
	}
	
	int		splashes = 4;
	Vector	point;

	for ( int i = 0; i < splashes; i++ )
	{
		point = RandomVector( -32.0f, 32.0f );
		point[2] = 0.0f;

		point += corner[i];

		if ( impactSpeed > 150 )
		{
			if ( bInSlime )
			{
				FX_GunshotSlimeSplash( centerPoint, normal, random->RandomFloat( 4, 6 ) );
			}
			else
			{
				FX_GunshotSplash( centerPoint, normal, random->RandomFloat( 4, 6 ) );
			}
		}
		else if ( !bInSlime )
		{
			FX_WaterRipple( point, random->RandomFloat( 0.25f, 0.5f ), &color, luminosity, random->RandomFloat( 0.5f, 1.0f ) );
		}
	}
}
Exemplo n.º 27
0
/*
=================
R_MarkFragments

=================
*/
int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projection,
				   int maxPoints, vec3_t pointBuffer, int maxFragments, markFragment_t *fragmentBuffer ) {
	int				numsurfaces, numPlanes;
	int				i, j, k, m, n;
	surfaceType_t	*surfaces[64];
	vec3_t			mins, maxs;
	int				returnedFragments;
	int				returnedPoints;
	vec3_t			normals[MAX_VERTS_ON_POLY+2];
	float			dists[MAX_VERTS_ON_POLY+2];
	vec3_t			clipPoints[2][MAX_VERTS_ON_POLY];
	int				numClipPoints;
	float			*v;
	srfSurfaceFace_t *surf;
	srfGridMesh_t	*cv;
	drawVert_t		*dv;
	vec3_t			normal;
	vec3_t			projectionDir;
	vec3_t			v1, v2;
	int				*indexes;

	//increment view count for double check prevention
	tr.viewCount++;

	//
	VectorNormalize2( projection, projectionDir );
	// find all the brushes that are to be considered
	ClearBounds( mins, maxs );
	for ( i = 0 ; i < numPoints ; i++ ) {
		vec3_t	temp;

		AddPointToBounds( points[i], mins, maxs );
		VectorAdd( points[i], projection, temp );
		AddPointToBounds( temp, mins, maxs );
		// make sure we get all the leafs (also the one(s) in front of the hit surface)
		VectorMA( points[i], -20, projectionDir, temp );
		AddPointToBounds( temp, mins, maxs );
	}

	if (numPoints > MAX_VERTS_ON_POLY) numPoints = MAX_VERTS_ON_POLY;
	// create the bounding planes for the to be projected polygon
	for ( i = 0 ; i < numPoints ; i++ ) {
		VectorSubtract(points[(i+1)%numPoints], points[i], v1);
		VectorAdd(points[i], projection, v2);
		VectorSubtract(points[i], v2, v2);
		CrossProduct(v1, v2, normals[i]);
		VectorNormalizeFast(normals[i]);
		dists[i] = DotProduct(normals[i], points[i]);
	}
	// add near and far clipping planes for projection
	VectorCopy(projectionDir, normals[numPoints]);
	dists[numPoints] = DotProduct(normals[numPoints], points[0]) - 32;
	VectorCopy(projectionDir, normals[numPoints+1]);
	VectorInverse(normals[numPoints+1]);
	dists[numPoints+1] = DotProduct(normals[numPoints+1], points[0]) - 20;
	numPlanes = numPoints + 2;

	numsurfaces = 0;
	R_BoxSurfaces_r(tr.world->nodes, mins, maxs, surfaces, 64, &numsurfaces, projectionDir);
	//assert(numsurfaces <= 64);
	//assert(numsurfaces != 64);

	returnedPoints = 0;
	returnedFragments = 0;

	for ( i = 0 ; i < numsurfaces ; i++ ) {

		if (*surfaces[i] == SF_GRID) {

			cv = (srfGridMesh_t *) surfaces[i];
			for ( m = 0 ; m < cv->height - 1 ; m++ ) {
				for ( n = 0 ; n < cv->width - 1 ; n++ ) {
					// We triangulate the grid and chop all triangles within
					// the bounding planes of the to be projected polygon.
					// LOD is not taken into account, not such a big deal though.
					//
					// It's probably much nicer to chop the grid itself and deal
					// with this grid as a normal SF_GRID surface so LOD will
					// be applied. However the LOD of that chopped grid must
					// be synced with the LOD of the original curve.
					// One way to do this; the chopped grid shares vertices with
					// the original curve. When LOD is applied to the original
					// curve the unused vertices are flagged. Now the chopped curve
					// should skip the flagged vertices. This still leaves the
					// problems with the vertices at the chopped grid edges.
					//
					// To avoid issues when LOD applied to "hollow curves" (like
					// the ones around many jump pads) we now just add a 2 unit
					// offset to the triangle vertices.
					// The offset is added in the vertex normal vector direction
					// so all triangles will still fit together.
					// The 2 unit offset should avoid pretty much all LOD problems.

					numClipPoints = 3;

					dv = cv->verts + m * cv->width + n;

					VectorCopy(dv[0].xyz, clipPoints[0][0]);
					VectorMA(clipPoints[0][0], MARKER_OFFSET, dv[0].normal, clipPoints[0][0]);
					VectorCopy(dv[cv->width].xyz, clipPoints[0][1]);
					VectorMA(clipPoints[0][1], MARKER_OFFSET, dv[cv->width].normal, clipPoints[0][1]);
					VectorCopy(dv[1].xyz, clipPoints[0][2]);
					VectorMA(clipPoints[0][2], MARKER_OFFSET, dv[1].normal, clipPoints[0][2]);
					// check the normal of this triangle
					VectorSubtract(clipPoints[0][0], clipPoints[0][1], v1);
					VectorSubtract(clipPoints[0][2], clipPoints[0][1], v2);
					CrossProduct(v1, v2, normal);
					VectorNormalizeFast(normal);
					if (DotProduct(normal, projectionDir) < -0.1) {
						// add the fragments of this triangle
						R_AddMarkFragments(numClipPoints, clipPoints,
										   numPlanes, normals, dists,
										   maxPoints, pointBuffer,
										   maxFragments, fragmentBuffer,
										   &returnedPoints, &returnedFragments, mins, maxs);

						if ( returnedFragments == maxFragments ) {
							return returnedFragments;	// not enough space for more fragments
						}
					}

					VectorCopy(dv[1].xyz, clipPoints[0][0]);
					VectorMA(clipPoints[0][0], MARKER_OFFSET, dv[1].normal, clipPoints[0][0]);
					VectorCopy(dv[cv->width].xyz, clipPoints[0][1]);
					VectorMA(clipPoints[0][1], MARKER_OFFSET, dv[cv->width].normal, clipPoints[0][1]);
					VectorCopy(dv[cv->width+1].xyz, clipPoints[0][2]);
					VectorMA(clipPoints[0][2], MARKER_OFFSET, dv[cv->width+1].normal, clipPoints[0][2]);
					// check the normal of this triangle
					VectorSubtract(clipPoints[0][0], clipPoints[0][1], v1);
					VectorSubtract(clipPoints[0][2], clipPoints[0][1], v2);
					CrossProduct(v1, v2, normal);
					VectorNormalizeFast(normal);
					if (DotProduct(normal, projectionDir) < -0.05) {
						// add the fragments of this triangle
						R_AddMarkFragments(numClipPoints, clipPoints,
										   numPlanes, normals, dists,
										   maxPoints, pointBuffer,
										   maxFragments, fragmentBuffer,
										   &returnedPoints, &returnedFragments, mins, maxs);

						if ( returnedFragments == maxFragments ) {
							return returnedFragments;	// not enough space for more fragments
						}
					}
				}
			}
		}
		else if (*surfaces[i] == SF_FACE) {

			surf = ( srfSurfaceFace_t * ) surfaces[i];
			// check the normal of this face
			if (DotProduct(surf->plane.normal, projectionDir) > -0.5) {
				continue;
			}

			/*
			VectorSubtract(clipPoints[0][0], clipPoints[0][1], v1);
			VectorSubtract(clipPoints[0][2], clipPoints[0][1], v2);
			CrossProduct(v1, v2, normal);
			VectorNormalize(normal);
			if (DotProduct(normal, projectionDir) > -0.5) continue;
			*/
#ifdef _XBOX
			const unsigned char * const indexes = (unsigned char *)( (byte *)surf + surf->ofsIndices );
			int nextSurfPoint = NEXT_SURFPOINT(surf->flags);
#else
			indexes = (int *)( (byte *)surf + surf->ofsIndices );
#endif
			for ( k = 0 ; k < surf->numIndices ; k += 3 ) {
				for ( j = 0 ; j < 3 ; j++ ) {
#ifdef _XBOX
					const unsigned short* v = surf->srfPoints + nextSurfPoint * indexes[k+j];
					float fVec[3];
					Q_CastShort2Float(&fVec[0], (short*)v + 0);
					Q_CastShort2Float(&fVec[1], (short*)v + 1);
					Q_CastShort2Float(&fVec[2], (short*)v + 2);
					VectorMA( fVec, MARKER_OFFSET, surf->plane.normal, clipPoints[0][j] );
#else
					v = surf->points[0] + VERTEXSIZE * indexes[k+j];;
					VectorMA( v, MARKER_OFFSET, surf->plane.normal, clipPoints[0][j] );
#endif
				}
				// add the fragments of this face
				R_AddMarkFragments( 3 , clipPoints,
								   numPlanes, normals, dists,
								   maxPoints, pointBuffer,
								   maxFragments, fragmentBuffer,
								   &returnedPoints, &returnedFragments, mins, maxs);
				if ( returnedFragments == maxFragments ) {
					return returnedFragments;	// not enough space for more fragments
				}
			}
			continue;
		}
		else {
			// ignore all other world surfaces
			// might be cool to also project polygons on a triangle soup
			// however this will probably create huge amounts of extra polys
			// even more than the projection onto curves
			continue;
		}
	}
	return returnedFragments;
}
Exemplo n.º 28
0
/*
** RB_DrawSun
*/
void RB_DrawSun( void )
{
#if 0
	float    size;
	float    dist;
	vec3_t   origin, vec1, vec2;
	vec3_t   temp;
	matrix_t transformMatrix;
	matrix_t modelViewMatrix;

	if ( !backEnd.skyRenderedThisView )
	{
		return;
	}

	if ( !r_drawSun->integer )
	{
		return;
	}

	GL_PushMatrix();

	GL_BindProgram( &tr.genericShader );

	// set uniforms
	GLSL_SetUniform_TCGen_Environment( &tr.genericShader,  qfalse );
	GLSL_SetUniform_InverseVertexColor( &tr.genericShader,  qfalse );

	if ( glConfig2.vboVertexSkinningAvailable )
	{
		GLSL_SetUniform_VertexSkinning( &tr.genericShader, qfalse );
	}

	GLSL_SetUniform_DeformGen( &tr.genericShader, DGEN_NONE );
	GLSL_SetUniform_AlphaTest( &tr.genericShader, -1.0 );

	MatrixSetupTranslation( transformMatrix, backEnd.viewParms.orientation.origin[ 0 ], backEnd.viewParms.orientation.origin[ 1 ],
	                        backEnd.viewParms.orientation.origin[ 2 ] );
	MatrixMultiply( backEnd.viewParms.world.viewMatrix, transformMatrix, modelViewMatrix );

	GL_LoadProjectionMatrix( backEnd.viewParms.projectionMatrix );
	GL_LoadModelViewMatrix( modelViewMatrix );

	GLSL_SetUniform_ModelMatrix( &tr.genericShader, backEnd.orientation.transformMatrix );
	GLSL_SetUniform_ModelViewProjectionMatrix( &tr.genericShader, glState.modelViewProjectionMatrix[ glState.stackIndex ] );

	GLSL_SetUniform_PortalClipping( &tr.genericShader, backEnd.viewParms.isPortal );

	if ( backEnd.viewParms.isPortal )
	{
		float plane[ 4 ];

		// clipping plane in world space
		plane[ 0 ] = backEnd.viewParms.portalPlane.normal[ 0 ];
		plane[ 1 ] = backEnd.viewParms.portalPlane.normal[ 1 ];
		plane[ 2 ] = backEnd.viewParms.portalPlane.normal[ 2 ];
		plane[ 3 ] = backEnd.viewParms.portalPlane.dist;

		GLSL_SetUniform_PortalPlane( &tr.genericShader, plane );
	}

	dist = backEnd.viewParms.skyFar / 1.75; // div sqrt(3)
	size = dist * 0.4;

	VectorScale( tr.sunDirection, dist, origin );
	PerpendicularVector( vec1, tr.sunDirection );
	CrossProduct( tr.sunDirection, vec1, vec2 );

	VectorScale( vec1, size, vec1 );
	VectorScale( vec2, size, vec2 );

	// farthest depth range
	glDepthRange( 1.0, 1.0 );

	// FIXME: use quad stamp
	Tess_Begin( Tess_StageIteratorGeneric, tr.sunShader, NULL, tess.skipTangentSpaces, qfalse, -1, tess.fogNum );
	VectorCopy( origin, temp );
	VectorSubtract( temp, vec1, temp );
	VectorSubtract( temp, vec2, temp );
	VectorCopy( temp, tess.xyz[ tess.numVertexes ] );
	tess.xyz[ tess.numVertexes ][ 3 ] = 1;
	tess.texCoords[ tess.numVertexes ][ 0 ] = 0;
	tess.texCoords[ tess.numVertexes ][ 1 ] = 0;
	tess.colors[ tess.numVertexes ][ 0 ] = 1;
	tess.colors[ tess.numVertexes ][ 1 ] = 1;
	tess.colors[ tess.numVertexes ][ 2 ] = 1;
	tess.numVertexes++;

	VectorCopy( origin, temp );
	VectorAdd( temp, vec1, temp );
	VectorSubtract( temp, vec2, temp );
	VectorCopy( temp, tess.xyz[ tess.numVertexes ] );
	tess.xyz[ tess.numVertexes ][ 3 ] = 1;
	tess.texCoords[ tess.numVertexes ][ 0 ] = 0;
	tess.texCoords[ tess.numVertexes ][ 1 ] = 1;
	tess.colors[ tess.numVertexes ][ 0 ] = 1;
	tess.colors[ tess.numVertexes ][ 1 ] = 1;
	tess.colors[ tess.numVertexes ][ 2 ] = 1;
	tess.numVertexes++;

	VectorCopy( origin, temp );
	VectorAdd( temp, vec1, temp );
	VectorAdd( temp, vec2, temp );
	VectorCopy( temp, tess.xyz[ tess.numVertexes ] );
	tess.xyz[ tess.numVertexes ][ 3 ] = 1;
	tess.texCoords[ tess.numVertexes ][ 0 ] = 1;
	tess.texCoords[ tess.numVertexes ][ 1 ] = 1;
	tess.colors[ tess.numVertexes ][ 0 ] = 1;
	tess.colors[ tess.numVertexes ][ 1 ] = 1;
	tess.colors[ tess.numVertexes ][ 2 ] = 1;
	tess.numVertexes++;

	VectorCopy( origin, temp );
	VectorSubtract( temp, vec1, temp );
	VectorAdd( temp, vec2, temp );
	VectorCopy( temp, tess.xyz[ tess.numVertexes ] );
	tess.xyz[ tess.numVertexes ][ 3 ] = 1;
	tess.texCoords[ tess.numVertexes ][ 0 ] = 1;
	tess.texCoords[ tess.numVertexes ][ 1 ] = 0;
	tess.colors[ tess.numVertexes ][ 0 ] = 1;
	tess.colors[ tess.numVertexes ][ 1 ] = 1;
	tess.colors[ tess.numVertexes ][ 2 ] = 1;
	tess.numVertexes++;

	tess.indexes[ tess.numIndexes++ ] = 0;
	tess.indexes[ tess.numIndexes++ ] = 1;
	tess.indexes[ tess.numIndexes++ ] = 2;
	tess.indexes[ tess.numIndexes++ ] = 0;
	tess.indexes[ tess.numIndexes++ ] = 2;
	tess.indexes[ tess.numIndexes++ ] = 3;

	Tess_End();

	// back to standard depth range
	glDepthRange( 0.0, 1.0 );

	GL_PopMatrix();
#endif
}
Exemplo n.º 29
0
void CG_AddScorePlum( localEntity_t *le ) {
	refEntity_t	*re;
	vec3_t		origin, delta, dir, vec, up = {0, 0, 1};
	float		c, len;
	int			i, score, digits[10], numdigits, negative;

	re = &le->refEntity;

	c = ( le->endTime - cg.time ) * le->lifeRate;

	score = le->radius;
	if (score < 0) {
		re->shaderRGBA[0] = 0xff;
		re->shaderRGBA[1] = 0x11;
		re->shaderRGBA[2] = 0x11;
	}
	else {
		re->shaderRGBA[0] = 0xff;
		re->shaderRGBA[1] = 0xff;
		re->shaderRGBA[2] = 0xff;
		if (score >= 50) {
			re->shaderRGBA[1] = 0;
		} else if (score >= 20) {
			re->shaderRGBA[0] = re->shaderRGBA[1] = 0;
		} else if (score >= 10) {
			re->shaderRGBA[2] = 0;
		} else if (score >= 2) {
			re->shaderRGBA[0] = re->shaderRGBA[2] = 0;
		}

	}
	if (c < 0.25)
		re->shaderRGBA[3] = 0xff * 4 * c;
	else
		re->shaderRGBA[3] = 0xff;

	re->radius = NUMBER_SIZE / 2;

	VectorCopy(le->pos.trBase, origin);
	origin[2] += 110 - c * 100;

	VectorSubtract(cg.refdef.vieworg, origin, dir);
	CrossProduct(dir, up, vec);
	VectorNormalize(vec);

	VectorMA(origin, -10 + 20 * sin(c * 2 * M_PI), vec, origin);

	// if the view would be "inside" the sprite, kill the sprite
	// so it doesn't add too much overdraw
	VectorSubtract( origin, cg.refdef.vieworg, delta );
	len = VectorLength( delta );
	if ( len < 20 ) {
		CG_FreeLocalEntity( le );
		return;
	}

	negative = qfalse;
	if (score < 0) {
		negative = qtrue;
		score = -score;
	}

	for (numdigits = 0; !(numdigits && !score); numdigits++) {
		digits[numdigits] = score % 10;
		score = score / 10;
	}

	if (negative) {
		digits[numdigits] = 10;
		numdigits++;
	}

	for (i = 0; i < numdigits; i++) {
		VectorMA(origin, (float) (((float) numdigits / 2) - i) * NUMBER_SIZE, vec, re->origin);
		re->customShader = cgs.media.numberShaders[digits[numdigits-1-i]];
		trap_R_AddRefEntityToScene( re );
	}
}
Exemplo n.º 30
0
/*
   =================
   MakeMeshNormals

   =================
 */
void MakeMeshNormals( mesh_t in ){
	int i, j, k, dist;
	vec3_t normal;
	vec3_t sum;
	int count;
	vec3_t base;
	vec3_t delta;
	int x, y;
	bspDrawVert_t   *dv;
	vec3_t around[8], temp;
	qboolean good[8];
	qboolean wrapWidth, wrapHeight;
	float len;
	int neighbors[8][2] =
	{
		{0,1}, {1,1}, {1,0}, {1,-1}, {0,-1}, {-1,-1}, {-1,0}, {-1,1}
	};


	wrapWidth = qfalse;
	for ( i = 0 ; i < in.height ; i++ ) {
		VectorSubtract( in.verts[i * in.width].xyz,
						in.verts[i * in.width + in.width - 1].xyz, delta );
		len = VectorLength( delta );
		if ( len > 1.0 ) {
			break;
		}
	}
	if ( i == in.height ) {
		wrapWidth = qtrue;
	}

	wrapHeight = qfalse;
	for ( i = 0 ; i < in.width ; i++ ) {
		VectorSubtract( in.verts[i].xyz,
						in.verts[i + ( in.height - 1 ) * in.width].xyz, delta );
		len = VectorLength( delta );
		if ( len > 1.0 ) {
			break;
		}
	}
	if ( i == in.width ) {
		wrapHeight = qtrue;
	}


	for ( i = 0 ; i < in.width ; i++ ) {
		for ( j = 0 ; j < in.height ; j++ ) {
			count = 0;
			dv = &in.verts[j * in.width + i];
			VectorCopy( dv->xyz, base );
			for ( k = 0 ; k < 8 ; k++ ) {
				VectorClear( around[k] );
				good[k] = qfalse;

				for ( dist = 1 ; dist <= 3 ; dist++ ) {
					x = i + neighbors[k][0] * dist;
					y = j + neighbors[k][1] * dist;
					if ( wrapWidth ) {
						if ( x < 0 ) {
							x = in.width - 1 + x;
						}
						else if ( x >= in.width ) {
							x = 1 + x - in.width;
						}
					}
					if ( wrapHeight ) {
						if ( y < 0 ) {
							y = in.height - 1 + y;
						}
						else if ( y >= in.height ) {
							y = 1 + y - in.height;
						}
					}

					if ( x < 0 || x >= in.width || y < 0 || y >= in.height ) {
						break;                  // edge of patch
					}
					VectorSubtract( in.verts[y * in.width + x].xyz, base, temp );
					if ( VectorNormalize( temp, temp ) == 0 ) {
						continue;               // degenerate edge, get more dist
					}
					else {
						good[k] = qtrue;
						VectorCopy( temp, around[k] );
						break;                  // good edge
					}
				}
			}

			VectorClear( sum );
			for ( k = 0 ; k < 8 ; k++ ) {
				if ( !good[k] || !good[( k + 1 ) & 7] ) {
					continue;   // didn't get two points
				}
				CrossProduct( around[( k + 1 ) & 7], around[k], normal );
				if ( VectorNormalize( normal, normal ) == 0 ) {
					continue;
				}
				VectorAdd( normal, sum, sum );
				count++;
			}
			if ( count == 0 ) {
//Sys_Printf("bad normal\n");
				count = 1;
			}
			VectorNormalize( sum, dv->normal );
		}
	}
}