Esempio n. 1
0
/**
 * @brief Precache all menu models for faster access
 * @sa CL_ViewPrecacheModels
 * @todo Does not precache armoured models
 */
static float CL_PrecacheCharacterModels (float alreadyLoadedPercent)
{
	teamDef_t* td;
	int i, j;
	const float percent = 40.0f;

	if (!cl_precache->integer)
		return 0;

	/* search the name */
	for (i = 0, td = csi.teamDef; i < csi.numTeamDefs; i++, td++)
		for (j = NAME_NEUTRAL; j < NAME_LAST; j++) {
			/* search one of the model definitions */
			for (linkedList_t const* list = td->models[j]; list; list = list->next) {
				teamDef_t::model_t const& m = *static_cast<teamDef_t::model_t const*>(list->data);
				/* register body */
				char model[MAX_QPATH];
				Com_sprintf(model, sizeof(model), "%s/%s", m.path, m.body);
				if (!R_FindModel(model))
					Com_Printf("Com_PrecacheCharacterModels: Could not register model %s\n", model);
				/* register head */
				Com_sprintf(model, sizeof(model), "%s/%s", m.path, m.head);
				if (!R_FindModel(model))
					Com_Printf("Com_PrecacheCharacterModels: Could not register model %s\n", model);

				alreadyLoadedPercent += percent / (td->numModels[j] * csi.numTeamDefs * NAME_LAST);
				SCR_DrawLoadingScreen(true, alreadyLoadedPercent);
			}
		}
	/* some genders may not have models - ensure that we do the wanted percent step */
	return percent;
}
Esempio n. 2
0
/**
 * @brief Loads the image or model for a given particle art
 */
static inline void CL_ParticleLoadArt (ptlArt_t *a)
{
	/* register the art */
	switch (a->type) {
	case ART_PIC:
		{
			const char *imageName;
			/* only one image */
			if (a->name[0] != '+')
				imageName = a->name;
			else /* load several frames */
				imageName = va("%s%c%c", a->name + 1, a->frame / 10 + '0', a->frame % 10 + '0');
			a->art.image = R_FindPics(imageName);
			if (!a->art.image)
				Com_Printf("CL_ParticleLoadArt: Could not load image: '%s'\n", imageName);
		}
		break;
	case ART_MODEL:
		/** @todo Support the frame data from ptlArt_t for models, too */
		a->art.model = R_FindModel(a->name);
		break;
	default:
		Com_Error(ERR_DROP, "CL_ParticleLoadArt: Unknown art type\n");
	}
}
Esempio n. 3
0
/**
 * @brief Precaches all models at game startup - for faster access
 */
void CL_ViewPrecacheModels (void)
{
	float percent = 30.0f;
	float alreadyLoadedPercent = 30.0f;

	float loaded = CL_PrecacheCharacterModels(alreadyLoadedPercent);
	alreadyLoadedPercent += loaded;
	if (loaded == 0)
		percent = 100 - alreadyLoadedPercent;

	for (int i = 0; i < csi.numODs; i++) {
		const objDef_t* od = INVSH_GetItemByIDX(i);

		alreadyLoadedPercent += percent / csi.numODs;
		SCR_DrawLoadingScreen(true, alreadyLoadedPercent);

		if (od->type[0] == '\0' || od->isDummy)
			continue;

		if (od->model[0] != '\0') {
			cls.modelPool[i] = R_FindModel(od->model);
			if (cls.modelPool[i])
				Com_DPrintf(DEBUG_CLIENT, "CL_PrecacheModels: Registered object model: '%s' (%i)\n", od->model, i);
		}
	}

	/* now make sure that all the precached models are stored until we quit the game
	 * otherwise they would be freed with every map change */
	R_SwitchModelMemPoolTag();

	SCR_DrawLoadingScreen(false, 100.f);
}
/**
 * @brief Adds a camera edicts to the client for displaying them
 * @sa EV_CAMERA_APPEAR
 */
void CL_CameraAppear (const eventRegister_t *self, dbuffer *msg)
{
	int entnum;
	int team;
	int levelflags;
	int dir;
	int rotate;
	vec3_t origin;
	camera_type_t cameraType;

	NET_ReadFormat(msg, self->formatString, &entnum, &origin, &team, &dir, &cameraType, &levelflags, &rotate);

	le_t *le = LE_Get(entnum);
	if (!le) {
		le = LE_Add(entnum);
	} else {
		le->inuse = true;
	}

	VectorCopy(origin, le->origin);
	le->type = ET_CAMERA;
	le->team = team;
	le->angles[YAW] = directionAngles[le->angle];
	le->flags |= LE_CHECK_LEVELFLAGS;
	le->levelflags = levelflags;
	le->model1 = R_FindModel(va("objects/cameras/camera%i", cameraType));
	if (rotate) {
		const char *rotateAnim = "rotate";
		R_AnimChange(&le->as, le->model1, rotateAnim);
	}

	Com_DPrintf(DEBUG_CLIENT, "CL_CameraAppear: entnum: %i\n", entnum);
}
Esempio n. 5
0
/**
 * @brief Parse values for a sequence model
 * @return 1 - increase the command position of the sequence by one
 * @sa seqEnt_vals
 * @sa CL_SequenceFindEnt
 */
