Class: Snow::Mat3
- Inherits:
-
Data
- Object
- Data
- Snow::Mat3
- Includes:
- ArraySupport, BaseMarshalSupport, FiddlePointerSupport, InspectSupport
- Defined in:
- lib/snow-math/mat3.rb,
lib/snow-math/ptr.rb,
lib/snow-math/to_a.rb,
lib/snow-math/inspect.rb,
lib/snow-math/marshal.rb,
ext/snow-math/snow-math.c
Overview
A 3x3 matrix class. Often useful for representation rotations.
Constant Summary collapse
- IDENTITY =
self.new.freeze
- ONE =
self.new(Array.new(9, 1)).freeze
- ZERO =
self.new(Array.new(9, 0)).freeze
Class Method Summary collapse
-
.angle_axis(*args) ⇒ Object
Returns a Mat3 describing a rotation around the given axis.
-
.new(*args) ⇒ Object
(also: [])
Allocates a new Mat3.
Instance Method Summary collapse
-
#==(sm_other) ⇒ Object
Tests this Mat3 and another Mat3 for equivalency.
-
#address ⇒ Object
Returns the memory address of the object.
-
#adjoint(*args) ⇒ Object
Returns an ajoint matrix.
-
#adjoint! ⇒ Object
Calls #adjoint(self).
-
#cofactor(*args) ⇒ Object
Returns a cofactor matrix.
-
#cofactor! ⇒ Object
Calls #cofactor(self).
-
#copy(*args) ⇒ Object
(also: #dup, #clone)
Returns a copy of self.
-
#determinant ⇒ Object
Returns the matrix determinant.
-
#fetch ⇒ Object
(also: #[])
Gets the component of the Mat3 at the given index.
-
#get_column3(*args) ⇒ Object
Returns a Vec3 whose components are that of the column at the given index.
-
#get_row3(*args) ⇒ Object
Returns a Vec3 whose components are that of the row at the given index.
-
#initialize(*args) ⇒ Object
constructor
Sets the Mat3’s components.
-
#inverse(*args) ⇒ Object
Returns the matrix inverse on success, nil on failure.
-
#inverse! ⇒ Object
Calls #inverse(self).
-
#inverse_rotate_vec3(*args) ⇒ Object
Convenience function to rotate a Vec3 by an inverse matrix and return the result.
-
#length ⇒ Object
Returns the length of the Mat3 in components.
-
#load_identity ⇒ Object
Sets self to the identity matrix.
-
#multiply(rhs, out = nil) ⇒ Object
(also: #*)
Multiplies self and RHS and returns the result.
-
#multiply!(rhs) ⇒ Object
Calls #multiply(rhs, self).
-
#multiply_mat3(*args) ⇒ Object
Multiplies this Mat3 and another and returns the result.
-
#multiply_mat3!(rhs) ⇒ Object
Calls #multiply_mat3(rhs, self).
-
#orthogonal(*args) ⇒ Object
Returns an orthogonal matrix.
-
#rotate_vec3(*args) ⇒ Object
Rotates a Vec3 using self and returns the result.
-
#scale(*args) ⇒ Object
(also: #**)
Scales Mat3’s columns by X, Y, and Z and returns the result.
-
#scale!(x, y, z) ⇒ Object
Calls scale(x, y, z, self).
-
#set(*args) ⇒ Object
Sets the Mat3’s components.
-
#set_column3(sm_index, sm_value) ⇒ Object
Sets the matrix’s column at the given index to the given vector.
-
#set_row3(sm_index, sm_value) ⇒ Object
Sets the matrix’s row at the given index to the given vector.
-
#size ⇒ Object
Returns the length in bytes of the Mat3.
-
#store ⇒ Object
(also: #[]=)
Sets the Mat3’s component at the index to the value.
-
#to_mat4(*args) ⇒ Object
Returns a Mat4 converted from the Mat3.
- #to_quat ⇒ Object
-
#to_s ⇒ Object
Returns a string representation of self.
-
#transpose(*args) ⇒ Object
(also: #~)
Transposes this matrix and returns the result.
-
#transpose! ⇒ Object
Calls #transpose(self).
Methods included from BaseMarshalSupport
Methods included from InspectSupport
Methods included from ArraySupport
Methods included from FiddlePointerSupport
Constructor Details
#initialize(*args) ⇒ Object
Sets the Mat3’s components.
call-seq:
set(m1, m2, ..., m8, m9) -> new mat3 with components
set([m1, m2, ..., m8, m9]) -> new mat3 with components
set(mat3) -> copy of mat3
set(mat4) -> new mat3 from mat4's inner 9x9 matrix
set(quat) -> quat as mat3
set(Vec3, Vec3, Vec3) -> new mat3 with given row vectors
6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 |
# File 'ext/snow-math/snow-math.c', line 6459
static VALUE sm_mat3_init(int argc, VALUE *argv, VALUE sm_self)
{
mat3_t *self = sm_unwrap_mat3(sm_self, NULL);
size_t arr_index = 0;
rb_check_frozen(sm_self);
switch (argc) {
case 0: {
/* Identity (handled in _new) */
break;
}
/* Copy Mat3 or provided [Numeric..] */
case 1: {
/* Copy Mat3 */
if (SM_IS_A(argv[0], mat3)) {
sm_unwrap_mat3(argv[0], *self);
break;
}
/* Copy Mat4 */
if (SM_IS_A(argv[0], mat4)) {
mat4_to_mat3(*sm_unwrap_mat4(argv[0], NULL), *self);
break;
}
/* Build from Quaternion */
if (SM_IS_A(argv[0], quat)) {
mat3_from_quat(*sm_unwrap_quat(argv[0], NULL), *self);
break;
}
/* Optional offset into array provided */
if (0) {
case 2:
arr_index = NUM2SIZET(argv[1]);
}
/* Array of values */
if (SM_RB_IS_A(argv[0], rb_cArray)) {
VALUE arrdata = argv[0];
const size_t arr_end = arr_index + 9;
s_float_t *mat_elem = *self;
for (; arr_index < arr_end; ++arr_index, ++mat_elem) {
*mat_elem = rb_num2dbl(rb_ary_entry(arrdata, (long)arr_index));
}
break;
}
rb_raise(rb_eArgError, "Expected either an array of Numerics or a Mat3");
break;
}
/* Mat3(Vec3, Vec3, Vec3) */
case 3: {
size_t arg_index;
s_float_t *mat_elem = *self;
for (arg_index = 0; arg_index < 3; ++arg_index, mat_elem += 3) {
if (!SM_IS_A(argv[arg_index], vec3) && !SM_IS_A(argv[arg_index], vec4) && !SM_IS_A(argv[arg_index], quat)) {
rb_raise(
rb_eArgError,
"Argument %d must be a Vec3, Vec4, or Quat when supplying three arguments to initialize/set",
(int)(arg_index + 1));
}
sm_unwrap_vec3(argv[arg_index], mat_elem);
}
break;
}
/* Mat3(Numeric m00 .. m16) */
case 9: {
s_float_t *mat_elem = *self;
VALUE *argv_p = argv;
for (; argc; --argc, ++argv_p, ++mat_elem) {
*mat_elem = (s_float_t)rb_num2dbl(*argv_p);
}
break;
}
default: {
rb_raise(rb_eArgError, "Invalid arguments to initialize/set");
break;
}
} /* switch (argc) */
return sm_self;
}
|
Class Method Details
.angle_axis(*args) ⇒ Object
Returns a Mat3 describing a rotation around the given axis.
call-seq:
angle_axis(angle_degrees, axis_vec3, output = nil) -> output or new mat3
6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 |
# File 'ext/snow-math/snow-math.c', line 6585
static VALUE sm_mat3_angle_axis(int argc, VALUE *argv, VALUE self)
{
VALUE sm_angle;
VALUE sm_axis;
VALUE sm_out;
s_float_t angle;
const vec3_t *axis;
rb_scan_args(argc, argv, "21", &sm_angle, &sm_axis, &sm_out);
if (!SM_IS_A(sm_axis, vec3) && !SM_IS_A(sm_axis, vec4) && !SM_IS_A(sm_axis, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_THREE_OR_FOUR_FORMAT_LIT,
rb_obj_classname(sm_axis));
return Qnil;
}
angle = (s_float_t)rb_num2dbl(sm_angle);
axis = sm_unwrap_vec3(sm_axis, NULL);
if (SM_IS_A(sm_out, mat3)) {
rb_check_frozen(sm_out);
mat3_t *out = sm_unwrap_mat3(sm_out, NULL);
mat3_rotation(angle, (*axis)[0], (*axis)[1], (*axis)[2], *out);
} else {
mat3_t out;
mat3_rotation(angle, (*axis)[0], (*axis)[1], (*axis)[2], out);
sm_out = sm_wrap_mat3(out, self);
rb_obj_call_init(sm_out, 0, 0);
}
return sm_out;
}
|
.new(*args) ⇒ Object Also known as: []
Allocates a new Mat3.
call-seq:
new() -> identity mat3
new(m1, m2, ..., m8, m9) -> new mat3 with components
new([m1, m2, ..., m8, m9]) -> new mat3 with components
new(mat3) -> copy of mat3
new(mat4) -> new mat3 from mat4's inner 9x9 matrix
new(quat) -> quat as mat3
new(Vec3, Vec3, Vec3) -> new mat3 with given row vectors
6439 6440 6441 6442 6443 6444 |
# File 'ext/snow-math/snow-math.c', line 6439
static VALUE sm_mat3_new(int argc, VALUE *argv, VALUE self)
{
VALUE sm_mat = sm_wrap_mat3(g_mat3_identity, self);
rb_obj_call_init(sm_mat, argc, argv);
return sm_mat;
}
|
Instance Method Details
#==(sm_other) ⇒ Object
Tests this Mat3 and another Mat3 for equivalency.
call-seq:
mat3 == other_mat3 -> bool
6872 6873 6874 6875 6876 6877 6878 6879 |
# File 'ext/snow-math/snow-math.c', line 6872
static VALUE sm_mat3_equals(VALUE sm_self, VALUE sm_other)
{
if (!RTEST(sm_other) || !SM_IS_A(sm_other, mat3)) {
return Qfalse;
}
return mat3_equals(*sm_unwrap_mat3(sm_self, NULL), *sm_unwrap_mat3(sm_other, NULL)) ? Qtrue : Qfalse;
}
|
#address ⇒ Object
Returns the memory address of the object.
call-seq: address -> fixnum
6894 6895 6896 6897 6898 6899 |
# File 'ext/snow-math/snow-math.c', line 6894
static VALUE sm_get_address(VALUE sm_self)
{
void *data_ptr = NULL;
Data_Get_Struct(sm_self, void, data_ptr);
return ULL2NUM((unsigned long long)data_ptr);
}
|
#adjoint(*args) ⇒ Object
Returns an ajoint matrix.
call-seq:
adjoint(output = nil) -> output or new mat3
6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 |
# File 'ext/snow-math/snow-math.c', line 6123
static VALUE sm_mat3_adjoint(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_out;
mat3_t *self;
rb_scan_args(argc, argv, "01", &sm_out);
self = sm_unwrap_mat3(sm_self, NULL);
if (argc == 1) {
if (!RTEST(sm_out)) {
goto SM_LABEL(skip_output);
}{
mat3_t *output;
SM_RAISE_IF_NOT_TYPE(sm_out, mat3);
rb_check_frozen(sm_out);
output = sm_unwrap_mat3(sm_out, NULL);
mat3_adjoint (*self, *output);
}} else if (argc == 0) {
SM_LABEL(skip_output): {
mat3_t output;
mat3_adjoint (*self, output);
sm_out = sm_wrap_mat3(output, rb_obj_class(sm_self));
rb_obj_call_init(sm_out, 0, 0);
}} else {
rb_raise(rb_eArgError, "Invalid number of arguments to adjoint");
}
return sm_out;
}
|
#adjoint! ⇒ Object
Calls #adjoint(self)
call-seq: adjoint! -> self
70 71 72 |
# File 'lib/snow-math/mat3.rb', line 70 def adjoint! adjoint self end |
#cofactor(*args) ⇒ Object
Returns a cofactor matrix.
call-seq:
cofactor(output = nil) -> output or new mat3
6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 |
# File 'ext/snow-math/snow-math.c', line 6193
static VALUE sm_mat3_cofactor(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_out;
mat3_t *self;
rb_scan_args(argc, argv, "01", &sm_out);
self = sm_unwrap_mat3(sm_self, NULL);
if (argc == 1) {
if (!RTEST(sm_out)) {
goto SM_LABEL(skip_output);
}{
mat3_t *output;
SM_RAISE_IF_NOT_TYPE(sm_out, mat3);
rb_check_frozen(sm_out);
output = sm_unwrap_mat3(sm_out, NULL);
mat3_cofactor (*self, *output);
}} else if (argc == 0) {
SM_LABEL(skip_output): {
mat3_t output;
mat3_cofactor (*self, output);
sm_out = sm_wrap_mat3(output, rb_obj_class(sm_self));
rb_obj_call_init(sm_out, 0, 0);
}} else {
rb_raise(rb_eArgError, "Invalid number of arguments to cofactor");
}
return sm_out;
}
|
#cofactor! ⇒ Object
Calls #cofactor(self)
call-seq: cofactor! -> self
79 80 81 |
# File 'lib/snow-math/mat3.rb', line 79 def cofactor! cofactor self end |
#copy(*args) ⇒ Object Also known as: dup, clone
Returns a copy of self.
call-seq:
copy(output = nil) -> output or new mat3
6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 |
# File 'ext/snow-math/snow-math.c', line 6018
static VALUE sm_mat3_copy(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_out;
mat3_t *self;
rb_scan_args(argc, argv, "01", &sm_out);
self = sm_unwrap_mat3(sm_self, NULL);
if (argc == 1) {
if (!RTEST(sm_out)) {
goto SM_LABEL(skip_output);
}{
mat3_t *output;
SM_RAISE_IF_NOT_TYPE(sm_out, mat3);
rb_check_frozen(sm_out);
output = sm_unwrap_mat3(sm_out, NULL);
mat3_copy (*self, *output);
}} else if (argc == 0) {
SM_LABEL(skip_output): {
mat3_t output;
mat3_copy (*self, output);
sm_out = sm_wrap_mat3(output, rb_obj_class(sm_self));
rb_obj_call_init(sm_out, 0, 0);
}} else {
rb_raise(rb_eArgError, "Invalid number of arguments to copy");
}
return sm_out;
}
|
#determinant ⇒ Object
Returns the matrix determinant.
call-seq:
determinant -> float
6366 6367 6368 6369 |
# File 'ext/snow-math/snow-math.c', line 6366
static VALUE sm_mat3_determinant(VALUE sm_self)
{
return mat3_determinant(*sm_unwrap_mat3(sm_self, NULL));
}
|
#fetch ⇒ Object Also known as: []
Gets the component of the Mat3 at the given index.
call-seq: fetch(index) -> float
5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 |
# File 'ext/snow-math/snow-math.c', line 5951
static VALUE sm_mat3_fetch (VALUE sm_self, VALUE sm_index)
{
static const int max_index = sizeof(mat3_t) / sizeof(s_float_t);
const mat3_t *self = sm_unwrap_mat3(sm_self, NULL);
int index = NUM2INT(sm_index);
if (index < 0 || index >= max_index) {
rb_raise(rb_eRangeError,
"Index %d is out of bounds, must be from 0 through %d", index, max_index - 1);
}
return rb_float_new(self[0][NUM2INT(sm_index)]);
}
|
#get_column3(*args) ⇒ Object
Returns a Vec3 whose components are that of the column at the given index.
call-seq:
get_column3(index, output = nil) -> output or new vec3
6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 |
# File 'ext/snow-math/snow-math.c', line 6690
static VALUE sm_mat3_get_column3(int argc, VALUE *argv, VALUE sm_self)
{
mat3_t *self;
int index;
VALUE sm_out;
self = sm_unwrap_mat3(sm_self, NULL);
index = NUM2INT(argv[0]);
sm_out = Qnil;
if (index < 0 || index > 2) {
rb_raise(rb_eRangeError, "Index %d is out of range, must be (0 .. 2)", index);
return Qnil;
}
switch (argc) {
case 2: {
vec3_t *out;
sm_out = argv[1];
if (RTEST(sm_out)) {
if (!SM_IS_A(sm_out, vec3) && !SM_IS_A(sm_out, vec4) && !SM_IS_A(sm_out, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_THREE_OR_FOUR_FORMAT_LIT,
rb_obj_classname(sm_out));
return Qnil;
}
rb_check_frozen(sm_out);
} else {
goto SM_LABEL(no_output);
}
out = sm_unwrap_vec3(sm_out, NULL);
mat3_get_column3(*self, index, *out);
break;
}
case 1: SM_LABEL(no_output): {
vec3_t out;
mat3_get_column3(*self, index, out);
sm_out = sm_wrap_vec3(out, Qnil);
rb_obj_call_init(sm_out, 0, 0);
break;
}
default: {
rb_raise(rb_eArgError, "Invalid number of arguments to get_column3 - expected 1 or 2");
break;
}
}
return sm_out;
}
|
#get_row3(*args) ⇒ Object
Returns a Vec3 whose components are that of the row at the given index.
call-seq:
get_row3(index, output = nil) -> output or new vec3
6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 |
# File 'ext/snow-math/snow-math.c', line 6626
static VALUE sm_mat3_get_row3(int argc, VALUE *argv, VALUE sm_self)
{
mat3_t *self;
int index;
VALUE sm_out;
self = sm_unwrap_mat3(sm_self, NULL);
index = NUM2INT(argv[0]);
sm_out = Qnil;
if (index < 0 || index > 2) {
rb_raise(rb_eRangeError, "Index %d is out of range, must be (0 .. 2)", index);
return Qnil;
}
switch (argc) {
case 2: {
vec3_t *out;
sm_out = argv[1];
if (RTEST(sm_out)) {
if (!SM_IS_A(sm_out, vec3) && !SM_IS_A(sm_out, vec4) && !SM_IS_A(sm_out, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_THREE_OR_FOUR_FORMAT_LIT,
rb_obj_classname(sm_out));
return Qnil;
}
rb_check_frozen(sm_out);
} else {
goto SM_LABEL(no_output);
}
out = sm_unwrap_vec3(sm_out, NULL);
mat3_get_row3(*self, index, *out);
break;
}
case 1: SM_LABEL(no_output): {
vec3_t out;
mat3_get_row3(*self, index, out);
sm_out = sm_wrap_vec3(out, Qnil);
rb_obj_call_init(sm_out, 0, 0);
break;
}
default: {
rb_raise(rb_eArgError, "Invalid number of arguments to get_row3 - expected 1 or 2");
break;
}
}
return sm_out;
}
|
#inverse(*args) ⇒ Object
Returns the matrix inverse on success, nil on failure.
call-seq:
inverse(output = nil) -> output, new mat3, or nil
6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 |
# File 'ext/snow-math/snow-math.c', line 6379
static VALUE sm_mat3_inverse(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_out = Qnil;
mat3_t *self;
rb_scan_args(argc, argv, "01", &sm_out);
self = sm_unwrap_mat3(sm_self, NULL);
if (argc == 1) {
mat3_t *output;
if (!RTEST(sm_out)) {
goto SM_LABEL(skip_output);
}
if (!SM_IS_A(sm_out, mat3)) {
rb_raise(rb_eTypeError,
"Invalid argument to output of inverse_general: expected %s, got %s",
rb_class2name(s_sm_mat3_klass),
rb_obj_classname(sm_out));
return Qnil;
}
rb_check_frozen(sm_out);
output = sm_unwrap_mat3(sm_out, NULL);
if (!mat3_inverse(*self, *output)) {
return Qnil;
}
} else if (argc == 0) {
SM_LABEL(skip_output): {
mat3_t output;
if (!mat3_inverse(*self, output)) {
return Qnil;
}
sm_out = sm_wrap_mat3(output, rb_obj_class(sm_self));
rb_obj_call_init(sm_out, 0, 0);
}
} else {
rb_raise(rb_eArgError, "Invalid number of arguments to inverse");
}
return sm_out;
}
|
#inverse! ⇒ Object
Calls #inverse(self)
call-seq: inverse! -> self
61 62 63 |
# File 'lib/snow-math/mat3.rb', line 61 def inverse! inverse self end |
#inverse_rotate_vec3(*args) ⇒ Object
Convenience function to rotate a Vec3 by an inverse matrix and return the result.
call-seq:
inv_rotate_vec3(vec3, output = nil) -> output or new vec3
6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 |
# File 'ext/snow-math/snow-math.c', line 6317
static VALUE sm_mat3_inv_rotate_vec3(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_rhs;
VALUE sm_out;
mat3_t *self;
vec3_t *rhs;
rb_scan_args(argc, argv, "11", &sm_rhs, &sm_out);
self = sm_unwrap_mat3(sm_self, NULL);
if (!SM_IS_A(sm_rhs, vec3) && !SM_IS_A(sm_rhs, vec4) && !SM_IS_A(sm_rhs, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_THREE_OR_FOUR_FORMAT_LIT,
rb_obj_classname(sm_rhs));
return Qnil;
}
rhs = sm_unwrap_vec3(sm_rhs, NULL);
if (argc == 2) {
if (!RTEST(sm_out)) {
goto SM_LABEL(skip_output);
}{
vec3_t *output;
if (!SM_IS_A(sm_out, vec3) && !SM_IS_A(sm_out, vec4) && !SM_IS_A(sm_out, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_THREE_OR_FOUR_FORMAT_LIT,
rb_obj_classname(sm_out));
return Qnil;
}
rb_check_frozen(sm_out);
output = sm_unwrap_vec3(sm_out, NULL);
mat3_inv_rotate_vec3(*self, *rhs, *output);
}} else if (argc == 1) {
SM_LABEL(skip_output): {
vec3_t output;
mat3_inv_rotate_vec3(*self, *rhs, output);
sm_out = sm_wrap_vec3(output, rb_obj_class(sm_rhs));
rb_obj_call_init(sm_out, 0, 0);
}} else {
rb_raise(rb_eArgError, "Invalid number of arguments to inverse_rotate_vec3");
}
return sm_out;
}
|
#length ⇒ Object
Returns the length of the Mat3 in components. Result is always 9.
call-seq: length -> fixnum
6005 6006 6007 6008 |
# File 'ext/snow-math/snow-math.c', line 6005
static VALUE sm_mat3_length (VALUE self)
{
return SIZET2NUM(sizeof(mat3_t) / sizeof(s_float_t));
}
|
#load_identity ⇒ Object
Sets self to the identity matrix.
call-seq:
load_identity -> self
6824 6825 6826 6827 6828 6829 |
# File 'ext/snow-math/snow-math.c', line 6824
static VALUE sm_mat3_identity(VALUE sm_self)
{
mat3_t *self = sm_unwrap_mat3(sm_self, NULL);
mat3_identity(*self);
return sm_self;
}
|
#multiply(rhs, out = nil) ⇒ Object Also known as: *
Multiplies self and RHS and returns the result. This is a wrapper around other multiply methods. See multiply_mat3, rotate_vec3, and #scale for more reference.
In the third form, the scalar value provided is passed for all three columns when calling scale.
call-seq:
multiply(mat3, output = nil) -> output or new mat3
multiply(vec3, output = nil) -> output or new vec3
multiply(scalar, output = nil) -> output or new mat3
105 106 107 108 109 110 111 112 |
# File 'lib/snow-math/mat3.rb', line 105 def multiply(rhs, out = nil) case rhs when ::Snow::Mat3 then multiply_mat3(rhs, out) when ::Snow::Vec3 then rotate_vec3(rhs, out) when Numeric then scale(rhs, rhs, rhs, out) else raise TypeError, "Invalid type for RHS" end end |
#multiply!(rhs) ⇒ Object
Calls #multiply(rhs, self).
call-seq:
multiply!(mat3) -> self
multiply!(vec3) -> vec3
multiply!(scalar) -> self
122 123 124 125 126 127 128 |
# File 'lib/snow-math/mat3.rb', line 122 def multiply!(rhs) multiply rhs, case rhs when Mat3, Numeric then self when Vec3 then rhs else raise TypeError, "Invalid type for RHS" end end |
#multiply_mat3(*args) ⇒ Object
Multiplies this Mat3 and another and returns the result.
call-seq:
multiply_mat3(mat3, output = nil) -> output or new mat3
6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 |
# File 'ext/snow-math/snow-math.c', line 6228
static VALUE sm_mat3_multiply(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_rhs;
VALUE sm_out;
mat3_t *self;
mat3_t *rhs;
rb_scan_args(argc, argv, "11", &sm_rhs, &sm_out);
self = sm_unwrap_mat3(sm_self, NULL);
SM_RAISE_IF_NOT_TYPE(sm_rhs, mat3);
rhs = sm_unwrap_mat3(sm_rhs, NULL);
if (argc == 2) {
if (!RTEST(sm_out)) {
goto SM_LABEL(skip_output);
}{
mat3_t *output;
SM_RAISE_IF_NOT_TYPE(sm_out, mat3);
rb_check_frozen(sm_out);
output = sm_unwrap_mat3(sm_out, NULL);
mat3_multiply(*self, *rhs, *output);
}} else if (argc == 1) {
SM_LABEL(skip_output): {
mat3_t output;
mat3_multiply(*self, *rhs, output);
sm_out = sm_wrap_mat3(output, rb_obj_class(sm_self));
rb_obj_call_init(sm_out, 0, 0);
}} else {
rb_raise(rb_eArgError, "Invalid number of arguments to multiply_mat3");
}
return sm_out;
}
|
#multiply_mat3!(rhs) ⇒ Object
Calls #multiply_mat3(rhs, self)
call-seq: multiply_mat3!(rhs) -> self
88 89 90 |
# File 'lib/snow-math/mat3.rb', line 88 def multiply_mat3!(rhs) multiply_mat3 rhs, self end |
#orthogonal(*args) ⇒ Object
Returns an orthogonal matrix.
call-seq:
orthogonal(output = nil) -> output or new mat3
6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 |
# File 'ext/snow-math/snow-math.c', line 6158
static VALUE sm_mat3_orthogonal(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_out;
mat3_t *self;
rb_scan_args(argc, argv, "01", &sm_out);
self = sm_unwrap_mat3(sm_self, NULL);
if (argc == 1) {
if (!RTEST(sm_out)) {
goto SM_LABEL(skip_output);
}{
mat3_t *output;
SM_RAISE_IF_NOT_TYPE(sm_out, mat3);
rb_check_frozen(sm_out);
output = sm_unwrap_mat3(sm_out, NULL);
mat3_orthogonal (*self, *output);
}} else if (argc == 0) {
SM_LABEL(skip_output): {
mat3_t output;
mat3_orthogonal (*self, output);
sm_out = sm_wrap_mat3(output, rb_obj_class(sm_self));
rb_obj_call_init(sm_out, 0, 0);
}} else {
rb_raise(rb_eArgError, "Invalid number of arguments to orthogonal");
}
return sm_out;
}
|
#rotate_vec3(*args) ⇒ Object
Rotates a Vec3 using self and returns the result.
call-seq:
rotate_vec3(vec3, output = nil) -> output or new vec3
6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 |
# File 'ext/snow-math/snow-math.c', line 6267
static VALUE sm_mat3_rotate_vec3(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_rhs;
VALUE sm_out;
mat3_t *self;
vec3_t *rhs;
rb_scan_args(argc, argv, "11", &sm_rhs, &sm_out);
self = sm_unwrap_mat3(sm_self, NULL);
if (!SM_IS_A(sm_rhs, vec3) && !SM_IS_A(sm_rhs, vec4) && !SM_IS_A(sm_rhs, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_THREE_OR_FOUR_FORMAT_LIT,
rb_obj_classname(sm_rhs));
return Qnil;
}
rhs = sm_unwrap_vec3(sm_rhs, NULL);
if (argc == 2) {
if (!RTEST(sm_out)) {
goto SM_LABEL(skip_output);
}{
vec3_t *output;
if (!SM_IS_A(sm_out, vec3) && !SM_IS_A(sm_out, vec4) && !SM_IS_A(sm_out, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_THREE_OR_FOUR_FORMAT_LIT,
rb_obj_classname(sm_out));
return Qnil;
}
rb_check_frozen(sm_out);
output = sm_unwrap_vec3(sm_out, NULL);
mat3_rotate_vec3(*self, *rhs, *output);
}} else if (argc == 1) {
SM_LABEL(skip_output): {
vec3_t output;
mat3_rotate_vec3(*self, *rhs, output);
sm_out = sm_wrap_vec3(output, rb_obj_class(sm_rhs));
rb_obj_call_init(sm_out, 0, 0);
}} else {
rb_raise(rb_eArgError, "Invalid number of arguments to rotate_vec3");
}
return sm_out;
}
|
#scale(*args) ⇒ Object Also known as: **
Scales Mat3’s columns by X, Y, and Z and returns the result.
call-seq:
scale(x, y, z, output = nil) -> output or new mat3
6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 6862 |
# File 'ext/snow-math/snow-math.c', line 6839
static VALUE sm_mat3_scale(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_out;
VALUE sm_x, sm_y, sm_z;
s_float_t x, y, z;
mat3_t *self = sm_unwrap_mat3(sm_self, NULL);
rb_scan_args(argc, argv, "31", &sm_x, &sm_y, &sm_z, &sm_out);
x = rb_num2dbl(sm_x);
y = rb_num2dbl(sm_y);
z = rb_num2dbl(sm_z);
if (SM_IS_A(sm_out, mat3)) {
rb_check_frozen(sm_out);
mat3_scale(*self, x, y, z, *sm_unwrap_mat3(sm_out, NULL));
} else {
mat3_t out;
mat3_scale(*self, x, y, z, out);
sm_out = sm_wrap_mat3(out, rb_obj_class(sm_self));
rb_obj_call_init(sm_out, 0, 0);
}
return sm_out;
}
|
#scale!(x, y, z) ⇒ Object
Calls scale(x, y, z, self)
call-seq: scale!(x, y, z) -> self
135 136 137 |
# File 'lib/snow-math/mat3.rb', line 135 def scale!(x, y, z) scale x, y, z, self end |
#set(*args) ⇒ Object
Sets the Mat3’s components.
call-seq:
set(m1, m2, ..., m8, m9) -> new mat3 with components
set([m1, m2, ..., m8, m9]) -> new mat3 with components
set(mat3) -> copy of mat3
set(mat4) -> new mat3 from mat4's inner 9x9 matrix
set(quat) -> quat as mat3
set(Vec3, Vec3, Vec3) -> new mat3 with given row vectors
6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 |
# File 'ext/snow-math/snow-math.c', line 6459
static VALUE sm_mat3_init(int argc, VALUE *argv, VALUE sm_self)
{
mat3_t *self = sm_unwrap_mat3(sm_self, NULL);
size_t arr_index = 0;
rb_check_frozen(sm_self);
switch (argc) {
case 0: {
/* Identity (handled in _new) */
break;
}
/* Copy Mat3 or provided [Numeric..] */
case 1: {
/* Copy Mat3 */
if (SM_IS_A(argv[0], mat3)) {
sm_unwrap_mat3(argv[0], *self);
break;
}
/* Copy Mat4 */
if (SM_IS_A(argv[0], mat4)) {
mat4_to_mat3(*sm_unwrap_mat4(argv[0], NULL), *self);
break;
}
/* Build from Quaternion */
if (SM_IS_A(argv[0], quat)) {
mat3_from_quat(*sm_unwrap_quat(argv[0], NULL), *self);
break;
}
/* Optional offset into array provided */
if (0) {
case 2:
arr_index = NUM2SIZET(argv[1]);
}
/* Array of values */
if (SM_RB_IS_A(argv[0], rb_cArray)) {
VALUE arrdata = argv[0];
const size_t arr_end = arr_index + 9;
s_float_t *mat_elem = *self;
for (; arr_index < arr_end; ++arr_index, ++mat_elem) {
*mat_elem = rb_num2dbl(rb_ary_entry(arrdata, (long)arr_index));
}
break;
}
rb_raise(rb_eArgError, "Expected either an array of Numerics or a Mat3");
break;
}
/* Mat3(Vec3, Vec3, Vec3) */
case 3: {
size_t arg_index;
s_float_t *mat_elem = *self;
for (arg_index = 0; arg_index < 3; ++arg_index, mat_elem += 3) {
if (!SM_IS_A(argv[arg_index], vec3) && !SM_IS_A(argv[arg_index], vec4) && !SM_IS_A(argv[arg_index], quat)) {
rb_raise(
rb_eArgError,
"Argument %d must be a Vec3, Vec4, or Quat when supplying three arguments to initialize/set",
(int)(arg_index + 1));
}
sm_unwrap_vec3(argv[arg_index], mat_elem);
}
break;
}
/* Mat3(Numeric m00 .. m16) */
case 9: {
s_float_t *mat_elem = *self;
VALUE *argv_p = argv;
for (; argc; --argc, ++argv_p, ++mat_elem) {
*mat_elem = (s_float_t)rb_num2dbl(*argv_p);
}
break;
}
default: {
rb_raise(rb_eArgError, "Invalid arguments to initialize/set");
break;
}
} /* switch (argc) */
return sm_self;
}
|
#set_column3(sm_index, sm_value) ⇒ Object
Sets the matrix’s column at the given index to the given vector.
call-seq:
set_column3(index, value) -> self
6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 |
# File 'ext/snow-math/snow-math.c', line 6789
static VALUE sm_mat3_set_column3(VALUE sm_self, VALUE sm_index, VALUE sm_value)
{
const vec3_t *value;
int index;
mat3_t *self;
if (!SM_IS_A(sm_value, vec3) && !SM_IS_A(sm_value, vec4) && !SM_IS_A(sm_value, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_THREE_OR_FOUR_FORMAT_LIT,
rb_obj_classname(sm_value));
return Qnil;
}
self = sm_unwrap_mat3(sm_self, NULL);
value = sm_unwrap_vec3(sm_value, NULL);
index = NUM2INT(sm_index);
if (index < 0 || index > 2) {
rb_raise(rb_eRangeError, "Index %d is out of range, must be (0 .. 2)", index);
return Qnil;
}
mat3_set_column3(index, *value, *self);
return sm_self;
}
|
#set_row3(sm_index, sm_value) ⇒ Object
Sets the matrix’s row at the given index to the given vector.
call-seq:
set_row3(index, vec3) -> self
6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 |
# File 'ext/snow-math/snow-math.c', line 6754
static VALUE sm_mat3_set_row3(VALUE sm_self, VALUE sm_index, VALUE sm_value)
{
const vec3_t *value;
int index;
mat3_t *self;
if (!SM_IS_A(sm_value, vec3) && !SM_IS_A(sm_value, vec4) && !SM_IS_A(sm_value, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_THREE_OR_FOUR_FORMAT_LIT,
rb_obj_classname(sm_value));
return Qnil;
}
self = sm_unwrap_mat3(sm_self, NULL);
value = sm_unwrap_vec3(sm_value, NULL);
index = NUM2INT(sm_index);
if (index < 0 || index > 2) {
rb_raise(rb_eRangeError, "Index %d is out of range, must be (0 .. 2)", index);
return Qnil;
}
mat3_set_row3(index, *value, *self);
return sm_self;
}
|
#size ⇒ Object
Returns the length in bytes of the Mat3. When compiled to use doubles as the base type, this is always 72. Otherwise, when compiled to use floats, it’s always 36.
call-seq: size -> fixnum
5993 5994 5995 5996 |
# File 'ext/snow-math/snow-math.c', line 5993
static VALUE sm_mat3_size (VALUE self)
{
return SIZET2NUM(sizeof(mat3_t));
}
|
#store ⇒ Object Also known as: []=
Sets the Mat3’s component at the index to the value.
call-seq: store(index, value) -> value
5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 |
# File 'ext/snow-math/snow-math.c', line 5970
static VALUE sm_mat3_store (VALUE sm_self, VALUE sm_index, VALUE sm_value)
{
static const int max_index = sizeof(mat3_t) / sizeof(s_float_t);
mat3_t *self = sm_unwrap_mat3(sm_self, NULL);
int index = NUM2INT(sm_index);
rb_check_frozen(sm_self);
if (index < 0 || index >= max_index) {
rb_raise(rb_eRangeError,
"Index %d is out of bounds, must be from 0 through %d", index, max_index - 1);
}
self[0][index] = (s_float_t)rb_num2dbl(sm_value);
return sm_value;
}
|
#to_mat4(*args) ⇒ Object
Returns a Mat4 converted from the Mat3.
call-seq:
to_mat4(output = nil) -> output or new mat4
6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 |
# File 'ext/snow-math/snow-math.c', line 6053
static VALUE sm_mat3_to_mat4(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_out;
mat3_t *self;
rb_scan_args(argc, argv, "01", &sm_out);
self = sm_unwrap_mat3(sm_self, NULL);
if (argc == 1) {
if (!RTEST(sm_out)) {
goto SM_LABEL(skip_output);
}{
mat4_t *output;
SM_RAISE_IF_NOT_TYPE(sm_out, mat4);
rb_check_frozen(sm_out);
output = sm_unwrap_mat4(sm_out, NULL);
mat3_to_mat4 (*self, *output);
}} else if (argc == 0) {
SM_LABEL(skip_output): {
mat4_t output;
mat3_to_mat4 (*self, output);
sm_out = sm_wrap_mat4(output, s_sm_mat3_klass);
rb_obj_call_init(sm_out, 0, 0);
}} else {
rb_raise(rb_eArgError, "Invalid number of arguments to to_mat4");
}
return sm_out;
}
|
#to_s ⇒ Object
Returns a string representation of self.
Mat3[].to_s # => "{ 1.0, 0.0, 0.0,\n
# 0.0, 1.0, 0.0,\n"
# 0.0, 0.0, 1.0 }"
call-seq:
to_s -> string
6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 |
# File 'ext/snow-math/snow-math.c', line 6562
static VALUE sm_mat3_to_s(VALUE self)
{
const s_float_t *v;
v = (const s_float_t *)*sm_unwrap_mat3(self, NULL);
return rb_sprintf(
"{ "
"%f, %f, %f" ",\n "
"%f, %f, %f" ",\n "
"%f, %f, %f"
" }",
v[0], v[1], v[2],
v[3], v[4], v[5],
v[6], v[7], v[8] );
}
|
#transpose(*args) ⇒ Object Also known as: ~
Transposes this matrix and returns the result.
call-seq:
transpose(output = nil) -> output or new mat3
6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 |
# File 'ext/snow-math/snow-math.c', line 6088
static VALUE sm_mat3_transpose(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_out;
mat3_t *self;
rb_scan_args(argc, argv, "01", &sm_out);
self = sm_unwrap_mat3(sm_self, NULL);
if (argc == 1) {
if (!RTEST(sm_out)) {
goto SM_LABEL(skip_output);
}{
mat3_t *output;
SM_RAISE_IF_NOT_TYPE(sm_out, mat3);
rb_check_frozen(sm_out);
output = sm_unwrap_mat3(sm_out, NULL);
mat3_transpose (*self, *output);
}} else if (argc == 0) {
SM_LABEL(skip_output): {
mat3_t output;
mat3_transpose (*self, output);
sm_out = sm_wrap_mat3(output, rb_obj_class(sm_self));
rb_obj_call_init(sm_out, 0, 0);
}} else {
rb_raise(rb_eArgError, "Invalid number of arguments to transpose");
}
return sm_out;
}
|
#transpose! ⇒ Object
Calls #transpose(self)
call-seq: transpose! -> self
52 53 54 |
# File 'lib/snow-math/mat3.rb', line 52 def transpose! transpose self end |