blob: 18ecf2698cbab4d3d15aa653dce587ce92f2c002 [file] [log] [blame]
/*
VectorMath.dart
Copyright (C) 2012 John McCutchan <john@johnmccutchan.com>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#import ('dart:builtin');
#import ('dart:io');
class MatrixGen {
int rows;
int cols;
String get rowVecType() => 'vec$cols';
String get colVecType() => 'vec$rows';
String get matType() => 'mat${cols}x${rows}';
int _indent;
RandomAccessFile out;
MatrixGen() {
_indent = 0;
}
List<String> get matrixComponents() {
List<String> r = new List<String>();
for (int i = 0; i < cols; i++) {
r.add('col$i');
}
return r;
}
String matTypeTransposed() {
return 'mat${rows}x${cols}';
}
void iPush() {
_indent++;
}
void iPop() {
_indent--;
assert(_indent >= 0);
}
void iPrint(String s) {
String indent = "";
for (int i = 0; i < _indent; i++) {
indent = '$indent ';
}
out.writeStringSync('$indent$s\n');
print('$indent$s');
}
void writeLicense() {
iPrint('''/*
VectorMath.dart
Copyright (C) 2012 John McCutchan <john@johnmccutchan.com>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/''');
}
String Access(int row, int col, [String pre = 'col']) {
//assert(row < rows && row >= 0);
//assert(col < cols && col >= 0);
String rowName = '';
if (row == 0) {
rowName = 'x';
} else if (row == 1) {
rowName = 'y';
} else if (row == 2) {
rowName = 'z';
} else if (row == 3) {
rowName = 'w';
} else {
assert(row < 4);
}
return '$pre$col.$rowName';
}
String AccessV(int row) {
String rowName = '';
if (row == 0) {
rowName = 'x';
} else if (row == 1) {
rowName = 'y';
} else if (row == 2) {
rowName = 'z';
} else if (row == 3) {
rowName = 'w';
} else {
assert(row < 4 && row >= 0);
}
return rowName;
}
void generatePrologue() {
iPrint('\/\/\/ ${matType} is a column major matrix where each column is represented by [$colVecType]. This matrix has $cols columns and $rows rows.');
iPrint('class ${matType} {');
iPush();
for (int i = 0; i < cols; i++) {
iPrint('$colVecType col$i;');
}
}
String joinStrings(List<String> elements, [String pre = '', String post = '', String joiner = ', ']) {
bool first = true;
String r = '';
for (String e in elements) {
var extra = first ? '${pre}${e}${post}' : '${joiner}${pre}${e}${post}';
r = '$r$extra';
first = false;
}
return r;
}
void generateConstructors() {
int numArguments = cols * rows;
List<String> arguments = new List<String>(numArguments);
for (int i = 0; i < numArguments; i++) {
arguments[i] = 'arg$i';
}
List<String> columnArguments = new List<String>(cols);
for (int i = 0; i < cols; i++) {
columnArguments[i] = 'arg$i';
}
iPrint('\/\/\/ Constructs a new ${matType}. Supports GLSL like syntax so many possible inputs. Defaults to identity matrix.');
iPrint('${matType}([${joinStrings(arguments, 'Dynamic ')}]) {');
iPush();
iPrint('//Initialize the matrix as the identity matrix');
for (int i = 0; i < cols; i++) {
iPrint('col$i = new $colVecType();');
}
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
if (i == j) {
iPrint('${Access(j, i)} = 1.0;');
}
}
}
iPrint('if (${joinStrings(arguments, '', ' is num', ' && ')}) {');
iPush();
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
iPrint('${Access(j, i)} = arg${(i*rows)+j};');
}
}
iPrint('return;');
iPop();
iPrint('}');
iPrint('if (arg0 is num && ${joinStrings(arguments.getRange(1, numArguments-1), '', ' == null', ' && ')}) {');
iPush();
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
if (i == j) {
iPrint('${Access(j, i)} = arg0;');
}
}
}
iPrint('return;');
iPop();
iPrint('}');
iPrint('if (${joinStrings(columnArguments, '', ' is vec${cols}', ' && ')}) {');
iPush();
for (int i = 0; i < cols; i++) {
iPrint('col$i = arg$i;');
}
iPrint('return;');
iPop();
iPrint('}');
iPrint('if (arg0 is ${matType}) {');
iPush();
for (int i = 0; i < cols; i++) {
iPrint('col$i = arg0.col$i;');
}
iPrint('return;');
iPop();
iPrint('}');
for (int i = cols; i >= 2; i--) {
for (int j = rows; j >= 2; j--) {
if (i == cols && j == rows) {
continue;
}
iPrint('if (arg0 is mat${i}x${j}) {');
iPush();
for (int k = 0; k < i; k++) {
for (int l = 0; l < j; l++) {
iPrint('${Access(l, k)} = arg0.${Access(l, k)};');
}
}
iPrint('return;');
iPop();
iPrint('}');
}
}
int diagonals = rows < cols ? rows : cols;
for (int i = 1; i < diagonals; i++) {
iPrint('if (arg0 is vec${i+1} && ${joinStrings(arguments.getRange(1, numArguments-1), '', ' == null', ' && ')}) {');
iPush();
for (int j = 0; j < i+1; j++) {
iPrint('${Access(j, j)} = arg0.${AccessV(j)};');
}
iPop();
iPrint('}');
}
iPop();
iPrint('}');
// Outer product constructor
iPrint('\/\/\/ Constructs a new [${matType}] from computing the outer product of [u] and [v].');
iPrint('${matType}.outer(vec${cols} u, vec${rows} v) {');
iPush();
for (int i = 0; i < cols; i++) {
iPrint('col$i = new $colVecType();');
}
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
iPrint('${Access(j, i)} = u.${AccessV(i)} * v.${AccessV(j)};');
}
}
iPop();
iPrint('}');
iPrint('\/\/\/ Constructs a new [${matType}] filled with zeros.');
iPrint('${matType}.zero() {');
iPush();
for (int i = 0; i < cols; i++) {
iPrint('col$i = new $colVecType();');
}
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
iPrint('${Access(j, i)} = 0.0;');
}
}
iPop();
iPrint('}');
iPrint('\/\/\/ Constructs a new identity [${matType}].');
iPrint('${matType}.identity() {');
iPush();
for (int i = 0; i < cols; i++) {
iPrint('col$i = new $colVecType();');
}
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
if (i == j) {
iPrint('${Access(j, i)} = 1.0;');
} else {
iPrint('${Access(j, i)} = 0.0;');
}
}
}
iPop();
iPrint('}');
iPrint('\/\/\/ Constructs a new [${matType}] which is a copy of [other].');
iPrint('${matType}.copy($matType other) {');
iPush();
for (int i = 0; i < cols; i++) {
iPrint('col$i = new $colVecType();');
}
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
iPrint('${Access(j, i)} = other.${Access(j, i)};');
}
}
iPop();
iPrint('}');
if (rows == 2 && cols == 2) {
iPrint('\/\/\/ Constructs a new [${matType}] representing a rotation by [radians].');
iPrint('${matType}.rotation(num radians_) {');
iPush();
for (int i = 0; i < cols; i++) {
iPrint('col$i = new $colVecType();');
}
iPrint('setRotation(radians_);');
iPop();
iPrint('}');
}
if ((rows == 3 && cols == 3) || (rows == 4 && cols == 4)) {
iPrint('\/\/\/\/ Constructs a new [${matType}] representation a rotation of [radians] around the X axis');
iPrint('${matType}.rotationX(num radians_) {');
iPush();
for (int i = 0; i < cols; i++) {
iPrint('col$i = new $colVecType();');
}
iPrint('setRotationAroundX(radians_);');
iPop();
iPrint('}');
iPrint('\/\/\/\/ Constructs a new [${matType}] representation a rotation of [radians] around the Y axis');
iPrint('${matType}.rotationY(num radians_) {');
iPush();
for (int i = 0; i < cols; i++) {
iPrint('col$i = new $colVecType();');
}
iPrint('setRotationAroundY(radians_);');
iPop();
iPrint('}');
iPrint('\/\/\/\/ Constructs a new [${matType}] representation a rotation of [radians] around the Z axis');
iPrint('${matType}.rotationZ(num radians_) {');
iPush();
for (int i = 0; i < cols; i++) {
iPrint('col$i = new $colVecType();');
}
iPrint('setRotationAroundZ(radians_);');
iPop();
iPrint('}');
}
iPrint('${matType}.raw(${joinStrings(arguments, 'num ')}) {');
iPush();
for (int i = 0; i < cols; i++) {
iPrint('col$i = new $colVecType();');
}
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
iPrint('${Access(j, i)} = arg${(i*rows)+j};');
}
}
iPop();
iPrint('}');
}
void generateRowColProperties() {
iPrint('\/\/\/ Returns the number of rows in the matrix.');
iPrint('num get rows() => $rows;');
iPrint('\/\/\/ Returns the number of columns in the matrix.');
iPrint('num get cols() => $cols;');
iPrint('\/\/\/ Returns the number of columns in the matrix.');
iPrint('num get length() => $cols;');
}
void generateRowGetterSetters() {
for (int i = 0; i < rows; i++) {
iPrint('\/\/\/ Returns row $i');
iPrint('$rowVecType get row$i() => getRow($i);');
}
for (int i = 0; i < rows; i++) {
iPrint('\/\/\/ Sets row $i to [arg]');
iPrint('set row$i($rowVecType arg) => setRow($i, arg);');
}
}
void generateIndexOperator() {
iPrint('\/\/\/ Gets the [column] of the matrix');
iPrint('$colVecType operator[](int column) {');
iPush();
iPrint('assert(column >= 0 && column < $cols);');
iPrint('switch (column) {');
iPush();
for (int i = 0; i < cols; i++) {
iPrint('case $i: return col$i;');
}
iPop();
iPrint('}');
iPrint('throw new IllegalArgumentException(column);');
iPop();
iPrint('}');
}
void generateAssignIndexOperator() {
iPrint('\/\/\/ Assigns the [column] of the matrix [arg]');
iPrint('$colVecType operator[]=(int column, $colVecType arg) {');
iPush();
iPrint('assert(column >= 0 && column < $cols);');
iPrint('switch (column) {');
iPush();
for (int i = 0; i < cols; i++) {
iPrint('case $i: col$i = arg; return col$i;');
}
iPop();
iPrint('}');
iPrint('throw new IllegalArgumentException(column);');
iPop();
iPrint('}');
}
void generateRowHelpers() {
iPrint('\/\/\/ Assigns the [column] of the matrix [arg]');
iPrint('void setRow(int row, $rowVecType arg) {');
iPush();
iPrint('assert(row >= 0 && row < $rows);');
for (int i = 0; i < cols; i++) {
iPrint('col$i[row] = arg.${AccessV(i)};');
}
iPop();
iPrint('}');
iPrint('\/\/\/ Gets the [row] of the matrix');
iPrint('$rowVecType getRow(int row) {');
iPush();
iPrint('assert(row >= 0 && row < $rows);');
iPrint('${rowVecType} r = new ${rowVecType}();');
for (int i = 0; i < cols; i++) {
iPrint('r.${AccessV(i)} = col$i[row];');
}
iPrint('return r;');
iPop();
iPrint('}');
}
void generateColumnHelpers() {
iPrint('\/\/\/ Assigns the [column] of the matrix [arg]');
iPrint('void setColumn(int column, $colVecType arg) {');
iPush();
iPrint('assert(column >= 0 && column < $cols);');
iPrint('this[column] = arg;');
iPop();
iPrint('}');
iPrint('\/\/\/ Gets the [column] of the matrix');
iPrint('$colVecType getColumn(int column) {');
iPush();
iPrint('assert(column >= 0 && column < $cols);');
iPrint('return new ${colVecType}(this[column]);');
iPop();
iPrint('}');
}
void generateToString() {
iPrint('\/\/\/ Returns a printable string');
iPrint('String toString() {');
iPush();
iPrint('String s = \'\';');
for (int i = 0; i < rows; i++) {
iPrint('s = \'\$s[$i] \${getRow($i)}\\n\';');
}
iPrint('return s;');
iPop();
iPrint('}');
}
void generateEpilogue() {
iPop();
iPrint('}');
}
String generateInlineDot(String rowPrefix, int row, String col, int len) {
String r = '';
for (int i = 0; i < len; i++) {
if (i != 0) {
r = '$r +';
}
r = '$r (${rowPrefix}.${Access(row, i)} * ${col}.${AccessV(i)})';
}
return r;
}
void generateMatrixVectorMultiply() {
iPrint('$colVecType r = new $colVecType();');
for (int i = 0; i < rows; i++) {
iPrint('r.${AccessV(i)} = ${generateInlineDot('this', i, 'arg', cols)};');
}
iPrint('return r;');
}
String generateInlineDotM(String rowPrefix, String colPrefix, int srow, int scol, int len) {
String r = '';
for (int i = 0; i < len; i++) {
if (i != 0) {
r = '$r +';
}
r = '$r (${rowPrefix}.${Access(srow, i)} * ${colPrefix}.${Access(i, scol)})';
}
return r;
}
void generateMatrixMatrixMultiply() {
iPrint('Dynamic r = null;');
iPrint('if (arg.cols == 2) {');
iPush();
iPrint('r = new mat2x${rows}();');
for (int i = 0; i < rows; i++) {
for (int j = 0; j < 2; j++) {
iPrint('r.${Access(i, j)} = ${generateInlineDotM('this', 'arg', i, j, cols)};');
}
}
iPrint('return r;');
iPop();
iPrint('}');
if (rows >= 3) {
iPrint('if (arg.cols == 3) {');
iPush();
iPrint('r = new mat3x${rows}();');
for (int i = 0; i < rows; i++) {
for (int j = 0; j < 3; j++) {
iPrint('r.${Access(i, j)} = ${generateInlineDotM('this', 'arg', i, j, cols)};');
}
}
iPrint('return r;');
iPop();
iPrint('}');
}
if (rows >= 4) {
iPrint('if (arg.cols == 4) {');
iPush();
iPrint('r = new mat4x${rows}();');
for (int i = 0; i < rows; i++) {
for (int j = 0; j < 4; j++) {
iPrint('r.${Access(i, j)} = ${generateInlineDotM('this', 'arg', i, j, cols)};');
}
}
iPrint('return r;');
iPop();
iPrint('}');
}
iPrint('return r;');
}
void generateMatrixScale() {
iPrint('${matType} r = new ${matType}();');
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
iPrint('r.${Access(j, i)} = ${Access(j, i)} * arg;');
}
}
iPrint('return r;');
}
void generateMult() {
iPrint('\/\/\/ Returns a new vector or matrix by multiplying [this] with [arg].');
iPrint('Dynamic operator*(Dynamic arg) {');
iPush();
iPrint('if (arg is num) {');
iPush();
generateMatrixScale();
iPop();
iPrint('}');
iPrint('if (arg is $rowVecType) {');
iPush();
generateMatrixVectorMultiply();
iPop();
iPrint('}');
iPrint('if ($cols == arg.rows) {');
iPush();
generateMatrixMatrixMultiply();
iPop();
iPrint('}');
iPrint('throw new IllegalArgumentException(arg);');
iPop();
iPrint('}');
}
void generateOp(String op) {
iPrint('\/\/\/ Returns new matrix after component wise [this] $op [arg]');
iPrint('${matType} operator$op(${matType} arg) {');
iPush();
iPrint('${matType} r = new ${matType}();');
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
iPrint('r.${Access(j, i)} = ${Access(j, i)} $op arg.${Access(j, i)};');
}
}
iPrint('return r;');
iPop();
iPrint('}');
}
void generateNegate() {
iPrint('\/\/\/ Returns new matrix -this');
iPrint('${matType} operator negate() {');
iPush();
iPrint('${matType} r = new ${matType}();');
for (int i = 0; i < cols; i++) {
iPrint('r[$i] = -this[$i];');
}
iPrint('return r;');
iPop();
iPrint('}');
}
void generateTranspose() {
iPrint('\/\/\/ Returns the tranpose of this.');
iPrint('${matTypeTransposed()} transposed() {');
iPush();
iPrint('${matTypeTransposed()} r = new ${matTypeTransposed()}();');
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
iPrint('r.${Access(j, i)} = ${Access(i, j)};');
}
}
iPrint('return r;');
iPop();
iPrint('}');
}
void generateAbsolute() {
iPrint('\/\/\/ Returns the component wise absolute value of this.');
iPrint('${matType} absolute() {');
iPush();
iPrint('${matType} r = new ${matType}();');
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
iPrint('r.${Access(j, i)} = ${Access(j, i)}.abs();');
}
}
iPrint('return r;');
iPop();
iPrint('}');
}
void generateDeterminant() {
if (matType == 'mat2x2') {
iPrint('\/\/\/ Returns the determinant of this matrix.');
iPrint('num determinant() {');
iPush();
iPrint('return (col0.x * col1.y) - (col0.y*col1.x);');
iPop();
iPrint('}');
}
if (matType == 'mat3x3') {
iPrint('\/\/\/ Returns the determinant of this matrix.');
iPrint('num determinant() {');
iPush();
iPrint('num x = col0.x*((col1.y*col2.z)-(col1.z*col2.y));');
iPrint('num y = col0.y*((col1.x*col2.z)-(col1.z*col2.x));');
iPrint('num z = col0.z*((col1.x*col2.y)-(col1.y*col2.x));');
iPrint('return x - y + z;');
iPop();
iPrint('}');
}
if (matType == 'mat4x4') {
iPrint('\/\/\/ Returns the determinant of this matrix.');
iPrint('num determinant() {');
iPush();
iPrint('num det2_01_01 = col0.x * col1.y - col0.y * col1.x;');
iPrint('num det2_01_02 = col0.x * col1.z - col0.z * col1.x;');
iPrint('num det2_01_03 = col0.x * col1.w - col0.w * col1.x;');
iPrint('num det2_01_12 = col0.y * col1.z - col0.z * col1.y;');
iPrint('num det2_01_13 = col0.y * col1.w - col0.w * col1.y;');
iPrint('num det2_01_23 = col0.z * col1.w - col0.w * col1.z;');
iPrint('num det3_201_012 = col2.x * det2_01_12 - col2.y * det2_01_02 + col2.z * det2_01_01;');
iPrint('num det3_201_013 = col2.x * det2_01_13 - col2.y * det2_01_03 + col2.w * det2_01_01;');
iPrint('num det3_201_023 = col2.x * det2_01_23 - col2.z * det2_01_03 + col2.w * det2_01_02;');
iPrint('num det3_201_123 = col2.y * det2_01_23 - col2.z * det2_01_13 + col2.w * det2_01_12;');
iPrint('return ( - det3_201_123 * col3.x + det3_201_023 * col3.y - det3_201_013 * col3.z + det3_201_012 * col3.w);');
iPop();
iPrint('}');
}
}
void generateTrace() {
if (rows == cols) {
iPrint('\/\/\/ Returns the trace of the matrix. The trace of a matrix is the sum of the diagonal entries');
iPrint('num trace() {');
iPush();
iPrint('num t = 0.0;');
for (int i = 0; i < cols; i++) {
iPrint('t += ${Access(i, i)};');
}
iPrint('return t;');
iPop();
iPrint('}');
}
}
void generateInfinityNorm() {
iPrint('\/\/\/ Returns infinity norm of the matrix. Used for numerical analysis.');
iPrint('num infinityNorm() {');
iPush();
iPrint('num norm = 0.0;');
for (int i = 0; i < cols; i++) {
iPrint('{');
iPush();
iPrint('num row_norm = 0.0;');
for (int j = 0; j < rows; j++) {
iPrint('row_norm += this[$i][$j].abs();');
}
iPrint('norm = row_norm > norm ? row_norm : norm;');
iPop();
iPrint('}');
}
iPrint('return norm;');
iPop();
iPrint('}');
}
void generateError() {
iPrint('\/\/\/ Returns relative error between [this] and [correct]');
iPrint('num relativeError($matType correct) {');
iPush();
iPrint('num this_norm = infinityNorm();');
iPrint('num correct_norm = correct.infinityNorm();');
iPrint('num diff_norm = (this_norm - correct_norm).abs();');
iPrint('return diff_norm/correct_norm;');
iPop();
iPrint('}');
iPrint('\/\/\/ Returns absolute error between [this] and [correct]');
iPrint('num absoluteError($matType correct) {');
iPush();
iPrint('num this_norm = infinityNorm();');
iPrint('num correct_norm = correct.infinityNorm();');
iPrint('num diff_norm = (this_norm - correct_norm).abs();');
iPrint('return diff_norm;');
iPop();
iPrint('}');
}
void generateTranslate() {
if (rows == 4 && cols == 4) {
iPrint('\/\/\/ Returns the translation vector from this homogeneous transformation matrix.');
iPrint('vec3 getTranslation() {');
iPush();
iPrint('return new vec3(col3.x, col3.y, col3.z);');
iPop();
iPrint('}');
iPrint('\/\/\/ Sets the translation vector in this homogeneous transformation matrix.');
iPrint('void setTranslation(vec3 T) {');
iPush();
iPrint('col3.xyz = T;');
iPop();
iPrint('}');
}
}
void generateRotation() {
if (rows == 4 && cols == 4) {
iPrint('\/\/\/ Returns the rotation matrix from this homogeneous transformation matrix.');
iPrint('mat3x3 getRotation() {');
iPush();
iPrint('mat3x3 r = new mat3x3();');
iPrint('r.col0 = new vec3(this.col0.x,this.col0.y,this.col0.z);');
iPrint('r.col1 = new vec3(this.col1.x,this.col1.y,this.col1.z);');
iPrint('r.col2 = new vec3(this.col2.x,this.col2.y,this.col2.z);');
iPrint('return r;');
iPop();
iPrint('}');
iPrint('\/\/\/ Sets the rotation matrix in this homogeneous transformation matrix.');
iPrint('void setRotation(mat3x3 rotation) {');
iPush();
iPrint('this.col0.xyz = rotation.col0;');
iPrint('this.col1.xyz = rotation.col1;');
iPrint('this.col2.xyz = rotation.col2;');
iPop();
iPrint('}');
iPrint('\/\/\/ Transposes just the upper 3x3 rotation matrix.');
iPrint('void transposeRotation() {');
iPush();
iPrint('num temp;');
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i == j) {
continue;
}
iPrint('temp = this.${Access(j, i)};');
iPrint('this.${Access(j, i)} = this.${Access(i, j)};');
iPrint('this.${Access(i, j)} = temp;');
}
}
iPop();
iPrint('}');
}
}
void generateInvert() {
if (rows != cols) {
// Only square matrices have inverses
return;
}
if (rows == 2) {
iPrint('\/\/\/ Invert the matrix. Returns the determinant.');
iPrint('num invert() {');
iPush();
iPrint('num det = determinant();');
iPrint('if (det == 0.0) {');
iPush();
iPrint('return 0.0;');
iPop();
iPrint('}');
iPrint('num invDet = 1.0 / det;');
iPrint('num temp = col0.x;');
iPrint('col0.x = col1.y * invDet;');
iPrint('col0.y = - col0.y * invDet;');
iPrint('col1.x = - col1.x * invDet;');
iPrint('col1.y = temp * invDet;');
iPrint('return det;');
iPop();
iPrint('}');
} else if (rows == 3) {
iPrint('/\/\/\ Invert the matrix. Returns the determinant.');
iPrint('num invert() {');
iPush();
iPrint('num det = determinant();');
iPrint('if (det == 0.0) {');
iPush();
iPrint('return 0.0;');
iPop();
iPrint('}');
iPrint('num invDet = 1.0 / det;');
iPrint('vec3 i = new vec3.zero();');
iPrint('vec3 j = new vec3.zero();');
iPrint('vec3 k = new vec3.zero();');
iPrint('i.x = invDet * (col1.y * col2.z - col1.z * col2.y);');
iPrint('i.y = invDet * (col0.z * col2.y - col0.y * col2.z);');
iPrint('i.z = invDet * (col0.y * col1.z - col0.z * col1.y);');
iPrint('j.x = invDet * (col1.z * col2.x - col1.x * col2.z);');
iPrint('j.y = invDet * (col0.x * col2.z - col0.z * col2.x);');
iPrint('j.z = invDet * (col0.z * col1.x - col0.x * col1.z);');
iPrint('k.x = invDet * (col1.x * col2.y - col1.y * col2.x);');
iPrint('k.y = invDet * (col0.y * col2.x - col0.x * col2.y);');
iPrint('k.z = invDet * (col0.x * col1.y - col0.y * col1.x);');
iPrint('col0 = i;');
iPrint('col1 = j;');
iPrint('col2 = k;');
iPrint('return det;');
iPop();
iPrint('}');
} else if (rows == 4) {
iPrint('num invert() {');
iPush();
iPrint('num det = determinant();');
iPrint('if (det == 0.0) {');
iPush();
iPrint('return 0.0;');
iPop();
iPrint('}');
iPrint('num invDet = 1.0 / det;');
iPrint('selfScaleAdjoint(invDet);');
iPrint('return det;');
iPop();
iPrint('}');
iPrint('num invertRotation() {');
iPush();
iPrint('num det = determinant();');
iPrint('if (det == 0.0) {');
iPush();
iPrint('return 0.0;');
iPop();
iPrint('}');
iPrint('num invDet = 1.0 / det;');
iPrint('vec4 i = new vec4.zero();');
iPrint('vec4 j = new vec4.zero();');
iPrint('vec4 k = new vec4.zero();');
iPrint('i.x = invDet * (col1.y * col2.z - col1.z * col2.y);');
iPrint('i.y = invDet * (col0.z * col2.y - col0.y * col2.z);');
iPrint('i.z = invDet * (col0.y * col1.z - col0.z * col1.y);');
iPrint('j.x = invDet * (col1.z * col2.x - col1.x * col2.z);');
iPrint('j.y = invDet * (col0.x * col2.z - col0.z * col2.x);');
iPrint('j.z = invDet * (col0.z * col1.x - col0.x * col1.z);');
iPrint('k.x = invDet * (col1.x * col2.y - col1.y * col2.x);');
iPrint('k.y = invDet * (col0.y * col2.x - col0.x * col2.y);');
iPrint('k.z = invDet * (col0.x * col1.y - col0.y * col1.x);');
iPrint('col0 = i;');
iPrint('col1 = j;');
iPrint('col2 = k;');
iPrint('return det;');
iPop();
iPrint('}');
}
}
void generateSetRotation() {
if (rows == 2 && cols == 2) {
iPrint('\/\/\/ Turns the matrix into a rotation of [radians]');
iPrint('void setRotation(num radians_) {');
iPush();
iPrint('num c = Math.cos(radians_);');
iPrint('num s = Math.sin(radians_);');
iPrint('col0.x = c;');
iPrint('col0.y = s;');
iPrint('col1.x = -s;');
iPrint('col1.y = c;');
iPop();
iPrint('}');
}
if (rows == 3 && cols == 3) {
iPrint('\/\/\/ Turns the matrix into a rotation of [radians] around X');
iPrint('void setRotationAroundX(num radians_) {');
iPush();
iPrint('num c = Math.cos(radians_);');
iPrint('num s = Math.sin(radians_);');
iPrint('col0.x = 1.0;');
iPrint('col0.y = 0.0;');
iPrint('col0.z = 0.0;');
iPrint('col1.x = 0.0;');
iPrint('col1.y = c;');
iPrint('col1.z = s;');
iPrint('col2.x = 0.0;');
iPrint('col2.y = -s;');
iPrint('col2.z = c;');
iPop();
iPrint('}');
iPrint('\/\/\/ Turns the matrix into a rotation of [radians] around Y');
iPrint('void setRotationAroundY(num radians_) {');
iPush();
iPrint('num c = Math.cos(radians_);');
iPrint('num s = Math.sin(radians_);');
iPrint('col0.x = c;');
iPrint('col0.y = 0.0;');
iPrint('col0.z = -s;');
iPrint('col1.x = 0.0;');
iPrint('col1.y = 1.0;');
iPrint('col1.z = 0.0;');
iPrint('col2.x = s;');
iPrint('col2.y = 0.0;');
iPrint('col2.z = c;');
iPop();
iPrint('}');
iPrint('\/\/\/ Turns the matrix into a rotation of [radians] around Z');
iPrint('void setRotationAroundZ(num radians_) {');
iPush();
iPrint('num c = Math.cos(radians_);');
iPrint('num s = Math.sin(radians_);');
iPrint('col0.x = c;');
iPrint('col0.y = s;');
iPrint('col0.z = 0.0;');
iPrint('col1.x = -s;');
iPrint('col1.y = c;');
iPrint('col1.z = 0.0;');
iPrint('col2.x = 0.0;');
iPrint('col2.y = 0.0;');
iPrint('col2.z = 1.0;');
iPop();
iPrint('}');
}
if (rows == 4 && cols == 4) {
iPrint('\/\/\/ Sets the upper 3x3 to a rotation of [radians] around X');
iPrint('void setRotationAroundX(num radians_) {');
iPush();
iPrint('num c = Math.cos(radians_);');
iPrint('num s = Math.sin(radians_);');
iPrint('col0.x = 1.0;');
iPrint('col0.y = 0.0;');
iPrint('col0.z = 0.0;');
iPrint('col1.x = 0.0;');
iPrint('col1.y = c;');
iPrint('col1.z = s;');
iPrint('col2.x = 0.0;');
iPrint('col2.y = -s;');
iPrint('col2.z = c;');
iPrint('col0.w = 0.0;');
iPrint('col1.w = 0.0;');
iPrint('col2.w = 0.0;');
iPop();
iPrint('}');
iPrint('\/\/\/ Sets the upper 3x3 to a rotation of [radians] around Y');
iPrint('void setRotationAroundY(num radians_) {');
iPush();
iPrint('num c = Math.cos(radians_);');
iPrint('num s = Math.sin(radians_);');
iPrint('col0.x = c;');
iPrint('col0.y = 0.0;');
iPrint('col0.z = -s;');
iPrint('col1.x = 0.0;');
iPrint('col1.y = 1.0;');
iPrint('col1.z = 0.0;');
iPrint('col2.x = s;');
iPrint('col2.y = 0.0;');
iPrint('col2.z = c;');
iPrint('col0.w = 0.0;');
iPrint('col1.w = 0.0;');
iPrint('col2.w = 0.0;');
iPop();
iPrint('}');
iPrint('\/\/\/ Sets the upper 3x3 to a rotation of [radians] around Z');
iPrint('void setRotationAroundZ(num radians_) {');
iPush();
iPrint('num c = Math.cos(radians_);');
iPrint('num s = Math.sin(radians_);');
iPrint('col0.x = c;');
iPrint('col0.y = s;');
iPrint('col0.z = 0.0;');
iPrint('col1.x = -s;');
iPrint('col1.y = c;');
iPrint('col1.z = 0.0;');
iPrint('col2.x = 0.0;');
iPrint('col2.y = 0.0;');
iPrint('col2.z = 1.0;');
iPrint('col0.w = 0.0;');
iPrint('col1.w = 0.0;');
iPrint('col2.w = 0.0;');
iPop();
iPrint('}');
}
}
String generateInlineDet2(String a, String b, String c, String d) {
return '($a * $d - $b * $c)';
}
String generateInlineDet3(String a1, String a2, String a3, String b1, String b2, String b3, String c1, String c2, String c3) {
return '($a1 * ${generateInlineDet2(b2, b3, c2, c3)} - $b1 * ${generateInlineDet2(a2, a3, c2, c3)} + $c1 * ${generateInlineDet2(a2, a3, b2, b3)})';
}
void generateAdjugate() {
if (rows != cols) {
return;
}
iPrint('\/\/\/ Converts into Adjugate matrix and scales by [scale]');
if (rows == 2) {
iPrint('void selfScaleAdjoint(num scale) {');
iPush();
iPrint('num temp = ${Access(0, 0)};');
iPrint('${Access(0, 0)} = ${Access(1,1)} * scale;');
iPrint('${Access(0, 1)} = - ${Access(0,1)} * scale;');
iPrint('${Access(1, 0)} = - ${Access(1, 0)} * scale;');
iPrint('${Access(1, 1)} = temp * scale;');
iPop();
iPrint('}');
}
if (cols == 3) {
iPrint('void selfScaleAdjoint(num scale) {');
iPush();
iPrint('num m00 = ${Access(0, 0)};');
iPrint('num m01 = ${Access(0, 1)};');
iPrint('num m02 = ${Access(0, 2)};');
iPrint('num m10 = ${Access(1, 0)};');
iPrint('num m11 = ${Access(1, 1)};');
iPrint('num m12 = ${Access(1, 2)};');
iPrint('num m20 = ${Access(2, 0)};');
iPrint('num m21 = ${Access(2, 1)};');
iPrint('num m22 = ${Access(2, 2)};');
iPrint('${Access(0, 0)} = (m11 * m22 - m12 * m21) * scale;');
iPrint('${Access(1, 0)} = (m12 * m20 - m10 * m22) * scale;');
iPrint('${Access(2, 0)} = (m10 * m21 - m11 * m20) * scale;');
iPrint('${Access(0, 1)} = (m02 * m21 - m01 * m22) * scale;');
iPrint('${Access(1, 1)} = (m00 * m22 - m02 * m20) * scale;');
iPrint('${Access(2, 1)} = (m01 * m20 - m00 * m21) * scale;');
iPrint('${Access(0, 2)} = (m01 * m12 - m02 * m11) * scale;');
iPrint('${Access(1, 2)} = (m02 * m10 - m00 * m12) * scale;');
iPrint('${Access(2, 2)} = (m00 * m00 - m01 * m10) * scale;');
iPop();
iPrint('}');
}
if (cols == 4) {
iPrint('void selfScaleAdjoint(num scale) {');
iPush();
iPrint('\/\/ Adapted from code by Richard Carling.');
iPrint('num a1 = ${Access(0,0)};');
iPrint('num b1 = ${Access(0,1)};');
iPrint('num c1 = ${Access(0,2)};');
iPrint('num d1 = ${Access(0,3)};');
iPrint('num a2 = ${Access(1,0)};');
iPrint('num b2 = ${Access(1,1)};');
iPrint('num c2 = ${Access(1,2)};');
iPrint('num d2 = ${Access(1,3)};');
iPrint('num a3 = ${Access(2,0)};');
iPrint('num b3 = ${Access(2,1)};');
iPrint('num c3 = ${Access(2,2)};');
iPrint('num d3 = ${Access(2,3)};');
iPrint('num a4 = ${Access(3,0)};');
iPrint('num b4 = ${Access(3,1)};');
iPrint('num c4 = ${Access(3,2)};');
iPrint('num d4 = ${Access(3,3)};');
iPrint('${Access(0,0)} = ${generateInlineDet3( 'b2', 'b3', 'b4', 'c2', 'c3', 'c4', 'd2', 'd3', 'd4')} * scale;');
iPrint('${Access(1,0)} = - ${generateInlineDet3( 'a2', 'a3', 'a4', 'c2', 'c3', 'c4', 'd2', 'd3', 'd4')} * scale;');
iPrint('${Access(2,0)} = ${generateInlineDet3( 'a2', 'a3', 'a4', 'b2', 'b3', 'b4', 'd2', 'd3', 'd4')} * scale;');
iPrint('${Access(3,0)} = - ${generateInlineDet3( 'a2', 'a3', 'a4', 'b2', 'b3', 'b4', 'c2', 'c3', 'c4')} * scale;');
iPrint('${Access(0,1)} = - ${generateInlineDet3( 'b1', 'b3', 'b4', 'c1', 'c3', 'c4', 'd1', 'd3', 'd4')} * scale;');
iPrint('${Access(1,1)} = ${generateInlineDet3( 'a1', 'a3', 'a4', 'c1', 'c3', 'c4', 'd1', 'd3', 'd4')} * scale;');
iPrint('${Access(2,1)} = - ${generateInlineDet3( 'a1', 'a3', 'a4', 'b1', 'b3', 'b4', 'd1', 'd3', 'd4')} * scale;');
iPrint('${Access(3,1)} = ${generateInlineDet3( 'a1', 'a3', 'a4', 'b1', 'b3', 'b4', 'c1', 'c3', 'c4')} * scale;');
iPrint('${Access(0,2)} = ${generateInlineDet3( 'b1', 'b2', 'b4', 'c1', 'c2', 'c4', 'd1', 'd2', 'd4')} * scale;');
iPrint('${Access(1,2)} = - ${generateInlineDet3( 'a1', 'a2', 'a4', 'c1', 'c2', 'c4', 'd1', 'd2', 'd4')} * scale;');
iPrint('${Access(2,2)} = ${generateInlineDet3( 'a1', 'a2', 'a4', 'b1', 'b2', 'b4', 'd1', 'd2', 'd4')} * scale;');
iPrint('${Access(3,2)} = - ${generateInlineDet3( 'a1', 'a2', 'a4', 'b1', 'b2', 'b4', 'c1', 'c2', 'c4')} * scale;');
iPrint('${Access(0,3)} = - ${generateInlineDet3( 'b1', 'b2', 'b3', 'c1', 'c2', 'c3', 'd1', 'd2', 'd3')} * scale;');
iPrint('${Access(1,3)} = ${generateInlineDet3( 'a1', 'a2', 'a3', 'c1', 'c2', 'c3', 'd1', 'd2', 'd3')} * scale;');
iPrint('${Access(2,3)} = - ${generateInlineDet3( 'a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'd1', 'd2', 'd3')} * scale;');
iPrint('${Access(3,3)} = ${generateInlineDet3( 'a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3')} * scale;');
iPop();
iPrint('}');
}
}
void generateCopy() {
iPrint('$matType copy() {');
iPush();
iPrint('return new ${matType}.copy(this);');
iPop();
iPrint('}');
}
void generateSelfOp(String name, String op) {
iPrint('$matType self$name($matType o) {');
iPush();
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
iPrint('${Access(j,i)} = ${Access(j,i)} $op o.${Access(j,i)};');
}
}
iPrint('return this;');
iPop();
iPrint('}');
}
void generateSelfScalarOp(String name, String op) {
iPrint('$matType self$name(num o) {');
iPush();
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
iPrint('${Access(j,i)} = ${Access(j,i)} $op o;');
}
}
iPrint('return this;');
iPop();
iPrint('}');
}
void generateSelfNegate() {
iPrint('$matType selfNegate() {');
iPush();
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
iPrint('${Access(j,i)} = -${Access(j,i)};');
}
}
iPrint('return this;');
iPop();
iPrint('}');
}
generateSelfMultiplyMatrix() {
if (rows != cols) {
// Only generate this for square matrices
return;
}
iPrint('$matType selfMultiply($matType arg) {');
iPush();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
iPrint('num m$i$j = ${Access(i, j)};');
}
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
String r = '';
for (int k = 0; k < rows; k++) {
if (k != 0) {
r = '$r +';
}
r = '$r (m$i$k * arg.${Access(k, j)})';
}
iPrint('${Access(i, j)} = $r;');
}
}
iPrint('return this;');
iPop();
iPrint('}');
}
generateSelfTransposeMultiplyMatrix() {
if (rows != cols) {
// Only generate this for square matrices
return;
}
iPrint('$matType selfTransposeMultiply($matType arg) {');
iPush();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
iPrint('num m$i$j = ${Access(j, i)};');
}
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
String r = '';
for (int k = 0; k < rows; k++) {
if (k != 0) {
r = '$r +';
}
r = '$r (m$i$k * arg.${Access(k, j)})';
}
iPrint('${Access(i, j)} = $r;');
}
}
iPrint('return this;');
iPop();
iPrint('}');
}
generateSelfMultiplyTransposeMatrix() {
if (rows != cols) {
// Only generate this for square matrices
return;
}
iPrint('$matType selfMultiplyTranpose($matType arg) {');
iPush();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
iPrint('num m$i$j = ${Access(i, j)};');
}
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
String r = '';
for (int k = 0; k < rows; k++) {
if (k != 0) {
r = '$r +';
}
r = '$r (m$i$k * arg.${Access(j, k)})';
}
iPrint('${Access(i, j)} = $r;');
}
}
iPrint('return this;');
iPop();
iPrint('}');
}
/*
String generateInlineDot(String rowPrefix, int row, String col, int len) {
String r = '';
for (int i = 0; i < len; i++) {
if (i != 0) {
r = '$r +';
}
r = '$r (${rowPrefix}.${Access(row, i)} * ${col}.${AccessV(i)})';
}
return r;
}
*/
void generateTransforms() {
if (rows != cols) {
return;
}
if (rows == 2) {
iPrint('vec2 transformDirect(vec2 arg) {');
iPush();
iPrint('num x_ = ${generateInlineDot('this', 0, 'arg', 2)};');
iPrint('num y_ = ${generateInlineDot('this', 1, 'arg', 2)};');
iPrint('arg.x = x_;');
iPrint('arg.y = y_;');
iPrint('return arg;');
iPop();
iPrint('}');
iPrint('vec2 transform(vec2 arg) {');
iPush();
iPrint('vec2 d = arg.copy();');
iPrint('return transformDirect(d);');
iPop();
iPrint('}');
}
if (rows == 3) {
iPrint('vec3 transformDirect(vec3 arg) {');
iPush();
iPrint('num x_ = ${generateInlineDot('this', 0, 'arg', 3)};');
iPrint('num y_ = ${generateInlineDot('this', 1, 'arg', 3)};');
iPrint('num z_ = ${generateInlineDot('this', 2, 'arg', 3)};');
iPrint('arg.x = x_;');
iPrint('arg.y = y_;');
iPrint('arg.z = z_;');
iPrint('return arg;');
iPop();
iPrint('}');
iPrint('vec3 transform(vec3 arg) {');
iPush();
iPrint('vec3 d = arg.copy();');
iPrint('return transformDirect(d);');
iPop();
iPrint('}');
}
if (rows == 4) {
iPrint('vec3 transformDirect3(vec3 arg) {');
iPush();
iPrint('num x_ = ${generateInlineDot('this', 0, 'arg', 3)};');
iPrint('num y_ = ${generateInlineDot('this', 1, 'arg', 3)};');
iPrint('num z_ = ${generateInlineDot('this', 2, 'arg', 3)};');
iPrint('arg.x = x_;');
iPrint('arg.y = y_;');
iPrint('arg.z = z_;');
iPrint('return arg;');
iPop();
iPrint('}');
iPrint('vec3 transform3(vec3 arg) {');
iPush();
iPrint('vec3 d = arg.copy();');
iPrint('return transformDirect3(d);');
iPop();
iPrint('}');
iPrint('vec4 transformDirect(vec4 arg) {');
iPush();
iPrint('num x_ = ${generateInlineDot('this', 0, 'arg', 3)};');
iPrint('num y_ = ${generateInlineDot('this', 1, 'arg', 3)};');
iPrint('num z_ = ${generateInlineDot('this', 2, 'arg', 3)};');
iPrint('num w_ = ${generateInlineDot('this', 3, 'arg', 3)};');
iPrint('arg.x = x_;');
iPrint('arg.y = y_;');
iPrint('arg.z = z_;');
iPrint('arg.w = w_;');
iPrint('return arg;');
iPop();
iPrint('}');
iPrint('vec4 transform(vec4 arg) {');
iPush();
iPrint('vec4 d = arg.copy();');
iPrint('return transformDirect(d);');
iPop();
iPrint('}');
}
}
void generateBuffer() {
iPrint('\/\/\/ Copies [this] into [array] starting at [offset].');
iPrint('void copyIntoArray(Float32Array array, [int offset=0]) {');
iPush();
iPrint('int i = offset;');
for (int j = 0; j < cols; j++) {
for (int i = 0; i < rows; i++) {
iPrint('array[i] = ${Access(i,j)};');
iPrint('i++;');
}
}
iPop();
iPrint('}');
iPrint('\/\/\/ Returns a copy of [this] as a [Float32Array].');
iPrint('Float32Array copyAsArray() {');
iPush();
iPrint('Float32Array array = new Float32Array(${rows * cols});');
iPrint('int i = 0;');
for (int j = 0; j < cols; j++) {
for (int i = 0; i < rows; i++) {
iPrint('array[i] = ${Access(i,j)};');
iPrint('i++;');
}
}
iPrint('return array;');
iPop();
iPrint('}');
iPrint('\/\/\/ Copies elements from [array] into [this] starting at [offset].');
iPrint('void copyFromArray(Float32Array array, [int offset=0]) {');
iPush();
iPrint('int i = offset;');
for (int j = 0; j < cols; j++) {
for (int i = 0; i < rows; i++) {
iPrint('${Access(i,j)} = array[i];');
iPrint('i++;');
}
}
iPop();
iPrint('}');
}
void generate() {
writeLicense();
generatePrologue();
generateConstructors();
generateToString();
generateRowColProperties();
generateIndexOperator();
generateAssignIndexOperator();
generateRowGetterSetters();
generateRowHelpers();
generateColumnHelpers();
generateMult();
generateOp('+');
generateOp('-');
generateNegate();
generateTranspose();
generateAbsolute();
generateDeterminant();
generateTrace();
generateInfinityNorm();
generateError();
generateTranslate();
generateRotation();
generateInvert();
generateSetRotation();
generateAdjugate();
generateCopy();
generateSelfOp('Add', '+');
generateSelfOp('Sub', '-');
generateSelfScalarOp('Scale', '*');
generateSelfNegate();
generateSelfMultiplyMatrix();
generateSelfTransposeMultiplyMatrix();
generateSelfMultiplyTransposeMatrix();
generateTransforms();
generateBuffer();
generateEpilogue();
}
}
void main() {
String basePath = 'lib/VectorMath/gen';
var f = null;
var o;
f = new File('${basePath}/matrix2x2_gen.dart');
o = f.open(FileMode.WRITE);
o.then((opened) {
print('opened');
MatrixGen mg = new MatrixGen();
mg.rows = 2;
mg.cols = 2;
mg.out = opened;
mg.generate();
opened.closeSync();
});
f = new File('${basePath}/matrix2x3_gen.dart');
o = f.open(FileMode.WRITE);
o.then((opened) {
print('opened');
MatrixGen mg = new MatrixGen();
mg.cols = 2;
mg.rows = 3;
mg.out = opened;
mg.generate();
opened.closeSync();
});
f = new File('${basePath}/matrix2x4_gen.dart');
o = f.open(FileMode.WRITE);
o.then((opened) {
print('opened');
MatrixGen mg = new MatrixGen();
mg.cols = 2;
mg.rows = 4;
mg.out = opened;
mg.generate();
opened.closeSync();
});
f = new File('${basePath}/matrix3x2_gen.dart');
o = f.open(FileMode.WRITE);
o.then((opened) {
print('opened');
MatrixGen mg = new MatrixGen();
mg.rows = 2;
mg.cols = 3;
mg.out = opened;
mg.generate();
opened.closeSync();
});
f = new File('${basePath}/matrix3x3_gen.dart');
o = f.open(FileMode.WRITE);
o.then((opened) {
print('opened');
MatrixGen mg = new MatrixGen();
mg.rows = 3;
mg.cols = 3;
mg.out = opened;
mg.generate();
opened.closeSync();
});
f = new File('${basePath}/matrix3x4_gen.dart');
o = f.open(FileMode.WRITE);
o.then((opened) {
print('opened');
MatrixGen mg = new MatrixGen();
mg.rows = 4;
mg.cols = 3;
mg.out = opened;
mg.generate();
opened.closeSync();
});
f = new File('${basePath}/matrix4x2_gen.dart');
o = f.open(FileMode.WRITE);
o.then((opened) {
print('opened');
MatrixGen mg = new MatrixGen();
mg.rows = 2;
mg.cols = 4;
mg.out = opened;
mg.generate();
opened.closeSync();
});
f = new File('${basePath}/matrix4x3_gen.dart');
o = f.open(FileMode.WRITE);
o.then((opened) {
print('opened');
MatrixGen mg = new MatrixGen();
mg.cols = 4;
mg.rows = 3;
mg.out = opened;
mg.generate();
opened.closeSync();
});
f = new File('${basePath}/matrix4x4_gen.dart');
o = f.open(FileMode.WRITE);
o.then((opened) {
print('opened');
MatrixGen mg = new MatrixGen();
mg.rows = 4;
mg.cols = 4;
mg.out = opened;
mg.generate();
opened.closeSync();
});
}