static int SEQ_ExecuteModel (sequenceContext_t *context, const char *name, const char *data)
{
	/* get sequence entity */
	seqEnt_t *se = SEQ_FindEnt(context, name);
	if (!se) {
		int i;
		/* create new sequence entity */
		for (i = 0, se = context->ents; i < context->numEnts; i++, se++)
			if (!se->inuse)
				break;
		if (i >= context->numEnts) {
			if (context->numEnts >= MAX_SEQENTS)
				Com_Error(ERR_FATAL, "Too many sequence entities");
			se = &context->ents[context->numEnts++];
		}
		/* allocate */
		OBJZERO(*se);
		se->inuse = true;
		Q_strncpyz(se->name, name, sizeof(se->name));
		VectorSet(se->color, 0.7, 0.7, 0.7);
	}

	/* get values */
	while (*data) {
		const value_t *vp;
		for (vp = seqEnt_vals; vp->string; vp++)
			if (Q_streq(data, vp->string)) {
				data += strlen(data) + 1;
				Com_EParseValue(se, data, vp->type, vp->ofs, vp->size);
				break;
			}
		if (!vp->string) {
			if (Q_streq(data, "model")) {
				data += strlen(data) + 1;
				Com_DPrintf(DEBUG_CLIENT, "Registering model: %s\n", data);
				se->model = R_FindModel(data);
				if (se->model == NULL)
					se->inuse = false;
			} else if (Q_streq(data, "anim")) {
				if (se->model == NULL)
					Com_Error(ERR_FATAL, "could not change the animation - no model loaded yet");
				data += strlen(data) + 1;
				Com_DPrintf(DEBUG_CLIENT, "Change anim to: %s\n", data);
				R_AnimChange(&se->as, se->model, data);
			} else
				Com_Printf("SEQ_ExecuteModel: unknown token '%s'\n", data);
		}

		data += strlen(data) + 1;
	}
	return 1;
}
Esempio n. 6
0
/**
 * @brief Register misc_models
 * @sa CL_ViewLoadMedia
 */
void LM_Register (void)
{
	for (int i = 0; i < cl.numLMs; i++) {
		localModel_t& lm = cl.LMs[i];

		/* register the model */
		lm.model = R_FindModel(lm.name);
		if (lm.animname[0]) {
			R_AnimChange(&lm.as, lm.model, lm.animname);
			if (!lm.as.change)
				Com_Printf("LM_Register: Could not change anim of %s to '%s'\n",
						lm.name, lm.animname);
		}
		if (!lm.model)
			lm.inuse = false;
	}
}
Esempio n. 7
0
/**
 * @brief Draw 3D Marker on the 2D geoscape.
 * @param[in] screenPos Position on screenlongitude and latitude of the model to draw.
 * @param[in] direction angle giving the direction the model is heading toward.
 */
void R_Draw2DMapMarkers (const vec2_t screenPos, float direction, const char *model, int skin)
{
	modelInfo_t mi;
	vec2_t size;
	vec3_t scale, center, position, angles;
	float zoom = 0.4f;

	OBJZERO(mi);
	VectorCopy(vec3_origin, position);
	VectorCopy(vec3_origin, angles);

	mi.model = R_FindModel(model);
	if (!mi.model) {
		Com_Printf("Could not find model '%s'\n", model);
		return;
	}

	mi.name = model;
	mi.origin = position;
	mi.angles = angles;
	mi.skin = skin;

	size[0] = size[1] = MARKER_SIZE * zoom;
	R_ModelAutoScale(size, &mi, scale, center);
	/* reset the center, as we want to place the models onto the surface of the earth */
	mi.center = nullptr;

	/* go to a new matrix */
	glPushMatrix();

	/* Apply all transformation to model. Note that the transformations are applied starting
	 * from the last one and ending with the first one */

	/* move model to its location */
	glTranslatef(screenPos[0]* viddef.rx, screenPos[1]* viddef.ry, 0);
	/* scale model to proper resolution */
	glScalef(viddef.rx, viddef.ry, 1.0f);
	/* rotate model to proper direction. */
	glRotatef(-90.f + direction, 0, 0, 1);

	R_DrawModelDirect(&mi, nullptr, nullptr);

	/* restore previous matrix */
	glPopMatrix();
}
Esempio n. 8
0
/**
 * @brief Precaches the models and images for a sequence
 * @return 1 - increase the command position of the sequence by one
 * @sa R_RegisterModelShort
 * @sa R_RegisterImage
 */
static int SEQ_ExecutePrecache (sequenceContext_t *context, const char *name, const char *data)
{
	if (Q_streq(name, "models")) {
		while (*data) {
			Com_DPrintf(DEBUG_CLIENT, "Precaching model: %s\n", data);
			R_FindModel(data);
			data += strlen(data) + 1;
		}
	} else if (Q_streq(name, "pics")) {
		while (*data) {
			Com_DPrintf(DEBUG_CLIENT, "Precaching image: %s\n", data);
			R_FindPics(data);
			data += strlen(data) + 1;
		}
	} else
		Com_Printf("SEQ_ExecutePrecache: unknown format '%s'\n", name);
	return 1;
}
Esempio n. 9
0
/**
 * @brief Draw 3D Marker on the 3D geoscape.
 * @param[in] rotate vector giving the angles of earth rotation due to player view.
 * @param[in] pos longitude and latitude of the model to draw.
 * @param[in] direction angle giving the direction the model is heading toward.
 * @param[in] earthRadius Radius of earth on screen (this include zoom).
 */
