1import re 2import math 3import random 4 5PREAMBLE = """ 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 10class CaseGroup(object): 11 def __init__(self, name, description, children): 12 self.name = name 13 self.description = description 14 self.children = children 15 16class ShaderCase(object): 17 def __init__(self): 18 pass 19 20g_processedCases = {} 21 22def 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 29def 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 43def 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 56def 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 64def 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 83def shuffled(lst): 84 tmp = lst[:] 85 random.shuffle(tmp) 86 return tmp 87 88def 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 93def toFloat(lst): return [Scalar(float(v.x)) for v in lst] 94def toInt(lst): return [Scalar(int(v.x)) for v in lst] 95def toUint(lst): return [Uint(int(v.x)) for v in lst] 96def toBool(lst): return [Scalar(bool(v.x)) for v in lst] 97def toVec4(lst): return [v.toFloat().toVec4() for v in lst] 98def toVec3(lst): return [v.toFloat().toVec3() for v in lst] 99def toVec2(lst): return [v.toFloat().toVec2() for v in lst] 100def toIVec4(lst): return [v.toInt().toVec4() for v in lst] 101def toIVec3(lst): return [v.toInt().toVec3() for v in lst] 102def toIVec2(lst): return [v.toInt().toVec2() for v in lst] 103def toBVec4(lst): return [v.toBool().toVec4() for v in lst] 104def toBVec3(lst): return [v.toBool().toVec3() for v in lst] 105def toBVec2(lst): return [v.toBool().toVec2() for v in lst] 106def toUVec4(lst): return [v.toUint().toUVec4() for v in lst] 107def toUVec3(lst): return [v.toUint().toUVec3() for v in lst] 108def toUVec2(lst): return [v.toUint().toUVec2() for v in lst] 109def toMat2(lst): return [v.toMat2() for v in lst] 110def toMat2x3(lst): return [v.toMat2x3() for v in lst] 111def toMat2x4(lst): return [v.toMat2x4() for v in lst] 112def toMat3x2(lst): return [v.toMat3x2() for v in lst] 113def toMat3(lst): return [v.toMat3() for v in lst] 114def toMat3x4(lst): return [v.toMat3x4() for v in lst] 115def toMat4x2(lst): return [v.toMat4x2() for v in lst] 116def toMat4x3(lst): return [v.toMat4x3() for v in lst] 117def toMat4(lst): return [v.toMat4() for v in lst] 118 119# Random value generation. 120 121class 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 142def glslSign(a): return 0.0 if (a == 0) else +1.0 if (a > 0.0) else -1.0 143def glslMod(x, y): return x - y*math.floor(x/y) 144def glslClamp(x, mn, mx): return mn if (x < mn) else mx if (x > mx) else x 145 146class 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 206class 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 316class 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 342class 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 def __eq__(self, other): 370 return self.isEqual(other) 371 372 def __ne__(self, other): 373 return not self.isEqual(other) 374 375class Vec2(Vec): 376 def __init__(self, x, y): 377 assert(x.__class__ == y.__class__) 378 self.x = x 379 self.y = y 380 381 def applyUnary(self, func): return Vec2(func(self.x), func(self.y)) 382 def applyBinary(self, func, other): return Vec2(func(self.x, other.x), func(self.y, other.y)) 383 384 def expandVec(self, val): return val.toVec2() 385 def toScalar(self): return Scalar(self.x) 386 def toVec2(self): return Vec2(self.x, self.y) 387 def toVec3(self): return Vec3(self.x, self.y, 0.0) 388 def toVec4(self): return Vec4(self.x, self.y, 0.0, 0.0) 389 def toUVec2(self): return UVec2(self.x, self.y) 390 def toUVec3(self): return UVec3(self.x, self.y, 0.0) 391 def toUVec4(self): return UVec4(self.x, self.y, 0.0, 0.0) 392 def toMat2(self): return Mat2(float(self.x), 0.0, 0.0, float(self.y)); 393 394 def toFloat(self): return Vec2(float(self.x), float(self.y)) 395 def toInt(self): return Vec2(int(self.x), int(self.y)) 396 def toUint(self): return UVec2(int(self.x), int(self.y)) 397 def toBool(self): return Vec2(bool(self.x), bool(self.y)) 398 399 def getNumScalars(self): return 2 400 def getScalars(self): return [self.x, self.y] 401 402 def typeString(self): 403 if isinstance(self.x, bool): 404 return "bvec2" 405 elif isinstance(self.x, int): 406 return "ivec2" 407 elif isinstance(self.x, float): 408 return "vec2" 409 else: 410 assert False 411 412 def vec4Swizzle(self): 413 return ".xyxy" 414 415 def __str__(self): 416 if isinstance(self.x, bool): 417 return "bvec2(%s, %s)" % (str(self.x).lower(), str(self.y).lower()) 418 elif isinstance(self.x, int): 419 return "ivec2(%i, %i)" % (self.x, self.y) 420 elif isinstance(self.x, float): 421 return "vec2(%s, %s)" % (self.x, self.y) 422 else: 423 assert False 424 425 def distance(self, v): 426 assert isinstance(v, Vec2) 427 return (self - v).length() 428 429 def dot(self, v): 430 assert isinstance(v, Vec2) 431 return Scalar(self.x*v.x + self.y*v.y) 432 433 def abs(self): 434 if isinstance(self.x, bool): 435 return Vec2(self.x, self.y) 436 else: 437 return Vec2(abs(self.x), abs(self.y)) 438 439 def __neg__(self): 440 return Vec2(-self.x, -self.y) 441 442 def __add__(self, val): 443 if isinstance(val, Scalar): 444 return Vec2(self.x + val, self.y + val) 445 elif isinstance(val, Vec2): 446 return Vec2(self.x + val.x, self.y + val.y) 447 else: 448 assert False 449 450 def __sub__(self, val): 451 return self + (-val) 452 453 def __mul__(self, val): 454 if isinstance(val, Scalar): 455 val = val.toVec2() 456 assert isinstance(val, Vec2) 457 return Vec2(self.x * val.x, self.y * val.y) 458 459 def __div__(self, val): 460 if isinstance(val, Scalar): 461 return Vec2(self.x / val.x, self.y / val.x) 462 else: 463 assert isinstance(val, Vec2) 464 return Vec2(self.x / val.x, self.y / val.y) 465 466 def boolAny(self): return Scalar(self.x or self.y) 467 def boolAll(self): return Scalar(self.x and self.y) 468 def boolNot(self): return Vec2(not self.x, not self.y) 469 470class UVec2(Vec2): 471 def __init__(self, x, y): 472 assert isinstance(x, int) and isinstance(y, int) 473 assert x >= 0 and y >= 0 474 Vec2.__init__(self, x, y) 475 476 def typeString(self): 477 return "uvec2" 478 479 def __str__(self): 480 return "uvec2(%i, %i)" % (self.x, self.y) 481 482 def abs(self): 483 return Vec2.abs(self).toUint() 484 485class Vec3(Vec): 486 def __init__(self, x, y, z): 487 assert((x.__class__ == y.__class__) and (x.__class__ == z.__class__)) 488 self.x = x 489 self.y = y 490 self.z = z 491 492 def applyUnary(self, func): return Vec3(func(self.x), func(self.y), func(self.z)) 493 def applyBinary(self, func, other): return Vec3(func(self.x, other.x), func(self.y, other.y), func(self.z, other.z)) 494 495 def expandVec(self, val): return val.toVec3() 496 def toScalar(self): return Scalar(self.x) 497 def toVec2(self): return Vec2(self.x, self.y) 498 def toVec3(self): return Vec3(self.x, self.y, self.z) 499 def toVec4(self): return Vec4(self.x, self.y, self.z, 0.0) 500 def toUVec2(self): return UVec2(self.x, self.y) 501 def toUVec3(self): return UVec3(self.x, self.y, self.z) 502 def toUVec4(self): return UVec4(self.x, self.y, self.z, 0.0) 503 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)); 504 505 def toFloat(self): return Vec3(float(self.x), float(self.y), float(self.z)) 506 def toInt(self): return Vec3(int(self.x), int(self.y), int(self.z)) 507 def toUint(self): return UVec3(int(self.x), int(self.y), int(self.z)) 508 def toBool(self): return Vec3(bool(self.x), bool(self.y), bool(self.z)) 509 510 def getNumScalars(self): return 3 511 def getScalars(self): return [self.x, self.y, self.z] 512 513 def typeString(self): 514 if isinstance(self.x, bool): 515 return "bvec3" 516 elif isinstance(self.x, int): 517 return "ivec3" 518 elif isinstance(self.x, float): 519 return "vec3" 520 else: 521 assert False 522 523 def vec4Swizzle(self): 524 return ".xyzx" 525 526 def __str__(self): 527 if isinstance(self.x, bool): 528 return "bvec3(%s, %s, %s)" % (str(self.x).lower(), str(self.y).lower(), str(self.z).lower()) 529 elif isinstance(self.x, int): 530 return "ivec3(%i, %i, %i)" % (self.x, self.y, self.z) 531 elif isinstance(self.x, float): 532 return "vec3(%s, %s, %s)" % (self.x, self.y, self.z) 533 else: 534 assert False 535 536 def distance(self, v): 537 assert isinstance(v, Vec3) 538 return (self - v).length() 539 540 def dot(self, v): 541 assert isinstance(v, Vec3) 542 return Scalar(self.x*v.x + self.y*v.y + self.z*v.z) 543 544 def cross(self, v): 545 assert isinstance(v, Vec3) 546 return Vec3(self.y*v.z - v.y*self.z, 547 self.z*v.x - v.z*self.x, 548 self.x*v.y - v.x*self.y) 549 550 def abs(self): 551 if isinstance(self.x, bool): 552 return Vec3(self.x, self.y, self.z) 553 else: 554 return Vec3(abs(self.x), abs(self.y), abs(self.z)) 555 556 def __neg__(self): 557 return Vec3(-self.x, -self.y, -self.z) 558 559 def __add__(self, val): 560 if isinstance(val, Scalar): 561 return Vec3(self.x + val, self.y + val) 562 elif isinstance(val, Vec3): 563 return Vec3(self.x + val.x, self.y + val.y, self.z + val.z) 564 else: 565 assert False 566 567 def __sub__(self, val): 568 return self + (-val) 569 570 def __mul__(self, val): 571 if isinstance(val, Scalar): 572 val = val.toVec3() 573 assert isinstance(val, Vec3) 574 return Vec3(self.x * val.x, self.y * val.y, self.z * val.z) 575 576 def __div__(self, val): 577 if isinstance(val, Scalar): 578 return Vec3(self.x / val.x, self.y / val.x, self.z / val.x) 579 elif isinstance(val, Vec3): 580 return Vec3(self.x / val.x, self.y / val.y, self.z / val.z) 581 else: 582 assert False 583 584 def boolAny(self): return Scalar(self.x or self.y or self.z) 585 def boolAll(self): return Scalar(self.x and self.y and self.z) 586 def boolNot(self): return Vec3(not self.x, not self.y, not self.z) 587 588class UVec3(Vec3): 589 def __init__(self, x, y, z): 590 assert isinstance(x, int) and isinstance(y, int) and isinstance(z, int) 591 assert x >= 0 and y >= 0 and z >= 0 592 Vec3.__init__(self, x, y, z) 593 594 def typeString(self): 595 return "uvec3" 596 597 def __str__(self): 598 return "uvec3(%i, %i, %i)" % (self.x, self.y, self.z) 599 600 def abs(self): 601 return Vec3.abs(self).toUint() 602 603class Vec4(Vec): 604 def __init__(self, x, y, z, w): 605 assert((x.__class__ == y.__class__) and (x.__class__ == z.__class__) and (x.__class__ == w.__class__)) 606 self.x = x 607 self.y = y 608 self.z = z 609 self.w = w 610 611 def applyUnary(self, func): return Vec4(func(self.x), func(self.y), func(self.z), func(self.w)) 612 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)) 613 614 def expandVec(self, val): return val.toVec4() 615 def toScalar(self): return Scalar(self.x) 616 def toVec2(self): return Vec2(self.x, self.y) 617 def toVec3(self): return Vec3(self.x, self.y, self.z) 618 def toVec4(self): return Vec4(self.x, self.y, self.z, self.w) 619 def toUVec2(self): return UVec2(self.x, self.y) 620 def toUVec3(self): return UVec3(self.x, self.y, self.z) 621 def toUVec4(self): return UVec4(self.x, self.y, self.z, self.w) 622 def toMat2(self): return Mat2(float(self.x), float(self.y), float(self.z), float(self.w)) 623 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)); 624 625 def toFloat(self): return Vec4(float(self.x), float(self.y), float(self.z), float(self.w)) 626 def toInt(self): return Vec4(int(self.x), int(self.y), int(self.z), int(self.w)) 627 def toUint(self): return UVec4(int(self.x), int(self.y), int(self.z), int(self.w)) 628 def toBool(self): return Vec4(bool(self.x), bool(self.y), bool(self.z), bool(self.w)) 629 630 def getNumScalars(self): return 4 631 def getScalars(self): return [self.x, self.y, self.z, self.w] 632 633 def typeString(self): 634 if isinstance(self.x, bool): 635 return "bvec4" 636 elif isinstance(self.x, int): 637 return "ivec4" 638 elif isinstance(self.x, float): 639 return "vec4" 640 else: 641 assert False 642 643 def vec4Swizzle(self): 644 return "" 645 646 def __str__(self): 647 if isinstance(self.x, bool): 648 return "bvec4(%s, %s, %s, %s)" % (str(self.x).lower(), str(self.y).lower(), str(self.z).lower(), str(self.w).lower()) 649 elif isinstance(self.x, int): 650 return "ivec4(%i, %i, %i, %i)" % (self.x, self.y, self.z, self.w) 651 elif isinstance(self.x, float): 652 return "vec4(%s, %s, %s, %s)" % (self.x, self.y, self.z, self.w) 653 else: 654 assert False 655 656 def distance(self, v): 657 assert isinstance(v, Vec4) 658 return (self - v).length() 659 660 def dot(self, v): 661 assert isinstance(v, Vec4) 662 return Scalar(self.x*v.x + self.y*v.y + self.z*v.z + self.w*v.w) 663 664 def abs(self): 665 if isinstance(self.x, bool): 666 return Vec4(self.x, self.y, self.z, self.w) 667 else: 668 return Vec4(abs(self.x), abs(self.y), abs(self.z), abs(self.w)) 669 670 def __neg__(self): 671 return Vec4(-self.x, -self.y, -self.z, -self.w) 672 673 def __add__(self, val): 674 if isinstance(val, Scalar): 675 return Vec3(self.x + val, self.y + val) 676 elif isinstance(val, Vec4): 677 return Vec4(self.x + val.x, self.y + val.y, self.z + val.z, self.w + val.w) 678 else: 679 assert False 680 681 def __sub__(self, val): 682 return self + (-val) 683 684 def __mul__(self, val): 685 if isinstance(val, Scalar): 686 val = val.toVec4() 687 assert isinstance(val, Vec4) 688 return Vec4(self.x * val.x, self.y * val.y, self.z * val.z, self.w * val.w) 689 690 def __div__(self, val): 691 if isinstance(val, Scalar): 692 return Vec4(self.x / val.x, self.y / val.x, self.z / val.x, self.w / val.x) 693 elif isinstance(val, Vec4): 694 return Vec4(self.x / val.x, self.y / val.y, self.z / val.z, self.w / val.w) 695 else: 696 assert False 697 698 def boolAny(self): return Scalar(self.x or self.y or self.z or self.w) 699 def boolAll(self): return Scalar(self.x and self.y and self.z and self.w) 700 def boolNot(self): return Vec4(not self.x, not self.y, not self.z, not self.w) 701 702class UVec4(Vec4): 703 def __init__(self, x, y, z, w): 704 assert isinstance(x, int) and isinstance(y, int) and isinstance(z, int) and isinstance(w, int) 705 assert x >= 0 and y >= 0 and z >= 0 and w >= 0 706 Vec4.__init__(self, x, y, z, w) 707 708 def typeString(self): 709 return "uvec4" 710 711 def __str__(self): 712 return "uvec4(%i, %i, %i, %i)" % (self.x, self.y, self.z, self.w) 713 714 def abs(self): 715 return Vec4.abs(self).toUint() 716 717# \note Column-major storage. 718class Mat(object): 719 def __init__ (self, numCols, numRows, scalars): 720 assert len(scalars) == numRows*numCols 721 self.numCols = numCols 722 self.numRows = numRows 723 self.scalars = scalars 724 725 @staticmethod 726 def fromScalar (numCols, numRows, scalar): 727 scalars = [] 728 for col in range(0, numCols): 729 for row in range(0, numRows): 730 scalars.append(scalar if col == row else 0.0) 731 return Mat(numCols, numRows, scalars) 732 733 @staticmethod 734 def identity (numCols, numRows): 735 return Mat.fromScalar(numCols, numRows, 1.0) 736 737 def get (self, colNdx, rowNdx): 738 assert 0 <= colNdx and colNdx < self.numCols 739 assert 0 <= rowNdx and rowNdx < self.numRows 740 return self.scalars[colNdx*self.numRows + rowNdx] 741 742 def set (self, colNdx, rowNdx, scalar): 743 assert 0 <= colNdx and colNdx < self.numCols 744 assert 0 <= rowNdx and rowNdx < self.numRows 745 self.scalars[colNdx*self.numRows + rowNdx] = scalar 746 747 def toMatrix (self, numCols, numRows): 748 res = Mat.identity(numCols, numRows) 749 for col in range(0, min(self.numCols, numCols)): 750 for row in range(0, min(self.numRows, numRows)): 751 res.set(col, row, self.get(col, row)) 752 return res 753 754 def toMat2 (self): return self.toMatrix(2, 2) 755 def toMat2x3 (self): return self.toMatrix(2, 3) 756 def toMat2x4 (self): return self.toMatrix(2, 4) 757 def toMat3x2 (self): return self.toMatrix(3, 2) 758 def toMat3 (self): return self.toMatrix(3, 3) 759 def toMat3x4 (self): return self.toMatrix(3, 4) 760 def toMat4x2 (self): return self.toMatrix(4, 2) 761 def toMat4x3 (self): return self.toMatrix(4, 3) 762 def toMat4 (self): return self.toMatrix(4, 4) 763 764 def typeString(self): 765 if self.numRows == self.numCols: 766 return "mat%d" % self.numRows 767 else: 768 return "mat%dx%d" % (self.numCols, self.numRows) 769 770 def __str__(self): 771 return "%s(%s)" % (self.typeString(), ", ".join(["%s" % s for s in self.scalars])) 772 773 def isTypeEqual (self, other): 774 return isinstance(other, Mat) and self.numRows == other.numRows and self.numCols == other.numCols 775 776 def isEqual(self, other): 777 assert self.isTypeEqual(other) 778 return (self.scalars == other.scalars) 779 780 def compMul(self, val): 781 assert self.isTypeEqual(val) 782 return Mat(self.numRows, self.numCols, [self.scalars(i) * val.scalars(i) for i in range(self.numRows*self.numCols)]) 783 784class Mat2(Mat): 785 def __init__(self, m00, m01, m10, m11): 786 Mat.__init__(self, 2, 2, [m00, m10, m01, m11]) 787 788class Mat3(Mat): 789 def __init__(self, m00, m01, m02, m10, m11, m12, m20, m21, m22): 790 Mat.__init__(self, 3, 3, [m00, m10, m20, 791 m01, m11, m21, 792 m02, m12, m22]) 793 794class Mat4(Mat): 795 def __init__(self, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33): 796 Mat.__init__(self, 4, 4, [m00, m10, m20, m30, 797 m01, m11, m21, m31, 798 m02, m12, m22, m32, 799 m03, m13, m23, m33]) 800