コード例 #1
0
ファイル: cl_localentity.cpp プロジェクト: yason/ufoai
/**
 * @brief Slides a door
 *
 * @note Though doors, sliding doors need a very different handling:
 * because it's movement is animated (unlike the rotating door),
 * the final position that is used to calculate the routing data
 * is set once the animation finished (because this recalculation
 * might be very expensive).
 *
 * @param[in,out] le The local entity of the inline model
 * @param[in] speed The speed to slide with - a negative value to close the door
 * @sa Door_SlidingUse
 */
void LET_SlideDoor (le_t* le, int speed)
{
	vec3_t moveAngles, moveDir;

	/* get the movement angle vector */
	GET_SLIDING_DOOR_SHIFT_VECTOR(le->dir, speed, moveAngles);

	/* this origin is only an offset to the absolute mins/maxs for rendering */
	VectorAdd(le->origin, moveAngles, le->origin);

	/* get the direction vector from the movement angles that were set on the entity */
	AngleVectors(moveAngles, moveDir, nullptr, nullptr);
	moveDir[0] = fabsf(moveDir[0]);
	moveDir[1] = fabsf(moveDir[1]);
	moveDir[2] = fabsf(moveDir[2]);
	/* calculate the distance from the movement angles and the entity size */
	const int distance = DotProduct(moveDir, le->size);

	bool endPos = false;
	if (speed > 0) {
		/* check whether the distance the door may slide is slided already
		 * - if so, stop the movement of the door */
		if (fabs(le->origin[le->dir & 3]) >= distance)
			endPos = true;
	} else {
		/* the sliding door has not origin set - except when it is opened. This door type is no
		 * origin brush based bmodel entity. So whenever the origin vector is not the zero vector,
		 * the door is opened. */
		if (VectorEmpty(le->origin))
			endPos = true;
	}

	if (endPos) {
		vec3_t distanceVec;
		/* the door finished its move - either close or open, so make sure to recalc the routing
		 * data and set the mins/maxs for the inline brush model */
		cBspModel_t* model = CM_InlineModel(cl.mapTiles, le->inlineModelName);

		assert(model);

		/* we need the angles vector normalized */
		GET_SLIDING_DOOR_SHIFT_VECTOR(le->dir, (speed < 0) ? -1 : 1, moveAngles);

		/* the bounding box of the door is updated in one step - here is no lerping needed */
		VectorMul(distance, moveAngles, distanceVec);

		model->cbmBox.shift(distanceVec);
		CL_RecalcRouting(le);

		/* reset the think function as the movement finished */
		LE_SetThink(le, nullptr);
	} else
		le->thinkDelay = 1000;
}
コード例 #2
0
ファイル: aabb.cpp プロジェクト: ArkyRomania/ufoai
/**
 * @brief Rotates AABB around given origin point; note that it will expand the box unless all angles are multiples of 90 degrees
 * @note Not fully verified so far
 */
