示例#1
0
static void UI_CheckBoxNodeDraw (uiNode_t* node)
{
	const float value = UI_GetReferenceFloat(node, EXTRADATA(node).value);
	vec2_t pos;
	const char *image = UI_GetReferenceString(node, node->image);
	int texx, texy;

	/* image set? */
	if (Q_strnull(image))
		return;

	/* outer status */
	if (node->disabled) {
		texy = 96;
	} else if (node->state) {
		texy = 32;
	} else {
		texy = 0;
	}

	/* inner status */
	if (value == 0) {
		texx = 0;
	} else if (value > 0) {
		texx = 32;
	} else { /* value < 0 */
		texx = 64;
	}

	UI_GetNodeAbsPos(node, pos);
	UI_DrawNormImageByName(qfalse, pos[0], pos[1], node->size[0], node->size[1],
		texx + node->size[0], texy + node->size[1], texx, texy, image);
}
static void UI_TBarNodeDraw (uiNode_t *node)
{
	/* dataImageOrModel is the texture name */
	float shx;
	vec2_t nodepos;
	const char* ref = UI_GetReferenceString(node, node->image);
	float pointWidth;
	float width;
	if (Q_strnull(ref))
		return;

	UI_GetNodeAbsPos(node, nodepos);

	pointWidth = TEXTURE_WIDTH / 100.0;	/* relative to the texture */

	{
		float ps;
		const float min = UI_GetReferenceFloat(node, EXTRADATA(node).super.min);
		const float max = UI_GetReferenceFloat(node, EXTRADATA(node).super.max);
		float value = UI_GetReferenceFloat(node, EXTRADATA(node).super.value);
		/* clamp the value */
		if (value > max)
			value = max;
		if (value < min)
			value = min;
		ps = (value - min) / (max - min) * 100;
		shx = EXTRADATA(node).texl[0];	/* left gap to the texture */
		shx += round(ps * pointWidth); /* add size from 0..TEXTURE_WIDTH */
	}

	width = (shx * node->size[0]) / TEXTURE_WIDTH;

	UI_DrawNormImageByName(qfalse, nodepos[0], nodepos[1], width, node->size[1],
		shx, EXTRADATA(node).texh[1], EXTRADATA(node).texl[0], EXTRADATA(node).texl[1], ref);
}
示例#3
0
/**
 * @brief Handles CustomButton draw
 */
static void UI_CustomButtonNodeDraw (uiNode_t *node)
{
	const char *text;
	int texY;
	const float *textColor;
	const char *image;
	vec2_t pos;
	static vec4_t disabledColor = {0.5, 0.5, 0.5, 1.0};
	uiSpriteStatus_t iconStatus = SPRITE_STATUS_NORMAL;
	const char *font = UI_GetFontFromNode(node);

	if (!node->onClick || node->disabled) {
		/** @todo need custom color when button is disabled */
		textColor = disabledColor;
		texY = UI_CUSTOMBUTTON_TEX_HEIGHT * 2;
		iconStatus = SPRITE_STATUS_DISABLED;
	} else if (node->state) {
		textColor = node->selectedColor;
		texY = UI_CUSTOMBUTTON_TEX_HEIGHT;
		iconStatus = SPRITE_STATUS_HOVER;
	} else {
		textColor = node->color;
		texY = 0;
	}

	UI_GetNodeAbsPos(node, pos);

	image = UI_GetReferenceString(node, node->image);
	if (image) {
		const int texX = rint(EXTRADATA(node).texl[0]);
		texY += EXTRADATA(node).texl[1];
		UI_DrawNormImageByName(qfalse, pos[0], pos[1], node->size[0], node->size[1],
			texX + node->size[0], texY + node->size[1], texX, texY, image);
	}

	if (EXTRADATA(node).background) {
		UI_DrawSpriteInBox(qfalse, EXTRADATA(node).background, iconStatus, pos[0], pos[1], node->size[0], node->size[1]);
	}

	if (EXTRADATA(node).super.icon) {
		UI_DrawSpriteInBox(EXTRADATA(node).super.flipIcon, EXTRADATA(node).super.icon, iconStatus, pos[0], pos[1], node->size[0], node->size[1]);
	}

	text = UI_GetReferenceString(node, node->text);
	if (text != NULL && *text != '\0') {
		R_Color(textColor);
		UI_DrawStringInBox(font, node->contentAlign,
			pos[0] + node->padding, pos[1] + node->padding,
			node->size[0] - node->padding - node->padding, node->size[1] - node->padding - node->padding,
			text, LONGLINES_PRETTYCHOP);
		R_Color(NULL);
	}
}
示例#4
0
/**
 * @param[in] status The state of the sprite node
 * @param[in] sprite Context sprite
 * @param[in] posX Absolute X position of the top-left corner
 * @param[in] posY Absolute Y position of the top-left corner
 * @param[in] sizeX Width of the bounded box
 * @param[in] sizeY Height of the bounded box
 * @todo use named const for status
 */
