Class: Snow::Quat
- Inherits:
-
Object
- Object
- Snow::Quat
- Defined in:
- lib/snow-math/quat.rb,
lib/snow-math/ptr.rb,
lib/snow-math/to_a.rb,
lib/snow-math/inspect.rb,
lib/snow-math/marshal.rb,
lib/snow-math/swizzle.rb,
ext/snow-math/snow-math.c
Overview
A simple quaternion class for representation rotations.
Constant Summary collapse
- @@SWIZZLE_CHARS =
/^[xyzw]{3,4}$/- @@SWIZZLE_MAPPING =
{ 3 => ::Snow::Vec3, 4 => self, 'x' => 0, 'y' => 1, 'z' => 2, 'w' => 3 }
Class Method Summary collapse
-
.angle_axis(*args) ⇒ Object
Returns a quaternion describing a rotation around a given axis.
-
.new(*args) ⇒ Object
(also: [])
Allocates a new Quat.
Instance Method Summary collapse
-
#==(sm_other) ⇒ Object
Tests this Vec4 or Quat and another Vec4 or Quat for equivalency.
-
#add(*args) ⇒ Object
(also: #+)
Adds this and another vector or quaternion’s components together and returns the result.
-
#add!(rhs) ⇒ Object
Calls #add(rhs, self).
-
#address ⇒ Object
Returns the memory address of the object.
-
#copy(*args) ⇒ Object
(also: #dup, #clone)
Returns a copy of self.
-
#divide(*args) ⇒ Object
(also: #/)
Divides this vector or quaternion’s components by a scalar value and returns the result.
-
#divide!(rhs) ⇒ Object
Calls #divide(rhs, self).
-
#dot_product(sm_other) ⇒ Object
(also: #**)
Returns the dot product of self and another Vec4 or Quat.
-
#fetch ⇒ Object
(also: #[])
Gets the component of the Quat at the given index.
-
#initialize(*args) ⇒ Object
constructor
Sets the Quat’s components.
-
#inverse(*args) ⇒ Object
(also: #~)
Returns the inverse of this Quat.
-
#inverse! ⇒ Object
Calls #inverse(self).
-
#length ⇒ Object
Returns the length of the Quat in components.
-
#load_identity ⇒ Object
Sets self to the identity quaternion.
-
#magnitude ⇒ Object
Returns the magnitude of self.
-
#magnitude_squared ⇒ Object
Returns the squared magnitude of self.
-
#multiply(rhs, output = nil) ⇒ Object
(also: #*)
Wrapper around #multiply_quat, #multiply_vec3, and #scale respectively.
-
#multiply!(rhs) ⇒ Object
Calls #multiply(rhs, self) for scaling and Quat multiplication, otherwise calls #multiply(rhs, rhs) for Vec3 multiplication.
-
#multiply_quat(*args) ⇒ Object
Concatenates this quaternion and another and returns the result.
-
#multiply_quat!(rhs) ⇒ Object
Calls #multiply_quat(rhs, self).
-
#multiply_vec3(*args) ⇒ Object
Multiplies a quaternion and vec3, returning the rotated vec3.
-
#multiply_vec3!(rhs) ⇒ Object
Calls #multiply_vec3(rhs, rhs).
-
#negate(*args) ⇒ Object
(also: #-@)
Negates this vector or quaternions’s components and returns the result.
-
#negate! ⇒ Object
Calls #negate(self).
-
#normalize(*args) ⇒ Object
Returns a normalized Vec4 or Quat, depending on the type of the receiver and output.
-
#normalize! ⇒ Object
Calls #normalize(self).
-
#scale(*args) ⇒ Object
Scales this vector or quaternion’s components by a scalar value and returns the result.
-
#scale!(rhs) ⇒ Object
Calls #scale(rhs, self).
-
#set(*args) ⇒ Object
Sets the Quat’s components.
-
#size ⇒ Object
Returns the length in bytes of the Quat.
-
#slerp(*args) ⇒ Object
Returns a quaternion interpolated between self and destination using spherical linear interpolation.
-
#slerp!(destination, alpha) ⇒ Object
Calls #slerp(destination, alpha, self).
-
#store ⇒ Object
(also: #[]=)
Sets the Quat’s component at the index to the value.
-
#subtract(*args) ⇒ Object
(also: #-)
Subtracts another vector or quaternion’s components from this vector’s and returns the result.
-
#subtract!(rhs) ⇒ Object
Calls #subtract(rhs, self).
-
#to_s ⇒ Object
Returns a string representation of self.
-
#w ⇒ Object
Returns the W component of the quaternion.
-
#w=(value) ⇒ Object
Sets the W component of the quaternion.
-
#x ⇒ Object
Returns the X component of the quaternion.
-
#x=(value) ⇒ Object
Sets the X component of the quaternion.
-
#y ⇒ Object
Returns the Y component of the quaternion.
-
#y=(value) ⇒ Object
Sets the Y component of the quaternion.
-
#z ⇒ Object
Returns the Z component of the quaternion.
-
#z=(value) ⇒ Object
Sets the Z component of the quaternion.
Methods included from SwizzleSupport
#__under_method_missing__, #method_missing
Methods included from BaseMarshalSupport
Methods included from InspectSupport
Methods included from ArraySupport
Methods included from FiddlePointerSupport
Constructor Details
#initialize(*args) ⇒ Object
Sets the Quat’s components.
call-seq:
set(x, y, z, w = 1) -> new quaternion with components [x, y, z, w]
set([x, y, z, w]) -> new quaternion with components [x, y, z, w]
set(quat) -> copy of quat
set(vec3) -> new quaternion with the components [vec3.xyz, 1]
set(vec4) -> new quaternion with the components of vec4
set(mat3) -> new quaternion from mat3
set(mat4) -> new quaternion from mat4
2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 |
# File 'ext/snow-math/snow-math.c', line 2883
static VALUE sm_quat_init(int argc, VALUE *argv, VALUE sm_self)
{
quat_t *self = sm_unwrap_quat(sm_self, NULL);
size_t arr_index = 0;
switch(argc) {
// Default value
case 0: { break; }
// Copy or by-array
case 1: {
if (SM_IS_A(argv[0], vec3)) {
sm_unwrap_vec3(argv[0], *self);
break;
}
if (SM_IS_A(argv[0], quat) ||
SM_IS_A(argv[0], vec4)) {
sm_unwrap_quat(argv[0], *self);
break;
}
if (SM_IS_A(argv[0], mat4)) {
const mat4_t *mat = sm_unwrap_mat4(argv[0], NULL);
quat_from_mat4(*mat, *self);
break;
}
if (SM_IS_A(argv[0], mat3)) {
const mat3_t *mat = sm_unwrap_mat3(argv[0], NULL);
quat_from_mat3(*mat, *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 + 3;
s_float_t *vec_elem = *self;
for (; arr_index < arr_end; ++arr_index, ++vec_elem) {
*vec_elem = (s_float_t)rb_num2dbl(rb_ary_entry(arrdata, (long)arr_index));
}
break;
}
rb_raise(rb_eArgError, "Expected either an array of Numerics or a Quat");
break;
}
// W
case 4: {
self[0][3] = (s_float_t)rb_num2dbl(argv[3]);
case 3: // X, Y, Z
self[0][0] = (s_float_t)rb_num2dbl(argv[0]);
self[0][1] = (s_float_t)rb_num2dbl(argv[1]);
self[0][2] = (s_float_t)rb_num2dbl(argv[2]);
break;
}
default: {
rb_raise(rb_eArgError, "Invalid arguments to Quat.initialize");
break;
}
} // switch (argc)
return sm_self;
}
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Snow::SwizzleSupport
Class Method Details
.angle_axis(*args) ⇒ Object
Returns a quaternion describing a rotation around a given axis.
call-seq:
angle_axis(angle_degrees, axis_vec3, output = nil) -> output or new quat
2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 |
# File 'ext/snow-math/snow-math.c', line 2987
static VALUE sm_quat_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, quat) || SM_IS_A(sm_out, vec4)) {
quat_t *out = sm_unwrap_quat(sm_out, NULL);
quat_from_angle_axis(angle, (*axis)[0], (*axis)[1], (*axis)[2], *out);
} else {
quat_t out;
quat_from_angle_axis(angle, (*axis)[0], (*axis)[1], (*axis)[2], out);
sm_out = sm_wrap_quat(out, self);
rb_obj_call_init(sm_out, 0, 0);
}
return sm_out;
}
|
.new(*args) ⇒ Object Also known as: []
Allocates a new Quat.
call-seq:
new() -> new identity quaternion
new(x, y, z, w = 1) -> new quaternion with components [x, y, z, w]
new([x, y, z, w]) -> new quaternion with components [x, y, z, w]
new(quat) -> copy of quat
new(vec3) -> new quaternion with the components [vec3.xyz, 1]
new(vec4) -> new quaternion with the components of vec4
new(mat3) -> new quaternion from mat3
new(mat4) -> new quaternion from mat4
2862 2863 2864 2865 2866 2867 |
# File 'ext/snow-math/snow-math.c', line 2862
static VALUE sm_quat_new(int argc, VALUE *argv, VALUE self)
{
VALUE sm_quat = sm_wrap_quat(g_quat_identity, self);
rb_obj_call_init(sm_quat, argc, argv);
return sm_quat;
}
|
Instance Method Details
#==(sm_other) ⇒ Object
Tests this Vec4 or Quat and another Vec4 or Quat for equivalency.
call-seq:
quat == other_quat -> bool
vec4 == other_vec4 -> bool
quat == vec4 -> bool
vec4 == quat -> bool
2608 2609 2610 2611 2612 2613 2614 2615 |
# File 'ext/snow-math/snow-math.c', line 2608
static VALUE sm_vec4_equals(VALUE sm_self, VALUE sm_other)
{
if (!RTEST(sm_other) || (!SM_IS_A(sm_other, vec4) && !SM_IS_A(sm_other, quat))) {
return Qfalse;
}
return vec4_equals(*sm_unwrap_vec4(sm_self, NULL), *sm_unwrap_vec4(sm_other, NULL)) ? Qtrue : Qfalse;
}
|
#add(*args) ⇒ Object Also known as: +
Adds this and another vector or quaternion’s components together and returns the result. The result type is that of the receiver.
call-seq:
add(vec4, output = nil) -> output or new vec4 or quat
2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 |
# File 'ext/snow-math/snow-math.c', line 2281
static VALUE sm_vec4_add(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_rhs;
VALUE sm_out;
vec4_t *self;
vec4_t *rhs;
rb_scan_args(argc, argv, "11", &sm_rhs, &sm_out);
self = sm_unwrap_vec4(sm_self, NULL);
if (!SM_IS_A(sm_rhs, vec4) && !SM_IS_A(sm_rhs, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_FOUR_FORMAT_LIT,
rb_obj_classname(sm_rhs));
return Qnil;
}
rhs = sm_unwrap_vec4(sm_rhs, NULL);
if (argc == 2) {
if (!RTEST(sm_out)) {
goto SM_LABEL(skip_output);
}{
if (!SM_IS_A(sm_rhs, vec4) && !SM_IS_A(sm_rhs, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_FOUR_FORMAT_LIT,
rb_obj_classname(sm_rhs));
return Qnil;
}
vec4_t *output = sm_unwrap_vec4(sm_out, NULL);
vec4_add(*self, *rhs, *output);
}} else if (argc == 1) {
SM_LABEL(skip_output): {
vec4_t output;
vec4_add(*self, *rhs, output);
sm_out = sm_wrap_vec4(output, rb_obj_class(sm_self));
rb_obj_call_init(sm_out, 0, 0);
}} else {
rb_raise(rb_eArgError, "Invalid number of arguments to vec4");
}
return sm_out;
}
|
#add!(rhs) ⇒ Object
Calls #add(rhs, self)
call-seq: add!(rhs) -> self
159 160 161 |
# File 'lib/snow-math/quat.rb', line 159 def add!(rhs) add rhs, self end |
#address ⇒ Object
Returns the memory address of the object.
call-seq: address -> fixnum
5564 5565 5566 5567 5568 5569 |
# File 'ext/snow-math/snow-math.c', line 5564
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);
}
|
#copy(*args) ⇒ Object Also known as: dup, clone
Returns a copy of self.
call-seq:
copy(output = nil) -> output or new vec4 / quat
1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 |
# File 'ext/snow-math/snow-math.c', line 1985
static VALUE sm_vec4_copy(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_out;
vec4_t *self;
rb_scan_args(argc, argv, "01", &sm_out);
self = sm_unwrap_vec4(sm_self, NULL);
if (argc == 1) {
if (!RTEST(sm_out)) {
goto SM_LABEL(skip_output);
}{
if (!SM_IS_A(sm_out, vec4) && !SM_IS_A(sm_out, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_FOUR_FORMAT_LIT,
rb_obj_classname(sm_out));
return Qnil;
}
vec4_t *output = sm_unwrap_vec4(sm_out, NULL);
vec4_copy (*self, *output);
}} else if (argc == 0) {
SM_LABEL(skip_output): {
vec4_t output;
vec4_copy (*self, output);
sm_out = sm_wrap_vec4(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;
}
|
#divide(*args) ⇒ Object Also known as: /
Divides this vector or quaternion’s components by a scalar value and returns the result. The return type is that of the receiver.
call-seq:
divide(scalar, output = nil) -> output or new vec4
2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 |
# File 'ext/snow-math/snow-math.c', line 2575
static VALUE sm_vec4_divide(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_out;
VALUE sm_scalar;
s_float_t scalar;
vec4_t *self = sm_unwrap_vec4(sm_self, NULL);
rb_scan_args(argc, argv, "11", &sm_scalar, &sm_out);
scalar = rb_num2dbl(sm_scalar);
if ((SM_IS_A(sm_out, vec4) || SM_IS_A(sm_out, quat))) {
vec4_divide(*self, scalar, *sm_unwrap_vec4(sm_out, NULL));
} else {
vec4_t out;
vec4_divide(*self, scalar, out);
sm_out = sm_wrap_vec4(out, rb_obj_class(sm_self));
rb_obj_call_init(sm_out, 0, 0);
}
return sm_out;
}
|
#divide!(rhs) ⇒ Object
Calls #divide(rhs, self)
call-seq: divide!(rhs) -> self
180 181 182 |
# File 'lib/snow-math/quat.rb', line 180 def divide!(rhs) divide rhs, self end |
#dot_product(sm_other) ⇒ Object Also known as: **
Returns the dot product of self and another Vec4 or Quat.
call-seq:
dot_product(vec4) -> float
dot_product(quat) -> float
2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 |
# File 'ext/snow-math/snow-math.c', line 2378
static VALUE sm_vec4_dot_product(VALUE sm_self, VALUE sm_other)
{
if (!SM_IS_A(sm_other, vec4) &&
!SM_IS_A(sm_other, quat)) {
rb_raise(rb_eArgError,
kSM_WANT_FOUR_FORMAT_LIT,
rb_obj_classname(sm_other));
return Qnil;
}
return rb_float_new(
vec4_dot_product(
*sm_unwrap_vec4(sm_self, NULL),
*sm_unwrap_vec4(sm_other, NULL)));
}
|
#fetch ⇒ Object Also known as: []
Gets the component of the Quat at the given index.
call-seq: fetch(index) -> float
2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 |
# File 'ext/snow-math/snow-math.c', line 2656
static VALUE sm_quat_fetch (VALUE sm_self, VALUE sm_index)
{
static const int max_index = sizeof(quat_t) / sizeof(s_float_t);
const quat_t *self = sm_unwrap_quat(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)]);
}
|
#inverse(*args) ⇒ Object Also known as: ~
Returns the inverse of this Quat. Note that this is not the same as the inverse of, for example, a Vec4.
call-seq:
inverse(output = nil) -> output or new quat
2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 |
# File 'ext/snow-math/snow-math.c', line 2723
static VALUE sm_quat_inverse(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_out;
quat_t *self;
rb_scan_args(argc, argv, "01", &sm_out);
self = sm_unwrap_quat(sm_self, NULL);
if (argc == 1) {
if (!RTEST(sm_out)) {
goto SM_LABEL(skip_output);
}{
if (!SM_IS_A(sm_out, vec4) && !SM_IS_A(sm_out, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_FOUR_FORMAT_LIT,
rb_obj_classname(sm_out));
return Qnil;
}
quat_t *output = sm_unwrap_quat(sm_out, NULL);
quat_inverse (*self, *output);
}} else if (argc == 0) {
SM_LABEL(skip_output): {
quat_t output;
quat_inverse (*self, output);
sm_out = sm_wrap_quat(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
102 103 104 |
# File 'lib/snow-math/quat.rb', line 102 def inverse! inverse self end |
#length ⇒ Object
Returns the length of the Quat in components. Result is always 4.
call-seq: length -> fixnum
2709 2710 2711 2712 |
# File 'ext/snow-math/snow-math.c', line 2709
static VALUE sm_quat_length (VALUE self)
{
return SIZET2NUM(sizeof(quat_t) / sizeof(s_float_t));
}
|
#load_identity ⇒ Object
Sets self to the identity quaternion.
call-seq:
load_identity -> self
3027 3028 3029 3030 3031 3032 |
# File 'ext/snow-math/snow-math.c', line 3027
static VALUE sm_quat_identity(VALUE sm_self)
{
quat_t *self = sm_unwrap_quat(sm_self, NULL);
quat_identity(*self);
return sm_self;
}
|
#magnitude ⇒ Object
Returns the magnitude of self.
call-seq:
magnitude -> float
2530 2531 2532 2533 |
# File 'ext/snow-math/snow-math.c', line 2530
static VALUE sm_vec4_magnitude(VALUE sm_self)
{
return rb_float_new(vec4_length(*sm_unwrap_vec4(sm_self, NULL)));
}
|
#magnitude_squared ⇒ Object
Returns the squared magnitude of self.
call-seq:
magnitude_squared -> float
2517 2518 2519 2520 |
# File 'ext/snow-math/snow-math.c', line 2517
static VALUE sm_vec4_magnitude_squared(VALUE sm_self)
{
return rb_float_new(vec4_length_squared(*sm_unwrap_vec4(sm_self, NULL)));
}
|
#multiply(rhs, output = nil) ⇒ Object Also known as: *
Wrapper around #multiply_quat, #multiply_vec3, and #scale respectively.
call-seq:
multiply(quat, output = nil) -> output or new quat
multiply(scalar, output = nil) -> output or new quat
multiply(vec3, output = nil) -> output or new vec3
133 134 135 136 137 138 139 140 |
# File 'lib/snow-math/quat.rb', line 133 def multiply(rhs, output = nil) case rhs when ::Snow::Quat then multiply_quat(rhs, output) when ::Snow::Vec3 then multiply_vec3(rhs, output) when Numeric then scale(rhs, output) else raise TypeError, "Invalid type for RHS" end end |
#multiply!(rhs) ⇒ Object
Calls #multiply(rhs, self) for scaling and Quat multiplication, otherwise calls #multiply(rhs, rhs) for Vec3 multiplication.
call-seq:
multiply!(quat) -> self
multiply!(scalar) -> self
multiply!(vec3) -> vec3
149 150 151 152 153 154 |
# File 'lib/snow-math/quat.rb', line 149 def multiply!(rhs) case rhs when ::Snow::Vec3 then multiply(rhs, rhs) else multiply(rhs, self) end end |
#multiply_quat(*args) ⇒ Object
Concatenates this quaternion and another and returns the result.
call-seq:
multiply_quat(quat, output = nil) -> output or new quat
2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 |
# File 'ext/snow-math/snow-math.c', line 2761
static VALUE sm_quat_multiply(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_rhs;
VALUE sm_out;
quat_t *self;
quat_t *rhs;
rb_scan_args(argc, argv, "11", &sm_rhs, &sm_out);
self = sm_unwrap_quat(sm_self, NULL);
if (!!SM_IS_A(sm_rhs, vec4) && !SM_IS_A(sm_rhs, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_FOUR_FORMAT_LIT,
rb_obj_classname(sm_rhs));
return Qnil;
}
rhs = sm_unwrap_quat(sm_rhs, NULL);
if (argc == 2) {
if (!RTEST(sm_out)) {
goto SM_LABEL(skip_output);
}{
if (!!SM_IS_A(sm_out, vec4) && !SM_IS_A(sm_out, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_FOUR_FORMAT_LIT,
rb_obj_classname(sm_out));
return Qnil;
}
quat_t *output = sm_unwrap_quat(sm_out, NULL);
quat_multiply(*self, *rhs, *output);
}} else if (argc == 1) {
SM_LABEL(skip_output): {
quat_t output;
quat_multiply(*self, *rhs, output);
sm_out = sm_wrap_quat(output, rb_obj_class(sm_self));
rb_obj_call_init(sm_out, 0, 0);
}} else {
rb_raise(rb_eArgError, "Invalid number of arguments to quat");
}
return sm_out;
}
|
#multiply_quat!(rhs) ⇒ Object
Calls #multiply_quat(rhs, self)
call-seq: multiply_quat!(rhs) -> self
116 117 118 |
# File 'lib/snow-math/quat.rb', line 116 def multiply_quat!(rhs) multiply_quat rhs, self end |
#multiply_vec3(*args) ⇒ Object
Multiplies a quaternion and vec3, returning the rotated vec3.
call-seq:
multiply_vec3(quat, output = nil) -> output or new quat
2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 |
# File 'ext/snow-math/snow-math.c', line 2808
static VALUE sm_quat_multiply_vec3(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_rhs;
VALUE sm_out;
quat_t *self;
vec3_t *rhs;
rb_scan_args(argc, argv, "11", &sm_rhs, &sm_out);
self = sm_unwrap_quat(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);
}{
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;
}
vec3_t *output = sm_unwrap_vec3(sm_out, NULL);
quat_multiply_vec3(*self, *rhs, *output);
}} else if (argc == 1) {
SM_LABEL(skip_output): {
vec3_t output;
quat_multiply_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 quat");
}
return sm_out;
}
|
#multiply_vec3!(rhs) ⇒ Object
Calls #multiply_vec3(rhs, rhs)
call-seq: multiply_vec3!(rhs) -> rhs
123 124 125 |
# File 'lib/snow-math/quat.rb', line 123 def multiply_vec3!(rhs) multiply_vec3 rhs, rhs end |
#negate(*args) ⇒ Object Also known as: -@
Negates this vector or quaternions’s components and returns the result.
call-seq:
negate(output = nil) -> output or new vec4 or quat
2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 |
# File 'ext/snow-math/snow-math.c', line 2100
static VALUE sm_vec4_negate(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_out;
vec4_t *self;
rb_scan_args(argc, argv, "01", &sm_out);
self = sm_unwrap_vec4(sm_self, NULL);
if (argc == 1) {
if (!RTEST(sm_out)) {
goto SM_LABEL(skip_output);
}{
if (!SM_IS_A(sm_out, vec4) && !SM_IS_A(sm_out, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_FOUR_FORMAT_LIT,
rb_obj_classname(sm_out));
return Qnil;
}
vec4_t *output = sm_unwrap_vec4(sm_out, NULL);
vec4_negate (*self, *output);
}} else if (argc == 0) {
SM_LABEL(skip_output): {
vec4_t output;
vec4_negate (*self, output);
sm_out = sm_wrap_vec4(output, rb_obj_class(sm_self));
rb_obj_call_init(sm_out, 0, 0);
}} else {
rb_raise(rb_eArgError, "Invalid number of arguments to negate");
}
return sm_out;
}
|
#negate! ⇒ Object
Calls #negate(self)
call-seq: negate! -> self
109 110 111 |
# File 'lib/snow-math/quat.rb', line 109 def negate! negate self end |
#normalize(*args) ⇒ Object
Returns a normalized Vec4 or Quat, depending on the type of the receiver and output.
call-seq:
normalize(output = nil) -> output or new vec4 / quat
2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 |
# File 'ext/snow-math/snow-math.c', line 2024
static VALUE sm_vec4_normalize(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_out;
vec4_t *self;
rb_scan_args(argc, argv, "01", &sm_out);
self = sm_unwrap_vec4(sm_self, NULL);
if (argc == 1) {
if (!RTEST(sm_out)) {
goto SM_LABEL(skip_output);
}{
if (!SM_IS_A(sm_out, vec4) && !SM_IS_A(sm_out, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_FOUR_FORMAT_LIT,
rb_obj_classname(sm_out));
}
vec4_t *output = sm_unwrap_vec4(sm_out, NULL);
vec4_normalize (*self, *output);
}} else if (argc == 0) {
SM_LABEL(skip_output): {
vec4_t output;
vec4_normalize (*self, output);
sm_out = sm_wrap_vec4(output, rb_obj_class(sm_self));
rb_obj_call_init(sm_out, 0, 0);
}} else {
rb_raise(rb_eArgError, "Invalid number of arguments to normalize");
}
return sm_out;
}
|
#normalize! ⇒ Object
Calls #normalize(self)
call-seq: normalize! -> self
95 96 97 |
# File 'lib/snow-math/quat.rb', line 95 def normalize! normalize self end |
#scale(*args) ⇒ Object
Scales this vector or quaternion’s components by a scalar value and returns the result. The return type is that of the receiver.
call-seq:
scale(scalar, output = nil) -> output or new vec4
2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 |
# File 'ext/snow-math/snow-math.c', line 2544
static VALUE sm_vec4_scale(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_out;
VALUE sm_scalar;
s_float_t scalar;
vec4_t *self = sm_unwrap_vec4(sm_self, NULL);
rb_scan_args(argc, argv, "11", &sm_scalar, &sm_out);
scalar = rb_num2dbl(sm_scalar);
if ((SM_IS_A(sm_out, vec4) || SM_IS_A(sm_out, quat))) {
vec4_scale(*self, scalar, *sm_unwrap_vec4(sm_out, NULL));
} else {
vec4_t out;
vec4_scale(*self, scalar, out);
sm_out = sm_wrap_vec4(out, rb_obj_class(sm_self));
rb_obj_call_init(sm_out, 0, 0);
}
return sm_out;
}
|
#scale!(rhs) ⇒ Object
Calls #scale(rhs, self)
call-seq: scale!(rhs) -> self
173 174 175 |
# File 'lib/snow-math/quat.rb', line 173 def scale!(rhs) scale rhs, self end |
#set(*args) ⇒ Object
Sets the Quat’s components.
call-seq:
set(x, y, z, w = 1) -> new quaternion with components [x, y, z, w]
set([x, y, z, w]) -> new quaternion with components [x, y, z, w]
set(quat) -> copy of quat
set(vec3) -> new quaternion with the components [vec3.xyz, 1]
set(vec4) -> new quaternion with the components of vec4
set(mat3) -> new quaternion from mat3
set(mat4) -> new quaternion from mat4
2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 |
# File 'ext/snow-math/snow-math.c', line 2883
static VALUE sm_quat_init(int argc, VALUE *argv, VALUE sm_self)
{
quat_t *self = sm_unwrap_quat(sm_self, NULL);
size_t arr_index = 0;
switch(argc) {
// Default value
case 0: { break; }
// Copy or by-array
case 1: {
if (SM_IS_A(argv[0], vec3)) {
sm_unwrap_vec3(argv[0], *self);
break;
}
if (SM_IS_A(argv[0], quat) ||
SM_IS_A(argv[0], vec4)) {
sm_unwrap_quat(argv[0], *self);
break;
}
if (SM_IS_A(argv[0], mat4)) {
const mat4_t *mat = sm_unwrap_mat4(argv[0], NULL);
quat_from_mat4(*mat, *self);
break;
}
if (SM_IS_A(argv[0], mat3)) {
const mat3_t *mat = sm_unwrap_mat3(argv[0], NULL);
quat_from_mat3(*mat, *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 + 3;
s_float_t *vec_elem = *self;
for (; arr_index < arr_end; ++arr_index, ++vec_elem) {
*vec_elem = (s_float_t)rb_num2dbl(rb_ary_entry(arrdata, (long)arr_index));
}
break;
}
rb_raise(rb_eArgError, "Expected either an array of Numerics or a Quat");
break;
}
// W
case 4: {
self[0][3] = (s_float_t)rb_num2dbl(argv[3]);
case 3: // X, Y, Z
self[0][0] = (s_float_t)rb_num2dbl(argv[0]);
self[0][1] = (s_float_t)rb_num2dbl(argv[1]);
self[0][2] = (s_float_t)rb_num2dbl(argv[2]);
break;
}
default: {
rb_raise(rb_eArgError, "Invalid arguments to Quat.initialize");
break;
}
} // switch (argc)
return sm_self;
}
|
#size ⇒ Object
Returns the length in bytes of the Quat. When compiled to use doubles as the base type, this is always 32. Otherwise, when compiled to use floats, it’s always 16.
call-seq: size -> fixnum
2697 2698 2699 2700 |
# File 'ext/snow-math/snow-math.c', line 2697
static VALUE sm_quat_size (VALUE self)
{
return SIZET2NUM(sizeof(quat_t));
}
|
#slerp(*args) ⇒ Object
Returns a quaternion interpolated between self and destination using spherical linear interpolation. Alpha is the interpolation value and must be clamped from 0 to 1.
call-seq:
slerp(destination, alpha, output = nil) -> output or new quat
3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 |
# File 'ext/snow-math/snow-math.c', line 3044
static VALUE sm_quat_slerp(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_out;
VALUE sm_destination;
VALUE sm_alpha;
quat_t *destination;
quat_t *self = sm_unwrap_vec4(sm_self, NULL);
s_float_t alpha;
rb_scan_args(argc, argv, "21", &sm_destination, &sm_alpha, &sm_out);
alpha = rb_num2dbl(sm_alpha);
if (!SM_IS_A(sm_destination, vec4) && !SM_IS_A(sm_destination, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_FOUR_FORMAT_LIT,
rb_obj_classname(sm_destination));
return Qnil;
}
destination = sm_unwrap_quat(sm_destination, NULL);
if ((SM_IS_A(sm_out, vec4) || SM_IS_A(sm_out, quat))) {
quat_slerp(*self, *destination, alpha, *sm_unwrap_quat(sm_out, NULL));
} else {
quat_t out;
quat_slerp(*self, *destination, alpha, out);
sm_out = sm_wrap_quat(out, rb_obj_class(sm_self));
rb_obj_call_init(sm_out, 0, 0);
}
return sm_out;
}
|
#slerp!(destination, alpha) ⇒ Object
Calls #slerp(destination, alpha, self)
call-seq: slerp!(destination, alpha) -> self
187 188 189 |
# File 'lib/snow-math/quat.rb', line 187 def slerp!(destination, alpha) slerp(destination, alpha, self) end |
#store ⇒ Object Also known as: []=
Sets the Quat’s component at the index to the value.
call-seq: store(index, value) -> value
2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 |
# File 'ext/snow-math/snow-math.c', line 2675
static VALUE sm_quat_store (VALUE sm_self, VALUE sm_index, VALUE sm_value)
{
static const int max_index = sizeof(quat_t) / sizeof(s_float_t);
quat_t *self = sm_unwrap_quat(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);
}
self[0][index] = (s_float_t)rb_num2dbl(sm_value);
return sm_value;
}
|
#subtract(*args) ⇒ Object Also known as: -
Subtracts another vector or quaternion’s components from this vector’s and returns the result. The return type is that of the receiver.
call-seq:
subtract(vec4, output = nil) -> output or new vec4
2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 |
# File 'ext/snow-math/snow-math.c', line 2329
static VALUE sm_vec4_subtract(int argc, VALUE *argv, VALUE sm_self)
{
VALUE sm_rhs;
VALUE sm_out;
vec4_t *self;
vec4_t *rhs;
rb_scan_args(argc, argv, "11", &sm_rhs, &sm_out);
self = sm_unwrap_vec4(sm_self, NULL);
if (!SM_IS_A(sm_rhs, vec4) && !SM_IS_A(sm_rhs, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_FOUR_FORMAT_LIT,
rb_obj_classname(sm_rhs));
return Qnil;
}
rhs = sm_unwrap_vec4(sm_rhs, NULL);
if (argc == 2) {
if (!RTEST(sm_out)) {
goto SM_LABEL(skip_output);
}{
if (!SM_IS_A(sm_rhs, vec4) && !SM_IS_A(sm_rhs, quat)) {
rb_raise(rb_eTypeError,
kSM_WANT_FOUR_FORMAT_LIT,
rb_obj_classname(sm_rhs));
return Qnil;
}
vec4_t *output = sm_unwrap_vec4(sm_out, NULL);
vec4_subtract(*self, *rhs, *output);
}} else if (argc == 1) {
SM_LABEL(skip_output): {
vec4_t output;
vec4_subtract(*self, *rhs, output);
sm_out = sm_wrap_vec4(output, rb_obj_class(sm_self));
rb_obj_call_init(sm_out, 0, 0);
}} else {
rb_raise(rb_eArgError, "Invalid number of arguments to vec4");
}
return sm_out;
}
|
#subtract!(rhs) ⇒ Object
Calls #subtract(rhs, self)
call-seq: subtract!(rhs) -> self
166 167 168 |
# File 'lib/snow-math/quat.rb', line 166 def subtract!(rhs) subtract rhs, self end |
#to_s ⇒ Object
Returns a string representation of self.
Quat[].to_s # => "{ 0.0, 0.0, 0.0, 1.0 }"
call-seq:
to_s -> string
2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 |
# File 'ext/snow-math/snow-math.c', line 2968
static VALUE sm_quat_to_s(VALUE self)
{
const s_float_t *v;
v = (const s_float_t *)*sm_unwrap_quat(self, NULL);
return rb_sprintf(
"{ "
"%f, %f, %f, %f"
" }",
v[0], v[1], v[2], v[3]);
}
|
#w ⇒ Object
Returns the W component of the quaternion.
call-seq: w -> float
81 82 83 |
# File 'lib/snow-math/quat.rb', line 81 def w self[3] end |
#w=(value) ⇒ Object
Sets the W component of the quaternion.
call-seq: w = value -> value
88 89 90 |
# File 'lib/snow-math/quat.rb', line 88 def w=(value) self[3] = value end |
#x ⇒ Object
Returns the X component of the quaternion.
call-seq: x -> float
39 40 41 |
# File 'lib/snow-math/quat.rb', line 39 def x self[0] end |
#x=(value) ⇒ Object
Sets the X component of the quaternion.
call-seq: x = value -> value
46 47 48 |
# File 'lib/snow-math/quat.rb', line 46 def x=(value) self[0] = value end |
#y ⇒ Object
Returns the Y component of the quaternion.
call-seq: y -> float
53 54 55 |
# File 'lib/snow-math/quat.rb', line 53 def y self[1] end |
#y=(value) ⇒ Object
Sets the Y component of the quaternion.
call-seq: y = value -> value
60 61 62 |
# File 'lib/snow-math/quat.rb', line 60 def y=(value) self[1] = value end |
#z ⇒ Object
Returns the Z component of the quaternion.
call-seq: z -> float
67 68 69 |
# File 'lib/snow-math/quat.rb', line 67 def z self[2] end |
#z=(value) ⇒ Object
Sets the Z component of the quaternion.
call-seq: z = value -> value
74 75 76 |
# File 'lib/snow-math/quat.rb', line 74 def z=(value) self[2] = value end |