void AABB::rotateAround (const vec3_t origin, const vec3_t angles) {
	/* reject non-rotations */
	if (VectorEmpty(angles))
		return;

	/* construct box-centered coordinates (center and corners) */
	vec3_t center, halfDiagonal;

	VectorInterpolation(mins, maxs, 0.5f, center);
	VectorSubtract(maxs, center, halfDiagonal);

	/* offset coordinate frame to rotation origin */
	VectorSubtract(center, origin, center);

	/* rotate center by given angles */
	vec3_t m[3];
	VectorCreateRotationMatrix(angles, m);

	vec3_t newCenter;
	VectorRotate(m, center, newCenter);

	/* short-circuit calculation of the rotated box half-extents */
	/* shortcut is: instead of calculating all 8 AABB corners, use the symmetry by rotating box around it's center. */
	VectorAbs(m[0]);
	VectorAbs(m[1]);
	VectorAbs(m[2]);

	vec3_t newHalfDiagonal;
	VectorRotate(m, halfDiagonal, newHalfDiagonal);

	/* de-offset coordinate frame from rotation origin */
	VectorAdd(newCenter, origin, newCenter);

	/* finally, combine results into new AABB */
	VectorAdd(newCenter, newHalfDiagonal, maxs);
	VectorSubtract(newCenter, newHalfDiagonal, mins);
}
コード例 #3
0
ファイル: symbols.c プロジェクト: gligneul/Monga-Language
void SymbolsAdd(char* identifier, AstDeclaration* declaration, int line)
{
    int current = 0;
    int last = 0;
    Symbol* new_symbol = NULL;

    if (!symbols)
        init();

    /* Verifies if this declaration shadows a symbol in the current block */
    if (!VectorEmpty(blocks))
        last = (int)(intptr_t)VectorPeek(blocks);
    for (current = VectorSize(symbols) - 1; current >= last; current--) {
        Symbol* symbol = (Symbol*)VectorGet(symbols, current);
        if (symbol->identifier == identifier)
            ErrorL(line, "symbol '%s' is already declared", identifier);
    }

    /* Inserts the the symbol */
    new_symbol = NEW(Symbol);
    new_symbol->identifier = identifier;
    new_symbol->declaration = declaration;
    VectorPush(symbols, new_symbol);
}
コード例 #4
0
ファイル: gl_world.c プロジェクト: Bad-ptr/q2pro
void GL_DrawBspModel( mmodel_t *model ) {
    mface_t *face;
    int count, mask = 0;
    vec3_t bounds[2];
    vec_t dot;
    vec3_t transformed, temp;
    entity_t *ent = glr.ent;
    glCullResult_t cull;

    if( glr.entrotated ) {
        cull = GL_CullSphere( ent->origin, model->radius );
        if( cull == CULL_OUT ) {
            c.spheresCulled++;
            return;
        }
        if( cull == CULL_CLIP ) {
            VectorCopy( model->mins, bounds[0] );
            VectorCopy( model->maxs, bounds[1] );
            cull = GL_CullLocalBox( ent->origin, bounds );
            if( cull == CULL_OUT ) {
                c.rotatedBoxesCulled++;
                return;
            }
        }
        VectorSubtract( glr.fd.vieworg, ent->origin, temp );
        transformed[0] = DotProduct( temp, glr.entaxis[0] );
        transformed[1] = DotProduct( temp, glr.entaxis[1] );
        transformed[2] = DotProduct( temp, glr.entaxis[2] );
    } else {
        VectorAdd( model->mins, ent->origin, bounds[0] );
        VectorAdd( model->maxs, ent->origin, bounds[1] );
        cull = GL_CullBox( bounds );
        if( cull == CULL_OUT ) {
            c.boxesCulled++;
            return;
        }
        VectorSubtract( glr.fd.vieworg, ent->origin, transformed );
        if( VectorEmpty( ent->origin ) && model->drawframe != glr.drawframe ) {
            mask = SURF_TRANS33|SURF_TRANS66;
        }
    }

    // protect against infinite loop if the same inline model
    // with alpha faces is referenced by multiple entities
    model->drawframe = glr.drawframe;

#if USE_DLIGHTS
    glr.dlightframe++;
    if( gl_dynamic->integer == 1 ) {
        GL_TransformLights( model );
    }
#endif

    if( gl_dynamic->integer ) {
        GL_BeginLights();
    }

    qglPushMatrix();
    qglTranslatef( ent->origin[0], ent->origin[1], ent->origin[2] );
    if( glr.entrotated ) {
        qglRotatef( ent->angles[YAW],   0, 0, 1 );
        qglRotatef( ent->angles[PITCH], 0, 1, 0 );
        qglRotatef( ent->angles[ROLL],  1, 0, 0 );
    }

    // draw visible faces
    // FIXME: go by headnode instead?
    face = model->firstface;
    count = model->numfaces;
    while( count-- ) {
        dot = PlaneDiffFast( transformed, face->plane );
        if( BSP_CullFace( face, dot ) ) {
            c.facesCulled++;
        } else if( face->drawflags & mask ) {
            // FIXME: alpha faces are not supported
            // on rotated or translated inline models
            GL_AddAlphaFace( face );
        } else {
            GL_AddSolidFace( face );
        }
        face++;
    }

    if( gl_dynamic->integer ) {
        GL_EndLights();
    }

    GL_DrawSolidFaces();

    qglPopMatrix();
}
コード例 #5
0
ファイル: lightmap.cpp プロジェクト: Isaacssv552/ufoai
/**
 * @brief
 * @sa FinalLightFace
 */