void UI_DrawSpriteInBox (const uiSprite_t* sprite, uiSpriteStatus_t status, int posX, int posY, int sizeX, int sizeY)
{
	int texX;
	int texY;
	const char* image;

	/** @todo Add warning */
	if (status >= SPRITE_STATUS_MAX)
		return;

	/** @todo merge all this cases */
	if (sprite->single || sprite->blend) {
		texX = sprite->pos[SPRITE_STATUS_NORMAL][0];
		texY = sprite->pos[SPRITE_STATUS_NORMAL][1];
		image = sprite->image[SPRITE_STATUS_NORMAL];
	} else if (sprite->pack64) {
		texX = sprite->pos[SPRITE_STATUS_NORMAL][0];
		texY = sprite->pos[SPRITE_STATUS_NORMAL][1] + (64 * status);
		image = sprite->image[SPRITE_STATUS_NORMAL];
	} else {
		texX = sprite->pos[status][0];
		texY = sprite->pos[status][1];
		image = sprite->image[status];
		if (!image) {
			texX = sprite->pos[SPRITE_STATUS_NORMAL][0];
			texY = sprite->pos[SPRITE_STATUS_NORMAL][1];
			image = sprite->image[SPRITE_STATUS_NORMAL];
		}
	}
	if (!image)
		return;

	posX += (sizeX - sprite->size[0]) / 2;
	posY += (sizeY - sprite->size[1]) / 2;

	if (sprite->blend) {
		const vec_t *color;
		color = sprite->color[status];
		R_Color(color);
	}

	UI_DrawNormImageByName(posX, posY, sprite->size[0], sprite->size[1],
		texX + sprite->size[0], texY + sprite->size[1], texX, texY, image);
	if (sprite->blend)
		R_Color(NULL);
}
/**
 * @brief Handles RadioButton draw
 * @todo need to implement image. We can't do everything with only one icon (or use another icon)
 */
static void UI_RadioButtonNodeDraw (uiNode_t *node)
{
	vec2_t pos;
	uiSpriteStatus_t iconStatus;
	const qboolean disabled = node->disabled || node->parent->disabled;
	int texY;
	const char *image;
	const qboolean isSelected = UI_RadioButtonNodeIsSelected(node);

	if (disabled) {
		iconStatus = SPRITE_STATUS_DISABLED;
		texY = UI_4STATUS_TEX_HEIGHT * 2;
	} else if (isSelected) {
		iconStatus = SPRITE_STATUS_CLICKED;
		texY = UI_4STATUS_TEX_HEIGHT * 3;
	} else if (node->state) {
		iconStatus = SPRITE_STATUS_HOVER;
		texY = UI_4STATUS_TEX_HEIGHT;
	} else {
		iconStatus = SPRITE_STATUS_NORMAL;
		texY = 0;
	}

	UI_GetNodeAbsPos(node, pos);

	image = UI_GetReferenceString(node, node->image);
	if (image) {
		const int texX = 0;
		UI_DrawNormImageByName(qfalse, pos[0], pos[1], node->size[0], node->size[1],
			texX + node->size[0], texY + node->size[1], texX, texY, image);
	}

	if (EXTRADATA(node).background) {
		UI_DrawSpriteInBox(qfalse, EXTRADATA(node).background, iconStatus, pos[0], pos[1], node->size[0], node->size[1]);
	}

	if (EXTRADATA(node).icon) {
		UI_DrawSpriteInBox(EXTRADATA(node).flipIcon, EXTRADATA(node).icon, iconStatus, pos[0], pos[1], node->size[0], node->size[1]);
	}
}
示例#6
0
/**
 * @sa CMod_GetMapSize
 * @note we only need to handle the 2d plane and can ignore the z level
 * @param[in] node Node description of the radar
 */
