Commits

Jason McKesson committed 558b1a7

Added viewport and subimage Lua file helpers.

Comments (0)

Files changed (3)

Documents/Positioning/GenWindingOrder.lua

 require "SvgWriter"
 require "vmath"
+require "SubImage"
 
 -- Sizing
-local numSubImages = 2;
-local subImageWidth, subImageHeight = 300, 300;
-local subImageSpacing = 100;
+local subImages = SubImage.SubImage(2, 1, 300, 300, 100, 0);
 
-local imageWidth = (subImageWidth * numSubImages) + (subImageSpacing * (numSubImages - 1));
-local imageHeight = subImageHeight;
-
-local subImageSize = {subImageWidth, imageHeight};
 local pointSize = 10
-local circleRadius = subImageWidth / 8
-
-local subImagePositions = {}
-
-for i = 1, numSubImages, 1 do
-	subImagePositions[i] = {(subImageWidth + subImageSpacing) * (i-1), 0};
-end
-
-
+local circleRadius = subImages:SubSize().x / 8
 
 -- Styles
 local styleLib = SvgWriter.StyleLibrary();
 
 local trianglePoints =
 {
-	vmath.vec2{subImageWidth * 0.3, (subImageHeight * 0.2)},
-	vmath.vec2{subImageWidth * 0.8, (subImageHeight * 0.6)},
-	vmath.vec2{subImageWidth * 0.1, (subImageHeight * 0.8)},
+	subImages:SubSize() * vmath.vec2{0.3, 0.2},
+	subImages:SubSize() * vmath.vec2{0.8, 0.6},
+	subImages:SubSize() * vmath.vec2{0.1, 0.8},
 }
 
 local cwLabelOffsets = 
 
 
 -- The SVG itself.
-local writer = SvgWriter.SvgWriter("WindingOrder.svg", {imageWidth .."px", imageHeight .. "px"});
+local writer = SvgWriter.SvgWriter("testSubImage.svg", {subImages:Size().x .."px", subImages:Size().y .. "px"});
 	writer:StyleLibrary(styleLib);
 	writer:BeginDefinitions();
 		writer:BeginMarker({pointSize, pointSize}, {pointSize/2, pointSize/2}, "auto", true, nil, "point");
 	writer:EndDefinitions();
 
 	--First subimage: just the triangle.
-	writer:Use("g_triangle", subImagePositions[1], subImageSize, {"black", "fill_none", "pointed"});
-	writer:Use("g_triangle", subImagePositions[2], subImageSize, {"black", "fill_none", "pointed"});
-	writer:Use("g_cwLabels", subImagePositions[1], subImageSize, {"black", "text"});
-	writer:Use("g_cwCircle", subImagePositions[1], subImageSize, {"black", "fill_none"});
-	writer:Use("g_ccwLabels", subImagePositions[2], subImageSize, {"black", "text"});
-	writer:Use("g_ccwCircle", subImagePositions[2], subImageSize, {"black", "fill_none"});
---	writer:Rect(subImagePositions[1], subImageSize, nil, {"black", "fill_none"});
---	writer:Rect(subImagePositions[2], subImageSize, nil, {"black", "fill_none"});
+	writer:Use("g_triangle", subImages:Offset(1, 1), subImages:SubSize(), {"black", "fill_none", "pointed"});
+	writer:Use("g_triangle", subImages:Offset(2, 1), subImages:SubSize(), {"black", "fill_none", "pointed"});
+	writer:Use("g_cwLabels", subImages:Offset(1, 1), subImages:SubSize(), {"black", "text"});
+	writer:Use("g_cwCircle", subImages:Offset(1, 1), subImages:SubSize(), {"black", "fill_none"});
+	writer:Use("g_ccwLabels", subImages:Offset(2, 1), subImages:SubSize(), {"black", "text"});
+	writer:Use("g_ccwCircle", subImages:Offset(2, 1), subImages:SubSize(), {"black", "fill_none"});
+--	writer:Rect(subImages:Offset(1, 1), subImages:SubSize(), nil, {"black", "fill_none"});
+--	writer:Rect(subImages:Offset(2, 1), subImages:SubSize(), nil, {"black", "fill_none"});
 	
 writer:Close();
 

Documents/Tools/SubImage.lua

