Class: CGLM::Mat3

Inherits:
MatrixType show all
Defined in:
lib/cglm/mat3.rb,
ext/cglm/rb_cglm.c

Instance Attribute Summary

Attributes inherited from Base

#addr

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#copy_to, #dup, #initialize, #initialize_dup

Constructor Details

This class inherits a constructor from CGLM::Base

Class Method Details

.alignmentObject



177
# File 'ext/cglm/rb_cglm_mat3.c', line 177

VALUE rb_cglm_mat3_alignment_bytes(VALUE klass) { return SIZET2NUM(MAT3_ALIGNMENT); }

.identity([dest]) ⇒ dest | new Mat3

Sets dest to the identity if provided. If omitted, a new Mat4 is created and set to the identity. dest or the new Mat3 is returned.

Returns:



8
9
10
11
12
13
14
# File 'ext/cglm/rb_cglm_mat3.c', line 8

VALUE rb_cglm_mat3_new_identity(int argc, VALUE *argv, VALUE self) {
  VALUE dest;
  rb_scan_args(argc, argv, "01", &dest);
  if (NIL_P(dest)) dest = MAT3_NEW(ALLOC_MAT3);
  glm_mat3_identity(VAL2MAT3(dest));
  return dest;
}

.random([dest]) ⇒ dest | new Mat3

Fills dest or a new Mat3 with a random rotation about a random axis with a random angle, and returns it.

Returns:



213
214
215
216
217
218
219
220
221
222
223
# File 'ext/cglm/rb_cglm_mat3.c', line 213

VALUE rb_cglm_mat3_new_random(int argc, VALUE *argv, VALUE self) {
  VALUE dest;
  rb_scan_args(argc, argv, "01", &dest);
  if (NIL_P(dest)) dest = MAT3_NEW(ALLOC_MAT3);

  mat4 m4;
  glm_rotate_make(m4, drand48(), (vec3){drand48(), drand48(), drand48()});
  glm_mat4_pick3(m4, VAL2MAT3(dest));

  return dest;
}

.random([dest]) ⇒ dest | new Mat3

Fills dest or a new Mat3 with a random rotation about a random axis with a random angle, and returns it.

Returns:



213
214
215
216
217
218
219
220
221
222
223
# File 'ext/cglm/rb_cglm_mat3.c', line 213

VALUE rb_cglm_mat3_new_random(int argc, VALUE *argv, VALUE self) {
  VALUE dest;
  rb_scan_args(argc, argv, "01", &dest);
  if (NIL_P(dest)) dest = MAT3_NEW(ALLOC_MAT3);

  mat4 m4;
  glm_rotate_make(m4, drand48(), (vec3){drand48(), drand48(), drand48()});
  glm_mat4_pick3(m4, VAL2MAT3(dest));

  return dest;
}

.sizeObject



175
# File 'ext/cglm/rb_cglm_mat3.c', line 175

VALUE rb_cglm_mat3_size_bytes(VALUE klass) { return SIZET2NUM(mat3_size()); }

Instance Method Details

#*(other) ⇒ Object

Performs multiplication with other and returns the result.

  • other is a Mat3 or Vec3.


6
7
8
9
10
11
12
13
# File 'lib/cglm/mat3.rb', line 6

def *(other)
  case other
  when Mat3    then mul_mat3(other)
  when Vec3    then mul_vec3(other)
  when Numeric then mul_scalar(other)
  else raise ArgumentError, "Don't know how to multiply Mat3 with object: #{other.inspect}"
  end
end

#==(other) ⇒ Object



179
180
181
182
# File 'ext/cglm/rb_cglm_mat3.c', line 179

VALUE rb_cglm_mat3_equal(VALUE self, VALUE other) {
  if (memcmp(&VAL2MAT3(self), &VAL2MAT3(other), sizeof(mat3))) return Qfalse;
  return Qtrue;
}

#[](index) ⇒ Object



143
144
145
146
147
# File 'ext/cglm/rb_cglm_mat3.c', line 143

VALUE rb_cglm_mat3_aref(VALUE self, VALUE index) {
  CHECK_RANGE(index, 0, 2);
  float *addr = (float *) VAL2MAT3(self);
  return VEC3_NEW(addr + (NUM2INT(index) * 3));
}

#[]=(index, val) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'ext/cglm/rb_cglm_mat3.c', line 149