void R_Draw3DMapMarkers (const vec2_t nodePos, const vec2_t nodeSize, const vec3_t rotate, const vec2_t pos, float direction, float earthRadius, const char *model, int skin)
{
	/* normalize */
	const float nx = nodePos[0] * viddef.rx;
	const float ny = nodePos[1] * viddef.ry;
	const float nw = nodeSize[0] * viddef.rx;
	const float nh = nodeSize[1] * viddef.ry;

	/* Earth center is in the middle of node.
	 * Due to Orthographic view, this is also camera position */
	const vec3_t earthPos = {nx + nw / 2.0f, ny + nh / 2.0f, 0.0f};

	modelInfo_t mi;
	vec2_t size;
	vec3_t scale, center, position, angles;
	float zoom = 0.4f;

	OBJZERO(mi);
	VectorCopy(vec3_origin, position);
	VectorCopy(vec3_origin, angles);

	mi.model = R_FindModel(model);
	if (!mi.model) {
		Com_Printf("Could not find model '%s'\n", model);
		return;
	}

	mi.name = model;
	mi.origin = position;
	mi.angles = angles;
	mi.skin = skin;

	size[0] = size[1] = MARKER_SIZE * zoom;
	R_ModelAutoScale(size, &mi, scale, center);
	/* reset the center, as we want to place the models onto the surface of the earth */
	mi.center = nullptr;

	/* go to a new matrix */
	glPushMatrix();

	/* Apply all transformation to model. Note that the transformations are applied starting
	 * from the last one and ending with the first one */

	/* center model on earth. Translate also along z to avoid seeing
	 * bottom part of the model through earth (only half of earth is drawn) */
	glTranslatef(earthPos[0], earthPos[1], 10.0f);
	/* scale model to proper resolution */
	glScalef(viddef.rx, viddef.ry, 1.0f);
	/* place model on earth: make it tangent to earth surface, heading toward it if direction is used. */
	glRotatef(-rotate[1], 1, 0, 0);
	glRotatef(rotate[2], 0, 1, 0);
	glRotatef(rotate[0] - pos[0], 0, 0, 1);
	glRotatef(90.0f - pos[1], 1, 0, 0);
	glTranslatef(0, 0, earthRadius);
	glRotatef(90.0f + direction, 0, 0, 1);

	R_DrawModelDirect(&mi, nullptr, nullptr);

	/* restore previous matrix */
	glPopMatrix();
}
Esempio n. 10
0
/**
 * @brief Register local entities for SOLID_BSP models like func_breakable or func_door
 * @note func_breakable, func_door
 * @sa G_SendEdictsAndBrushModels
 * @sa EV_ADD_BRUSH_MODEL
 * @sa CL_SpawnParseEntitystring
 */
void CL_AddBrushModel (const eventRegister_t *self, struct dbuffer *msg)
{
	le_t *le;
	int entnum, modelnum1, levelflags, speed, dir;
	entity_type_t type;
	const cBspModel_t *model;
	int angle;
	vec3_t origin, angles;

	NET_ReadFormat(msg, self->formatString, &type, &entnum, &modelnum1, &levelflags, &origin, &angles, &speed, &angle, &dir);

	if (type != ET_BREAKABLE && type != ET_DOOR && type != ET_ROTATING && type != ET_DOOR_SLIDING && type != ET_TRIGGER_RESCUE && type != ET_TRIGGER_NEXTMAP)
		Com_Error(ERR_DROP, "Invalid le announced via EV_ADD_BRUSH_MODEL type: %i\n", type);
	else if (modelnum1 > MAX_MODELS || modelnum1 < 1)
		Com_Error(ERR_DROP, "Invalid le modelnum1 announced via EV_ADD_BRUSH_MODEL\n");

	/* check if the ent is already visible */
	le = LE_Get(entnum);
	if (le)
		Com_Error(ERR_DROP, "le announced a second time - le for entnum %i (type: %i) already exists (via EV_ADD_BRUSH_MODEL)\n", entnum, type);

	le = LE_Add(entnum);
	assert(le);

	le->rotationSpeed = speed / 100.0f;
	le->slidingSpeed = speed;
	le->angle = angle;
	le->dir = dir;
	le->type = type;
	le->modelnum1 = modelnum1;
	le->levelflags = levelflags;
	le->addFunc = LE_BrushModelAction;
	LE_SetThink(le, LET_BrushModel);
	/* The origin and angles are REQUIRED for doors to work! */
	VectorCopy(origin, le->origin);
	/* store the initial position - needed for sliding doors */
	VectorCopy(le->origin, le->oldOrigin);
	VectorCopy(angles, le->angles);

	Com_sprintf(le->inlineModelName, sizeof(le->inlineModelName), "*%i", le->modelnum1);
	model = LE_GetClipModel(le);
	le->model1 = R_FindModel(le->inlineModelName);
	if (!le->model1)
		Com_Error(ERR_DROP, "CL_AddBrushModel: Could not register inline model %i", le->modelnum1);

	/* Transfer model mins and maxs to entity */
	VectorCopy(model->mins, le->mins);
	VectorCopy(model->maxs, le->maxs);
	VectorSubtract(le->maxs, le->mins, le->size);
	VecToPos(le->origin, le->pos);

	/* to allow tracing against this le */
	if (!LE_IsNotSolid(le)) {
		/* This is to help the entity collision code out */
		/* Copy entity origin and angles to model*/
		CM_SetInlineModelOrientation(cl.mapTiles, le->inlineModelName, le->origin, le->angles);

		le->contents = CONTENTS_SOLID;

		CL_RecalcRouting(le);
	}
}
Esempio n. 11
0
/**
 * @brief Call before entering a new level, or after vid_restart
 */
