TGB/Other Resources/Primitives

From TDN



Primitives for TGB


Synopsis: Scene objects for quads, rectangles, triangles, rounded rectangles, progress bars, arcs, ellipses, etc. Multiple rendering modes for outlines, fills and vertex colouring for fake 2D lighting etc.

Resource created by: Matthew "Ashteth" Kee


Includes the following files:

t2dDraw - A C++ only singleton that does all the actual drawing. Using this class allows common drawing routines to be shared.
Status: 80% complete

t2dRoundedQuad- A rectangle in which the four corners may be toggled into rounded circles. There is no gradient effect for this class. The outline may optionally be displayed in a different colour.
Status: Complete

t2dQuad - A rectangle. May be rendered as a solid colour or blended with each corner assigned a seperate color. A border may optionally be displayed. The border has its own colour settings.
Status: Complete

t2dTriangle - A triangle. May be rendered as a solid colour or blended with each of the three vertices using a seperate colour. Triangle vertices may be assigned to any of the four corners of the t2dSceneObject bounding box. They may also be assigned to positions half way between any two adjacent points on the bounding box's outer parameter. In other words, you have 8 points to chose from to assign vertices to. A border may optionally be displayed. The border has its own colour settings.
Status: Complete

t2dEllipse - A disk / circle / ellipse rendering class. May be rendered as a solid or blended with an inner and outer colour. The ellipse is automatically sized to the size of the t2dSceneObject bounding box. Optionally, an inner radius may be assigned. The width of the inner radius will not be rendered. Currenty if an inner radius is assigned, the ellipse displays as a circle with its radius as the smaller of the width/height of the bounding box. This was done to make life simpler for the programmer, but eventually should be changed.
Status: 90% complete

t2dProgressBar - A quad in which the bounding box is filled a percent of completion (from zero to 1).
Status: 90% complete

t2dArc - Render a portion (or all) of a circle with an inner and outer radius. May be rendered as a solid colour or blended with an inner and outer colour.
Status: 90% complete

t2dPolygon - An Arbitrary set of points that may be rendered with an optional border.
Status: 25% complete

t2dLineStrip - A line strip of 1 or more points. May be solid coloured or blended.
Status: 75% complete

To download, please follow this link.

Drawing Lines in Vanilla TGB


If you are looking to draw lines/polygons in TGB without recompiling the source, here is some source for drawing a line, tested with TGB 1.1.3 (and recently, 1.7.4). The trick is that all of the points must be drawn inside the range -1, 1. So you can't normally just draw a line between two points of your choosing. This code accounts for that and resizes the shape so the line draws between two world points. Similar logic can be used to draw polygons. If there is enough demand (contact user J. Alan Atherton) then I can come up with code for drawing polygons. Drawing anything else just from TGB would be slow at this point, so you'll want to wait for the above project to complete.

// Draws a line between point 1 and point 2.
// Points should be in t2dvector format, e.g. "4.3 6.5"
function drawLine(%p1, %p2, %color) {
   // Vector between two points
   %v = t2dVectorSub(%p2, %p1);
   
   // Size of bounding box of line
   %w = mAbs(getWord(%v, 0));
   %h = mAbs(getWord(%v, 1));
   
   // Extract individual coordinates of points
   %x1 = getWord(%p1, 0);
   %y1 = getWord(%p1, 1);
   
   // All of that mess figures out whether x2 should be on the right or left
   %x2 = mClamp((getWord(%p2, 0)-%x1)/%w, -1, 1);
   %y2 = mClamp((getWord(%p2, 1)-%y1)/%h, -1, 1);
   
   // Make p1 be on the opposite corner from p2
   %x1 = -1*%x2;
   %y1 = -1*%y2;
   
   %s = new t2dShapeVector();
   %s.setLineColor(%color);
   
   // This defines the shape... number of vertices, then a point for each vertex
   %s.setPolyCustom(2, %x1 SPC %y1 SPC %x2 SPC %y2);
   
   %s.setSize(%w SPC %h);

   // I don't know exactly why this works, but it does.
   %s.setPosition(t2dVectorAdd(%p1, t2dVectorScale(%v, 0.5)));
   
   // No need to fill
   %s.setFillMode(0);
   
   // So it draws.
   %s.addToScene(mainScene);
   
   return %s;
}