VALUE rb_cglm_mat3_aset(VALUE self, VALUE index, VALUE val) {
  CHECK_RANGE(index, 0, 2);
  if (rb_funcall(val, rb_intern("kind_of?"), 1, rb_cVec4))
    memcpy(&(VAL2MAT4(self)[NUM2INT(index)]), &VAL2VEC4(val), sizeof(vec3));
  else if (rb_funcall(val, rb_intern("kind_of?"), 1, rb_cVec3))
    memcpy(&(VAL2MAT4(self)[NUM2INT(index)]), &VAL2VEC3(val), sizeof(vec3));
  else {
    VALUE row = rb_cglm_mat3_aref(self, index);
    for (int i = 0; i < 3; i++) {
      VALUE v = rb_funcall(val, rb_intern("[]"), 1, INT2NUM(i));
      if (!NIL_P(v)) {
        rb_funcall(row, rb_intern("[]="), 2, INT2NUM(i), v);
      }
    }
  }
  return self;
}

#determinantObject Also known as: det



98
99
100
# File 'ext/cglm/rb_cglm_mat3.c', line 98

VALUE rb_cglm_mat3_determinant(VALUE self) {
  return glm_mat3_det(VAL2MAT3(self));
}

#=~(b) ⇒ Object Also known as: =~

Returns true if each member of a is very close to, but not necessarily exactly equal to, each corresponding member of b. This is useful in many circumstances because imprecision introduced by floating point calculations can lead to two expressions which are otherwise mathematically equivalent returning false.



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'ext/cglm/rb_cglm_mat3.c', line 192

VALUE rb_cglm_mat3_equalish(int argc, VALUE *argv, VALUE self) {
  VALUE other, epsilon;
  float feps = FLT_EPSILON;
  rb_scan_args(argc, argv, "11", &other, &epsilon);
  if (!NIL_P(epsilon)) feps = NUM2FLT(epsilon);
  mat3 *a = &VAL2MAT3(self);
  mat3 *b = &VAL2MAT3(other);
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
      if (fabsf((*a)[i][j] - (*b)[i][j]) > feps)
        return Qfalse;
    }
  }
  return Qtrue;
}

#inspectObject



19
20
21
22
23
24
25
# File 'lib/cglm/mat3.rb', line 19

def inspect
  vals = to_a
  longest_val_size = vals.flatten.reduce(0) { |a, v| a < v.to_s.size ? v.to_s.size : a }
  vals.map! { |row| row.map { |val| val.to_s.rjust(longest_val_size) }.join(', ') }
  left = "#<#{self.class}@#{addr.to_i.to_s(16)} ["
  left + vals.join(",\n" + (" " * left.size)) + "]>"
end

#inverse([dest]) ⇒ dest | new Mat3

Places the inverse of self into dest, creating a new Mat3 if dest is omitted. Returns dest.

Returns:



107
108
109
110
111
112
113
# File 'ext/cglm/rb_cglm_mat3.c', line 107

VALUE rb_cglm_mat3_inverse(int argc, VALUE *argv, VALUE self) {
  VALUE dest;
  rb_scan_args(argc, argv, "01", &dest);
  if (NIL_P(dest)) dest = MAT3_NEW(ALLOC_MAT3);
  glm_mat3_inv(VAL2MAT3(self), VAL2MAT3(dest));
  return dest;
}

#invert!self

Calcaultes the inverse of self, modifies self in-place, and returns self.

Returns:

  • (self)


120
121
122
123
# File 'ext/cglm/rb_cglm_mat3.c', line 120

VALUE rb_cglm_mat3_inverse_self(VALUE self) {
  glm_mat3_inv(VAL2MAT3(self), VAL2MAT3(self));
  return self;
}

#mul_mat3(other[, dest]) ⇒ dest | new Mat3

Multiplies this Mat3 with other, returning the result.

Returns:



20
21
22
23
24
25
26
# File 'ext/cglm/rb_cglm_mat3.c', line 20

VALUE rb_cglm_mat3_mul_mat3(int argc, VALUE *argv, VALUE self) {
  VALUE other, dest;
  rb_scan_args(argc, argv, "11", &other, &dest);
  if (NIL_P(dest)) dest = MAT3_NEW(ALLOC_MAT3);
  glm_mat3_mul(VAL2MAT3(self), VAL2MAT3(other), VAL2MAT3(dest));
  return dest;
}

#mul_scalar(scalar[, dest]) ⇒ dest | new Mat3

Multiplies each element in this matrix by the specified scalar amount. Places the result in dest and returns it, creating a new Mat3 if dest is omitted.

Returns:



80
81
82
83
84
85
86
# File 'ext/cglm/rb_cglm_mat3.c', line 80

VALUE rb_cglm_mat3_mul_scalar(int argc, VALUE *argv, VALUE self) {
  VALUE scalar, dest;
  rb_scan_args(argc, argv, "11", &scalar, &dest);
  if (NIL_P(dest)) dest = MAT3_NEW(ALLOC_MAT3);
  glm_mat3_scale(VAL2MAT3(dest), NUM2FLT(scalar));
  return dest;
}

