Add SkMatrix44::setColMajord, etc.

We have accessors for efficiently getting the matirx data, and it would be nice
if we had similar methods for setting the matrix entries.

Review URL: https://codereview.appspot.com/6851063

git-svn-id: http://skia.googlecode.com/svn/trunk@6494 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
vollick@chromium.org 2012-11-19 21:02:06 +00:00
parent 8a1cdaece7
commit f11cf9ff88
3 changed files with 124 additions and 40 deletions

View File

@ -126,11 +126,26 @@ public:
this->set(row, col, SkDoubleToMScalar(value));
}
/** These methods allow one to efficiently read matrix entries into an
* array. The given array must have room for exactly 16 entries. Whenever
* possible, they will try to use memcpy rather than an entry-by-entry
* copy.
*/
void asColMajorf(float[]) const;
void asColMajord(double[]) const;
void asRowMajorf(float[]) const;
void asRowMajord(double[]) const;
/** These methods allow one to efficiently set all matrix entries from an
* array. The given array must have room for exactly 16 entries. Whenever
* possible, they will try to use memcpy rather than an entry-by-entry
* copy.
*/
void setColMajorf(const float[]);
void setColMajord(const double[]);
void setRowMajorf(const float[]);
void setRowMajord(const double[]);
bool isIdentity() const;
void setIdentity();
void reset() { this->setIdentity();}

View File

