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
- SIZE =
INT2FIX(sizeof(mat3_t))
- LENGTH =
INT2FIX(sizeof(mat3_t) / sizeof(s_float_t))
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.
-
#orthogonal? ⇒ Boolean
call-seq: orthogonal? -> true or false.
-
#pitch ⇒ Object
Returns the pitch (X-axis rotation) of this matrix in degrees.
-
#roll ⇒ Object
Returns the roll (Z-axis rotation) of this matrix in degrees.
-
#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).
-
#yaw ⇒ Object
Returns the yaw (Y-axis rotation) of this matrix in degrees.
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
6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 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 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 |
# File 'ext/snow-math/snow-math.c', line 6304 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 = 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)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
6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 |
# File 'ext/snow-math/snow-math.c', line 6430 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)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
6284 6285 6286 6287 6288 6289 |
# File 'ext/snow-math/snow-math.c', line 6284 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
6717 6718 6719 6720 6721 6722 6723 6724 |
# File 'ext/snow-math/snow-math.c', line 6717 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
6739 6740 6741 6742 6743 6744 |
# File 'ext/snow-math/snow-math.c', line 6739 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
5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 |
# File 'ext/snow-math/snow-math.c', line 5968 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
6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 |
# File 'ext/snow-math/snow-math.c', line 6038 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
5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 |
# File 'ext/snow-math/snow-math.c', line 5863 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
6211 6212 6213 6214 |
# File 'ext/snow-math/snow-math.c', line 6211 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
5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 |
# File 'ext/snow-math/snow-math.c', line 5796 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 DBL2NUM(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
6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 |
# File 'ext/snow-math/snow-math.c', line 6535 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
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 |
# File 'ext/snow-math/snow-math.c', line 6471 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
6224 6225 6226 6227 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 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 |
# File 'ext/snow-math/snow-math.c', line 6224 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
6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 |
# File 'ext/snow-math/snow-math.c', line 6162 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
5850 5851 5852 5853 |
# File 'ext/snow-math/snow-math.c', line 5850 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
6669 6670 6671 6672 6673 6674 |
# File 'ext/snow-math/snow-math.c', line 6669 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 ::Snow::Mat3, Numeric then self when ::Snow::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
6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 |
# File 'ext/snow-math/snow-math.c', line 6073 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
6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 |
# File 'ext/snow-math/snow-math.c', line 6003 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; } |
#orthogonal? ⇒ Boolean
call-seq:
orthogonal? -> true or false
Returns whether self is an orthogonal matrix (its columns and rows are all unit vectors). Note that this allocates a new matrix. You probably don’t want to call it often.
175 176 177 178 |
# File 'lib/snow-math/mat3.rb', line 175 def orthogonal? temp = self.transpose multiply_mat3(temp, temp) == IDENTITY end |
#pitch ⇒ Object
Returns the pitch (X-axis rotation) of this matrix in degrees. This assumes the matrix is orthogonal.
143 144 145 146 147 148 149 |
# File 'lib/snow-math/mat3.rb', line 143 def pitch tx = self[6] tz = self[8] Math::atan2( self[7], Math::sqrt(tx * tx + tz * tz)) * ::Snow::RADIANS_TO_DEGREES end |
#roll ⇒ Object
Returns the roll (Z-axis rotation) of this matrix in degrees. This assumes the matrix is orthogonal.
163 164 165 |
# File 'lib/snow-math/mat3.rb', line 163 def roll Math::atan2(self[1], self[4]) * ::Snow::RADIANS_TO_DEGREES end |
#rotate_vec3(*args) ⇒ Object
Rotates a Vec3 using self and returns the result.
call-seq:
rotate_vec3(vec3, output = nil) -> output or new vec3
6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 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 6149 6150 6151 |
# File 'ext/snow-math/snow-math.c', line 6112 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
6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 |
# File 'ext/snow-math/snow-math.c', line 6684 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 = NUM2DBL(sm_x); y = NUM2DBL(sm_y); z = 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
6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 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 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 |
# File 'ext/snow-math/snow-math.c', line 6304 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 = 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)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
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 |
# File 'ext/snow-math/snow-math.c', line 6634 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
6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 |
# File 'ext/snow-math/snow-math.c', line 6599 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
5838 5839 5840 5841 |
# File 'ext/snow-math/snow-math.c', line 5838 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
5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 |
# File 'ext/snow-math/snow-math.c', line 5815 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)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
5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 |
# File 'ext/snow-math/snow-math.c', line 5898 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_mat4_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_quat ⇒ Object
43 44 45 |
# File 'lib/snow-math/mat3.rb', line 43 def to_quat Quat.new(self) end |
#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
6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 |
# File 'ext/snow-math/snow-math.c', line 6407 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
5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 |
# File 'ext/snow-math/snow-math.c', line 5933 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 |
#yaw ⇒ Object
Returns the yaw (Y-axis rotation) of this matrix in degrees. This assumes the matrix is orthogonal.
155 156 157 |
# File 'lib/snow-math/mat3.rb', line 155 def yaw -Math::atan2(self[6], self[8]) * ::Snow::RADIANS_TO_DEGREES end |