void CL_ViewLoadMedia (void)
{
	le_t* le;
	int i, max;
	float loadingPercent;

	CL_ViewUpdateRenderData();

	if (CL_GetConfigString(CS_TILES)[0] == '\0')
		return;					/* no map loaded */

	GAME_InitMissionBriefing(_(CL_GetConfigString(CS_MAPTITLE)));

	loadingPercent = 0;

	/* register models, pics, and skins */
	SCR_DrawLoading(loadingPercent);
	R_ModBeginLoading(CL_GetConfigString(CS_TILES), CL_GetConfigStringInteger(CS_LIGHTMAP),
			CL_GetConfigString(CS_POSITIONS), CL_GetConfigString(CS_NAME), CL_GetConfigString(CS_MAPZONE));
	CL_SpawnParseEntitystring();

	loadingPercent += 10.0f;
	SCR_DrawLoading(loadingPercent);

	LM_Register();
	CL_ParticleRegisterArt();

	for (i = 1, max = 0; i < MAX_MODELS && CL_GetConfigString(CS_MODELS + i)[0] != '\0'; i++)
		max++;

	max += csi.numODs;

	for (i = 1; i < MAX_MODELS; i++) {
		const char* name = CL_GetConfigString(CS_MODELS + i);
		if (name[0] == '\0')
			break;
		SCR_DrawLoading(loadingPercent);
		cl.model_draw[i] = R_FindModel(name);
		if (!cl.model_draw[i]) {
			Cmd_ExecuteString("fs_info");
			Com_Error(ERR_DROP, "Could not load model '%s'\n", name);
		}

		/* initialize clipping for bmodels */
		if (name[0] == '*')
			cl.model_clip[i] = CM_InlineModel(cl.mapTiles, name);
		else
			cl.model_clip[i] = nullptr;

		loadingPercent += 100.0f / (float)max;
	}

	/* update le model references */
	le = nullptr;
	while ((le = LE_GetNextInUse(le))) {
		if (le->modelnum1 > 0)
			le->model1 = LE_GetDrawModel(le->modelnum1);
		if (le->modelnum2 > 0)
			le->model2 = LE_GetDrawModel(le->modelnum2);
	}

	refdef.ready = true;

	/* waiting for EV_START */
	SCR_EndLoadingPlaque();
}
Esempio n. 12
0
void draw_stats()
{
	if (mdview.baseModel)
	{
		iTextX = 2*TEXT_WIDTH;	// arb start pos 2 in from both edges
		iTextY = 4*TEXT_DEPTH;	// ... or 4... :-)

//		// Displays text at a 2d screen coord. 0,0 is top left corner, add TEXT_DEPTH per Y to go down a line
//
//		Text_DisplayFlat("testing testing HELLO!!", 100,100, 0, 255,0, true);
//		
//		Vec3 v={0,0,0};
//		Text_Display("testing testing HELLO!!", v, 255,0,0);
//
//
		gl_model *model = mdview.baseModel;

		stat_skeleton( model, NULL );

		// anim locks on the whole model?, if so display 'em...
		//
		char sString[1024];
		for (int i=0; i<2; i++)
		{
			// display anim locks at bottom of screen...
			//
			Sequence_t* pSeq=NULL;

			bool bIsUpper = false;

			if (i==0 && iAnimLockNumber_Upper )
			{
				pSeq = Animation_GetUpperSequence( iAnimLockNumber_Upper-1 );			
				bIsUpper = true;
			}

			if (i==1 && iAnimLockNumber_Lower )
			{
				pSeq = Animation_GetLowerSequence( iAnimLockNumber_Lower-1 );
				bIsUpper = false;
			}

			if (pSeq)
			{				
				int iYpos = g_iScreenHeight-((!i?4:3)*TEXT_DEPTH);

				// cheat, do this next bit here just to get the X coord, then overwrite later
				sprintf(sString,"%s anim lock: %s  Frames: %4d...%4d%s",!i?"Upper":"Lower",String_EnsureMinLength(pSeq->sName.c_str(),iAnimLockLongestString),pSeq->iTargetFrame,(pSeq->iTargetFrame+pSeq->iFrameCount)-1,String_EnsureMinLength((pSeq->iLoopFrame==-1)?"":va("  loop: %3d(%3d)",pSeq->iLoopFrame,pSeq->iTargetFrame+pSeq->iLoopFrame),25));				
				int iXpos = (g_iScreenWidth/2)-( (strlen(sString)/2)*TEXT_WIDTH);

				if (pSeq->bMultiSeq)
				{
					Sequence_t *pCurrentMultiSeq = GetMultiLockedSequenceFromFrame(bIsUpper?pModel_Upper->currentFrame:pModel_Lower->currentFrame, bIsUpper );
					int iStrlenAtCurrentSeqPoint = 0;

					sprintf(sString,"%s anim lock: ",bIsUpper?"Upper":"Lower");

					MultiSequenceLock_t* pMultiLock = (bIsUpper)?&MultiSequenceLock_Upper:&MultiSequenceLock_Lower;
					MultiSequenceLock_t::iterator it;
					for (it = pMultiLock->begin(); it != pMultiLock->end(); ++it)
					{
						int iSeqIndex = *it;

						pSeq = (bIsUpper)?Animation_GetUpperSequence(iSeqIndex):Animation_GetLowerSequence(iSeqIndex);
						
						assert(pSeq);
						if (pSeq)
						{
							if (pSeq == pCurrentMultiSeq)
								iStrlenAtCurrentSeqPoint = strlen(sString);

							strcat(sString,va("%s  ",pSeq->sName.c_str()));
						}
					}

//					int iXpos = (g_iScreenWidth/2)-( (strlen(sString)/2)*TEXT_WIDTH);					
				
					Text_DisplayFlat(sString, iXpos, iYpos, 255,0,0, true);

					// now overlay the highlighted one for current...
					//
					if (pCurrentMultiSeq)
					{
						iXpos += iStrlenAtCurrentSeqPoint*TEXT_WIDTH;
		
						Text_DisplayFlat(pCurrentMultiSeq->sName.c_str(), iXpos, iYpos, 255,0,255, true);					
					}
				}
				else
				{
					sprintf(sString,"%s anim lock: %s  Frames: %4d...%4d%s",!i?"Upper":"Lower",String_EnsureMinLength(pSeq->sName.c_str(),iAnimLockLongestString),pSeq->iTargetFrame,(pSeq->iTargetFrame+pSeq->iFrameCount)-1,String_EnsureMinLength((pSeq->iLoopFrame==-1)?"":va("  loop: %3d(%3d)",pSeq->iLoopFrame,pSeq->iTargetFrame+pSeq->iLoopFrame),25));
					
//					int iXpos = (g_iScreenWidth/2)-( (strlen(sString)/2)*TEXT_WIDTH);					
				
					Text_DisplayFlat(sString, iXpos, iYpos, 255,0,0, true);
				}
			}

			if (RunningNT() == 4)	// only needed on NT4, NT 2000 and W95/98 are ok
			{
				pSeq = NULL;

				if (i==0 && iAnimDisplayNumber_Upper)
					pSeq = Animation_GetUpperSequence( iAnimDisplayNumber_Upper-1);
				if (i==1 && iAnimDisplayNumber_Lower)
					pSeq = Animation_GetLowerSequence( iAnimDisplayNumber_Lower-1);

				if (pSeq)
				{	
					if (pSeq->bMultiSeq)
					{
						assert(0);	// should never be able to get here in the animlock display-cycler				
					}
					else
					{
						sprintf(sString,"( %s anim     : %s  Frames: %4d...%4d%s )",!i?"Upper":"Lower",String_EnsureMinLength(pSeq->sName.c_str(),iAnimLockLongestString),pSeq->iTargetFrame,(pSeq->iTargetFrame+pSeq->iFrameCount)-1,String_EnsureMinLength((pSeq->iLoopFrame==-1)?"":va("  loop: %3d(%3d)",pSeq->iLoopFrame,pSeq->iTargetFrame+pSeq->iLoopFrame),25));					
						
						int iXpos = (g_iScreenWidth/2)-( ((strlen(sString)/2)/*+2*/)*TEXT_WIDTH);	// 2 chars back from LOCk string, because of bracket+space at start
						int iYpos = g_iScreenHeight-((!i?7:6)*TEXT_DEPTH);

						Text_DisplayFlat(sString, iXpos, iYpos, 0,200,200, true);	// dim yellow
					}
				}
			}
		}

		// display current FPS and interp state...
		//
		sprintf(sString,"FPS: %2.2f %s",1/(mdview.animSpeed),mdview.animate?"(Playing)":"(Stopped)");

		iTextX = 
		Text_DisplayFlat(sString,	(g_iScreenWidth/2)-( (strlen(sString)/2)*TEXT_WIDTH),
									1*TEXT_DEPTH,
									255,255,255,
									false
						);

		if (mdview.interpolate)
		{
			iTextX = Text_DisplayFlat("(Interpolated)", iTextX+(2*TEXT_WIDTH),1*TEXT_DEPTH, 255/2,255/2,255/2,false);
		}

		iTextX = Text_DisplayFlat(va("(LOD: %d)",mdview.iLODLevel+1), iTextX+(2*TEXT_WIDTH), 1*TEXT_DEPTH, 255/2,255,255/2,false);
/*		Text_DisplayFlat(sString,	g_iScreenWidth-((strlen(sString)+2)*TEXT_WIDTH),
																	 2 *TEXT_DEPTH,
									255,255,255,
									false
						);*/

		iTextX = Text_DisplayFlat(va("( FOV: %g )",mdview.dFOV), iTextX+(2*TEXT_WIDTH),1*TEXT_DEPTH, 255, 255, 255, false);


		if (mdview.bUseAlpha)
		{
			Text_DisplayFlat("( Alpha )", iTextX+(2*TEXT_WIDTH),1*TEXT_DEPTH, 128, 128, 128, false);
		}

		// display head skin numbers in top left...
		//
		gl_model* pModel = R_FindModel( mdview.baseModel, "head");
		if (pModel)
		{
			sprintf(sString,"Head skin: %s", va("\"%s%s\"",model->sHeadSkinName,!mdview.iSkinNumber?"":va("-%1d",mdview.iSkinNumber)));

			Text_DisplayFlat(sString,	2*TEXT_WIDTH,//(g_iScreenWidth/2)-( (strlen(sString)/2)*TEXT_WIDTH),
										1*TEXT_DEPTH,
										200,200,200,
										false
							);
		}

		// display which format anim table this is using (if any)...
		//
		if (mdview.bAnimCFGLoaded)
		{
			if (mdview.bAnimIsMultiPlayerFormat)
				sprintf(sString,"( MultiPlayer ) ");
			else
				sprintf(sString,"( SinglePlayer ) ");

			int iYpos = g_iScreenHeight-(2*TEXT_DEPTH);
			int iXpos = g_iScreenWidth -(strlen(sString)*TEXT_WIDTH);

			Text_DisplayFlat(sString, iXpos, iYpos, 128,128,128, true);	// grey
		}


		// display current picmip state...
		//
		{
			extern int TextureList_GetMip(void);

			int iYpos = g_iScreenHeight-(2*TEXT_DEPTH);
			int iXpos = 1*TEXT_WIDTH;

			sprintf(sString,"( PICMIP: %d )",TextureList_GetMip());
			Text_DisplayFlat(sString,	
								iXpos, iYpos,
								100,100,100,
								false
							);
		}
	}
}
Esempio n. 13
0
/**
 * @brief Draws a model in 2d mode (for rendering model data from the ui)
 * @param[in,out] mi All the needed model information to render the model
 * @param[in,out] pmi The model information of the parent model. This is used
 * in those cases, where the model that should get rendered here is placed relativly
 * to an already existing model in the world.
 * @param[in] tagname If a parent model is given, a @c tagname is given in most cases, too. It's used
 * to transform the model location relative to the parent model location again. E.g. a
 * @c tagname of tag_rweapon will transform the location to the right hand of an actor.
 * @sa R_DrawAliasModel
 */