@ -82,6 +82,52 @@ void SkMatrix44::asRowMajord(double dst[]) const {
}
}
void SkMatrix44::setColMajorf(const float src[]) {
SkMScalar* dst = &fMat[0][0];
#ifdef SK_MSCALAR_IS_DOUBLE
for (int i = 0; i < 16; ++i) {
dst[i] = SkMScalarToFloat(src[i]);
}
#elif defined SK_MSCALAR_IS_FLOAT
memcpy(dst, src, 16 * sizeof(float));
#endif
}
void SkMatrix44::setColMajord(const double src[]) {
SkMScalar* dst = &fMat[0][0];
#ifdef SK_MSCALAR_IS_DOUBLE
memcpy(dst, src, 16 * sizeof(double));
#elif defined SK_MSCALAR_IS_FLOAT
for (int i = 0; i < 16; ++i) {
dst[i] = SkMScalarToDouble(src[i]);
}
#endif
}
void SkMatrix44::setRowMajorf(const float src[]) {
SkMScalar* dst = &fMat[0][0];
for (int i = 0; i < 4; ++i) {
dst[0] = SkMScalarToFloat(src[0]);
dst[4] = SkMScalarToFloat(src[1]);
dst[8] = SkMScalarToFloat(src[2]);
dst[12] = SkMScalarToFloat(src[3]);
src += 4;
dst += 1;
}
}
void SkMatrix44::setRowMajord(const double src[]) {
SkMScalar* dst = &fMat[0][0];
for (int i = 0; i < 4; ++i) {
dst[0] = SkMScalarToDouble(src[0]);
dst[4] = SkMScalarToDouble(src[1]);
dst[8] = SkMScalarToDouble(src[2]);
dst[12] = SkMScalarToDouble(src[3]);
src += 4;
dst += 1;
}
}
///////////////////////////////////////////////////////////////////////////////
bool SkMatrix44::isIdentity() const {

View File

@ -123,57 +123,80 @@ static void test_concat(skiatest::Reporter* reporter) {
}
static void test_determinant(skiatest::Reporter* reporter) {
SkMatrix44 a;
REPORTER_ASSERT(reporter, nearly_equal_double(1, a.determinant()));
a.set(1, 1, SkFloatToMScalar(2));
REPORTER_ASSERT(reporter, nearly_equal_double(2, a.determinant()));
SkMatrix44 b;
REPORTER_ASSERT(reporter, a.invert(&b));
REPORTER_ASSERT(reporter, nearly_equal_double(0.5, b.determinant()));
SkMatrix44 c = b = a;
c.set(0, 1, SkFloatToMScalar(4));
b.set(1, 0, SkFloatToMScalar(4));
REPORTER_ASSERT(reporter,
nearly_equal_double(a.determinant(),
b.determinant()));
SkMatrix44 d = a;
d.set(0, 0, SkFloatToMScalar(8));
REPORTER_ASSERT(reporter, nearly_equal_double(16, d.determinant()));
SkMatrix44 a;
REPORTER_ASSERT(reporter, nearly_equal_double(1, a.determinant()));
a.set(1, 1, SkFloatToMScalar(2));
REPORTER_ASSERT(reporter, nearly_equal_double(2, a.determinant()));
SkMatrix44 b;
REPORTER_ASSERT(reporter, a.invert(&b));
REPORTER_ASSERT(reporter, nearly_equal_double(0.5, b.determinant()));
SkMatrix44 c = b = a;
c.set(0, 1, SkFloatToMScalar(4));
b.set(1, 0, SkFloatToMScalar(4));
REPORTER_ASSERT(reporter,
nearly_equal_double(a.determinant(),
b.determinant()));
SkMatrix44 d = a;
d.set(0, 0, SkFloatToMScalar(8));
REPORTER_ASSERT(reporter, nearly_equal_double(16, d.determinant()));
SkMatrix44 e = a;
e.postConcat(d);
REPORTER_ASSERT(reporter, nearly_equal_double(32, e.determinant()));
e.set(0, 0, SkFloatToMScalar(0));
REPORTER_ASSERT(reporter, nearly_equal_double(0, e.determinant()));
SkMatrix44 e = a;
e.postConcat(d);
REPORTER_ASSERT(reporter, nearly_equal_double(32, e.determinant()));
e.set(0, 0, SkFloatToMScalar(0));
REPORTER_ASSERT(reporter, nearly_equal_double(0, e.determinant()));
}
static void test_transpose(skiatest::Reporter* reporter) {
SkMatrix44 a;
SkMatrix44 b;
SkMatrix44 a;
SkMatrix44 b;
int i = 0;
for (int row = 0; row < 4; ++row) {
for (int col = 0; col < 4; ++col) {
a.setDouble(row, col, i);
b.setDouble(col, row, i++);
int i = 0;
for (int row = 0; row < 4; ++row) {
for (int col = 0; col < 4; ++col) {
a.setDouble(row, col, i);
b.setDouble(col, row, i++);
}
}
}
a.transpose();
REPORTER_ASSERT(reporter, nearly_equal(a, b));
a.transpose();
REPORTER_ASSERT(reporter, nearly_equal(a, b));
}
static void test_get_set_double(skiatest::Reporter* reporter) {
SkMatrix44 a;
for (int row = 0; row < 4; ++row) {
for (int col = 0; col < 4; ++col) {
a.setDouble(row, col, 3.141592653589793);
REPORTER_ASSERT(reporter, nearly_equal_double(3.141592653589793,
a.getDouble(row, col)));
a.setDouble(row, col, 0);
REPORTER_ASSERT(reporter, nearly_equal_double(0, a.getDouble(row, col)));
SkMatrix44 a;
for (int row = 0; row < 4; ++row) {
for (int col = 0; col < 4; ++col) {
a.setDouble(row, col, 3.141592653589793);
REPORTER_ASSERT(reporter,
nearly_equal_double(3.141592653589793,
a.getDouble(row, col)));
a.setDouble(row, col, 0);
REPORTER_ASSERT(reporter,
nearly_equal_double(0, a.getDouble(row, col)));
}
}
}
}
static void test_set_row_col_major(skiatest::Reporter* reporter) {
SkMatrix44 a, b, c, d;
for (int row = 0; row < 4; ++row)
for (int col = 0; col < 4; ++col)
a.setDouble(row, col, row * 4 + col);
double bufferd[16];
float bufferf[16];
a.asColMajord(bufferd);
b.setColMajord(bufferd);
REPORTER_ASSERT(reporter, nearly_equal(a, b));
b.setRowMajord(bufferd);
b.transpose();
REPORTER_ASSERT(reporter, nearly_equal(a, b));
a.asColMajorf(bufferf);
b.setColMajorf(bufferf);
REPORTER_ASSERT(reporter, nearly_equal(a, b));
b.setRowMajorf(bufferf);
b.transpose();
REPORTER_ASSERT(reporter, nearly_equal(a, b));
}
static void TestMatrix44(skiatest::Reporter* reporter) {