#mul_scalar!(scalar) ⇒ self

Multiplies each element in this matrix by the specified scalar amount, modifying self in-place and returning it.

Returns:

  • (self)


93
94
95
96
# File 'ext/cglm/rb_cglm_mat3.c', line 93

VALUE rb_cglm_mat3_mul_scalar_self(VALUE self, VALUE scalar) {
  glm_mat3_scale(VAL2MAT3(self), NUM2FLT(scalar));
  return self;
}

#mul_vec3(other[, dest]) ⇒ dest | new Vec3

Multiplies this Vec3 with other, returning the result.

Returns:



32
33
34
35
36
37
38
# File 'ext/cglm/rb_cglm_mat3.c', line 32

VALUE rb_cglm_mat3_mul_vec3(int argc, VALUE *argv, VALUE self) {
  VALUE other, dest;
  rb_scan_args(argc, argv, "11", &other, &dest);
  if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
  glm_mat3_mulv(VAL2MAT3(self), VAL2VEC3(other), VAL2VEC3(dest));
  return dest;
}

#swap_col!(col1, col2) ⇒ self

Swaps two matrix columns and returns self.

Returns:

  • (self)


129
130
131
132
# File 'ext/cglm/rb_cglm_mat3.c', line 129

VALUE rb_cglm_mat3_swap_col_self(VALUE self, VALUE col1, VALUE col2) {
  glm_mat3_swap_col(VAL2MAT3(self), NUM2INT(col1), NUM2INT(col2));
  return self;
}

#swap_row!(row1, row2) ⇒ self

Swaps two matrix rows and returns self.

Returns:

  • (self)


138
139
140
141
# File 'ext/cglm/rb_cglm_mat3.c', line 138

VALUE rb_cglm_mat3_swap_row_self(VALUE self, VALUE row1, VALUE row2) {
  glm_mat3_swap_row(VAL2MAT3(self), NUM2INT(row1), NUM2INT(row2));
  return self;
}

#to_aObject



15
16
17
# File 'lib/cglm/mat3.rb', line 15

def to_a
  3.times.map { |i| self[i].to_a }
end

#to_flat_aObject

Returns a flat array of floats, rather than the 2D array returned by

to_a. Equivalent to to_a.flatten, but more efficient.



29
30
31
32
# File 'lib/cglm/mat3.rb', line 29

def to_flat_a
  addr = self.addr
  addr[0, addr.size].unpack("F*")
end

#to_mat4(*args) ⇒ Object



167
168
169
170
171
172
173
# File 'ext/cglm/rb_cglm_mat3.c', line 167

VALUE rb_cglm_mat3_to_mat4(int argc, VALUE *argv, VALUE self) {
  VALUE dest;
  if (argc == 0) dest = MAT4_NEW(ALLOC_MAT4);
  dest = argv[0];
  glm_mat4_ins3(VAL2MAT3(self), VAL2MAT4(dest));
  return dest;
}

#to_quat([dest]) ⇒ dest | new Quat

Converts self to a Quat. If dest is omitted, a new Quat is created.

Returns:



66
67
68
69
70
71
72
# File 'ext/cglm/rb_cglm_mat3.c', line 66

VALUE rb_cglm_mat3_to_quat(int argc, VALUE *argv, VALUE self) {
  VALUE dest;
  rb_scan_args(argc, argv, "01", &dest);
  if (NIL_P(dest)) dest = QUAT_NEW(ALLOC_QUAT);
  glm_mat3_quat(VAL2MAT3(self), VAL2QUAT(dest));
  return dest;
}

#transpose([dest]) ⇒ dest | new Mat3

Transposes this matrix and places it into dest. If dest is omitted, a new Mat3 will be allocated.

Returns:



45
46
47
48
49
50
51
# File 'ext/cglm/rb_cglm_mat3.c', line 45

VALUE rb_cglm_mat3_transpose(int argc, VALUE *argv, VALUE self) {
  VALUE dest;
  rb_scan_args(argc, argv, "01", &dest);
  if (NIL_P(dest)) dest = MAT3_NEW(ALLOC_MAT3);
  glm_mat3_transpose_to(VAL2MAT3(self), VAL2MAT3(dest));
  return dest;
}

#transpose!self

Transposes this matrix in-place and returns self.

Returns:

  • (self)


57
58
59
60
# File 'ext/cglm/rb_cglm_mat3.c', line 57

VALUE rb_cglm_mat3_transpose_self(VALUE self) {
  glm_mat3_transpose(VAL2MAT3(self));
  return self;
}