void uiRadarNode::draw (uiNode_t* node)
{
	vec2_t pos;
	vec2_t screenPos;
#ifdef RADARSIZE_DEBUG
	int textposy = 40;
	static const vec4_t red = {1, 0, 0, 0.5};
#endif

	static const vec4_t backgroundColor = {0.0, 0.0, 0.0, 1};
	const float mapWidth = cl.mapData->mapBox.getWidthX();
	const float mapHeight = cl.mapData->mapBox.getWidthY();

	/** @todo use the same coef for x and y */
	const float mapCoefX = (float) node->box.size[0] / (float) mapWidth;
	const float mapCoefY = (float) node->box.size[1] / (float) mapHeight;

	if (cls.state != ca_active)
		return;

	UI_GetNodeAbsPos(node, pos);
	UI_GetNodeScreenPos(node, screenPos);
	R_CleanupDepthBuffer(pos[0], pos[1], node->box.size[0], node->box.size[1]);
	UI_DrawFill(pos[0], pos[1], mapWidth * mapCoefX, mapHeight * mapCoefY, backgroundColor);
#ifndef RADARSIZE_DEBUG
	UI_PushClipRect(screenPos[0], screenPos[1], node->box.size[0], node->box.size[1]);
#endif

	/* the cl struct is wiped with every new map */
	if (!cl.radarInitialized) {
		UI_InitRadar(node);
		cl.radarInitialized = true;
	}

	/* update context */
	radar.x = pos[0];
	radar.y = pos[1];
	radar.w = node->box.size[0];
	radar.h = node->box.size[1];
	if (radar.gridWidth < 6)
		radar.gridWidth = 6;
	if (radar.gridHeight < 6)
		radar.gridHeight = 6;

#ifdef RADARSIZE_DEBUG
	UI_DrawStringInBox("f_small", ALIGN_UL, 50, textposy, 500, 25, va("%fx%f %fx%f map", cl.mapData->mapBox.getMinX(), cl.mapData->mapBox.getMinY(), cl.mapData->getMaxX(), cl.mapData->getMaxY()));
	textposy += 25;
	UI_DrawStringInBox("f_small", ALIGN_UL, 50, textposy, 500, 25, va("%fx%f map", mapWidth, mapHeight));
	textposy += 25;
#endif

	/* draw background */
	for (int i = 0; i < radar.numImages; i++) {
		vec2_t imagePos;
		hudRadarImage_t* tile = &radar.images[i];
		int maxlevel = cl_worldlevel->integer;

		/* check the max level value for this map tile */
		if (maxlevel >= tile->maxlevel)
			maxlevel = tile->maxlevel - 1;
		assert(tile->path[maxlevel]);
		imagePos[0] = radar.x + mapCoefX * (tile->mapX - cl.mapData->mapBox.getMinX());
		imagePos[1] = radar.y + mapCoefY * (tile->mapY - cl.mapData->mapBox.getMinY());

		UI_DrawNormImageByName(false, imagePos[0], imagePos[1],
				mapCoefX * tile->mapWidth, mapCoefY * tile->mapHeight,
				0, 0, 0, 0, tile->path[maxlevel]);
#ifdef RADARSIZE_DEBUG
		UI_DrawStringInBox("f_small", ALIGN_UL, 50, textposy, 500, 25, va("%dx%d %dx%d %s", tile->x, tile->y, tile->width, tile->height, tile->path[maxlevel]));
		textposy += 25;
		UI_DrawStringInBox("f_small", ALIGN_UL, imagePos[0], imagePos[1], 500, 25, va("%dx%d", tile->gridX, tile->gridY));
#endif
	}

#ifdef RADARSIZE_DEBUG
	UI_DrawFill(pos[0], pos[1], 100.0f * mapCoefX, 100.0f * mapCoefY, red);
	UI_DrawFill(pos[0], pos[1], UNIT_SIZE * mapCoefX, UNIT_SIZE * mapCoefY, red);
#endif

	le_t* le = nullptr;
	while ((le = LE_GetNextInUse(le))) {
		vec3_t itempos;
		if (LE_IsInvisible(le))
			continue;

		/* convert to radar area coordinates */
		itempos[0] = pos[0] + (le->origin[0] - cl.mapData->mapBox.getMinX()) * mapCoefX;
		itempos[1] = pos[1] + (mapHeight - (le->origin[1] - cl.mapData->mapBox.getMinY())) * mapCoefY;

		switch (le->type) {
		case ET_ACTOR:
		case ET_ACTOR2x2:
			UI_RadarNodeDrawActor(le, itempos);
			break;
		case ET_ITEM:
			UI_RadarNodeDrawItem(le, itempos);
			break;
		default:
			break;
		}
#ifdef RADARSIZE_DEBUG
		UI_DrawStringInBox("f_small", ALIGN_UL, 50, textposy, 500, 25, va("%fx%f %dx%d actor", le->origin[0], le->origin[1], le->pos[0], le->pos[1]));
		textposy += 25;
		UI_DrawFill(itempos[0], itempos[1], UNIT_SIZE * mapCoefX, 1, red);
		UI_DrawFill(itempos[0], itempos[1], 1, UNIT_SIZE * mapCoefY, red);
#endif
	}

#ifndef RADARSIZE_DEBUG
	UI_PopClipRect();
#endif
}
示例#7
0
/**
 * @brief Normalized access to the texture structure of tab to display a junction between each tabs
 * @param[in] image The normalized tab texture to use
 * @param[in] x The upper-left position of the screen to draw the texture
 * @param[in] y The upper-left position of the screen to draw the texture
 * @param[in] leftType The status of the left tab of the junction we display
 * @param[in] rightType The status of the right tab of the junction we display
 */