void BuildFacelights (unsigned int facenum)
{
	dBspSurface_t* face;
	dBspPlane_t* plane;
	dBspTexinfo_t* tex;
	float* center;
	float* sdir, *tdir;
	vec3_t normal, binormal;
	vec4_t tangent;
	lightinfo_t li;
	float scale;
	int i, j, numsamples;
	facelight_t* fl;
	int* headhints;
	const int grid_type = config.soft ? 1 : 0;

	if (facenum >= MAX_MAP_FACES) {
		Com_Printf("MAX_MAP_FACES hit\n");
		return;
	}

	face = &curTile->faces[facenum];
	plane = &curTile->planes[face->planenum];
	tex = &curTile->texinfo[face->texinfo];

	if (tex->surfaceFlags & SURF_WARP)
		return;		/* non-lit texture */

	sdir = tex->vecs[0];
	tdir = tex->vecs[1];

	/* lighting -extra antialiasing */
	if (config.extrasamples)
		numsamples = config.soft ? SOFT_SAMPLES : MAX_SAMPLES;
	else
		numsamples = 1;

	OBJZERO(li);

	scale = 1.0 / numsamples; /* each sample contributes this much */

	li.face = face;
	li.facedist = plane->dist;
	VectorCopy(plane->normal, li.facenormal);
	/* negate the normal and dist */
	if (face->side) {
		VectorNegate(li.facenormal, li.facenormal);
		li.facedist = -li.facedist;
	}

	/* get the origin offset for rotating bmodels */
	VectorCopy(face_offset[facenum], li.modelorg);

	/* calculate lightmap texture mins and maxs */
	CalcLightinfoExtents(&li);

	/* and the lightmap texture vectors */
	CalcLightinfoVectors(&li);

	/* now generate all of the sample points */
	CalcPoints(&li, 0, 0);

	fl = &facelight[config.compile_for_day][facenum];
	fl->numsamples = li.numsurfpt;
	fl->samples    = Mem_AllocTypeN(vec3_t, fl->numsamples);
	fl->directions = Mem_AllocTypeN(vec3_t, fl->numsamples);

	center = face_extents[facenum].center;  /* center of the face */

	/* Also setup the hints.  Each hint is specific to each light source, including sunlight. */
	headhints = Mem_AllocTypeN(int, (numlights[config.compile_for_day] + 1));

	/* calculate light for each sample */
	for (i = 0; i < fl->numsamples; i++) {
		float* const sample    = fl->samples[i];    /* accumulate lighting here */
		float* const direction = fl->directions[i]; /* accumulate direction here */

		if (tex->surfaceFlags & SURF_PHONG)
			/* interpolated normal */
			SampleNormal(&li, li.surfpt[i], normal);
		else
			/* or just plane normal */
			VectorCopy(li.facenormal, normal);

		for (j = 0; j < numsamples; j++) {  /* with antialiasing */
			vec3_t pos;

			/* add offset for supersampling */
			VectorMA(li.surfpt[i], sampleofs[grid_type][j][0] * li.step, li.textoworld[0], pos);
			VectorMA(pos, sampleofs[grid_type][j][1] * li.step, li.textoworld[1], pos);

			NudgeSamplePosition(pos, normal, center, pos);

			GatherSampleLight(pos, normal, sample, direction, scale, headhints);
		}
		if (VectorNotEmpty(direction)) {
			vec3_t dir;

			/* normalize it */
			VectorNormalize(direction);

			/* finalize the lighting direction for the sample */
			TangentVectors(normal, sdir, tdir, tangent, binormal);

			dir[0] = DotProduct(direction, tangent);
			dir[1] = DotProduct(direction, binormal);
			dir[2] = DotProduct(direction, normal);

			VectorCopy(dir, direction);
		}
	}

	/* Free the hints. */
	Mem_Free(headhints);

	for (i = 0; i < fl->numsamples; i++) {  /* pad them */
		float* const direction = fl->directions[i];
		if (VectorEmpty(direction))
			VectorSet(direction, 0.0, 0.0, 1.0);
	}

	/* free the sample positions for the face */
	Mem_Free(li.surfpt);
}
コード例 #6
0
ファイル: lightmap.cpp プロジェクト: Isaacssv552/ufoai
/**
 * @brief Create lights out of patches and entity lights
 * @sa LightWorld
 * @sa BuildPatch
 */