void R_DrawModelDirect (modelInfo_t * mi, modelInfo_t * pmi, const char *tagname)
{
	image_t *skin;
	mAliasMesh_t *mesh;

	if (Q_strnull(mi->name))
		return;

	/* register the model */
	mi->model = R_FindModel(mi->name);

	/* check if the model exists */
	if (!mi->model) {
		Com_Printf("No model found for '%s'\n", mi->name);
		return;
	}

	skin = R_AliasModelState(mi->model, &mi->mesh, &mi->frame, &mi->oldframe, &mi->skin);
	if (skin == NULL) {
		Com_Printf("Model '%s' is broken\n", mi->name);
		return;
	}

	glPushMatrix();
	glScalef(viddef.rx, viddef.ry, (viddef.rx + viddef.ry) / 2);

	R_Color(mi->color);

	if (pmi) {
		/* register the parent model */
		pmi->model = R_FindModel(pmi->name);

		/* transform - the next transform for the child model will be relative from the
		 * parent model location now */
		R_TransformModelDirect(pmi);

		/* tag transformation */
		if (tagname) {
			const mAliasTagOrientation_t *current = NULL;
			const mAliasTagOrientation_t *old = NULL;
			R_GetTags(pmi->model, tagname, pmi->frame, pmi->oldframe, &current, &old);
			if (current != NULL && old != NULL) {
				float interpolated[16];

				/* do interpolation */
				R_InterpolateTransform(pmi->backlerp, pmi->model->alias.num_frames, current, old, interpolated);

				/* transform */
				glMultMatrixf(interpolated);
				R_CheckError();
			}
		}
	}

	/* transform */
	R_TransformModelDirect(mi);

	/* we have to reenable this here - we are in 2d mode here already */
	glEnable(GL_DEPTH_TEST);

	/* draw it */
	R_BindTexture(skin->texnum);

	/* draw the model */
	mesh = &mi->model->alias.meshes[0];
	refdef.aliasCount += mesh->num_tris;
	if (mi->model->alias.num_frames == 1)
		R_DrawAliasStaticWithReset(mesh, vec4_origin);
	else
		R_DrawAliasFrameLerp(&mi->model->alias, mesh, mi->backlerp, mi->frame, mi->oldframe, vec4_origin);

	/* show model bounding box */
	if (r_showbox->integer)
		R_DrawBoundingBox(mi->model->alias.frames[mi->frame].mins, mi->model->alias.frames[mi->frame].maxs);

	glDisable(GL_DEPTH_TEST);

	glPopMatrix();

	R_Color(NULL);
}
Esempio n. 14
0
/**
 * @todo need to merge UI model case, and the common case (looks to be a copy-pasted code)
 */