static inline void UI_TabNodeDrawJunction (const char *image, int x, int y, ui_tabStatus_t leftType, ui_tabStatus_t rightType)
{
	UI_DrawNormImageByName(false, x, y, TILE_WIDTH, TILE_HEIGHT, TILE_WIDTH + TILE_SIZE * (1 + rightType), TILE_HEIGHT + TILE_SIZE * leftType,
		0 + TILE_SIZE * (1 + rightType), 0 + TILE_SIZE * leftType, image);
}
示例#8
0
/**
 * @brief Normalized access to the texture structure of tab to display the plain part of a tab
 * @param[in] image The normalized tab texture to use
 * @param[in] x The upper-left position of the screen to draw the texture
 * @param[in] y The upper-left position of the screen to draw the texture
 * @param[in] width The width size of the screen to use (stretch)
 * @param[in] type The status of the tab we display
 */
static inline void UI_TabNodeDrawPlain (const char *image, int x, int y, int width, ui_tabStatus_t type)
{
	/* Hack sl=1 to not use the pixel on the left border on the texture (create graphic bug) */
	UI_DrawNormImageByName(false, x, y, width, TILE_HEIGHT, TILE_WIDTH + TILE_SIZE * 0, TILE_HEIGHT + TILE_SIZE * type,
		1 + TILE_SIZE * 0, 0 + TILE_SIZE * type, image);
}
示例#9
0
/**
 * @brief Draws a base.
 */
