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.
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
6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 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 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 |
# File 'ext/snow-math/snow-math.c', line 6248
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
6374 6375 6376 6377 6378 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 |
# File 'ext/snow-math/snow-math.c', line 6374
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
6228 6229 6230 6231 6232 6233 |
# File 'ext/snow-math/snow-math.c', line 6228
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
6661 6662 6663 6664 6665 6666 6667 6668 |
# File 'ext/snow-math/snow-math.c', line 6661
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
6683 6684 6685 6686 6687 6688 |
# File 'ext/snow-math/snow-math.c', line 6683
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
5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 |
# File 'ext/snow-math/snow-math.c', line 5912
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
66 67 68 |
# File 'lib/snow-math/mat3.rb', line 66 def adjoint! adjoint self end |
#cofactor(*args) ⇒ Object
Returns a cofactor matrix.
call-seq:
cofactor(output = nil) -> output or new mat3
5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 |
# File 'ext/snow-math/snow-math.c', line 5982
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
75 76 77 |
# File 'lib/snow-math/mat3.rb', line 75 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
5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 |
# File 'ext/snow-math/snow-math.c', line 5807
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
6155 6156 6157 6158 |
# File 'ext/snow-math/snow-math.c', line 6155
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
5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 |
# File 'ext/snow-math/snow-math.c', line 5740
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
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 |
# File 'ext/snow-math/snow-math.c', line 6479
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
6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 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 6462 6463 6464 6465 6466 6467 6468 6469 |
# File 'ext/snow-math/snow-math.c', line 6415
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
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 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 |
# File 'ext/snow-math/snow-math.c', line 6168
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
57 58 59 |
# File 'lib/snow-math/mat3.rb', line 57 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
6106 6107 6108 6109 6110 6111 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 |
# File 'ext/snow-math/snow-math.c', line 6106
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
5794 5795 5796 5797 |
# File 'ext/snow-math/snow-math.c', line 5794
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
6613 6614 6615 6616 6617 6618 |
# File 'ext/snow-math/snow-math.c', line 6613
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
101 102 103 104 105 106 107 108 |
# File 'lib/snow-math/mat3.rb', line 101 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 call-seq: multiply!(vec3) -> vec3 call-seq: multiply!(scalar) -> self
117 118 119 120 121 122 123 |
# File 'lib/snow-math/mat3.rb', line 117 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
6017 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 6044 6045 6046 |
# File 'ext/snow-math/snow-math.c', line 6017
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
84 85 86 |
# File 'lib/snow-math/mat3.rb', line 84 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
5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 |
# File 'ext/snow-math/snow-math.c', line 5947
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
6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 |
# File 'ext/snow-math/snow-math.c', line 6056
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
6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 |
# File 'ext/snow-math/snow-math.c', line 6628
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
130 131 132 |
# File 'lib/snow-math/mat3.rb', line 130 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
6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 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 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 |
# File 'ext/snow-math/snow-math.c', line 6248
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
6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 |
# File 'ext/snow-math/snow-math.c', line 6578
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
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 |
# File 'ext/snow-math/snow-math.c', line 6543
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
5782 5783 5784 5785 |
# File 'ext/snow-math/snow-math.c', line 5782
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
5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 |
# File 'ext/snow-math/snow-math.c', line 5759
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
5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 |
# File 'ext/snow-math/snow-math.c', line 5842
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
6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 |
# File 'ext/snow-math/snow-math.c', line 6351
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
5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 |
# File 'ext/snow-math/snow-math.c', line 5877
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
48 49 50 |
# File 'lib/snow-math/mat3.rb', line 48 def transpose! transpose self end |