+
+require "vmath"
+
+module(..., package.seeall);
+
+local ClassMembers = {}
+
+local function AddMembers(classInst, members)
+	members = members or ClassMembers;
+	for funcName, func in pairs(members) do
+		classInst[funcName] = func;
+	end
+end
+
+function ClassMembers:Size()
+	local size = vmath.vec2(0.0, 0.0);
+	
+	size.x = self.subImageSize.x * self.imageArray.x +
+		(self.spacing.x * (self.imageArray.x - 1));
+
+	size.y = self.subImageSize.y * self.imageArray.y +
+		(self.spacing.y * (self.imageArray.y - 1));
+		
+	return size;
+end
+
+function ClassMembers:Offset(x, y)
+	if(y == nil) then
+		y = x.y;
+		x = x.x;
+	end
+
+	x = x - 1;
+	y = y - 1;
+
+	local offset = vmath.vec2(0.0, 0.0);
+
+	offset.x = (self.subImageSize.x + self.spacing.x) * x;
+	offset.y = (self.subImageSize.y + self.spacing.y) * y;
+	
+	return offset;
+end
+
+function ClassMembers:NumImages()
+	return self.imageArray;
+end
+
+function ClassMembers:SubSize()
+	return self.subImageSize;
+end
+
+--Points must be in pixel coordinates, relative to the upper-left.
+function ClassMembers:Transform(image, points)
+	if(vmath.vtype(points) == "table") then
+		local ret = {};
+		local offset = self:Offset(image.x, image.y);
+		for i, realPoint in ipairs(points) do
+			ret[i] = vmath.vec2(points) + offset;
+		end
+		return ret;
+	end
+	
+	return vmath.vec2(points) + self:Offset(image.x, image.y);
+end
+
+
+
+function SubImage(subImagesX, subImagesY, subImageWidth, subImageHeight,
+				  subImageHSpacing, subImageVSpacing)
+
+	if(not subImageHeight) then
+		subImageVSpacing = subImageWidth.y;
+		subImageHSpacing = subImageWidth.x;
+		subImageHeight = subImagesY.y;
+		subImageWidth = subImagesY.x;
+		subImagesY = subImagesX.y;
+		subImagesX = subImagesX.x;
+	end
+	
+	local subImage = {};
+	
+	subImage.subImageSize = vmath.vec2(subImageWidth, subImageHeight);
+	subImage.imageArray = vmath.vec2(subImagesX, subImagesY);
+	subImage.spacing = vmath.vec2(subImageHSpacing, subImageVSpacing);
+	
+	AddMembers(subImage, ClassMembers);
+	
+	return subImage;
+end
+
+
+
+
+

Documents/Tools/Viewport.lua

