1 /** 2 * Copyright: Enalye 3 * License: Zlib 4 * Authors: Enalye 5 */ 6 module grimoire.stdlib.vec2; 7 8 import std.conv : to; 9 import std.math; 10 import grimoire.assembly, grimoire.compiler, grimoire.runtime; 11 import grimoire.stdlib.util; 12 13 private { 14 string _vec2iTypeName, _vec2fTypeName; 15 /// Ratio to multiply with to get a value in radians from a value in degrees. 16 enum double _degToRad = std.math.PI / 180.0; 17 /// Ratio to multiply with to get a value in degrees from a value in radians. 18 enum double _radToDeg = 180.0 / std.math.PI; 19 } 20 21 package void grLoadStdLibVec2(GrLibrary library) { 22 library.addClass("Vec2", ["x", "y"], [ 23 grAny("T", (t, d) { 24 return (t.baseType == grInt) || (t.baseType == grFloat); 25 }), grAny("T") 26 ], ["T"]); 27 28 GrType vec2iType = library.addTypeAlias("Vec2i", grGetClassType("Vec2", [ 29 grInt 30 ])); 31 GrType vec2fType = library.addTypeAlias("Vec2f", grGetClassType("Vec2", [ 32 grFloat 33 ])); 34 35 _vec2iTypeName = grMangleComposite("Vec2", [grInt]); 36 _vec2fTypeName = grMangleComposite("Vec2", [grFloat]); 37 38 // Ctors 39 library.addPrimitive(&_vec2i_1, "Vec2", [grInt], [vec2iType]); 40 library.addPrimitive(&_vec2f_1, "Vec2", [grFloat], [vec2fType]); 41 library.addPrimitive(&_vec2i_2, "Vec2", [grInt, grInt], [vec2iType]); 42 library.addPrimitive(&_vec2f_2, "Vec2", [grFloat, grFloat], [vec2fType]); 43 44 library.addPrimitive(&_vec2i_0, "Vec2i", [], [vec2iType]); 45 library.addPrimitive(&_vec2i_1, "Vec2i", [grInt], [vec2iType]); 46 library.addPrimitive(&_vec2i_2, "Vec2i", [grInt, grInt], [vec2iType]); 47 48 library.addPrimitive(&_vec2f_0, "Vec2f", [], [vec2fType]); 49 library.addPrimitive(&_vec2f_1, "Vec2f", [grFloat], [vec2fType]); 50 library.addPrimitive(&_vec2f_2, "Vec2f", [grFloat, grFloat], [vec2fType]); 51 52 // Cast 53 library.addCast(&_vec2i_vec2f, vec2iType, vec2fType); 54 library.addCast(&_vec2f_vec2i, vec2fType, vec2iType); 55 56 // Prints 57 library.addPrimitive(&_printVec2i, "print", [vec2iType]); 58 library.addPrimitive(&_printlVec2i, "printl", [vec2iType]); 59 library.addPrimitive(&_printVec2f, "print", [vec2fType]); 60 library.addPrimitive(&_printlVec2f, "printl", [vec2fType]); 61 62 // Operators 63 static foreach (op; ["+", "-", "*", "/", "%"]) { 64 library.addOperator(&_opBinaryVec2i!op, op, [vec2iType, vec2iType], vec2iType); 65 library.addOperator(&_opBinaryScalarVec2i!op, op, [vec2iType, grInt], vec2iType); 66 library.addOperator(&_opBinaryScalarRightVec2i!op, op, [ 67 grFloat, vec2iType 68 ], vec2iType); 69 } 70 static foreach (op; ["==", "!=", ">=", "<=", ">", "<"]) { 71 library.addOperator(&_opBinaryCompareVec2i!op, op, [ 72 vec2iType, vec2iType 73 ], grBool); 74 } 75 76 static foreach (op; ["+", "-", "*", "/", "%"]) { 77 library.addOperator(&_opBinaryCompareVec2f!op, op, [ 78 vec2fType, vec2fType 79 ], vec2fType); 80 library.addOperator(&_opBinaryScalarVec2f!op, op, [vec2fType, grFloat], vec2fType); 81 library.addOperator(&_opBinaryScalarRightVec2f!op, op, [ 82 grFloat, vec2fType 83 ], vec2fType); 84 } 85 static foreach (op; ["==", "!=", ">=", "<=", ">", "<"]) { 86 library.addOperator(&_opBinaryCompareVec2f!op, op, [ 87 vec2fType, vec2fType 88 ], grBool); 89 } 90 91 // Utility 92 library.addPrimitive(&_oneVec2i, "Vec2i_one", [], [vec2iType]); 93 library.addPrimitive(&_oneVec2f, "Vec2f_one", [], [vec2fType]); 94 library.addPrimitive(&_halfVec2f, "Vec2f_half", [], [vec2fType]); 95 library.addPrimitive(&_upVec2i, "Vec2i_up", [], [vec2iType]); 96 library.addPrimitive(&_upVec2f, "Vec2f_up", [], [vec2fType]); 97 library.addPrimitive(&_downVec2i, "Vec2i_down", [], [vec2iType]); 98 library.addPrimitive(&_downVec2f, "Vec2f_down", [], [vec2fType]); 99 library.addPrimitive(&_leftVec2i, "Vec2i_left", [], [vec2iType]); 100 library.addPrimitive(&_leftVec2f, "Vec2f_left", [], [vec2fType]); 101 library.addPrimitive(&_rightVec2i, "Vec2i_right", [], [vec2iType]); 102 library.addPrimitive(&_rightVec2f, "Vec2f_right", [], [vec2fType]); 103 104 library.addPrimitive(&_unpackVec2i, "unpack", [vec2iType], [grInt, grInt]); 105 library.addPrimitive(&_unpackVec2f, "unpack", [vec2fType], [ 106 grFloat, grFloat 107 ]); 108 109 library.addPrimitive(&_isZeroVec2i, "zero?", [vec2iType], [grBool]); 110 library.addPrimitive(&_isZeroVec2f, "zero?", [vec2fType], [grBool]); 111 112 // Operations 113 library.addPrimitive(&_sumVec2i, "sum", [vec2iType], [grInt]); 114 library.addPrimitive(&_sumVec2f, "sum", [vec2fType], [grFloat]); 115 library.addPrimitive(&_distanceVec2i, "distance", [vec2iType, vec2iType], [ 116 grFloat 117 ]); 118 library.addPrimitive(&_distanceVec2f, "distance", [vec2fType, vec2fType], [ 119 grFloat 120 ]); 121 library.addPrimitive(&_distanceVec2i, "distanceSq", [vec2iType, vec2iType], [ 122 grFloat 123 ]); 124 library.addPrimitive(&_distanceVec2f, "distanceSq", [vec2fType, vec2fType], [ 125 grFloat 126 ]); 127 library.addPrimitive(&_dotVec2i, "dot", [vec2iType, vec2iType], [grFloat]); 128 library.addPrimitive(&_dotVec2f, "dot", [vec2fType, vec2fType], [grFloat]); 129 library.addPrimitive(&_crossVec2i, "cross", [vec2iType, vec2iType], [ 130 grFloat 131 ]); 132 library.addPrimitive(&_crossVec2f, "cross", [vec2fType, vec2fType], [ 133 grFloat 134 ]); 135 library.addPrimitive(&_normalVec2i, "normal", [vec2iType], [vec2iType]); 136 library.addPrimitive(&_normalVec2f, "normal", [vec2fType], [vec2fType]); 137 library.addPrimitive(&_angleVec2i, "angle", [vec2iType], [grFloat]); 138 library.addPrimitive(&_angleVec2f, "angle", [vec2fType], [grFloat]); 139 library.addPrimitive(&_rotateVec2f, "rotate!", [vec2fType, grFloat], [ 140 vec2fType 141 ]); 142 library.addPrimitive(&_rotatedVec2f, "rotate", [vec2fType, grFloat], [ 143 vec2fType 144 ]); 145 library.addPrimitive(&_angledVec2f, "Vec2f_angled", [grFloat], [vec2fType]); 146 library.addPrimitive(&_lengthVec2i, "length", [vec2iType], [grFloat]); 147 library.addPrimitive(&_lengthVec2f, "length", [vec2fType], [grFloat]); 148 library.addPrimitive(&_lengthSquaredVec2i, "lengthSq", [vec2iType], [ 149 grFloat 150 ]); 151 library.addPrimitive(&_lengthSquaredVec2f, "lengthSq", [vec2fType], [ 152 grFloat 153 ]); 154 library.addPrimitive(&_normalizeVec2f, "normalize!", [vec2fType], [ 155 vec2fType 156 ]); 157 library.addPrimitive(&_normalizedVec2f, "normalize", [vec2fType], [ 158 vec2fType 159 ]); 160 } 161 162 // Ctors ------------------------------------------ 163 private void _vec2i_0(GrCall call) { 164 GrObject self = call.createObject(_vec2iTypeName); 165 if(!self) { 166 call.raise("UnknownClassError"); 167 return; 168 } 169 self.setInt("x", 0); 170 self.setInt("y", 0); 171 call.setObject(self); 172 } 173 174 private void _vec2i_1(GrCall call) { 175 GrObject self = call.createObject(_vec2iTypeName); 176 if(!self) { 177 call.raise("UnknownClassError"); 178 return; 179 } 180 const GrInt value = call.getInt(0); 181 self.setInt("x", value); 182 self.setInt("y", value); 183 call.setObject(self); 184 } 185 186 private void _vec2i_2(GrCall call) { 187 GrObject self = call.createObject(_vec2iTypeName); 188 if(!self) { 189 call.raise("UnknownClassError"); 190 return; 191 } 192 self.setInt("x", call.getInt(0)); 193 self.setInt("y", call.getInt(1)); 194 call.setObject(self); 195 } 196 197 private void _vec2f_0(GrCall call) { 198 GrObject self = call.createObject(_vec2fTypeName); 199 if(!self) { 200 call.raise("UnknownClassError"); 201 return; 202 } 203 self.setFloat("x", 0f); 204 self.setFloat("y", 0f); 205 call.setObject(self); 206 } 207 208 private void _vec2f_1(GrCall call) { 209 GrObject self = call.createObject(_vec2fTypeName); 210 if(!self) { 211 call.raise("UnknownClassError"); 212 return; 213 } 214 const GrFloat value = call.getFloat(0); 215 self.setFloat("x", value); 216 self.setFloat("y", value); 217 call.setObject(self); 218 } 219 220 private void _vec2f_2(GrCall call) { 221 GrObject self = call.createObject(_vec2fTypeName); 222 if(!self) { 223 call.raise("UnknownClassError"); 224 return; 225 } 226 self.setFloat("x", call.getFloat(0)); 227 self.setFloat("y", call.getFloat(1)); 228 call.setObject(self); 229 } 230 231 // Cast ------------------------------------------ 232 private void _vec2i_vec2f(GrCall call) { 233 GrObject self = call.getObject(0); 234 if (!self) { 235 call.raise("NullError"); 236 return; 237 } 238 GrObject v = call.createObject(_vec2fTypeName); 239 if(!v) { 240 call.raise("UnknownClassError"); 241 return; 242 } 243 v.setFloat("x", cast(GrFloat) self.getInt("x")); 244 v.setFloat("y", cast(GrFloat) self.getInt("y")); 245 call.setObject(v); 246 } 247 248 private void _vec2f_vec2i(GrCall call) { 249 GrObject self = call.getObject(0); 250 if (!self) { 251 call.raise("NullError"); 252 return; 253 } 254 GrObject v = call.createObject(_vec2iTypeName); 255 if(!v) { 256 call.raise("UnknownClassError"); 257 return; 258 } 259 v.setInt("x", cast(GrInt) self.getFloat("x")); 260 v.setInt("y", cast(GrInt) self.getFloat("y")); 261 call.setObject(v); 262 } 263 264 // Prints ------------------------------------------ 265 private void _printVec2i(GrCall call) { 266 GrObject self = call.getObject(0); 267 if (!self) { 268 _stdOut("Vec2(0, 0)"); 269 return; 270 } 271 _stdOut("Vec2(" ~ to!GrString(self.getInt("x")) ~ ", " ~ to!GrString(self.getInt("y")) ~ ")"); 272 } 273 274 private void _printlVec2i(GrCall call) { 275 GrObject self = call.getObject(0); 276 if (!self) { 277 _stdOut("{0;0}\n"); 278 return; 279 } 280 _stdOut("Vec2(" ~ to!GrString(self.getInt("x")) ~ ", " ~ to!GrString(self.getInt("y")) ~ ")\n"); 281 } 282 283 private void _printVec2f(GrCall call) { 284 GrObject self = call.getObject(0); 285 if (!self) { 286 _stdOut("{0;0}"); 287 return; 288 } 289 _stdOut("Vec2(" ~ to!GrString(self.getFloat("x")) ~ ", " ~ to!GrString(self.getFloat("y")) ~ ")"); 290 } 291 292 private void _printlVec2f(GrCall call) { 293 GrObject self = call.getObject(0); 294 if (!self) { 295 _stdOut("{0;0}\n"); 296 return; 297 } 298 _stdOut("Vec2(" ~ to!GrString(self.getFloat("x")) ~ ", " ~ to!GrString(self.getFloat("y")) ~ ")\n"); 299 } 300 301 /// Operators ------------------------------------------ 302 private void _opBinaryVec2i(string op)(GrCall call) { 303 GrObject self = call.createObject(_vec2iTypeName); 304 if(!self) { 305 call.raise("UnknownClassError"); 306 return; 307 } 308 GrObject v1 = call.getObject(0); 309 GrObject v2 = call.getObject(1); 310 if (!v1 || !v2) { 311 call.raise("NullError"); 312 return; 313 } 314 mixin("self.setInt(\"x\", v1.getInt(\"x\")" ~ op ~ "v2.getInt(\"x\"));"); 315 mixin("self.setInt(\"y\", v1.getInt(\"y\")" ~ op ~ "v2.getInt(\"y\"));"); 316 call.setObject(self); 317 } 318 319 private void _opBinaryScalarVec2i(string op)(GrCall call) { 320 GrObject self = call.createObject(_vec2iTypeName); 321 if(!self) { 322 call.raise("UnknownClassError"); 323 return; 324 } 325 GrObject v = call.getObject(0); 326 const GrInt s = call.getInt(1); 327 if (!v) { 328 call.raise("NullError"); 329 return; 330 } 331 mixin("self.setInt(\"x\", v.getInt(\"x\")" ~ op ~ "s);"); 332 mixin("self.setInt(\"y\", v.getInt(\"y\")" ~ op ~ "s);"); 333 call.setObject(self); 334 } 335 336 private void _opBinaryScalarRightVec2i(string op)(GrCall call) { 337 GrObject self = call.createObject(_vec2iTypeName); 338 if(!self) { 339 call.raise("UnknownClassError"); 340 return; 341 } 342 GrObject v = call.getObject(0); 343 const GrInt s = call.getInt(1); 344 if (!v) { 345 call.raise("NullError"); 346 return; 347 } 348 mixin("self.setInt(\"x\", s" ~ op ~ "v.getInt(\"x\"));"); 349 mixin("self.setInt(\"y\", s" ~ op ~ "v.getInt(\"y\"));"); 350 call.setObject(self); 351 } 352 353 private void _opBinaryCompareVec2i(string op)(GrCall call) { 354 GrObject v1 = call.getObject(0); 355 GrObject v2 = call.getObject(1); 356 if (!v1 || !v2) { 357 call.raise("NullError"); 358 return; 359 } 360 mixin("call.setBool( 361 v1.getInt(\"x\")" ~ op ~ "v2.getInt(\"x\") && 362 v1.getInt(\"y\")" ~ op ~ "v2.getInt(\"y\"));"); 363 } 364 365 private void _opBinaryVec2f(string op)(GrCall call) { 366 GrObject self = call.createObject(_vec2fTypeName); 367 if(!self) { 368 call.raise("UnknownClassError"); 369 return; 370 } 371 GrObject v1 = call.getObject(0); 372 GrObject v2 = call.getObject(1); 373 if (!v1 || !v2) { 374 call.raise("NullError"); 375 return; 376 } 377 mixin("self.setFloat(\"x\", v1.getFloat(\"x\")" ~ op ~ "v2.getFloat(\"x\"));"); 378 mixin("self.setFloat(\"y\", v1.getFloat(\"y\")" ~ op ~ "v2.getFloat(\"y\"));"); 379 call.setObject(self); 380 } 381 382 private void _opBinaryScalarVec2f(string op)(GrCall call) { 383 GrObject self = call.createObject(_vec2fTypeName); 384 if(!self) { 385 call.raise("UnknownClassError"); 386 return; 387 } 388 GrObject v = call.getObject(0); 389 const GrFloat s = call.getFloat(1); 390 if (!v) { 391 call.raise("NullError"); 392 return; 393 } 394 mixin("self.setFloat(\"x\", v.getFloat(\"x\")" ~ op ~ "s);"); 395 mixin("self.setFloat(\"y\", v.getFloat(\"y\")" ~ op ~ "s);"); 396 call.setObject(self); 397 } 398 399 private void _opBinaryScalarRightVec2f(string op)(GrCall call) { 400 GrObject self = call.createObject(_vec2fTypeName); 401 if(!self) { 402 call.raise("UnknownClassError"); 403 return; 404 } 405 GrObject v = call.getObject(0); 406 const GrFloat s = call.getFloat(1); 407 if (!v) { 408 call.raise("NullError"); 409 return; 410 } 411 mixin("self.setFloat(\"x\", s" ~ op ~ "v.getFloat(\"x\"));"); 412 mixin("self.setFloat(\"y\", s" ~ op ~ "v.getFloat(\"y\"));"); 413 call.setObject(self); 414 } 415 416 private void _opBinaryCompareVec2f(string op)(GrCall call) { 417 GrObject v1 = call.getObject(0); 418 GrObject v2 = call.getObject(1); 419 if (!v1 || !v2) { 420 call.raise("NullError"); 421 return; 422 } 423 mixin("call.setBool( 424 v1.getFloat(\"x\")" ~ op ~ "v2.getFloat(\"x\") && 425 v1.getFloat(\"y\")" ~ op 426 ~ "v2.getFloat(\"y\"));"); 427 } 428 429 // Utility ------------------------------------------ 430 private void _oneVec2i(GrCall call) { 431 GrObject self = call.createObject(_vec2iTypeName); 432 if(!self) { 433 call.raise("UnknownClassError"); 434 return; 435 } 436 self.setInt("x", 1); 437 self.setInt("y", 1); 438 call.setObject(self); 439 } 440 441 private void _oneVec2f(GrCall call) { 442 GrObject self = call.createObject(_vec2fTypeName); 443 if(!self) { 444 call.raise("UnknownClassError"); 445 return; 446 } 447 self.setFloat("x", 1f); 448 self.setFloat("y", 1f); 449 call.setObject(self); 450 } 451 452 private void _halfVec2f(GrCall call) { 453 GrObject self = call.createObject(_vec2fTypeName); 454 if(!self) { 455 call.raise("UnknownClassError"); 456 return; 457 } 458 self.setFloat("x", .5f); 459 self.setFloat("y", .5f); 460 call.setObject(self); 461 } 462 463 private void _upVec2i(GrCall call) { 464 GrObject self = call.createObject(_vec2iTypeName); 465 if(!self) { 466 call.raise("UnknownClassError"); 467 return; 468 } 469 self.setInt("y", 1); 470 call.setObject(self); 471 } 472 473 private void _upVec2f(GrCall call) { 474 GrObject self = call.createObject(_vec2fTypeName); 475 if(!self) { 476 call.raise("UnknownClassError"); 477 return; 478 } 479 self.setFloat("y", 1f); 480 call.setObject(self); 481 } 482 483 private void _downVec2i(GrCall call) { 484 GrObject self = call.createObject(_vec2iTypeName); 485 if(!self) { 486 call.raise("UnknownClassError"); 487 return; 488 } 489 self.setInt("y", -1); 490 call.setObject(self); 491 } 492 493 private void _downVec2f(GrCall call) { 494 GrObject self = call.createObject(_vec2fTypeName); 495 if(!self) { 496 call.raise("UnknownClassError"); 497 return; 498 } 499 self.setFloat("y", -1f); 500 call.setObject(self); 501 } 502 503 private void _leftVec2i(GrCall call) { 504 GrObject self = call.createObject(_vec2iTypeName); 505 if(!self) { 506 call.raise("UnknownClassError"); 507 return; 508 } 509 self.setInt("x", -1); 510 call.setObject(self); 511 } 512 513 private void _leftVec2f(GrCall call) { 514 GrObject self = call.createObject(_vec2fTypeName); 515 if(!self) { 516 call.raise("UnknownClassError"); 517 return; 518 } 519 self.setFloat("x", -1f); 520 call.setObject(self); 521 } 522 523 private void _rightVec2i(GrCall call) { 524 GrObject self = call.createObject(_vec2iTypeName); 525 if(!self) { 526 call.raise("UnknownClassError"); 527 return; 528 } 529 self.setInt("x", 1); 530 call.setObject(self); 531 } 532 533 private void _rightVec2f(GrCall call) { 534 GrObject self = call.createObject(_vec2fTypeName); 535 if(!self) { 536 call.raise("UnknownClassError"); 537 return; 538 } 539 self.setFloat("x", 1f); 540 call.setObject(self); 541 } 542 543 private void _unpackVec2i(GrCall call) { 544 GrObject self = call.getObject(0); 545 if (!self) { 546 call.raise("NullError"); 547 return; 548 } 549 call.setInt(self.getInt("x")); 550 call.setInt(self.getInt("y")); 551 } 552 553 private void _unpackVec2f(GrCall call) { 554 GrObject self = call.getObject(0); 555 if (!self) { 556 call.raise("NullError"); 557 return; 558 } 559 call.setFloat(self.getFloat("x")); 560 call.setFloat(self.getFloat("y")); 561 } 562 563 private void _isZeroVec2i(GrCall call) { 564 GrObject self = call.getObject(0); 565 if (!self) { 566 call.raise("NullError"); 567 return; 568 } 569 call.setBool(self.getInt("x") == 0 && self.getInt("y") == 0); 570 } 571 572 private void _isZeroVec2f(GrCall call) { 573 GrObject self = call.getObject(0); 574 if (!self) { 575 call.raise("NullError"); 576 return; 577 } 578 call.setBool(self.getFloat("x") == 0f && self.getFloat("y") == 0f); 579 } 580 581 // Operations ------------------------------------------ 582 private void _sumVec2i(GrCall call) { 583 GrObject self = call.getObject(0); 584 if (!self) { 585 call.raise("NullError"); 586 return; 587 } 588 call.setInt(self.getInt("x") + self.getInt("y")); 589 } 590 591 private void _sumVec2f(GrCall call) { 592 GrObject self = call.getObject(0); 593 if (!self) { 594 call.raise("NullError"); 595 return; 596 } 597 call.setFloat(self.getFloat("x") + self.getFloat("y")); 598 } 599 600 private void _distanceVec2i(GrCall call) { 601 GrObject v1 = call.getObject(0); 602 GrObject v2 = call.getObject(1); 603 if (!v1 || !v2) { 604 call.raise("NullError"); 605 return; 606 } 607 const GrFloat px = v1.getInt("x") - v2.getInt("x"); 608 const GrFloat py = v1.getInt("y") - v2.getInt("y"); 609 call.setFloat(std.math.sqrt(px * px + py * py)); 610 } 611 612 private void _distanceVec2f(GrCall call) { 613 GrObject v1 = call.getObject(0); 614 GrObject v2 = call.getObject(1); 615 if (!v1 || !v2) { 616 call.raise("NullError"); 617 return; 618 } 619 const GrFloat px = v1.getFloat("x") - v2.getFloat("x"); 620 const GrFloat py = v1.getFloat("y") - v2.getFloat("y"); 621 call.setFloat(std.math.sqrt(px * px + py * py)); 622 } 623 624 private void _distanceSquaredVec2i(GrCall call) { 625 GrObject v1 = call.getObject(0); 626 GrObject v2 = call.getObject(1); 627 if (!v1 || !v2) { 628 call.raise("NullError"); 629 return; 630 } 631 const GrFloat px = v1.getInt("x") - v2.getInt("x"); 632 const GrFloat py = v1.getInt("y") - v2.getInt("y"); 633 call.setFloat(px * px + py * py); 634 } 635 636 private void _distanceSquaredVec2f(GrCall call) { 637 GrObject v1 = call.getObject(0); 638 GrObject v2 = call.getObject(1); 639 if (!v1 || !v2) { 640 call.raise("NullError"); 641 return; 642 } 643 const GrFloat px = v1.getFloat("x") - v2.getFloat("x"); 644 const GrFloat py = v1.getFloat("y") - v2.getFloat("y"); 645 call.setFloat(px * px + py * py); 646 } 647 648 private void _dotVec2i(GrCall call) { 649 GrObject v1 = call.getObject(0); 650 GrObject v2 = call.getObject(1); 651 if (!v1 || !v2) { 652 call.raise("NullError"); 653 return; 654 } 655 call.setFloat(v1.getInt("x") * v2.getInt("x") + v1.getInt("y") * v2.getInt("y")); 656 } 657 658 private void _dotVec2f(GrCall call) { 659 GrObject v1 = call.getObject(0); 660 GrObject v2 = call.getObject(1); 661 if (!v1 || !v2) { 662 call.raise("NullError"); 663 return; 664 } 665 call.setFloat(v1.getFloat("x") * v2.getFloat("x") + v1.getFloat("y") * v2.getFloat("y")); 666 } 667 668 private void _crossVec2i(GrCall call) { 669 GrObject v1 = call.getObject(0); 670 GrObject v2 = call.getObject(1); 671 if (!v1 || !v2) { 672 call.raise("NullError"); 673 return; 674 } 675 call.setFloat(v1.getInt("x") * v2.getInt("y") - v1.getInt("y") * v2.getInt("x")); 676 } 677 678 private void _crossVec2f(GrCall call) { 679 GrObject v1 = call.getObject(0); 680 GrObject v2 = call.getObject(1); 681 if (!v1 || !v2) { 682 call.raise("NullError"); 683 return; 684 } 685 call.setFloat(v1.getFloat("x") * v2.getFloat("y") - v1.getFloat("y") * v2.getFloat("x")); 686 } 687 688 private void _normalVec2i(GrCall call) { 689 GrObject self = call.getObject(0); 690 if (!self) { 691 call.raise("NullError"); 692 return; 693 } 694 GrObject v = call.createObject(_vec2iTypeName); 695 if(!v) { 696 call.raise("UnknownClassError"); 697 return; 698 } 699 v.setInt("x", -self.getInt("y")); 700 v.setInt("y", self.getInt("x")); 701 call.setObject(v); 702 } 703 704 private void _normalVec2f(GrCall call) { 705 GrObject self = call.getObject(0); 706 if (!self) { 707 call.raise("NullError"); 708 return; 709 } 710 GrObject v = call.createObject(_vec2fTypeName); 711 if(!v) { 712 call.raise("UnknownClassError"); 713 return; 714 } 715 v.setFloat("x", -self.getFloat("y")); 716 v.setFloat("y", self.getFloat("x")); 717 call.setObject(v); 718 } 719 720 private void _angleVec2i(GrCall call) { 721 GrObject self = call.getObject(0); 722 if (!self) { 723 call.raise("NullError"); 724 return; 725 } 726 call.setFloat(std.math.atan2(cast(GrFloat) self.getInt("y"), 727 cast(GrFloat) self.getInt("x")) * _radToDeg); 728 } 729 730 private void _angleVec2f(GrCall call) { 731 GrObject self = call.getObject(0); 732 if (!self) { 733 call.raise("NullError"); 734 return; 735 } 736 call.setFloat(std.math.atan2(self.getFloat("y"), self.getFloat("x")) * _radToDeg); 737 } 738 739 private void _rotateVec2f(GrCall call) { 740 GrObject self = call.getObject(0); 741 if (!self) { 742 call.raise("NullError"); 743 return; 744 } 745 const GrFloat radians = call.getFloat(1) * _degToRad; 746 const GrFloat px = self.getFloat("x"), py = self.getFloat("y"); 747 const GrFloat c = std.math.cos(radians); 748 const GrFloat s = std.math.sin(radians); 749 self.setFloat("x", px * c - py * s); 750 self.setFloat("y", px * s + py * c); 751 call.setObject(self); 752 } 753 754 private void _rotatedVec2f(GrCall call) { 755 GrObject self = call.getObject(0); 756 if (!self) { 757 call.raise("NullError"); 758 return; 759 } 760 const GrFloat radians = call.getFloat(1) * _degToRad; 761 const GrFloat px = self.getFloat("x"), py = self.getFloat("y"); 762 const GrFloat c = std.math.cos(radians); 763 const GrFloat s = std.math.sin(radians); 764 765 GrObject v = call.createObject(_vec2fTypeName); 766 if(!v) { 767 call.raise("UnknownClassError"); 768 return; 769 } 770 v.setFloat("x", px * c - py * s); 771 v.setFloat("y", px * s + py * c); 772 call.setObject(v); 773 } 774 775 private void _angledVec2f(GrCall call) { 776 const GrFloat radians = call.getFloat(0) * _degToRad; 777 GrObject v = call.createObject(_vec2fTypeName); 778 if(!v) { 779 call.raise("UnknownClassError"); 780 return; 781 } 782 v.setFloat("x", std.math.cos(radians)); 783 v.setFloat("y", std.math.sin(radians)); 784 call.setObject(v); 785 } 786 787 private void _lengthVec2i(GrCall call) { 788 GrObject self = call.getObject(0); 789 if (!self) { 790 call.raise("NullError"); 791 return; 792 } 793 const GrInt x = self.getInt("x"); 794 const GrInt y = self.getInt("y"); 795 call.setFloat(std.math.sqrt(cast(GrFloat)(x * x + y * y))); 796 } 797 798 private void _lengthVec2f(GrCall call) { 799 GrObject self = call.getObject(0); 800 if (!self) { 801 call.raise("NullError"); 802 return; 803 } 804 const GrFloat x = self.getFloat("x"); 805 const GrFloat y = self.getFloat("y"); 806 call.setFloat(std.math.sqrt(x * x + y * y)); 807 } 808 809 private void _lengthSquaredVec2i(GrCall call) { 810 GrObject self = call.getObject(0); 811 if (!self) { 812 call.raise("NullError"); 813 return; 814 } 815 const GrInt x = self.getInt("x"); 816 const GrInt y = self.getInt("y"); 817 call.setFloat(x * x + y * y); 818 } 819 820 private void _lengthSquaredVec2f(GrCall call) { 821 GrObject self = call.getObject(0); 822 if (!self) { 823 call.raise("NullError"); 824 return; 825 } 826 const GrFloat x = self.getFloat("x"); 827 const GrFloat y = self.getFloat("y"); 828 call.setFloat(x * x + y * y); 829 } 830 831 private void _normalizeVec2f(GrCall call) { 832 GrObject self = call.getObject(0); 833 if (!self) { 834 call.raise("NullError"); 835 return; 836 } 837 const GrFloat x = self.getFloat("x"); 838 const GrFloat y = self.getFloat("y"); 839 const GrFloat len = std.math.sqrt(x * x + y * y); 840 if (len == 0) { 841 self.setFloat("x", len); 842 self.setFloat("y", len); 843 return; 844 } 845 self.setFloat("x", x / len); 846 self.setFloat("y", y / len); 847 call.setObject(self); 848 } 849 850 private void _normalizedVec2f(GrCall call) { 851 GrObject self = call.getObject(0); 852 if (!self) { 853 call.raise("NullError"); 854 return; 855 } 856 GrFloat x = self.getFloat("x"); 857 GrFloat y = self.getFloat("y"); 858 const GrFloat len = std.math.sqrt(x * x + y * y); 859 860 if (len == 0) { 861 x = len; 862 y = len; 863 return; 864 } 865 x /= len; 866 y /= len; 867 868 GrObject v = call.createObject(_vec2fTypeName); 869 if(!v) { 870 call.raise("UnknownClassError"); 871 return; 872 } 873 v.setFloat("x", x); 874 v.setFloat("y", y); 875 call.setObject(v); 876 }