Drawing Thick Lines in Vanilla TGB


If you want the lines to have some thickness, the below code works. Note that the thickness is in world coordinates. If you want thickness in screen coordinates, you'll have to do a little bit of work with the world/window conversion functions. And you'll have to dynamically update the shape whenever the camera zoom changes.
Anyway, the basic idea behind drawing a thick line is to really draw a rectangle. So you just have to figure out what the rectangle is that defines the line at a given thickness.

// Draws a thick line between point 1 and point 2.
// Points should be in t2dvector format, e.g. "4.3 6.5"
// *** Thickness is in world coordinates
// Written by J. Alan Atherton 2008
function drawLine(%point1, %point2, %color, %thickness) {

	// Validate thickness
	if(!%thickness || %thickness <= 0) {
		%thickness = 1;
	}	

	// Vector between two points
	%v = t2dVectorSub(%point2, %point1);
	
	// Norm is the direction perpendicular to the line (needed for thickness)
	%norm = VectorNormalize(VectorCross(%v SPC 0, "0 0 1"));
	
	// This is the offset from the line
	%half = t2dVectorScale(getWords(%norm, 0,1), 0.5*%thickness);
	
	// These are the actual points in world space that make up the line-rectangle
	%p1 = t2dVectorSub(%point1, %half);
	%p2 = t2dVectorAdd(%point1, %half);
	%p3 = t2dVectorAdd(%point2, %half);
	%p4 = t2dVectorSub(%point2, %half);
	
	// Set some initial values for finding the min/max
	%xmax = getWord(%p1,0);
	%xmin = getWord(%p1,0);

	%ymax = getWord(%p1,1);
	%ymin = getWord(%p1,1);
	
	// Find the min/max values
	for(%i = 1; %i <= 4; %i++) {
		%x = getWord(%p[%i],0);
		%y = getWord(%p[%i],1);
		if(%x > %xmax) {
			%xmax = %x;
		}
		if(%y > %ymax) {
			%ymax = %y;
		}

		if(%x < %xmin) {
			%xmin = %x;
		}
		if(%y < %ymin) {
			%ymin = %y;
		}
	}
	
	// Size of bounding box of rectangle
	%w = %xmax-%xmin;
	%h = %ymax-%ymin;
	
	// Extract individual coordinates of points, and change their coordinate system
	// The coord system for the shape is -1 to 1
	for(%i = 1; %i <= 4; %i++) {
		%x[%i] = (2*(getWord(%p[%i], 0) - %xmin) / %w) - 1;
		%y[%i] = (2*(getWord(%p[%i], 1) - %ymin) / %h) - 1;
	}
	
	// Create the shape object	
	%s = new t2dShapeVector();
	
	// Line color is the border, fill color is the inside
	%s.setLineColor(%color);
	%s.setFillColor(%color);
	
	// This defines the shape... number of vertices, then a point for each vertex
	%s.setPolyCustom(4, %x1 SPC %y1 SPC %x2 SPC %y2 SPC %x3 SPC %y3 SPC %x4 SPC %y4);
	
	%s.setSize(%w SPC %h);
	
	// We have to set the position to the center of the line
	%s.setPosition(t2dVectorAdd(%point1, t2dVectorScale(%v, 0.5)));
	
	// Need to fill, or if you want a hollow line you could set no fill
	%s.setFillMode(1);
	
	// So it draws.  You could change this to add to a particular scenegraph
	%s.addToScene(sceneWindow2D.getSceneGraph());
	
	return %s;
}