.doc/ext/rays/matrix.cpp in rays-0.1.12 vs .doc/ext/rays/matrix.cpp in rays-0.1.13
- old
+ new
@@ -1,17 +1,14 @@
#include "rays/ruby/matrix.h"
-#include <rucy.h>
+#include "rays/ruby/point.h"
#include "defs.h"
-using namespace Rucy;
+RUCY_DEFINE_VALUE_OR_ARRAY_FROM_TO(Rays::Matrix)
-
-RUCY_DEFINE_VALUE_FROM_TO(Rays::Matrix)
-
#define THIS to<Rays::Matrix*>(self)
#define CHECK RUCY_CHECK_OBJ(Rays::Matrix, self)
@@ -25,27 +22,13 @@
VALUE initialize(VALUE self)
{
CHECK;
check_arg_count(__FILE__, __LINE__, "Matrix#initialize", argc, 0, 1, 16);
- if (argc == 0) return self;
+ if (argc > 0)
+ *THIS = to<Rays::Matrix>(argc, argv);
- switch (argc)
- {
- case 1:
- *THIS = Rays::Matrix(to<float>(argv[0]));
- break;
-
- case 16:
- *THIS = Rays::Matrix(
- to<float>(argv[0]), to<float>(argv[1]), to<float>(argv[2]), to<float>(argv[3]),
- to<float>(argv[4]), to<float>(argv[5]), to<float>(argv[6]), to<float>(argv[7]),
- to<float>(argv[8]), to<float>(argv[9]), to<float>(argv[10]), to<float>(argv[11]),
- to<float>(argv[12]), to<float>(argv[13]), to<float>(argv[14]), to<float>(argv[15]));
- break;
- }
-
return self;
}
static
VALUE initialize_copy(VALUE self, VALUE obj)
@@ -54,27 +37,27 @@
*THIS = to<Rays::Matrix&>(obj);
return self;
}
static
-VALUE set(VALUE self)
+VALUE reset(VALUE self)
{
CHECK;
- check_arg_count(__FILE__, __LINE__, "Matrix#initialize", argc, 0, 1, 16);
+ check_arg_count(__FILE__, __LINE__, "Matrix#reset", argc, 0, 1, 16);
switch (argc)
{
case 0:
- *THIS = Rays::Matrix();
+ THIS->reset();
break;
case 1:
- *THIS = Rays::Matrix(to<float>(argv[0]));
+ THIS->reset(to<float>(argv[0]));
break;
case 16:
- *THIS = Rays::Matrix(
+ THIS->reset(
to<float>(argv[0]), to<float>(argv[1]), to<float>(argv[2]), to<float>(argv[3]),
to<float>(argv[4]), to<float>(argv[5]), to<float>(argv[6]), to<float>(argv[7]),
to<float>(argv[8]), to<float>(argv[9]), to<float>(argv[10]), to<float>(argv[11]),
to<float>(argv[12]), to<float>(argv[13]), to<float>(argv[14]), to<float>(argv[15]));
break;
@@ -82,17 +65,133 @@
return self;
}
static
-VALUE at(VALUE self, VALUE row, VALUE column)
+VALUE translate(VALUE self)
{
CHECK;
+ check_arg_count(__FILE__, __LINE__, "Matrix#translate", argc, 1, 2, 3);
+
+ THIS->translate(to<Rays::Point>(argc, argv));
+ return self;
+}
+
+static
+VALUE scale(VALUE self)
+{
+ CHECK;
+ check_arg_count(__FILE__, __LINE__, "Matrix#scale", argc, 1, 2, 3);
+
+ THIS->scale(to<Rays::Point>(argc, argv));
+ return self;
+}
+
+static
+VALUE rotate(VALUE self)
+{
+ CHECK;
+ check_arg_count(__FILE__, __LINE__, "Matrix#rotate", argc, 1, 2, 4);
+
+ float degree = to<float>(argv[0]);
+
+ if (argc == 1)
+ THIS->rotate(degree);
+ else
+ THIS->rotate(degree, to<Rays::Point>(argc - 1, argv + 1));
+
+ return self;
+}
+
+static
+VALUE to_a(VALUE self)
+{
+ CHECK;
+ return array(
+ THIS->x0, THIS->y0, THIS->z0, THIS->w0,
+ THIS->x1, THIS->y1, THIS->z1, THIS->w1,
+ THIS->x2, THIS->y2, THIS->z2, THIS->w2,
+ THIS->x3, THIS->y3, THIS->z3, THIS->w3);
+}
+
+static
+VALUE mult(VALUE self, VALUE val)
+{
+ CHECK;
+
+ if (val.is_kind_of(Rays::matrix_class()))
+ return value(*THIS * to<Rays::Matrix&>(val));
+
+ if (val.is_kind_of(Rays::point_class()))
+ return value(*THIS * to<Rays::Point&>(val));
+
+ if (val.is_array())
+ {
+ if (val.size() == 16)
+ return value(*THIS * to<Rays::Matrix>(val));
+ else
+ return value(*THIS * to<Rays::Point>(val));
+ }
+
+ argument_error(__FILE__, __LINE__);
+}
+
+static
+VALUE set_at(VALUE self, VALUE row, VALUE column, VALUE val)
+{
+ CHECK;
+ return value(THIS->at(row.as_i(), column.as_i()) = to<float>(val));
+}
+
+static
+VALUE get_at(VALUE self, VALUE row, VALUE column)
+{
+ CHECK;
return value(THIS->at(row.as_i(), column.as_i()));
}
+static
+VALUE compare(VALUE self, VALUE other)
+{
+ CHECK;
+ const Rays::Matrix& a = *THIS;
+ const Rays::Matrix& b = to<const Rays::Matrix&>(other);
+ for (int i = 0; i < Rays::Matrix::NELEM; ++i)
+ {
+ if (a[i] == b[i]) continue;
+ return value(a[i] < b[i] ? -1 : +1);
+ }
+ return value(0);
+}
+
+static
+VALUE inspect(VALUE self)
+{
+ CHECK;
+ return value(Xot::stringf("#<Rays::Matrix %s>", THIS->inspect().c_str()));
+}
+
+static
+VALUE s_translate(VALUE self)
+{
+ return translate(argc, argv, value(Rays::Matrix()));
+}
+
+static
+VALUE s_scale(VALUE self)
+{
+ return scale(argc, argv, value(Rays::Matrix()));
+}
+
+static
+VALUE s_rotate(VALUE self)
+{
+ return rotate(argc, argv, value(Rays::Matrix()));
+}
+
+
static Class cMatrix;
void
Init_matrix ()
{
@@ -100,12 +199,70 @@
cMatrix = rb_define_class_under(mRays, "Matrix", rb_cObject);
rb_define_alloc_func(cMatrix, alloc);
rb_define_private_method(cMatrix, "initialize", RUBY_METHOD_FUNC(initialize), -1);
rb_define_private_method(cMatrix, "initialize_copy", RUBY_METHOD_FUNC(initialize_copy), 1);
- rb_define_method(cMatrix, "set", RUBY_METHOD_FUNC(set), -1);
- rb_define_method(cMatrix, "at", RUBY_METHOD_FUNC(at), 2);
+ rb_define_method(cMatrix, "reset", RUBY_METHOD_FUNC(reset), -1);
+ rb_define_method(cMatrix, "translate", RUBY_METHOD_FUNC(translate), -1);
+ rb_define_method(cMatrix, "scale", RUBY_METHOD_FUNC(scale), -1);
+ rb_define_method(cMatrix, "rotate", RUBY_METHOD_FUNC(rotate), -1);
+ rb_define_method(cMatrix, "to_a", RUBY_METHOD_FUNC(to_a), 0);
+ cMatrix.define_method("*", mult);
+ cMatrix.define_method("[]=", set_at);
+ cMatrix.define_method("[]", get_at);
+ cMatrix.define_method("<=>", compare);
+ rb_define_method(cMatrix, "inspect", RUBY_METHOD_FUNC(inspect), 0);
+
+ rb_define_singleton_method(cMatrix, "translate", RUBY_METHOD_FUNC(s_translate), -1);
+ rb_define_singleton_method(cMatrix, "scale", RUBY_METHOD_FUNC(s_scale), -1);
+ rb_define_singleton_method(cMatrix, "rotate", RUBY_METHOD_FUNC(s_rotate), -1);
}
+
+
+namespace Rucy
+{
+
+
+ template <> Rays::Matrix
+ value_to<Rays::Matrix> (int argc, const Value* argv, bool convert)
+ {
+ if (argc == 1 && argv->is_array())
+ {
+ argc = argv->size();
+ argv = argv->as_array();
+ }
+
+ assert(argc == 0 || (argc > 0 && argv));
+
+ if (convert)
+ {
+ if (argc == 0)
+ return Rays::Matrix();
+ else if (argv->is_num())
+ {
+ switch (argc)
+ {
+ #define V(i) argv[i].as_f(true)
+ case 1: return Rays::Matrix(V(0));
+ case 16: return Rays::Matrix(
+ V(0), V(1), V(2), V(3),
+ V(4), V(5), V(6), V(7),
+ V(8), V(9), V(10), V(11),
+ V(12), V(13), V(14), V(15));
+ #undef V
+ default: argument_error(__FILE__, __LINE__);
+ }
+ }
+ }
+
+ if (argc != 1)
+ argument_error(__FILE__, __LINE__);
+
+ return value_to<Rays::Matrix&>(*argv, convert);
+ }
+
+
+}// Rucy
namespace Rays
{