+
+require "vmath"
+
+module(..., package.seeall);
+
+local function AddMembers(classInst, members)
+	for funcName, func in pairs(members) do
+		classInst[funcName] = func;
+	end
+end
+
+
+--2D Viewport.
+local View2D = {}
+
+function View2D:Size()
+	return self.pixelSize;
+end
+
+--Takes points in viewport space, returns points in pixel space.
+function View2D:Transform(points)
+	if(vmath.vtype(points) == "table") then
+		local ret = {};
+		for i, realPoint in ipairs(points) do
+			ret[i] = self:Transform(realPoint);
+		end
+		return ret;
+	end
+	
+	local point = vmath.vec2(points);
+	if(self.transform) then point = self.transform:Matrix():Transform(point) end;
+	
+	point = point / self.vpSize;
+	point = point * vmath.vec2(1, -1);
+	point = point * self.pixelSize;
+	point = point + self.pxOrigin;
+	
+	return point;
+end
+
+function View2D:SetTransform(transform)
+	self.transform = transform;
+end
+
+
+-- 3D Viewport
+local View3D = {}
+
+function View3D:Size()
+	return self.pixelSize;
+end
+
+--Takes points in 3D viewport space, returns points in 2D pixel space.
+function View3D:Transform(points)
+	if(vmath.vtype(points) == "table") then
+		local ret = {};
+		for i, realPoint in ipairs(points) do
+			ret[i] = self:Transform(realPoint);
+		end
+		return ret;
+	end
+	
+	local point = vmath.vec3(points);
+	if(self.transform) then point = self.transform:Matrix():Transform(point) end;
+	
+	point = point / self.vpSize;
+	point = point * vmath.vec2(1, -1);
+	point = point * self.pixelSize;
+	point = point + self.pxOrigin;
+	
+	return vmath.vec2(point);
+end
+
+function View3D:SetTransform(transform)
+	self.transform = transform;
+end
+
+
+
+-- Transform 2D.
+local function Identity3()
+	return vmath.mat3(vmath.vec3{1, 0, 0}, vmath.vec3{0, 1, 0}, vmath.vec3{0, 0, 1});
+end
+
+local Trans2D = {}
+
+function Trans2D:Translate(offset)
+	local trans = Identity3();
+	trans:SetCol(3, vmath.vec3(offset, 1));
+	self.currMatrix = self.currMatrix * trans;
+end
+
+function Trans2D:Scale(scale)
+	local scaleMat = Identity3();
+	scaleMat[1][1] = scale[1];
+	scaleMat[2][2] = scale[2];
+	self.currMatrix = self.currMatrix * scaleMat;
+end
+
+function Trans2D:Rotate(angleDeg)
+	local rotation = Identity3();
+	angleDeg = math.rad(angleDeg);
+	local sinAng, cosAng = math.sin(angleDeg), math.cos(angleDeg);
+	
+	rotation[1][1] = cosAng; rotation[2][1] = -sinAng;
+	rotation[1][2] = sinAng; rotation[2][2] = cosAng;
+	
+	self.currMatrix = self.currMatrix * rotation;
+end
+
+function Trans2D:Push()
+	if(not self.stack) then
+		self.stack = {};
+		self.stack.top = 0;
+	end
+	
+	self.stack[self.stack.top + 1] = self.currMatrix;
+	self.stack.top = self.stack.top + 1;
+end
+
+function Trans2D:Pop()
+	assert(self.stack, "No Push has been called yet.");
+	assert(self.stack.top > 0, "Matrix stack underflow.");
+	self.currMatrix = self.stack[self.stack.top];
+	self.stack.top = self.stack.top - 1;
+end
+
+function Trans2D:Identity()
+	self.currMatrix = Identity3();
+end
+
+function Trans2D:Matrix()
+	return self.currMatrix;
+end
+
+
+-- Transform 3D.
+local function Identity4()
+	return vmath.mat4(
+		vmath.vec4{1, 0, 0, 0},
+		vmath.vec4{0, 1, 0, 0},
+		vmath.vec3{0, 0, 1, 0},
+		vmath.vec3{0, 0, 0, 1});
+end
+
+local Trans3D = {}
+
+Trans3D.Push = Trans2D.Push;
+Trans3D.Pop = Trans2D.Pop;
+
+function Trans3D:Translate(offset)
+	local trans = Identity4();
+	trans:SetCol(4, vmath.vec4(offset, 1));
+	self.currMatrix = self.currMatrix * trans;
+end
+
+function Trans3D:Scale(scale)
+	local scaleMat = Identity4();
+	scaleMat[1][1] = scale[1];
+	scaleMat[2][2] = scale[2];
+	scaleMat[3][3] = scale[3];
+	self.currMatrix = self.currMatrix * scaleMat;
+end
+
+function Trans3D:RotateX(angleDeg)
+	local rotation = Identity4();
+	angleDeg = math.rad(angleDeg);
+	local sinAng, cosAng = math.sin(angleDeg), math.cos(angleDeg);
+	
+	rotation[2][2] = cosAng; rotation[3][2] = -sinAng;
+	rotation[2][3] = sinAng; rotation[3][3] = cosAng;
+	
+	self.currMatrix = self.currMatrix * rotation;
+end
+
+function Trans3D:RotateY(angleDeg)
+	local rotation = Identity4();
+	angleDeg = math.rad(angleDeg);
+	local sinAng, cosAng = math.sin(angleDeg), math.cos(angleDeg);
+	
+	rotation[1][1] = cosAng; rotation[3][1] = sinAng;
+	rotation[1][3] = -sinAng; rotation[3][3] = cosAng;
+	
+	self.currMatrix = self.currMatrix * rotation;
+end
+
+function Trans3D:RotateZ(angleDeg)
+	local rotation = Identity4();
+	angleDeg = math.rad(angleDeg);
+	local sinAng, cosAng = math.sin(angleDeg), math.cos(angleDeg);
+	
+	rotation[1][1] = cosAng; rotation[2][1] = -sinAng;
+	rotation[1][2] = sinAng; rotation[2][2] = cosAng;
+	
+	self.currMatrix = self.currMatrix * rotation;
+end
+
+function Trans3D:Identity()
+	self.currMatrix = Identity4();
+end
+
+function Trans3D:Matrix()
+	return self.currMatrix;
+end
+
+
+
+function Transform2D()
+	local transform = {};
+	transform.currMatrix = Identity3();
+	AddMembers(transform, Trans2D);
+	return transform;
+end
+
+function Transform3D()
+	local transform = {};
+	transform.currMatrix = Identity4();
+	AddMembers(transform, Trans3D);
+	return transform;
+end
+
+
+function Viewport2D(pixelSize, pxOrigin, vpSize)
+	local viewport = {};
+	
+	viewport.pixelSize = vmath.vec2(pixelSize);
+	viewport.pxOrigin = vmath.vec2(pxOrigin);
+	if(type(vpSize) == "number") then vpSize = vmath.vec2(vpSize, vpSize) end;
+	viewport.vpSize = vmath.vec2(vpSize);
+	
+	AddMembers(viewport, View2D);
+	return viewport;
+end
+
+function Viewport3D(pixelSize, vpOrigin, vpScale)
+	local viewport = {};
+	
+	viewport.pixelSize = vmath.vec2(pixelSize);
+	viewport.vpOrigin = vmath.vec3(vpOrigin);
+	if(type(vpScale) == "number") then vpSize = vmath.vec3(vpSize, vpSize, vpSize) end;
+	viewport.vpScale = vmath.vec3(vpSize);
+	
+	AddMembers(viewport, View3D);
+	return viewport;
+end