void UI_DrawModelNode (uiNode_t* node, const char* source)
{
	modelInfo_t mi;
	uiModel_t* model;
	vec3_t nodeorigin;
	vec2_t screenPos;

	assert(UI_NodeInstanceOf(node, "model"));			/**< We use model extradata */

	if (!source || source[0] == '\0')
		return;

	model = UI_GetUIModel(source);
	/* direct model name - no UI model definition */
	if (!model) {
		/* prevent the searching for a model def in the next frame */
		mi.model = R_FindModel(source);
		mi.name = source;
		if (!mi.model) {
			Com_Printf("Could not find model '%s'\n", source);
			return;
		}
	}

	/* compute the absolute origin ('origin' property is relative to the node center) */
	UI_GetNodeScreenPos(node, screenPos);
	UI_GetNodeAbsPos(node, nodeorigin);
	R_CleanupDepthBuffer(nodeorigin[0], nodeorigin[1], node->box.size[0], node->box.size[1]);
	if (EXTRADATA(node).clipOverflow) {
		UI_PushClipRect(screenPos[0], screenPos[1], node->box.size[0], node->box.size[1]);
	}
	nodeorigin[0] += node->box.size[0] / 2 + EXTRADATA(node).origin[0];
	nodeorigin[1] += node->box.size[1] / 2 + EXTRADATA(node).origin[1];
	nodeorigin[2] = EXTRADATA(node).origin[2];

	VectorMA(EXTRADATA(node).angles, cls.frametime, EXTRADATA(node).omega, EXTRADATA(node).angles);
	mi.origin = nodeorigin;
	mi.angles = EXTRADATA(node).angles;
	mi.scale = EXTRADATA(node).scale;
	mi.center = nullVector;
	mi.color = node->color;
	mi.mesh = 0;

	/* special case to draw models with UI model */
	if (model) {
		UI_DrawModelNodeWithUIModel(node, source, &mi, model);
		if (EXTRADATA(node).clipOverflow)
			UI_PopClipRect();
		return;
	}

	/* if the node is linked to a parent, the parent will display it */
	if (EXTRADATA(node).tag) {
		if (EXTRADATA(node).clipOverflow)
			UI_PopClipRect();
		return;
	}

	/* autoscale? */
	if (EXTRADATA(node).autoscale) {
		vec3_t autoScale;
		vec3_t autoCenter;
		const vec2_t size = {node->box.size[0] - node->padding, node->box.size[1] - node->padding};
		R_ModelAutoScale(size, &mi, autoScale, autoCenter);
	}

	/* no animation */
	mi.frame = 0;
	mi.oldframe = 0;
	mi.backlerp = 0;

	/* get skin */
	if (EXTRADATA(node).skin && *EXTRADATA(node).skin)
		mi.skin = atoi(UI_GetReferenceString(node, EXTRADATA(node).skin));
	else
		mi.skin = 0;

	/* do animations */
	if (EXTRADATA(node).animation && *EXTRADATA(node).animation) {
		const char* ref;
		ref = UI_GetReferenceString(node, EXTRADATA(node).animation);

		/* check whether the cvar value changed */
		if (strncmp(EXTRADATA(node).oldRefValue, source, MAX_OLDREFVALUE)) {
			Q_strncpyz(EXTRADATA(node).oldRefValue, source, MAX_OLDREFVALUE);
			/* model has changed but mem is already reserved in pool */
			Mem_Free(EXTRADATA(node).animationState);
			EXTRADATA(node).animationState = nullptr;
		}
		animState_t* as = EXTRADATA(node).animationState;
		if (!as) {
			as = Mem_PoolAllocType(animState_t, cl_genericPool);
			if (!as)
				Com_Error(ERR_DROP, "Model %s should have animState_t for animation %s - but doesn't\n", mi.name, ref);
			R_AnimChange(as, mi.model, ref);
			EXTRADATA(node).animationState = as;
		} else {
			const char* anim;
			/* change anim if needed */
			anim = R_AnimGetName(as, mi.model);
			if (anim && !Q_streq(anim, ref))
				R_AnimChange(as, mi.model, ref);
			R_AnimRun(as, mi.model, cls.frametime * 1000);
		}

		mi.frame = as->frame;
		mi.oldframe = as->oldframe;
		mi.backlerp = as->backlerp;
	}

	/* draw the main model on the node */
	R_DrawModelDirect(&mi, nullptr, nullptr);

	/* draw all children */
	if (node->firstChild) {
		uiNode_t* child;
		modelInfo_t pmi = mi;
		for (child = node->firstChild; child; child = child->next) {
			const char* tag;
			char childSource[MAX_VAR];
			const char* childRef;

			/* skip non "model" nodes */
			if (child->behaviour != node->behaviour)
				continue;

			/* skip invisible child */
			if (child->invis || !UI_CheckVisibility(child))
				continue;

			OBJZERO(mi);
			mi.angles = EXTRADATA(child).angles;
			mi.scale = EXTRADATA(child).scale;
			mi.center = nullVector;
			mi.origin = EXTRADATA(child).origin;
			mi.color = pmi.color;

			/* get the anchor name to link the model into the parent */
			tag = EXTRADATA(child).tag;

			/* init model name */
			childRef = UI_GetReferenceString(child, EXTRADATA(child).model);
			if (Q_strnull(childRef))
				childSource[0] = '\0';
			else
				Q_strncpyz(childSource, childRef, sizeof(childSource));
			mi.model = R_FindModel(childSource);
			mi.name = childSource;

			/* init skin */
			if (EXTRADATA(child).skin && *EXTRADATA(child).skin)
				mi.skin = atoi(UI_GetReferenceString(child, EXTRADATA(child).skin));
			else
				mi.skin = 0;

			R_DrawModelDirect(&mi, &pmi, tag);
		}
	}

	if (EXTRADATA(node).clipOverflow)
		UI_PopClipRect();
}
Esempio n. 15
0
/**
 * @brief Draw a model using UI model definition
 */