static void UI_BaseMapNodeDraw (uiNode_t * node)
{
	int width, height, row, col;
	const building_t *building;
	const base_t *base = B_GetCurrentSelectedBase();
	qboolean used[MAX_BUILDINGS];

	if (!base) {
		UI_PopWindow(qfalse);
		return;
	}

	/* reset the used flag */
	OBJZERO(used);

	width = node->size[0] / BASE_SIZE;
	height = node->size[1] / BASE_SIZE + BASE_IMAGE_OVERLAY;

	for (row = 0; row < BASE_SIZE; row++) {
		const char *image = NULL;
		for (col = 0; col < BASE_SIZE; col++) {
			vec2_t pos;
			UI_GetNodeAbsPos(node, pos);
			pos[0] += col * width;
			pos[1] += row * (height - BASE_IMAGE_OVERLAY);

			/* base tile */
			if (B_IsTileBlocked(base, col, row)) {
				building = NULL;
				image = "base/invalid";
			} else if (B_GetBuildingAt(base, col, row) == NULL) {
				building = NULL;
				image = "base/grid";
			} else {
				building = B_GetBuildingAt(base, col, row);
				assert(building);

				if (building->image)
					image = building->image;

				/* some buildings are drawn with two tiles - e.g. the hangar is no square map tile.
				 * These buildings have the needs parameter set to the second building part which has
				 * its own image set, too. We are searching for this second building part here. */
				if (B_BuildingGetUsed(used, building->idx))
					continue;
				B_BuildingSetUsed(used, building->idx);
			}

			/* draw tile */
			if (image != NULL)
				UI_DrawNormImageByName(qfalse, pos[0], pos[1], width * (building ? building->size[0] : 1), height * (building ? building->size[1] : 1), 0, 0, 0, 0, image);
			if (building) {
				switch (building->buildingStatus) {
				case B_STATUS_DOWN:
				case B_STATUS_CONSTRUCTION_FINISHED:
					break;
				case B_STATUS_UNDER_CONSTRUCTION:
					{
						const float time = max(0.0, B_GetConstructionTimeRemain(building));
						UI_DrawString("f_small", ALIGN_UL, pos[0] + 10, pos[1] + 10, pos[0] + 10, node->size[0], 0, va(ngettext("%3.1f day left", "%3.1f days left", time), time), 0, 0, NULL, qfalse, 0);
						break;
					}
					default:
						break;
				}
			}
		}
	}

	if (!node->state)
		return;

	UI_BaseMapGetCellAtPos(node, mousePosX, mousePosY, &col, &row);
	if (col == -1)
		return;

	/* if we are building */
	if (ccs.baseAction == BA_NEWBUILDING) {
		int y, x;
		int xCoord, yCoord, widthRect, heigthRect;
		vec2_t pos;

		assert(base->buildingCurrent);

		for (y = row; y < row + base->buildingCurrent->size[1]; y++) {
			for (x = col; x < col + base->buildingCurrent->size[0]; x++) {
				if (!B_MapIsCellFree(base, x, y))
					return;
			}
		}

		UI_GetNodeAbsPos(node, pos);
		xCoord = pos[0] + col * width;
		yCoord = pos[1] + row * (height - BASE_IMAGE_OVERLAY);
		widthRect = base->buildingCurrent->size[0] * width;
		heigthRect = base->buildingCurrent->size[1] * (height - BASE_IMAGE_OVERLAY);
		R_DrawRect(xCoord, yCoord, widthRect, heigthRect, white, 3, 1);
	}
}
示例#10
0
/**
 * @param[in] flip Flip the icon rendering (horizontal)
 * @param[in] sprite Context sprite
 * @param[in] status The state of the sprite node
 * @param[in] posX,posY Absolute X/Y position of the top-left corner
 * @param[in] sizeX,sizeY Width/height of the bounding box
 */
void UI_DrawSpriteInBox (bool flip, const uiSprite_t* sprite, uiSpriteStatus_t status, int posX, int posY, int sizeX, int sizeY)
{
	float texX;
	float texY;
	const char* image;

	/** @todo Add warning */
	if (status >= SPRITE_STATUS_MAX)
		return;

	/** @todo merge all this cases */
	if (sprite->single || sprite->blend) {
		texX = sprite->pos[SPRITE_STATUS_NORMAL][0];
		texY = sprite->pos[SPRITE_STATUS_NORMAL][1];
		image = sprite->image[SPRITE_STATUS_NORMAL];
	} else if (sprite->pack64) {
		texX = sprite->pos[SPRITE_STATUS_NORMAL][0];
		texY = sprite->pos[SPRITE_STATUS_NORMAL][1] + (64 * status);
		image = sprite->image[SPRITE_STATUS_NORMAL];
	} else {
		texX = sprite->pos[status][0];
		texY = sprite->pos[status][1];
		image = sprite->image[status];
		if (!image) {
			if (texX == 0 && texY == 0) {
				texX = sprite->pos[SPRITE_STATUS_NORMAL][0];
				texY = sprite->pos[SPRITE_STATUS_NORMAL][1];
				image = sprite->image[SPRITE_STATUS_NORMAL];
			} else {
				image = sprite->image[SPRITE_STATUS_NORMAL];
			}
		}
	}
	if (!image)
		return;

	if (sprite->blend) {
		const vec_t* color = sprite->color[status];
		R_Color(color);
	}

	if (sprite->tiled_17_1_3) {
		const vec2_t pos = Vector2FromInt(posX, posY);
		const vec2_t size = Vector2FromInt(sizeX, sizeY);
		UI_DrawPanel(pos, size, image, texX, texY, tile_template_17_1_3);
	} else if (sprite->tiled_25_1_3) {
		const vec2_t pos = Vector2FromInt(posX, posY);
		const vec2_t size = Vector2FromInt(sizeX, sizeY);
		UI_DrawPanel(pos, size, image, texX, texY, tile_template_25_1_3);
	} else if (sprite->tiled_popup) {
		const vec2_t pos = Vector2FromInt(posX, posY);
		const vec2_t size = Vector2FromInt(sizeX, sizeY);
		UI_DrawPanel(pos, size, image, texX, texY, tile_template_popup);
	} else if (sprite->border != 0) {
		const vec2_t pos = Vector2FromInt(posX, posY);
		const vec2_t size = Vector2FromInt(sizeX, sizeY);
		UI_DrawBorderedPanel(pos, size, image, texX, texY, sprite->size[0], sprite->size[1], sprite->border);
	} else {
		posX += (sizeX - sprite->size[0]) / 2;
		posY += (sizeY - sprite->size[1]) / 2;
		UI_DrawNormImageByName(flip, posX, posY, sprite->size[0], sprite->size[1],
			texX + sprite->size[0], texY + sprite->size[1], texX, texY, image);
	}

	if (sprite->blend)
		R_Color(nullptr);
}
示例#11
0
/**
 * @brief Draws an item to the screen
 * @param[in] node Context node
 * @param[in] org Node position on the screen (pixel). Single nodes: Use the center of the node.
 * @param[in] item The item to draw.
 * @param[in] x Position in container. Set this to -1 if it's drawn in a single container.
 * @param[in] y Position in container. Set this to -1 if it's drawn in a single container.
 * @param[in] scale
 * @param[in] color
 * @sa SCR_DrawCursor
 * Used to draw an item to the equipment containers. First look whether the objDef_t
 * includes an image - if there is none then draw the model
 */