void BuildLights (void)
{
	int i;
	light_t* l;

	/* surfaces */
	for (i = 0; i < MAX_MAP_FACES; i++) {
		/* iterate subdivided patches */
		for(const patch_t* p = face_patches[i]; p; p = p->next) {
			if (VectorEmpty(p->light))
				continue;

			numlights[config.compile_for_day]++;
			l = Mem_AllocType(light_t);

			VectorCopy(p->origin, l->origin);

			l->next = lights[config.compile_for_day];
			lights[config.compile_for_day] = l;

			l->type = emit_surface;

			l->intensity = ColorNormalize(p->light, l->color);
			l->intensity *= p->area * config.surface_scale;
		}
	}

	/* entities (skip the world) */
	for (i = 1; i < num_entities; i++) {
		float intensity;
		const char* color;
		const char* target;
		const entity_t* e = &entities[i];
		const char* name = ValueForKey(e, "classname");
		if (!Q_strstart(name, "light"))
			continue;

		/* remove those lights that are only for the night version */
		if (config.compile_for_day) {
			const int spawnflags = atoi(ValueForKey(e, "spawnflags"));
			if (!(spawnflags & 1))	/* day */
				continue;
		}

		numlights[config.compile_for_day]++;
		l = Mem_AllocType(light_t);

		GetVectorForKey(e, "origin", l->origin);

		/* link in */
		l->next = lights[config.compile_for_day];
		lights[config.compile_for_day] = l;

		intensity = FloatForKey(e, "light");
		if (!intensity)
			intensity = 300.0;
		color = ValueForKey(e, "_color");
		if (color && color[0] != '\0'){
			if (sscanf(color, "%f %f %f", &l->color[0], &l->color[1], &l->color[2]) != 3)
				Sys_Error("Invalid _color entity property given: %s", color);
			ColorNormalize(l->color, l->color);
		} else
			VectorSet(l->color, 1.0, 1.0, 1.0);
		l->intensity = intensity * config.entity_scale;
		l->type = emit_point;

		target = ValueForKey(e, "target");
		if (target[0] != '\0' || Q_streq(name, "light_spot")) {
			l->type = emit_spotlight;
			l->stopdot = FloatForKey(e, "_cone");
			if (!l->stopdot)
				l->stopdot = 10;
			l->stopdot = cos(l->stopdot * torad);
			if (target[0] != '\0') {	/* point towards target */
				entity_t* e2 = FindTargetEntity(target);
				if (!e2)
					Com_Printf("WARNING: light at (%i %i %i) has missing target '%s' - e.g. create an info_null that has a 'targetname' set to '%s'\n",
						(int)l->origin[0], (int)l->origin[1], (int)l->origin[2], target, target);
				else {
					vec3_t dest;
					GetVectorForKey(e2, "origin", dest);
					VectorSubtract(dest, l->origin, l->normal);
					VectorNormalize(l->normal);
				}
			} else {	/* point down angle */
				const float angle = FloatForKey(e, "angle");
				if (angle == ANGLE_UP) {
					l->normal[0] = l->normal[1] = 0.0;
					l->normal[2] = 1.0;
				} else if (angle == ANGLE_DOWN) {
					l->normal[0] = l->normal[1] = 0.0;
					l->normal[2] = -1.0;
				} else {
					l->normal[2] = 0;
					l->normal[0] = cos(angle * torad);
					l->normal[1] = sin(angle * torad);
				}
			}
		}
	}

	/* handle worldspawn light settings */
	{
		const entity_t* e = &entities[0];
		const char* ambient, *light, *angles, *color;
		float f;
		int i;

		if (config.compile_for_day) {
			ambient = ValueForKey(e, "ambient_day");
			light = ValueForKey(e, "light_day");
			angles = ValueForKey(e, "angles_day");
			color = ValueForKey(e, "color_day");
		} else {
			ambient = ValueForKey(e, "ambient_night");
			light = ValueForKey(e, "light_night");
			angles = ValueForKey(e, "angles_night");
			color = ValueForKey(e, "color_night");
		}

		if (light[0] != '\0')
			sun_intensity = atoi(light);

		if (angles[0] != '\0') {
			VectorClear(sun_angles);
			if (sscanf(angles, "%f %f", &sun_angles[0], &sun_angles[1]) != 2)
				Sys_Error("wrong angles values given: '%s'", angles);
			AngleVectors(sun_angles, sun_normal, nullptr, nullptr);
		}

		if (color[0] != '\0') {
			GetVectorFromString(color, sun_color);
			ColorNormalize(sun_color, sun_color);
		}

		if (ambient[0] != '\0')
			GetVectorFromString(ambient, sun_ambient_color);

		/* optionally pull brightness from worldspawn */
		f = FloatForKey(e, "brightness");
		if (f > 0.0)
			config.brightness = f;

		/* saturation as well */
		f = FloatForKey(e, "saturation");
		if (f > 0.0)
			config.saturation = f;
		else
			Verb_Printf(VERB_EXTRA, "Invalid saturation setting (%f) in worldspawn found\n", f);

		f = FloatForKey(e, "contrast");
		if (f > 0.0)
			config.contrast = f;
		else
			Verb_Printf(VERB_EXTRA, "Invalid contrast setting (%f) in worldspawn found\n", f);

		/* lightmap resolution downscale (e.g. 4 = 1 << 4) */
		i = atoi(ValueForKey(e, "quant"));
		if (i >= 1 && i <= 6)
			config.lightquant = i;
		else
			Verb_Printf(VERB_EXTRA, "Invalid quant setting (%i) in worldspawn found\n", i);
	}

	Verb_Printf(VERB_EXTRA, "light settings:\n * intensity: %i\n * sun_angles: pitch %f yaw %f\n * sun_color: %f:%f:%f\n * sun_ambient_color: %f:%f:%f\n",
		sun_intensity, sun_angles[0], sun_angles[1], sun_color[0], sun_color[1], sun_color[2], sun_ambient_color[0], sun_ambient_color[1], sun_ambient_color[2]);
	Verb_Printf(VERB_NORMAL, "%i direct lights for %s lightmap\n", numlights[config.compile_for_day], (config.compile_for_day ? "day" : "night"));
}