static void UI_DrawModelNodeWithUIModel (uiNode_t* node, const char* source, modelInfo_t* mi, uiModel_t* model)
{
	bool autoScaleComputed = false;
	vec3_t autoScale;
	vec3_t autoCenter;

	while (model) {
		/* no animation */
		mi->frame = 0;
		mi->oldframe = 0;
		mi->backlerp = 0;

		assert(model->model);
		mi->model = R_FindModel(model->model);
		if (!mi->model) {
			model = model->next;
			continue;
		}

		mi->skin = model->skin;
		mi->name = model->model;

		/* set mi pointers to model */
		mi->origin = model->origin;
		mi->angles = model->angles;
		mi->center = model->center;
		mi->color = model->color;
		mi->scale = model->scale;

		if (model->tag && model->parent) {
			/* tag and parent defined */
			uiModel_t* parentModel;
			modelInfo_t pmi;
			vec3_t pmiorigin;
			animState_t* as;
			/* place this model part on an already existing model tag */
			parentModel = UI_GetUIModel(model->parent);
			if (!parentModel) {
				Com_Printf("UI Model: Could not get the model '%s'\n", model->parent);
				break;
			}
			pmi.model = R_FindModel(parentModel->model);
			if (!pmi.model) {
				Com_Printf("UI Model: Could not get the model '%s'\n", parentModel->model);
				break;
			}

			pmi.name = parentModel->model;

			pmi.origin = pmiorigin;
			pmi.angles = parentModel->angles;
			pmi.scale = parentModel->scale;
			pmi.center = parentModel->center;
			pmi.color = parentModel->color;

			pmi.origin[0] = parentModel->origin[0] + mi->origin[0];
			pmi.origin[1] = parentModel->origin[1] + mi->origin[1];
			pmi.origin[2] = parentModel->origin[2];
			/* don't count window offset twice for tagged models */
			mi->origin[0] -= node->root->box.pos[0];
			mi->origin[1] -= node->root->box.pos[1];

			/* autoscale? */
			if (EXTRADATA(node).autoscale) {
				if (!autoScaleComputed)
					Sys_Error("Wrong order of model nodes - the tag and parent model node must be after the base model node");
				pmi.scale = autoScale;
				pmi.center = autoCenter;
			}

			as = &parentModel->animState;
			pmi.frame = as->frame;
			pmi.oldframe = as->oldframe;
			pmi.backlerp = as->backlerp;

			R_DrawModelDirect(mi, &pmi, model->tag);
		} else {
			/* no tag and no parent means - base model or single model */
			const char* ref;
			UI_InitModelInfoView(node, mi, model);
			Vector4Copy(node->color, mi->color);

			/* compute the scale and center for the first model.
			 * it think its the bigger of composite models.
			 * All next elements use the same result
			 */
			if (EXTRADATA(node).autoscale) {
				if (!autoScaleComputed) {
					vec2_t size;
					size[0] = node->box.size[0] - node->padding;
					size[1] = node->box.size[1] - node->padding;
					R_ModelAutoScale(size, mi, autoScale, autoCenter);
					autoScaleComputed = true;
				} else {
					mi->scale = autoScale;
					mi->center = autoCenter;
				}
			}

			/* get the animation given by node properties */
			if (EXTRADATA(node).animation && *EXTRADATA(node).animation) {
				ref = UI_GetReferenceString(node, EXTRADATA(node).animation);
			/* otherwise use the standard animation from UI model definition */
			} else
				ref = model->anim;

			/* only base models have animations */
			if (ref && *ref) {
				animState_t* as = &model->animState;
				const char* anim = R_AnimGetName(as, mi->model);
				/* initial animation or animation change */
				if (anim == nullptr || !Q_streq(anim, ref))
					R_AnimChange(as, mi->model, ref);
				else
					R_AnimRun(as, mi->model, cls.frametime * 1000);

				mi->frame = as->frame;
				mi->oldframe = as->oldframe;
				mi->backlerp = as->backlerp;
			}
			R_DrawModelDirect(mi, nullptr, nullptr);
		}

		/* next */
		model = model->next;
	}
}