void UI_DrawItem (uiNode_t *node, const vec3_t org, const item_t *item, int x, int y, const vec3_t scale, const vec4_t color)
{
	const objDef_t *od = item->item;
	vec4_t col;
	vec3_t origin;

	assert(od);
	assert(org[2] > -1000 && org[2] < 1000); 	/*< prevent use of vec2_t for org */

	Vector4Copy(color, col);
	/* no ammo in this weapon - highlight this item */
	if (od->weapon && od->reload && !item->ammoLeft) {
		col[1] *= 0.5;
		col[2] *= 0.5;
	}

	VectorCopy(org, origin);

	/* Calculate correct location of the image or the model (depends on rotation) */
	/** @todo Change the rotation of the image as well, right now only the location is changed.
	 * How is image-rotation handled right now? */
	if (x >= 0 || y >= 0) {
		/* Add offset of location in container. */
		origin[0] += x * C_UNIT;
		origin[1] += y * C_UNIT;

		/* Add offset for item-center (depends on rotation). */
		if (item->rotated) {
			origin[0] += od->sy * C_UNIT / 2.0;
			origin[1] += od->sx * C_UNIT / 2.0;
			/** @todo Image size calculation depends on handling of image-rotation.
			imgWidth = od->sy * C_UNIT;
			imgHeight = od->sx * C_UNIT;
			*/
		} else {
			origin[0] += od->sx * C_UNIT / 2.0;
			origin[1] += od->sy * C_UNIT / 2.0;
		}
	}

	/* don't handle the od->tech->image here - it's very ufopedia specific in most cases */
	if (od->image[0] != '\0') {
		const int imgWidth = od->sx * C_UNIT;
		const int imgHeight = od->sy * C_UNIT;
		origin[0] -= od->sx * C_UNIT / 2.0;
		origin[1] -= od->sy * C_UNIT / 2.0;

		/* Draw the image. */
		R_Color(color);
		UI_DrawNormImageByName(false, origin[0], origin[1], imgWidth, imgHeight, 0, 0, 0, 0, od->image);
		R_Color(NULL);
	} else {
		uiModel_t *model = NULL;
		const char *modelName = GAME_GetModelForItem(od, &model);

		/* no model definition in the tech struct, not in the fallback object definition */
		if (Q_strnull(modelName)) {
			Com_Printf("UI_DrawItem: No model given for item: '%s'\n", od->id);
			return;
		}

		if (model && node) {
			UI_DrawModelNode(node, modelName);
		} else {
			modelInfo_t mi;
			vec3_t angles = {-10, 160, 70};
			vec3_t size = {scale[0], scale[1], scale[2]};
			vec3_t center;

			if (item->rotated)
				angles[0] -= 90;

			if (od->scale)
				VectorScale(size, od->scale, size);

			VectorNegate(od->center, center);

			OBJZERO(mi);
			mi.origin = origin;
			mi.angles = angles;
			mi.center = center;
			mi.scale = size;
			mi.color = col;
			mi.name = modelName;

			/* draw the model */
			R_DrawModelDirect(&mi, NULL, NULL);
		}
	}
}