Home | History | Annotate | Download | only in scripts
      1 import re
      2 import math
      3 import random
      4 
      5 PREAMBLE = """
      6 # WARNING: This file is auto-generated. Do NOT modify it manually, but rather
      7 # modify the generating script file. Otherwise changes will be lost!
      8 """[1:]
      9 
     10 class CaseGroup(object):
     11 	def __init__(self, name, description, children):
     12 		self.name			= name
     13 		self.description	= description
     14 		self.children		= children
     15 
     16 class ShaderCase(object):
     17 	def __init__(self):
     18 		pass
     19 
     20 g_processedCases = {}
     21 
     22 def indentTextBlock(text, indent):
     23 	indentStr = indent * "\t"
     24 	lines = text.split("\n")
     25 	lines = [indentStr + line for line in lines]
     26 	lines = [ ["", line][line.strip() != ""] for line in lines]
     27 	return "\n".join(lines)
     28 
     29 def writeCase(f, case, indent, prefix):
     30 	print "    %s" % (prefix + case.name)
     31 	if isinstance(case, CaseGroup):
     32 		f.write(indentTextBlock('group %s "%s"\n\n' % (case.name, case.description), indent))
     33 		for child in case.children:
     34 			writeCase(f, child, indent + 1, prefix + case.name + ".")
     35 		f.write(indentTextBlock("\nend # %s\n" % case.name, indent))
     36 	else:
     37 		# \todo [petri] Fix hack.
     38 		fullPath = prefix + case.name
     39 		assert (fullPath not in g_processedCases)
     40 		g_processedCases[fullPath] = None
     41 		f.write(indentTextBlock(str(case) + "\n", indent))
     42 
     43 def writeAllCases(fileName, caseList):
     44 	# Write all cases to file.
     45 	print "  %s.." % fileName
     46 	f = file(fileName, "wb")
     47 	f.write(PREAMBLE + "\n")
     48 	for case in caseList:
     49 		writeCase(f, case, 0, "")
     50 	f.close()
     51 
     52 	print "done! (%d cases written)" % len(g_processedCases)
     53 
     54 # Template operations.
     55 
     56 def genValues(inputs, outputs):
     57 	res = []
     58 	for (name, values) in inputs:
     59 		res.append("input %s = [ %s ];" % (name, " | ".join([str(v) for v in values]).lower()))
     60 	for (name, values) in outputs:
     61 		res.append("output %s = [ %s ];" % (name, " | ".join([str(v) for v in values]).lower()))
     62 	return ("\n".join(res))
     63 
     64 def fillTemplate(template, params):
     65 	s = template
     66 
     67 	for (key, value) in params.items():
     68 		m = re.search(r"^(\s*)\$\{\{%s\}\}$" % key, s, re.M)
     69 		if m is not None:
     70 			start = m.start(0)
     71 			end = m.end(0)
     72 			ws = m.group(1)
     73 			if value is not None:
     74 				repl = "\n".join(["%s%s" % (ws, line) for line in value.split("\n")])
     75 				s = s[:start] + repl + s[end:]
     76 			else:
     77 				s = s[:start] + s[end+1:] # drop the whole line
     78 		else:
     79 			s = s.replace("${{%s}}" % key, value)
     80 	return s
     81 
     82 # Return shuffled version of list
     83 def shuffled(lst):
     84 	tmp = lst[:]
     85 	random.shuffle(tmp)
     86 	return tmp
     87 
     88 def repeatToLength(lst, toLength):
     89 	return (toLength / len(lst)) * lst + lst[: toLength % len(lst)]
     90 
     91 # Helpers to convert a list of Scalar/Vec values into another type.
     92 
     93 def toFloat(lst):	return [Scalar(float(v.x)) for v in lst]
     94 def toInt(lst):		return [Scalar(int(v.x)) for v in lst]
     95 def toUint(lst):	return [Uint(int(v.x)) for v in lst]
     96 def toBool(lst):	return [Scalar(bool(v.x)) for v in lst]
     97 def toVec4(lst):	return [v.toFloat().toVec4() for v in lst]
     98 def toVec3(lst):	return [v.toFloat().toVec3() for v in lst]
     99 def toVec2(lst):	return [v.toFloat().toVec2() for v in lst]
    100 def toIVec4(lst):	return [v.toInt().toVec4() for v in lst]
    101 def toIVec3(lst):	return [v.toInt().toVec3() for v in lst]
    102 def toIVec2(lst):	return [v.toInt().toVec2() for v in lst]
    103 def toBVec4(lst):	return [v.toBool().toVec4() for v in lst]
    104 def toBVec3(lst):	return [v.toBool().toVec3() for v in lst]
    105 def toBVec2(lst):	return [v.toBool().toVec2() for v in lst]
    106 def toUVec4(lst):	return [v.toUint().toUVec4() for v in lst]
    107 def toUVec3(lst):	return [v.toUint().toUVec3() for v in lst]
    108 def toUVec2(lst):	return [v.toUint().toUVec2() for v in lst]
    109 def toMat2(lst):	return [v.toMat2() for v in lst]
    110 def toMat2x3(lst):	return [v.toMat2x3() for v in lst]
    111 def toMat2x4(lst):	return [v.toMat2x4() for v in lst]
    112 def toMat3x2(lst):	return [v.toMat3x2() for v in lst]
    113 def toMat3(lst):	return [v.toMat3() for v in lst]
    114 def toMat3x4(lst):	return [v.toMat3x4() for v in lst]
    115 def toMat4x2(lst):	return [v.toMat4x2() for v in lst]
    116 def toMat4x3(lst):	return [v.toMat4x3() for v in lst]
    117 def toMat4(lst):	return [v.toMat4() for v in lst]
    118 
    119 # Random value generation.
    120 
    121 class GenRandom(object):
    122 	def __init__(self):
    123 		pass
    124 
    125 	def uniformVec4(self, count, mn, mx):
    126 		ret = [Vec4(random.uniform(mn, mx), random.uniform(mn, mx), random.uniform(mn, mx), random.uniform(mn, mx)) for x in xrange(count)]
    127 		ret[0].x = mn
    128 		ret[1].x = mx
    129 		ret[2].x = (mn + mx) * 0.5
    130 		return ret
    131 
    132 	def uniformBVec4(self, count):
    133 		ret = [Vec4(random.random() >= 0.5, random.random() >= 0.5, random.random() >= 0.5, random.random() >= 0.5) for x in xrange(count)]
    134 		ret[0].x = True
    135 		ret[1].x = False
    136 		return ret
    137 
    138 #	def uniform(self,
    139 
    140 # Math operating on Scalar/Vector types.
    141 
    142 def glslSign(a):			return 0.0 if (a == 0) else +1.0 if (a > 0.0) else -1.0
    143 def glslMod(x, y):			return x - y*math.floor(x/y)
    144 def glslClamp(x, mn, mx):	return mn if (x < mn) else mx if (x > mx) else x
    145 
    146 class GenMath(object):
    147 	@staticmethod
    148 	def unary(func):	return lambda val: val.applyUnary(func)
    149 
    150 	@staticmethod
    151 	def binary(func):	return lambda a, b: (b.expandVec(a)).applyBinary(func, a.expandVec(b))
    152 
    153 	@staticmethod
    154 	def frac(val):		return val.applyUnary(lambda x: x - math.floor(x))
    155 
    156 	@staticmethod
    157 	def exp2(val):		return val.applyUnary(lambda x: math.pow(2.0, x))
    158 
    159 	@staticmethod
    160 	def log2(val):		return val.applyUnary(lambda x: math.log(x, 2.0))
    161 
    162 	@staticmethod
    163 	def rsq(val):		return val.applyUnary(lambda x: 1.0 / math.sqrt(x))
    164 
    165 	@staticmethod
    166 	def sign(val):		return val.applyUnary(glslSign)
    167 
    168 	@staticmethod
    169 	def isEqual(a, b):	return Scalar(a.isEqual(b))
    170 
    171 	@staticmethod
    172 	def isNotEqual(a, b):	return Scalar(not a.isEqual(b))
    173 
    174 	@staticmethod
    175 	def step(a, b):		return (b.expandVec(a)).applyBinary(lambda edge, x: [1.0, 0.0][x < edge], a.expandVec(b))
    176 
    177 	@staticmethod
    178 	def length(a):		return a.length()
    179 
    180 	@staticmethod
    181 	def distance(a, b):	return a.distance(b)
    182 
    183 	@staticmethod
    184 	def dot(a, b):		return a.dot(b)
    185 
    186 	@staticmethod
    187 	def cross(a, b):	return a.cross(b)
    188 
    189 	@staticmethod
    190 	def normalize(a):	return a.normalize()
    191 
    192 	@staticmethod
    193 	def boolAny(a):		return a.boolAny()
    194 
    195 	@staticmethod
    196 	def boolAll(a):		return a.boolAll()
    197 
    198 	@staticmethod
    199 	def boolNot(a):		return a.boolNot()
    200 
    201 	@staticmethod
    202 	def abs(a):			return a.abs()
    203 
    204 # ..
    205 
    206 class Scalar(object):
    207 	def __init__(self, x):
    208 		self.x = x
    209 
    210 	def applyUnary(self, func):			return Scalar(func(self.x))
    211 	def applyBinary(self, func, other):	return Scalar(func(self.x, other.x))
    212 
    213 	def isEqual(self, other):	assert isinstance(other, Scalar); return (self.x == other.x)
    214 
    215 	def expandVec(self, val):	return val
    216 	def toScalar(self):			return Scalar(self.x)
    217 	def toVec2(self):			return Vec2(self.x, self.x)
    218 	def toVec3(self):			return Vec3(self.x, self.x, self.x)
    219 	def toVec4(self):			return Vec4(self.x, self.x, self.x, self.x)
    220 	def toUVec2(self):			return UVec2(self.x, self.x)
    221 	def toUVec3(self):			return UVec3(self.x, self.x, self.x)
    222 	def toUVec4(self):			return UVec4(self.x, self.x, self.x, self.x)
    223 	def toMat2(self):			return Mat.fromScalar(2, 2, float(self.x))
    224 	def toMat2x3(self):			return Mat.fromScalar(2, 3, float(self.x))
    225 	def toMat2x4(self):			return Mat.fromScalar(2, 4, float(self.x))
    226 	def toMat3x2(self):			return Mat.fromScalar(3, 2, float(self.x))
    227 	def toMat3(self):			return Mat.fromScalar(3, 3, float(self.x))
    228 	def toMat3x4(self):			return Mat.fromScalar(3, 4, float(self.x))
    229 	def toMat4x2(self):			return Mat.fromScalar(4, 2, float(self.x))
    230 	def toMat4x3(self):			return Mat.fromScalar(4, 3, float(self.x))
    231 	def toMat4(self):			return Mat.fromScalar(4, 4, float(self.x))
    232 
    233 	def toFloat(self):			return Scalar(float(self.x))
    234 	def toInt(self):			return Scalar(int(self.x))
    235 	def toUint(self):			return Uint(int(self.x))
    236 	def toBool(self):			return Scalar(bool(self.x))
    237 
    238 	def getNumScalars(self):	return 1
    239 	def getScalars(self):		return [self.x]
    240 
    241 	def typeString(self):
    242 		if isinstance(self.x, bool):
    243 			return "bool"
    244 		elif isinstance(self.x, int):
    245 			return "int"
    246 		elif isinstance(self.x, float):
    247 			return "float"
    248 		else:
    249 			assert False
    250 
    251 	def vec4Swizzle(self):
    252 		return ""
    253 
    254 	def __str__(self):
    255 		return str(self.x).lower()
    256 
    257 	def __float__(self):
    258 		return float(self.x)
    259 
    260 	def length(self):
    261 		return Scalar(abs(self.x))
    262 
    263 	def distance(self, v):
    264 		assert isinstance(v, Scalar)
    265 		return Scalar(abs(self.x - v.x))
    266 
    267 	def dot(self, v):
    268 		assert isinstance(v, Scalar)
    269 		return Scalar(self.x * v.x)
    270 
    271 	def normalize(self):
    272 		return Scalar(glslSign(self.x))
    273 
    274 	def abs(self):
    275 		if isinstance(self.x, bool):
    276 			return Scalar(self.x)
    277 		else:
    278 			return Scalar(abs(self.x))
    279 
    280 	def __neg__(self):
    281 		return Scalar(-self.x)
    282 
    283 	def __add__(self, val):
    284 		if not isinstance(val, Scalar):
    285 			print val
    286 		assert isinstance(val, Scalar)
    287 		return Scalar(self.x + val.x)
    288 
    289 	def __sub__(self, val):
    290 		return self + (-val)
    291 
    292 	def __mul__(self, val):
    293 		if isinstance(val, Scalar):
    294 			return Scalar(self.x * val.x)
    295 		elif isinstance(val, Vec2):
    296 			return Vec2(self.x * val.x, self.x * val.y)
    297 		elif isinstance(val, Vec3):
    298 			return Vec3(self.x * val.x, self.x * val.y, self.x * val.z)
    299 		elif isinstance(val, Vec4):
    300 			return Vec4(self.x * val.x, self.x * val.y, self.x * val.z, self.x * val.w)
    301 		else:
    302 			assert False
    303 
    304 	def __div__(self, val):
    305 		if isinstance(val, Scalar):
    306 			return Scalar(self.x / val.x)
    307 		elif isinstance(val, Vec2):
    308 			return Vec2(self.x / val.x, self.x / val.y)
    309 		elif isinstance(val, Vec3):
    310 			return Vec3(self.x / val.x, self.x / val.y, self.x / val.z)
    311 		elif isinstance(val, Vec4):
    312 			return Vec4(self.x / val.x, self.x / val.y, self.x / val.z, self.x / val.w)
    313 		else:
    314 			assert False
    315 
    316 class Uint(Scalar):
    317 	def __init__(self, x):
    318 		assert x >= 0
    319 		self.x = x
    320 
    321 	def typeString(self):
    322 		return "uint"
    323 
    324 	def abs(self):
    325 		return Scalar.abs(self).toUint()
    326 
    327 	def __neg__(self):
    328 		return Scalar.__neg__(self).toUint()
    329 
    330 	def __add__(self, val):
    331 		return Scalar.__add__(self, val).toUint()
    332 
    333 	def __sub__(self, val):
    334 		return self + (-val)
    335 
    336 	def __mul__(self, val):
    337 		return Scalar.__mul__(self, val).toUint()
    338 
    339 	def __div__(self, val):
    340 		return Scalar.__div__(self, val).toUint()
    341 
    342 class Vec(object):
    343 	@staticmethod
    344 	def fromScalarList(lst):
    345 		assert (len(lst) >= 1 and len(lst) <= 4)
    346 		if (len(lst) == 1):		return Scalar(lst[0])
    347 		elif (len(lst) == 2):	return Vec2(lst[0], lst[1])
    348 		elif (len(lst) == 3):	return Vec3(lst[0], lst[1], lst[2])
    349 		else:					return Vec4(lst[0], lst[1], lst[2], lst[3])
    350 
    351 	def isEqual(self, other):
    352 		assert isinstance(other, Vec);
    353 		return (self.getScalars() == other.getScalars())
    354 
    355 	def length(self):
    356 		return Scalar(math.sqrt(self.dot(self).x))
    357 
    358 	def normalize(self):
    359 		return self * Scalar(1.0 / self.length().x)
    360 
    361 	def swizzle(self, indexList):
    362 		inScalars = self.getScalars()
    363 		outScalars = map(lambda ndx: inScalars[ndx], indexList)
    364 		return Vec.fromScalarList(outScalars)
    365 
    366 	def __init__(self):
    367 		pass
    368 
    369 class Vec2(Vec):
    370 	def __init__(self, x, y):
    371 		assert(x.__class__ == y.__class__)
    372 		self.x = x
    373 		self.y = y
    374 
    375 	def applyUnary(self, func):			return Vec2(func(self.x), func(self.y))
    376 	def applyBinary(self, func, other):	return Vec2(func(self.x, other.x), func(self.y, other.y))
    377 
    378 	def expandVec(self, val):	return val.toVec2()
    379 	def toScalar(self):			return Scalar(self.x)
    380 	def toVec2(self):			return Vec2(self.x, self.y)
    381 	def toVec3(self):			return Vec3(self.x, self.y, 0.0)
    382 	def toVec4(self):			return Vec4(self.x, self.y, 0.0, 0.0)
    383 	def toUVec2(self):			return UVec2(self.x, self.y)
    384 	def toUVec3(self):			return UVec3(self.x, self.y, 0.0)
    385 	def toUVec4(self):			return UVec4(self.x, self.y, 0.0, 0.0)
    386 	def toMat2(self):			return Mat2(float(self.x), 0.0, 0.0, float(self.y));
    387 
    388 	def toFloat(self):			return Vec2(float(self.x), float(self.y))
    389 	def toInt(self):			return Vec2(int(self.x), int(self.y))
    390 	def toUint(self):			return UVec2(int(self.x), int(self.y))
    391 	def toBool(self):			return Vec2(bool(self.x), bool(self.y))
    392 
    393 	def getNumScalars(self):	return 2
    394 	def getScalars(self):		return [self.x, self.y]
    395 
    396 	def typeString(self):
    397 		if isinstance(self.x, bool):
    398 			return "bvec2"
    399 		elif isinstance(self.x, int):
    400 			return "ivec2"
    401 		elif isinstance(self.x, float):
    402 			return "vec2"
    403 		else:
    404 			assert False
    405 
    406 	def vec4Swizzle(self):
    407 		return ".xyxy"
    408 
    409 	def __str__(self):
    410 		if isinstance(self.x, bool):
    411 			return "bvec2(%s, %s)" % (str(self.x).lower(), str(self.y).lower())
    412 		elif isinstance(self.x, int):
    413 			return "ivec2(%i, %i)" % (self.x, self.y)
    414 		elif isinstance(self.x, float):
    415 			return "vec2(%s, %s)" % (self.x, self.y)
    416 		else:
    417 			assert False
    418 
    419 	def distance(self, v):
    420 		assert isinstance(v, Vec2)
    421 		return (self - v).length()
    422 
    423 	def dot(self, v):
    424 		assert isinstance(v, Vec2)
    425 		return Scalar(self.x*v.x + self.y*v.y)
    426 
    427 	def abs(self):
    428 		if isinstance(self.x, bool):
    429 			return Vec2(self.x, self.y)
    430 		else:
    431 			return Vec2(abs(self.x), abs(self.y))
    432 
    433 	def __neg__(self):
    434 		return Vec2(-self.x, -self.y)
    435 
    436 	def __add__(self, val):
    437 		if isinstance(val, Scalar):
    438 			return Vec2(self.x + val, self.y + val)
    439 		elif isinstance(val, Vec2):
    440 			return Vec2(self.x + val.x, self.y + val.y)
    441 		else:
    442 			assert False
    443 
    444 	def __sub__(self, val):
    445 		return self + (-val)
    446 
    447 	def __mul__(self, val):
    448 		if isinstance(val, Scalar):
    449 			val = val.toVec2()
    450 		assert isinstance(val, Vec2)
    451 		return Vec2(self.x * val.x, self.y * val.y)
    452 
    453 	def __div__(self, val):
    454 		if isinstance(val, Scalar):
    455 			return Vec2(self.x / val.x, self.y / val.x)
    456 		else:
    457 			assert isinstance(val, Vec2)
    458 			return Vec2(self.x / val.x, self.y / val.y)
    459 
    460 	def boolAny(self):	return Scalar(self.x or self.y)
    461 	def boolAll(self):	return Scalar(self.x and self.y)
    462 	def boolNot(self):	return Vec2(not self.x, not self.y)
    463 
    464 class UVec2(Vec2):
    465 	def __init__(self, x, y):
    466 		assert isinstance(x, int) and isinstance(y, int)
    467 		assert x >= 0 and y >= 0
    468 		Vec2.__init__(self, x, y)
    469 
    470 	def typeString(self):
    471 		return "uvec2"
    472 
    473 	def __str__(self):
    474 		return "uvec2(%i, %i)" % (self.x, self.y)
    475 
    476 	def abs(self):
    477 		return Vec2.abs(self).toUint()
    478 
    479 class Vec3(Vec):
    480 	def __init__(self, x, y, z):
    481 		assert((x.__class__ == y.__class__) and (x.__class__ == z.__class__))
    482 		self.x = x
    483 		self.y = y
    484 		self.z = z
    485 
    486 	def applyUnary(self, func):			return Vec3(func(self.x), func(self.y), func(self.z))
    487 	def applyBinary(self, func, other):	return Vec3(func(self.x, other.x), func(self.y, other.y), func(self.z, other.z))
    488 
    489 	def expandVec(self, val):	return val.toVec3()
    490 	def toScalar(self):			return Scalar(self.x)
    491 	def toVec2(self):			return Vec2(self.x, self.y)
    492 	def toVec3(self):			return Vec3(self.x, self.y, self.z)
    493 	def toVec4(self):			return Vec4(self.x, self.y, self.z, 0.0)
    494 	def toUVec2(self):			return UVec2(self.x, self.y)
    495 	def toUVec3(self):			return UVec3(self.x, self.y, self.z)
    496 	def toUVec4(self):			return UVec4(self.x, self.y, self.z, 0.0)
    497 	def toMat3(self):			return Mat3(float(self.x), 0.0, 0.0,  0.0, float(self.y), 0.0,  0.0, 0.0, float(self.z));
    498 
    499 	def toFloat(self):			return Vec3(float(self.x), float(self.y), float(self.z))
    500 	def toInt(self):			return Vec3(int(self.x), int(self.y), int(self.z))
    501 	def toUint(self):			return UVec3(int(self.x), int(self.y), int(self.z))
    502 	def toBool(self):			return Vec3(bool(self.x), bool(self.y), bool(self.z))
    503 
    504 	def getNumScalars(self):	return 3
    505 	def getScalars(self):		return [self.x, self.y, self.z]
    506 
    507 	def typeString(self):
    508 		if isinstance(self.x, bool):
    509 			return "bvec3"
    510 		elif isinstance(self.x, int):
    511 			return "ivec3"
    512 		elif isinstance(self.x, float):
    513 			return "vec3"
    514 		else:
    515 			assert False
    516 
    517 	def vec4Swizzle(self):
    518 		return ".xyzx"
    519 
    520 	def __str__(self):
    521 		if isinstance(self.x, bool):
    522 			return "bvec3(%s, %s, %s)" % (str(self.x).lower(), str(self.y).lower(), str(self.z).lower())
    523 		elif isinstance(self.x, int):
    524 			return "ivec3(%i, %i, %i)" % (self.x, self.y, self.z)
    525 		elif isinstance(self.x, float):
    526 			return "vec3(%s, %s, %s)" % (self.x, self.y, self.z)
    527 		else:
    528 			assert False
    529 
    530 	def distance(self, v):
    531 		assert isinstance(v, Vec3)
    532 		return (self - v).length()
    533 
    534 	def dot(self, v):
    535 		assert isinstance(v, Vec3)
    536 		return Scalar(self.x*v.x + self.y*v.y + self.z*v.z)
    537 
    538 	def cross(self, v):
    539 		assert isinstance(v, Vec3)
    540 		return Vec3(self.y*v.z - v.y*self.z,
    541 					self.z*v.x - v.z*self.x,
    542 					self.x*v.y - v.x*self.y)
    543 
    544 	def abs(self):
    545 		if isinstance(self.x, bool):
    546 			return Vec3(self.x, self.y, self.z)
    547 		else:
    548 			return Vec3(abs(self.x), abs(self.y), abs(self.z))
    549 
    550 	def __neg__(self):
    551 		return Vec3(-self.x, -self.y, -self.z)
    552 
    553 	def __add__(self, val):
    554 		if isinstance(val, Scalar):
    555 			return Vec3(self.x + val, self.y + val)
    556 		elif isinstance(val, Vec3):
    557 			return Vec3(self.x + val.x, self.y + val.y, self.z + val.z)
    558 		else:
    559 			assert False
    560 
    561 	def __sub__(self, val):
    562 		return self + (-val)
    563 
    564 	def __mul__(self, val):
    565 		if isinstance(val, Scalar):
    566 			val = val.toVec3()
    567 		assert isinstance(val, Vec3)
    568 		return Vec3(self.x * val.x, self.y * val.y, self.z * val.z)
    569 
    570 	def __div__(self, val):
    571 		if isinstance(val, Scalar):
    572 			return Vec3(self.x / val.x, self.y / val.x, self.z / val.x)
    573 		elif isinstance(val, Vec3):
    574 			return Vec3(self.x / val.x, self.y / val.y, self.z / val.z)
    575 		else:
    576 			assert False
    577 
    578 	def boolAny(self):	return Scalar(self.x or self.y or self.z)
    579 	def boolAll(self):	return Scalar(self.x and self.y and self.z)
    580 	def boolNot(self):	return Vec3(not self.x, not self.y, not self.z)
    581 
    582 class UVec3(Vec3):
    583 	def __init__(self, x, y, z):
    584 		assert isinstance(x, int) and isinstance(y, int) and isinstance(z, int)
    585 		assert x >= 0 and y >= 0 and z >= 0
    586 		Vec3.__init__(self, x, y, z)
    587 
    588 	def typeString(self):
    589 		return "uvec3"
    590 
    591 	def __str__(self):
    592 		return "uvec3(%i, %i, %i)" % (self.x, self.y, self.z)
    593 
    594 	def abs(self):
    595 		return Vec3.abs(self).toUint()
    596 
    597 class Vec4(Vec):
    598 	def __init__(self, x, y, z, w):
    599 		assert((x.__class__ == y.__class__) and (x.__class__ == z.__class__) and (x.__class__ == w.__class__))
    600 		self.x = x
    601 		self.y = y
    602 		self.z = z
    603 		self.w = w
    604 
    605 	def applyUnary(self, func):			return Vec4(func(self.x), func(self.y), func(self.z), func(self.w))
    606 	def applyBinary(self, func, other):	return Vec4(func(self.x, other.x), func(self.y, other.y), func(self.z, other.z), func(self.w, other.w))
    607 
    608 	def expandVec(self, val):	return val.toVec4()
    609 	def toScalar(self):			return Scalar(self.x)
    610 	def toVec2(self):			return Vec2(self.x, self.y)
    611 	def toVec3(self):			return Vec3(self.x, self.y, self.z)
    612 	def toVec4(self):			return Vec4(self.x, self.y, self.z, self.w)
    613 	def toUVec2(self):			return UVec2(self.x, self.y)
    614 	def toUVec3(self):			return UVec3(self.x, self.y, self.z)
    615 	def toUVec4(self):			return UVec4(self.x, self.y, self.z, self.w)
    616 	def toMat2(self):			return Mat2(float(self.x), float(self.y), float(self.z), float(self.w))
    617 	def toMat4(self):			return Mat4(float(self.x), 0.0, 0.0, 0.0,  0.0, float(self.y), 0.0, 0.0,  0.0, 0.0, float(self.z), 0.0,  0.0, 0.0, 0.0, float(self.w));
    618 
    619 	def toFloat(self):			return Vec4(float(self.x), float(self.y), float(self.z), float(self.w))
    620 	def toInt(self):			return Vec4(int(self.x), int(self.y), int(self.z), int(self.w))
    621 	def toUint(self):			return UVec4(int(self.x), int(self.y), int(self.z), int(self.w))
    622 	def toBool(self):			return Vec4(bool(self.x), bool(self.y), bool(self.z), bool(self.w))
    623 
    624 	def getNumScalars(self):	return 4
    625 	def getScalars(self):		return [self.x, self.y, self.z, self.w]
    626 
    627 	def typeString(self):
    628 		if isinstance(self.x, bool):
    629 			return "bvec4"
    630 		elif isinstance(self.x, int):
    631 			return "ivec4"
    632 		elif isinstance(self.x, float):
    633 			return "vec4"
    634 		else:
    635 			assert False
    636 
    637 	def vec4Swizzle(self):
    638 		return ""
    639 
    640 	def __str__(self):
    641 		if isinstance(self.x, bool):
    642 			return "bvec4(%s, %s, %s, %s)" % (str(self.x).lower(), str(self.y).lower(), str(self.z).lower(), str(self.w).lower())
    643 		elif isinstance(self.x, int):
    644 			return "ivec4(%i, %i, %i, %i)" % (self.x, self.y, self.z, self.w)
    645 		elif isinstance(self.x, float):
    646 			return "vec4(%s, %s, %s, %s)" % (self.x, self.y, self.z, self.w)
    647 		else:
    648 			assert False
    649 
    650 	def distance(self, v):
    651 		assert isinstance(v, Vec4)
    652 		return (self - v).length()
    653 
    654 	def dot(self, v):
    655 		assert isinstance(v, Vec4)
    656 		return Scalar(self.x*v.x + self.y*v.y + self.z*v.z + self.w*v.w)
    657 
    658 	def abs(self):
    659 		if isinstance(self.x, bool):
    660 			return Vec4(self.x, self.y, self.z, self.w)
    661 		else:
    662 			return Vec4(abs(self.x), abs(self.y), abs(self.z), abs(self.w))
    663 
    664 	def __neg__(self):
    665 		return Vec4(-self.x, -self.y, -self.z, -self.w)
    666 
    667 	def __add__(self, val):
    668 		if isinstance(val, Scalar):
    669 			return Vec3(self.x + val, self.y + val)
    670 		elif isinstance(val, Vec4):
    671 			return Vec4(self.x + val.x, self.y + val.y, self.z + val.z, self.w + val.w)
    672 		else:
    673 			assert False
    674 
    675 	def __sub__(self, val):
    676 		return self + (-val)
    677 
    678 	def __mul__(self, val):
    679 		if isinstance(val, Scalar):
    680 			val = val.toVec4()
    681 		assert isinstance(val, Vec4)
    682 		return Vec4(self.x * val.x, self.y * val.y, self.z * val.z, self.w * val.w)
    683 
    684 	def __div__(self, val):
    685 		if isinstance(val, Scalar):
    686 			return Vec4(self.x / val.x, self.y / val.x, self.z / val.x, self.w / val.x)
    687 		elif isinstance(val, Vec4):
    688 			return Vec4(self.x / val.x, self.y / val.y, self.z / val.z, self.w / val.w)
    689 		else:
    690 			assert False
    691 
    692 	def boolAny(self):	return Scalar(self.x or self.y or self.z or self.w)
    693 	def boolAll(self):	return Scalar(self.x and self.y and self.z and self.w)
    694 	def boolNot(self):	return Vec4(not self.x, not self.y, not self.z, not self.w)
    695 
    696 class UVec4(Vec4):
    697 	def __init__(self, x, y, z, w):
    698 		assert isinstance(x, int) and isinstance(y, int) and isinstance(z, int) and isinstance(w, int)
    699 		assert x >= 0 and y >= 0 and z >= 0 and w >= 0
    700 		Vec4.__init__(self, x, y, z, w)
    701 
    702 	def typeString(self):
    703 		return "uvec4"
    704 
    705 	def __str__(self):
    706 		return "uvec4(%i, %i, %i, %i)" % (self.x, self.y, self.z, self.w)
    707 
    708 	def abs(self):
    709 		return Vec4.abs(self).toUint()
    710 
    711 # \note Column-major storage.
    712 class Mat(object):
    713 	def __init__ (self, numCols, numRows, scalars):
    714 		assert len(scalars) == numRows*numCols
    715 		self.numCols	= numCols
    716 		self.numRows	= numRows
    717 		self.scalars	= scalars
    718 
    719 	@staticmethod
    720 	def fromScalar (numCols, numRows, scalar):
    721 		scalars = []
    722 		for col in range(0, numCols):
    723 			for row in range(0, numRows):
    724 				scalars.append(scalar if col == row else 0.0)
    725 		return Mat(numCols, numRows, scalars)
    726 
    727 	@staticmethod
    728 	def identity (numCols, numRows):
    729 		return Mat.fromScalar(numCols, numRows, 1.0)
    730 
    731 	def get (self, colNdx, rowNdx):
    732 		assert 0 <= colNdx and colNdx < self.numCols
    733 		assert 0 <= rowNdx and rowNdx < self.numRows
    734 		return self.scalars[colNdx*self.numRows + rowNdx]
    735 
    736 	def set (self, colNdx, rowNdx, scalar):
    737 		assert 0 <= colNdx and colNdx < self.numCols
    738 		assert 0 <= rowNdx and rowNdx < self.numRows
    739 		self.scalars[colNdx*self.numRows + rowNdx] = scalar
    740 
    741 	def toMatrix (self, numCols, numRows):
    742 		res = Mat.identity(numCols, numRows)
    743 		for col in range(0, min(self.numCols, numCols)):
    744 			for row in range(0, min(self.numRows, numRows)):
    745 				res.set(col, row, self.get(col, row))
    746 		return res
    747 
    748 	def toMat2 (self):		return self.toMatrix(2, 2)
    749 	def toMat2x3 (self):	return self.toMatrix(2, 3)
    750 	def toMat2x4 (self):	return self.toMatrix(2, 4)
    751 	def toMat3x2 (self):	return self.toMatrix(3, 2)
    752 	def toMat3 (self):		return self.toMatrix(3, 3)
    753 	def toMat3x4 (self):	return self.toMatrix(3, 4)
    754 	def toMat4x2 (self):	return self.toMatrix(4, 2)
    755 	def toMat4x3 (self):	return self.toMatrix(4, 3)
    756 	def toMat4 (self):		return self.toMatrix(4, 4)
    757 
    758 	def typeString(self):
    759 		if self.numRows == self.numCols:
    760 			return "mat%d" % self.numRows
    761 		else:
    762 			return "mat%dx%d" % (self.numCols, self.numRows)
    763 
    764 	def __str__(self):
    765 		return "%s(%s)" % (self.typeString(), ", ".join(["%s" % s for s in self.scalars]))
    766 
    767 	def isTypeEqual (self, other):
    768 		return isinstance(other, Mat) and self.numRows == other.numRows and self.numCols == other.numCols
    769 
    770 	def isEqual(self, other):
    771 		assert self.isTypeEqual(other)
    772 		return (self.scalars == other.scalars)
    773 
    774 	def compMul(self, val):
    775 		assert self.isTypeEqual(val)
    776 		return Mat(self.numRows, self.numCols, [self.scalars(i) * val.scalars(i) for i in range(self.numRows*self.numCols)])
    777 
    778 class Mat2(Mat):
    779 	def __init__(self, m00, m01, m10, m11):
    780 		Mat.__init__(self, 2, 2, [m00, m10, m01, m11])
    781 
    782 class Mat3(Mat):
    783 	def __init__(self, m00, m01, m02, m10, m11, m12, m20, m21, m22):
    784 		Mat.__init__(self, 3, 3, [m00, m10, m20,
    785 								  m01, m11, m21,
    786 								  m02, m12, m22])
    787 
    788 class Mat4(Mat):
    789 	def __init__(self, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33):
    790 		Mat.__init__(self, 4, 4, [m00, m10, m20, m30,
    791 								  m01, m11, m21, m31,
    792 								  m02, m12, m22, m32,
    793 								  m03, m13, m23, m33])
    794