Class: CGLM::Mat4
- Inherits:
-
MatrixType
- Object
- Base
- MatrixType
- CGLM::Mat4
- Defined in:
- lib/cglm/mat4.rb,
ext/cglm/rb_cglm.c
Instance Attribute Summary
Attributes inherited from Base
Class Method Summary collapse
- .alignment ⇒ Object
- .axis_angle_rotate_at(pivot_point, axis, angle) ⇒ new Mat4
-
.frustum([dest], left: , right: , bottom: , top: , near: , far: ) ⇒ dest | new Mat4
Sets up a perspective projection matrix.
-
.identity([dest]) ⇒ dest | new Mat4
Sets
dest
to the identity if provided. -
.look(eye, direction[, up, dest]) ⇒ dest | new Mat4
Convenience wrapper for Mat4.look_at for if you only have direction and not the target position.
-
.look_at(eye, target_position, up[, dest]) ⇒ dest | new Mat4
Sets up a view matrix.
-
.ortho([dest], left: , right: , bottom: , top: , near: , far: ) ⇒ dest | new Mat4
Sets up an orthographic projection matrix.
-
.ortho_aabb(aabb[, dest], padding: 0, padding_z: 0) ⇒ dest | new Mat4
Sets up an orthographic projection matrix using the given bounding box.
-
.ortho_cube(aspect, size[, dest]) ⇒ dest | new Mat4
Sets up a new cubed orthographic projection matrix (it has the same size in all dimensions).
-
.ortho_unit(aspect[, dest]) ⇒ dest | new Mat4
Sets up a unit orthographic projection matrix.
-
.perspective([dest], fovy: PI/4, aspect: , near: 0.1, far: 100.0) ⇒ dest | new Mat4
Sets up a perspective projection matrix.
-
.quat_rotate_at(quat, pivot_point[, dest]) ⇒ dest | new Mat4
Creates a new transformation matrix using the quaternion at the pivot point.
-
.random([dest]) ⇒ dest | new Mat4
Fills
dest
or a new Mat4 with a random translation and rotation, and returns it. -
.random([dest]) ⇒ dest | new Mat4
Fills
dest
or a new Mat4 with a random translation and rotation, and returns it. - .rotate(axis, angle[, dest]) ⇒ dest | new Mat4
- .scale(vec3) ⇒ new Mat4
- .size ⇒ Object
- .translate(vec3) ⇒ new Mat4
Instance Method Summary collapse
-
#*(other) ⇒ Object
Performs multiplication with
other
and returns the result. - #==(other) ⇒ Object
- #[](index) ⇒ Object
- #[]=(index, val) ⇒ Object
-
#inv_tr ⇒ self
inverse orthonormal rotation + translation matrix (ridgid-body).
-
#affine_mul(m[, dest]) ⇒ dest | new Mat4
This is similar to #mul but specialized to affine transform.
-
#affine_mul_rot(m[, dest]) ⇒ dest | new Mat4
This is similar to #mul but specialized to affine transform.
- #aspect ⇒ Numeric
- #bottom ⇒ Numeric
-
#decompose(t, r, s) ⇒ self
Decomposes
self
into a translation Vec4t
, rotation Mat4r
and scale Vec3s
. -
#decompose_rs(r, s) ⇒ self
Decomposes
self
into a rotation Mat4r
and scale Vec3s
. - #decompose_scale(vec3) ⇒ Object
- #determinant ⇒ Numeric (also: #det)
-
#=~(b) ⇒ Object
(also: #=~)
Returns true if each member of
a
is very close to, but not necessarily exactly equal to, each corresponding member ofb
. - #far ⇒ Numeric
- #fovy ⇒ Numeric
-
#frustum ⇒ Hash
Decomposes this perspective matrix into a hash containing the 6 frustum values:
:near
,:far
,:top
,:bottom
,:left
, and:right
. -
#initialize(initial_values = nil, **args) ⇒ Mat4
constructor
A new instance of Mat4.
- #inspect ⇒ Object
-
#invert([dest]) ⇒ dest | new Mat4
Computes the inverse of this matrix and stores it in
dest
, creating a new Mat4 ifdest
is omitted. -
#invert! ⇒ self
Computes the inverse of this matrix in-place and returns
self
. -
#invert_fast([dest]) ⇒ dest | new Mat4
Computes the inverse of this matrix and stores it in
dest
, creating a new Mat4 ifdest
is omitted. -
#invert_fast!([dest]) ⇒ dest | new Mat4
Computes the inverse of this matrix in-place and returns
self
. - #left ⇒ Numeric
- #left_and_right ⇒ Array
- #mul_mat4(*args) ⇒ Object
-
#mul_scalar(scalar[, dest]) ⇒ dest | new Mat3
Multiplies each element in this matrix by the specified scalar amount.
-
#mul_scalar!(scalar) ⇒ self
Multiplies each element in this matrix by the specified scalar amount, modifying
self
in-place and returning it. - #mul_vec3(*args) ⇒ Object
- #mul_vec4(*args) ⇒ Object
- #near ⇒ Numeric
- #near_and_far ⇒ Array
-
#perspective_resize!(aspect) ⇒ self
Resizes this perspective matrix by the given aspect ratio (
width / height
). -
#project(pos, viewport[, dest]) ⇒ dest | new Vec3
Maps the given object-space coordinates into window coordinates using
self
as the projection matrix. - #right ⇒ Numeric
- #rotate!(axis, angle) ⇒ self
- #rotate_at!(pivot_point, axis, angle) ⇒ self
- #rotate_x(float[, dest]) ⇒ dest | new Mat4
- #rotate_y(float[, dest]) ⇒ dest | new Mat4
- #rotate_z(float[, dest]) ⇒ dest | new Mat4
- #scale(vec3|float[, dest]) ⇒ dest | new Mat4
- #scale!(vec3|float) ⇒ self
-
#sizes([fovy]) ⇒ Hash
Returns the sizes of the near and far planes of this perspective projection.
-
#swap_col!(col1, col2) ⇒ self
Swaps two matrix columns and returns
self
. -
#swap_row!(row1, row2) ⇒ self
Swaps two matrix rows and returns
self
. - #to_a ⇒ Object
- #to_mat3(*args) ⇒ Object
- #to_quat(*args) ⇒ Object
- #to_transposed_mat3(*args) ⇒ Object
- #top ⇒ Numeric
- #top_and_bottom ⇒ Array
- #translate!(vec3) ⇒ self
- #translate(vec3[, dest]) ⇒ dest | new Mat4
- #translate_x!(float) ⇒ self
- #translate_y!(float) ⇒ Object
- #translate_z!(float) ⇒ self
- #transpose(*args) ⇒ Object
- #transpose! ⇒ Object
- #uniform_scale? ⇒ Boolean
-
#unproject(pos, viewport[, dest]) ⇒ dest | new Vec3
Maps the specified position into the space represented by this matrix, places it in
dest
or a new Vec3 ifdest
is omitted, and returns it. -
#unproject_i(pos, viewport[, dest]) ⇒ dest | new Vec3
Maps the specified position into the space represented by this matrix, places it in
dest
or a new Vec3 ifdest
is omitted, and returns it.
Methods inherited from MatrixType
Methods inherited from Base
#copy_to, #dup, #initialize_dup
Constructor Details
#initialize(initial_values = nil, **args) ⇒ Mat4
Returns a new instance of Mat4.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/cglm/mat4.rb', line 3 def initialize(initial_values = nil, **args) super(**args) case initial_values when Mat3 initial_values.to_a.each_with_index { |row, i| self[i] = row } when Mat4 addr[0, self.class.size] = initial_values.addr[0, self.class.size] when Array initial_values.each_with_index do |row, i| self[i] = row end when nil else raise ArgumentError, 'initial values should be a Mat4, a Mat3 or an array of Array/Vec3/Vec4' end end |
Class Method Details
.alignment ⇒ Object
219 |
# File 'ext/cglm/rb_cglm_mat4.c', line 219 VALUE rb_cglm_mat4_alignment_bytes(VALUE klass) { return SIZET2NUM(MAT4_ALIGNMENT); } |
.axis_angle_rotate_at(pivot_point, axis, angle) ⇒ new Mat4
249 250 251 252 253 254 255 256 257 258 |
# File 'ext/cglm/rb_cglm_affine.c', line 249
VALUE rb_cglm_rotate_at_new(VALUE klass, VALUE pivot, VALUE axis, VALUE angle) {
VALUE self = MAT4_NEW(ALLOC_MAT4);
mat4 *m;
vec3 *v1, *v2;
m = &VAL2MAT4(self);
v1 = &VAL2VEC3(pivot);
v2 = &VAL2VEC3(axis);
glm_rotate_atm(*m, *v1, (float) NUM2DBL(angle), *v2);
return self;
}
|
.frustum([dest], left: , right: , bottom: , top: , near: , far: ) ⇒ dest | new Mat4
Sets up a perspective projection matrix. dest
is a Mat4. If it is
omitted, it is created.
left
is the viewport leftright
is the viewport rightbottom
is the viewport bottomtop
is the viewport topnear
is the near clipping planefar
is the far clipping planedest
is the result matrix
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 |
# File 'ext/cglm/rb_cglm_cam.c', line 317
VALUE rb_cglm_cam_frustum(int argc, VALUE *argv, VALUE klass) {
static ID kwargs_ids[6];
if (!kwargs_ids[0]) {
kwargs_ids[0] = rb_intern_const("left");
kwargs_ids[1] = rb_intern_const("right");
kwargs_ids[2] = rb_intern_const("bottom");
kwargs_ids[3] = rb_intern_const("top");
kwargs_ids[4] = rb_intern_const("near");
kwargs_ids[5] = rb_intern_const("far");
};
VALUE dest, kwargs[6], opts;
rb_scan_args(argc, argv, "01:", &dest, &opts);
rb_get_kwargs(opts, kwargs_ids, 6, 0, kwargs);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
glm_frustum(NUM2FLT(kwargs[0]),
NUM2FLT(kwargs[1]),
NUM2FLT(kwargs[2]),
NUM2FLT(kwargs[3]),
NUM2FLT(kwargs[4]),
NUM2FLT(kwargs[5]),
VAL2MAT4(dest));
return dest;
}
|
.identity([dest]) ⇒ dest | new Mat4
Sets dest
to the identity if provided. If omitted, a new Mat4 is created
and set to the identity. dest
or the new Mat4 is returned.
8 9 10 11 12 13 14 |
# File 'ext/cglm/rb_cglm_mat4.c', line 8
VALUE rb_cglm_mat4_new_identity(int argc, VALUE *argv, VALUE self) {
VALUE dest;
rb_scan_args(argc, argv, "01", &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
glm_mat4_identity(VAL2MAT4(dest));
return dest;
}
|
.look(eye, direction[, up, dest]) ⇒ dest | new Mat4
Convenience wrapper for look_at for if you only have direction and not the target position.
If up
is omitted (or nil), it is assumed that you don't care what it is,
and one will be computed for you.
Note: The up
vector must not be parallel to the line of sight from the
eye point to the reference point.
130 131 132 133 134 135 136 137 138 139 |
# File 'ext/cglm/rb_cglm_cam.c', line 130
VALUE rb_cglm_cam_look(int argc, VALUE *argv, VALUE self) {
VALUE dest, eye, dir, up;
rb_scan_args(argc, argv, "31", &eye, &dir, &up, &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
if (NIL_P(up))
glm_look_anyup(VAL2VEC3(eye), VAL2VEC3(dir), VAL2MAT4(dest));
else
glm_look(VAL2VEC3(eye), VAL2VEC3(dir), VAL2VEC3(up), VAL2MAT4(dest));
return dest;
}
|
.look_at(eye, target_position, up[, dest]) ⇒ dest | new Mat4
Sets up a view matrix.
NOTE: The up
vector must not be parallel to the line of sight from the
eye point to the reference point.
148 149 150 151 152 153 154 |
# File 'ext/cglm/rb_cglm_cam.c', line 148
VALUE rb_cglm_cam_look_at(int argc, VALUE *argv, VALUE self) {
VALUE dest, eye, center, up;
rb_scan_args(argc, argv, "31", &eye, ¢er, &up, &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
glm_lookat(VAL2VEC3(eye), VAL2VEC3(center), VAL2VEC3(up), VAL2MAT4(dest));
return dest;
}
|
.ortho([dest], left: , right: , bottom: , top: , near: , far: ) ⇒ dest | new Mat4
Sets up an orthographic projection matrix. dest
is a Mat4. If it is
omitted, it is created.
left
is the viewport leftright
is the viewport rightbottom
is the viewport bottomtop
is the viewport topnear
is the near clipping planefar
is the far clipping planedest
is the result matrix
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'ext/cglm/rb_cglm_cam.c', line 279
VALUE rb_cglm_cam_ortho(int argc, VALUE *argv, VALUE klass) {
static ID kwargs_ids[6];
if (!kwargs_ids[0]) {
kwargs_ids[0] = rb_intern_const("left");
kwargs_ids[1] = rb_intern_const("right");
kwargs_ids[2] = rb_intern_const("bottom");
kwargs_ids[3] = rb_intern_const("top");
kwargs_ids[4] = rb_intern_const("near");
kwargs_ids[5] = rb_intern_const("far");
};
VALUE dest, kwargs[6], opts;
rb_scan_args(argc, argv, "01:", &dest, &opts);
rb_get_kwargs(opts, kwargs_ids, 6, 0, kwargs);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
glm_ortho(NUM2FLT(kwargs[0]),
NUM2FLT(kwargs[1]),
NUM2FLT(kwargs[2]),
NUM2FLT(kwargs[3]),
NUM2FLT(kwargs[4]),
NUM2FLT(kwargs[5]),
VAL2MAT4(dest));
return dest;
}
|
.ortho_aabb(aabb[, dest], padding: 0, padding_z: 0) ⇒ dest | new Mat4
Sets up an orthographic projection matrix using the given bounding box.
If dest
is omitted, a new Mat4 will be allocated and returned. Otherwise,
the result will be placed into dest
and returned.
If padding
is present and padding_z
is omitted, then the entire projection
will have the same padding (including near/far values). If both are present,
the near/far values will use padding_z
while all other values will be
padded with padding
.
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'ext/cglm/rb_cglm_cam.c', line 231
VALUE rb_cglm_cam_ortho_aabb(int argc, VALUE *argv, VALUE self) {
VALUE boxv, dest, opts;
static ID kwargs_ids[2];
if (!kwargs_ids[0]) {
kwargs_ids[0] = rb_intern_const("padding");
kwargs_ids[1] = rb_intern_const("padding_z");
}
VALUE kwargs[2];
rb_scan_args(argc, argv, "11:", &boxv, &dest, &opts);
rb_get_kwargs(opts, kwargs_ids, 0, 2, kwargs);
aabb box = VAL2AABB(boxv);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
if (RB_TYPE_P(kwargs[0], T_UNDEF)) {
if (RB_TYPE_P(kwargs[1], T_UNDEF)) {
glm_ortho_aabb(box.corners, VAL2MAT4(dest));
} else {
glm_ortho_aabb_pz(box.corners, NUM2FLT(kwargs[1]), VAL2MAT4(dest));
}
}
else{
if (RB_TYPE_P(kwargs[1], T_UNDEF)) {
glm_ortho_aabb_p(box.corners, NUM2FLT(kwargs[0]), VAL2MAT4(dest));
} else {
float padding = NUM2FLT(kwargs[0]);
float paddingz = NUM2FLT(kwargs[1]);
glm_ortho(box.corners[0][0] - padding, box.corners[1][0] + padding,
box.corners[0][1] - padding, box.corners[1][1] + padding,
-(box.corners[1][2] + paddingz), -(box.corners[0][2] - paddingz),
VAL2MAT4(dest));
}
}
return dest;
}
|
.ortho_cube(aspect, size[, dest]) ⇒ dest | new Mat4
Sets up a new cubed orthographic projection matrix (it has the same size in all dimensions).
199 200 201 202 203 204 205 |
# File 'ext/cglm/rb_cglm_cam.c', line 199
VALUE rb_cglm_cam_ortho_cube(int argc, VALUE *argv, VALUE self) {
VALUE aspect, size, dest;
rb_scan_args(argc, argv, "21", &aspect, &size, &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
glm_ortho_default_s(NUM2FLT(aspect), NUM2FLT(size), VAL2MAT4(dest));
return dest;
}
|
.ortho_unit(aspect[, dest]) ⇒ dest | new Mat4
Sets up a unit orthographic projection matrix.
211 212 213 214 215 216 217 |
# File 'ext/cglm/rb_cglm_cam.c', line 211
VALUE rb_cglm_cam_ortho_unit(int argc, VALUE *argv, VALUE self) {
VALUE aspect, dest;
rb_scan_args(argc, argv, "11", &aspect, &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
glm_ortho_default(NUM2FLT(aspect), VAL2MAT4(dest));
return dest;
}
|
.perspective([dest], fovy: PI/4, aspect: , near: 0.1, far: 100.0) ⇒ dest | new Mat4
Sets up a perspective projection matrix.
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'ext/cglm/rb_cglm_cam.c', line 171
VALUE rb_cglm_cam_perspective(int argc, VALUE *argv, VALUE self) {
static ID kwargs_ids[4];
if (!kwargs_ids[0]) {
kwargs_ids[0] = rb_intern_const("aspect");
kwargs_ids[1] = rb_intern_const("fovy");
kwargs_ids[2] = rb_intern_const("near");
kwargs_ids[3] = rb_intern_const("far");
};
VALUE dest, kwargs[4], opts;
rb_scan_args(argc, argv, "01:", &dest, &opts);
rb_get_kwargs(opts, kwargs_ids, 1, 3, kwargs);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
if (RB_TYPE_P(kwargs[1], T_UNDEF)) kwargs[1] = DBL2NUM(GLM_PI_4f);
if (RB_TYPE_P(kwargs[2], T_UNDEF)) kwargs[2] = DBL2NUM(0.1);
if (RB_TYPE_P(kwargs[3], T_UNDEF)) kwargs[3] = DBL2NUM(100.0);
glm_perspective(NUM2FLT(kwargs[1]),
NUM2FLT(kwargs[0]),
NUM2FLT(kwargs[2]),
NUM2FLT(kwargs[3]),
VAL2MAT4(dest));
return dest;
}
|
.quat_rotate_at(quat, pivot_point[, dest]) ⇒ dest | new Mat4
Creates a new transformation matrix using the quaternion at the pivot
point. Places the result into dest
, or creates a new Mat4 if dest
is
omitted. Returns dest
.
22 23 24 25 26 27 28 |
# File 'ext/cglm/rb_cglm_mat4.c', line 22
VALUE rb_cglm_mat4_new_rotate_at(int argc, VALUE *argv, VALUE self) {
VALUE q, pivot, dest;
rb_scan_args(argc, argv, "21", &q, &pivot, &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
glm_quat_rotate_atm(VAL2MAT4(dest), VAL2QUAT(q), VAL2VEC3(pivot));
return dest;
}
|
.random([dest]) ⇒ dest | new Mat4
Fills dest
or a new Mat4 with a random translation and rotation, and
returns it.
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'ext/cglm/rb_cglm_mat4.c', line 255
VALUE rb_cglm_mat4_new_random(int argc, VALUE *argv, VALUE self) {
VALUE dest;
rb_scan_args(argc, argv, "01", &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
glm_mat4_copy(GLM_MAT4_IDENTITY, VAL2MAT4(dest));
/* random position */
VAL2MAT4(dest)[3][0] = drand48();
VAL2MAT4(dest)[3][1] = drand48();
VAL2MAT4(dest)[3][2] = drand48();
/* random rotatation around random axis with random angle */
glm_rotate(VAL2MAT4(dest), drand48(), (vec3){drand48(), drand48(), drand48()});
/* random scale */
/* glm_scale(dest, (vec3){drand48(), drand48(), drand48()}); */
return dest;
}
|
.random([dest]) ⇒ dest | new Mat4
Fills dest
or a new Mat4 with a random translation and rotation, and
returns it.
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'ext/cglm/rb_cglm_mat4.c', line 255
VALUE rb_cglm_mat4_new_random(int argc, VALUE *argv, VALUE self) {
VALUE dest;
rb_scan_args(argc, argv, "01", &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
glm_mat4_copy(GLM_MAT4_IDENTITY, VAL2MAT4(dest));
/* random position */
VAL2MAT4(dest)[3][0] = drand48();
VAL2MAT4(dest)[3][1] = drand48();
VAL2MAT4(dest)[3][2] = drand48();
/* random rotatation around random axis with random angle */
glm_rotate(VAL2MAT4(dest), drand48(), (vec3){drand48(), drand48(), drand48()});
/* random scale */
/* glm_scale(dest, (vec3){drand48(), drand48(), drand48()}); */
return dest;
}
|
.rotate(axis, angle[, dest]) ⇒ dest | new Mat4
153 154 155 156 157 158 159 |
# File 'ext/cglm/rb_cglm_affine.c', line 153
VALUE rb_cglm_rotate_new(int argc, VALUE *argv, VALUE klass) {
VALUE axis, angle, dest;
rb_scan_args(argc, argv, "21", &axis, &angle, &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
glm_rotate_make(VAL2MAT4(dest), (float) NUM2DBL(angle), VAL2VEC3(axis));
return dest;
}
|
.scale(vec3) ⇒ new Mat4
142 143 144 145 146 147 148 |
# File 'ext/cglm/rb_cglm_affine.c', line 142
VALUE rb_cglm_scale_new(int argc, VALUE *argv, VALUE klass) {
VALUE vec_v, dest;
rb_scan_args(argc, argv, "11", &vec_v, &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
glm_scale_make(VAL2MAT4(dest), VAL2VEC3(vec_v));
return dest;
}
|
.size ⇒ Object
217 |
# File 'ext/cglm/rb_cglm_mat4.c', line 217 VALUE rb_cglm_mat4_size_bytes(VALUE klass) { return SIZET2NUM(mat4_size()); } |
.translate(vec3) ⇒ new Mat4
133 134 135 136 137 138 139 |
# File 'ext/cglm/rb_cglm_affine.c', line 133
VALUE rb_cglm_translate_new(int argc, VALUE *argv, VALUE klass) {
VALUE vec_v, dest;
rb_scan_args(argc, argv, "11", &vec_v, &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
glm_translate_make(VAL2MAT4(dest), VAL2VEC3(vec_v));
return dest;
}
|
Instance Method Details
#*(other) ⇒ Object
Performs multiplication with other
and returns the result.
other
is a Mat3 or Vec3.
35 36 37 38 39 40 41 42 43 44 |
# File 'lib/cglm/mat4.rb', line 35 def *(other) case other when Mat4 then mul_mat4(other) when Mat3 then mul_mat3(other) when Vec3 then mul_vec3(other) when Vec4 then mul_vec4(other) when Numeric then mul_scalar(other) else raise ArgumentError, "Don't know how to multiply Mat4 with object: #{other.inspect}" end end |
#==(other) ⇒ Object
221 222 223 224 |
# File 'ext/cglm/rb_cglm_mat4.c', line 221
VALUE rb_cglm_mat4_equal(VALUE self, VALUE other) {
if (memcmp(&VAL2MAT4(self), &VAL2MAT4(other), sizeof(mat4))) return Qfalse;
return Qtrue;
}
|
#[](index) ⇒ Object
30 31 32 33 34 |
# File 'ext/cglm/rb_cglm_mat4.c', line 30
VALUE rb_cglm_mat4_aref(VALUE self, VALUE index) {
CHECK_RANGE(index, 0, 3);
float *addr = (float *) VAL2MAT4(self);
return VEC4_NEW(addr + (NUM2INT(index) * 4));
}
|
#[]=(index, val) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'ext/cglm/rb_cglm_mat4.c', line 36
VALUE rb_cglm_mat4_aset(VALUE self, VALUE index, VALUE val) {
CHECK_RANGE(index, 0, 3);
if (rb_funcall(val, rb_intern("kind_of?"), 1, rb_cVec4))
memcpy(&(VAL2MAT4(self)[NUM2INT(index)]), &VAL2VEC4(val), sizeof(vec4));
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_mat4_aref(self, index);
for (int i = 0; i < 4; 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;
}
|
#inv_tr ⇒ self
inverse orthonormal rotation + translation matrix (ridgid-body)
X = | R T | X' = | R' -R'T |
| 0 1 | | 0 1 |
45 46 47 48 49 50 |
# File 'ext/cglm/rb_cglm_affine.c', line 45
VALUE rb_cglm_affine_inv_tr(VALUE mat) {
mat4 *m = NULL;
m = &VAL2MAT4(mat);
glm_inv_tr(*m);
return mat;
}
|
#affine_mul(m[, dest]) ⇒ dest | new Mat4
This is similar to #mul but specialized to affine transform.
Right Matrix format should be:
R R R X
R R R Y
R R R Z
0 0 0 W
This reduces some multiplications. It should be faster than #mul. if you are not sure about matrix format then DON'T use this! use #mul.
m
is the second affine Mat4 to multiplyself
against.dest
is the out Mat4 to place the result in, and will be allocated if omitted.
72 73 74 75 76 77 78 79 80 81 82 |
# File 'ext/cglm/rb_cglm_affine.c', line 72
VALUE rb_cglm_affine_mul(int argc, VALUE *argv, VALUE self) {
VALUE m_v, dest_v;
rb_scan_args(argc, argv, "11", &m_v, &dest_v);
if (NIL_P(dest_v)) dest_v = MAT4_NEW(ALLOC_MAT4);
mat4 *m1 = NULL, *m2 = NULL, *dest = NULL;
m1 = &VAL2MAT4(self);
m2 = &VAL2MAT4(m_v);
dest = &VAL2MAT4(dest_v);
glm_mul(*m1, *m2, *dest);
return dest_v;
}
|
#affine_mul_rot(m[, dest]) ⇒ dest | new Mat4
This is similar to #mul but specialized to affine transform.
Right Matrix format should be:
R R R 0
R R R 0
R R R 0
0 0 0 1
This reduces some multiplications. It should be faster than #mul. if you are not sure about matrix format then DON'T use this! use #mul.
m
is the second affine Mat4 to multiplyself
against.dest
is the out Mat4 to place the result in, and will be allocated if omitted.
23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'ext/cglm/rb_cglm_affine.c', line 23
VALUE rb_cglm_affine_mul_rot(int argc, VALUE *argv, VALUE self) {
VALUE m_v, dest_v;
rb_scan_args(argc, argv, "11", &m_v, &dest_v);
if (NIL_P(dest_v)) dest_v = MAT4_NEW(ALLOC_MAT4);
mat4 *m1 = NULL, *m2 = NULL, *dest = NULL;
m1 = &VAL2MAT4(self);
m2 = &VAL2MAT4(m_v);
dest = &VAL2MAT4(dest_v);
glm_mul_rot(*m1, *m2, *dest);
return dest_v;
}
|
#aspect ⇒ Numeric
4 5 6 |
# File 'ext/cglm/rb_cglm_cam.c', line 4 VALUE rb_cglm_cam_decomp_aspect(VALUE self) { return DBL2NUM(glm_persp_aspect(VAL2MAT4(self))); } |
#bottom ⇒ Numeric
79 80 81 82 83 |
# File 'ext/cglm/rb_cglm_cam.c', line 79
VALUE rb_cglm_cam_decomp_bottom(VALUE self) {
float top, bottom;
glm_persp_decomp_y(VAL2MAT4(self), &top, &bottom);
return DBL2NUM(bottom);
}
|
#decompose(t, r, s) ⇒ self
Decomposes self
into a translation Vec4 t
, rotation Mat4 r
and scale
Vec3 s
.
296 297 298 299 300 301 302 303 304 305 306 |
# File 'ext/cglm/rb_cglm_affine.c', line 296
VALUE rb_cglm_decompose(VALUE self, VALUE trans, VALUE rot, VALUE scale) {
mat4 *m, *r;
vec3 *s;
vec4 *t;
m = &VAL2MAT4(self);
t = &VAL2VEC4(trans);
r = &VAL2MAT4(rot);
s = &VAL2VEC3(scale);
glm_decompose(*m, *t, *r, *s);
return self;
}
|
#decompose_rs(r, s) ⇒ self
Decomposes self
into a rotation Mat4 r
and scale Vec3 s
.
281 282 283 284 285 286 287 288 289 |
# File 'ext/cglm/rb_cglm_affine.c', line 281
VALUE rb_cglm_decompose_rs(VALUE self, VALUE rot, VALUE scale) {
mat4 *m, *r;
vec3 *s;
m = &VAL2MAT4(self);
r = &VAL2MAT4(rot);
s = &VAL2VEC3(scale);
glm_decompose_rs(*m, *r, *s);
return self;
}
|
#decompose_scale(vec3) ⇒ Object
261 262 263 264 265 266 267 268 |
# File 'ext/cglm/rb_cglm_affine.c', line 261
VALUE rb_cglm_decompose_scale(VALUE self, VALUE out) {
mat4 *m;
vec3 *v;
m = &VAL2MAT4(self);
v = &VAL2VEC3(self);
glm_decompose_scalev(*m, *v);
return out;
}
|
#determinant ⇒ Numeric Also known as: det
143 144 145 |
# File 'ext/cglm/rb_cglm_mat4.c', line 143 VALUE rb_cglm_mat4_determinant(VALUE self) { return DBL2NUM(glm_mat4_det(VAL2MAT4(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.
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'ext/cglm/rb_cglm_mat4.c', line 234
VALUE rb_cglm_mat4_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);
mat4 *a = &VAL2MAT4(self);
mat4 *b = &VAL2MAT4(other);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (fabsf((*a)[i][j] - (*b)[i][j]) > feps)
return Qfalse;
}
}
return Qtrue;
}
|
#far ⇒ Numeric
93 94 95 96 97 |
# File 'ext/cglm/rb_cglm_cam.c', line 93 VALUE rb_cglm_cam_decomp_far(VALUE self) { float f; glm_persp_decomp_far(VAL2MAT4(self), &f); return DBL2NUM(f); } |
#fovy ⇒ Numeric
9 10 11 |
# File 'ext/cglm/rb_cglm_cam.c', line 9 VALUE rb_cglm_cam_decomp_fovy(VALUE self) { return DBL2NUM(glm_persp_fovy(VAL2MAT4(self))); } |
#frustum ⇒ Hash
Decomposes this perspective matrix into a hash containing the 6 frustum
values: :near
, :far
, :top
, :bottom
, :left
, and :right
.
106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'ext/cglm/rb_cglm_cam.c', line 106
VALUE rb_cglm_cam_frustum_decomp(VALUE self) {
VALUE hash = rb_hash_new();
float left, top, right, bottom, n, f;
glm_persp_decomp(VAL2MAT4(self), &n, &f, &top, &bottom, &left, &right);
rb_hash_aset(hash, ID2SYM(rb_intern("near")), DBL2NUM(n));
rb_hash_aset(hash, ID2SYM(rb_intern("far")), DBL2NUM(f));
rb_hash_aset(hash, ID2SYM(rb_intern("left")), DBL2NUM(left));
rb_hash_aset(hash, ID2SYM(rb_intern("right")), DBL2NUM(right));
rb_hash_aset(hash, ID2SYM(rb_intern("bottom")), DBL2NUM(bottom));
rb_hash_aset(hash, ID2SYM(rb_intern("top")), DBL2NUM(top));
return hash;
}
|
#inspect ⇒ Object
24 25 26 27 28 29 30 |
# File 'lib/cglm/mat4.rb', line 24 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 |
#invert([dest]) ⇒ dest | new Mat4
Computes the inverse of this matrix and stores it in dest
, creating a
new Mat4 if dest
is omitted. Returns dest
.
152 153 154 155 156 157 158 |
# File 'ext/cglm/rb_cglm_mat4.c', line 152
VALUE rb_cglm_mat4_invert(int argc, VALUE *argv, VALUE self) {
VALUE dest;
rb_scan_args(argc, argv, "01", &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
glm_mat4_inv(VAL2MAT4(self), VAL2MAT4(dest));
return dest;
}
|
#invert! ⇒ self
Computes the inverse of this matrix in-place and returns self
.
164 165 166 167 |
# File 'ext/cglm/rb_cglm_mat4.c', line 164 VALUE rb_cglm_mat4_invert_self(VALUE self) { glm_mat4_inv(VAL2MAT4(self), VAL2MAT4(self)); return self; } |
#invert_fast([dest]) ⇒ dest | new Mat4
Computes the inverse of this matrix and stores it in dest
, creating a
new Mat4 if dest
is omitted. Returns dest
.
- NOTE: This method uses reciprocal approximation without extra corrections, e.g Newton-Raphson. This should work faster than normal, but will be less precise.
178 179 180 181 182 183 184 |
# File 'ext/cglm/rb_cglm_mat4.c', line 178
VALUE rb_cglm_mat4_invert_fast(int argc, VALUE *argv, VALUE self) {
VALUE dest;
rb_scan_args(argc, argv, "01", &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
glm_mat4_inv_fast(VAL2MAT4(self), VAL2MAT4(dest));
return dest;
}
|
#invert_fast!([dest]) ⇒ dest | new Mat4
Computes the inverse of this matrix in-place and returns self
.
- NOTE: This method uses reciprocal approximation without extra corrections, e.g Newton-Raphson. This should work faster than normal, but will be less precise.
194 195 196 197 |
# File 'ext/cglm/rb_cglm_mat4.c', line 194 VALUE rb_cglm_mat4_invert_fast_self(VALUE self) { glm_mat4_inv_fast(VAL2MAT4(self), VAL2MAT4(self)); return self; } |
#left ⇒ Numeric
58 59 60 61 62 |
# File 'ext/cglm/rb_cglm_cam.c', line 58
VALUE rb_cglm_cam_decomp_left(VALUE self) {
float left, right;
glm_persp_decomp_x(VAL2MAT4(self), &left, &right);
return DBL2NUM(left);
}
|
#left_and_right ⇒ Array
14 15 16 17 18 |
# File 'ext/cglm/rb_cglm_cam.c', line 14
VALUE rb_cglm_cam_decomp_left_and_right(VALUE self) {
float left, right;
glm_persp_decomp_x(VAL2MAT4(self), &left, &right);
return rb_ary_new_from_args(2, DBL2NUM(left), DBL2NUM(right));
}
|
#mul_mat4(*args) ⇒ Object
70 71 72 73 74 75 76 |
# File 'ext/cglm/rb_cglm_mat4.c', line 70
VALUE rb_cglm_mat4_mul_mat4(int argc, VALUE *argv, VALUE self) {
VALUE other, dest;
rb_scan_args(argc, argv, "11", &other, &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
glm_mat4_mul(VAL2MAT4(self), VAL2MAT4(other), VAL2MAT4(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 Mat4 if dest
is omitted.
122 123 124 125 126 127 128 129 |
# File 'ext/cglm/rb_cglm_mat4.c', line 122
VALUE rb_cglm_mat4_mul_scalar(int argc, VALUE *argv, VALUE self) {
VALUE scalar, dest;
rb_scan_args(argc, argv, "11", &scalar, &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
memcpy(&VAL2MAT4(self), &VAL2MAT4(dest), sizeof(mat4));
glm_mat4_scale(VAL2MAT4(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.
136 137 138 139 |
# File 'ext/cglm/rb_cglm_mat4.c', line 136
VALUE rb_cglm_mat4_mul_scalar_self(VALUE self, VALUE scalar) {
glm_mat4_scale(VAL2MAT4(self), NUM2FLT(scalar));
return self;
}
|
#mul_vec3(*args) ⇒ Object
86 87 88 89 90 91 92 93 |
# File 'ext/cglm/rb_cglm_mat4.c', line 86
VALUE rb_cglm_mat4_mul_vec3(int argc, VALUE *argv, VALUE self) {
VALUE other, last, dest;
rb_scan_args(argc, argv, "12", &other, &last, &dest);
if (NIL_P(last)) last = DBL2NUM(1.0);
if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
glm_mat4_mulv3(VAL2MAT4(self), VAL2VEC3(other), NUM2FLT(last), VAL2VEC3(dest));
return dest;
}
|
#mul_vec4(*args) ⇒ Object
78 79 80 81 82 83 84 |
# File 'ext/cglm/rb_cglm_mat4.c', line 78
VALUE rb_cglm_mat4_mul_vec4(int argc, VALUE *argv, VALUE self) {
VALUE other, dest;
rb_scan_args(argc, argv, "11", &other, &dest);
if (NIL_P(dest)) dest = VEC4_NEW(ALLOC_VEC4);
glm_mat4_mulv(VAL2MAT4(self), VAL2VEC4(other), VAL2VEC4(dest));
return dest;
}
|
#near ⇒ Numeric
86 87 88 89 90 |
# File 'ext/cglm/rb_cglm_cam.c', line 86 VALUE rb_cglm_cam_decomp_near(VALUE self) { float n; glm_persp_decomp_near(VAL2MAT4(self), &n); return DBL2NUM(n); } |
#near_and_far ⇒ Array
51 52 53 54 55 |
# File 'ext/cglm/rb_cglm_cam.c', line 51
VALUE rb_cglm_cam_decomp_near_and_far(VALUE self) {
float n, f;
glm_persp_decomp_z(VAL2MAT4(self), &n, &f);
return rb_ary_new_from_args(2, DBL2NUM(n), DBL2NUM(f));
}
|
#perspective_resize!(aspect) ⇒ self
Resizes this perspective matrix by the given aspect ratio (width / height
).
This makes it very easy to resize the projective matrix when the window or
viewport is changed.
162 163 164 165 |
# File 'ext/cglm/rb_cglm_cam.c', line 162
VALUE rb_cglm_cam_perspective_resize_self(VALUE self, VALUE aspect) {
glm_perspective_resize(NUM2FLT(aspect), VAL2MAT4(self));
return self;
}
|
#project(pos, viewport[, dest]) ⇒ dest | new Vec3
Maps the given object-space coordinates into window coordinates using
self
as the projection matrix.
pos
is a Vec3 specifying the object-space coordinates.viewport
is a Vec4 specifying the dimensions of the viewport in[x, y, width, height]
format.dest
is the Vec3 to place the results into, and will be created if omitted.
87 88 89 90 91 92 93 |
# File 'ext/cglm/rb_cglm_project.c', line 87
VALUE rb_cglm_project_project(int argc, VALUE *argv, VALUE self) {
VALUE pos, viewport, dest;
rb_scan_args(argc, argv, "21", &pos, &viewport, &dest);
if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
glm_project(VAL2VEC3(pos), VAL2MAT4(self), VAL2VEC4(viewport), VAL2VEC3(dest));
return dest;
}
|
#right ⇒ Numeric
65 66 67 68 69 |
# File 'ext/cglm/rb_cglm_cam.c', line 65
VALUE rb_cglm_cam_decomp_right(VALUE self) {
float left, right;
glm_persp_decomp_x(VAL2MAT4(self), &left, &right);
return DBL2NUM(right);
}
|
#rotate!(axis, angle) ⇒ self
228 229 230 231 232 233 234 235 |
# File 'ext/cglm/rb_cglm_affine.c', line 228
VALUE rb_cglm_rotate_self(VALUE self, VALUE axis, VALUE angle) {
mat4 *mat;
vec3 *vec;
mat = &VAL2MAT4(self);
vec = &VAL2VEC3(axis);
glm_rotate(*mat, (float) NUM2DBL(angle), *vec);
return self;
}
|
#rotate_at!(pivot_point, axis, angle) ⇒ self
238 239 240 241 242 243 244 245 246 |
# File 'ext/cglm/rb_cglm_affine.c', line 238
VALUE rb_cglm_rotate_self_at(VALUE self, VALUE pivot, VALUE axis, VALUE angle) {
mat4 *m;
vec3 *v1, *v2;
m = &VAL2MAT4(self);
v1 = &VAL2VEC3(pivot);
v2 = &VAL2VEC3(axis);
glm_rotate_at(*m, *v1, (float) NUM2DBL(angle), *v2);
return self;
}
|
#rotate_x(float[, dest]) ⇒ dest | new Mat4
192 193 194 195 196 197 198 199 200 201 |
# File 'ext/cglm/rb_cglm_affine.c', line 192
VALUE rb_cglm_rotate_x(int argc, VALUE *argv, VALUE self) {
VALUE angle, dest;
rb_scan_args(argc, argv, "11", &angle, &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
mat4 *m1, *m2;
m1 = &VAL2MAT4(self);
m2 = &VAL2MAT4(dest);
glm_rotate_x(*m1, (float) NUM2DBL(angle), *m2);
return dest;
}
|
#rotate_y(float[, dest]) ⇒ dest | new Mat4
204 205 206 207 208 209 210 211 212 213 |
# File 'ext/cglm/rb_cglm_affine.c', line 204
VALUE rb_cglm_rotate_y(int argc, VALUE *argv, VALUE self) {
VALUE angle, dest;
rb_scan_args(argc, argv, "11", &angle, &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
mat4 *m1, *m2;
m1 = &VAL2MAT4(self);
m2 = &VAL2MAT4(dest);
glm_rotate_y(*m1, (float) NUM2DBL(angle), *m2);
return dest;
}
|
#rotate_z(float[, dest]) ⇒ dest | new Mat4
216 217 218 219 220 221 222 223 224 225 |
# File 'ext/cglm/rb_cglm_affine.c', line 216
VALUE rb_cglm_rotate_z(int argc, VALUE *argv, VALUE self) {
VALUE angle, dest;
rb_scan_args(argc, argv, "11", &angle, &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
mat4 *m1, *m2;
m1 = &VAL2MAT4(self);
m2 = &VAL2MAT4(dest);
glm_rotate_z(*m1, (float) NUM2DBL(angle), *m2);
return dest;
}
|
#scale(vec3|float[, dest]) ⇒ dest | new Mat4
162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'ext/cglm/rb_cglm_affine.c', line 162
VALUE rb_cglm_scale(int argc, VALUE *argv, VALUE self) {
VALUE factor, dest;
rb_scan_args(argc, argv, "11", &factor, &dest);
if (NIL_P(dest)) dest = MAT4_NEW(ALLOC_MAT4);
if (RB_FLOAT_TYPE_P(factor) || RB_INTEGER_TYPE_P(factor)) {
memcpy(&VAL2MAT4(dest), &VAL2MAT4(self), sizeof(mat4));
glm_scale_uni(VAL2MAT4(dest), (float) NUM2DBL(factor));
} else {
glm_scale_to(VAL2MAT4(self), VAL2VEC3(factor), VAL2MAT4(dest));
}
return dest;
}
|
#scale!(vec3|float) ⇒ self
178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'ext/cglm/rb_cglm_affine.c', line 178
VALUE rb_cglm_scale_self(VALUE self, VALUE factor) {
mat4 *m1 = NULL;
m1 = &VAL2MAT4(self);
if (RB_FLOAT_TYPE_P(factor) || RB_INTEGER_TYPE_P(factor)) {
glm_scale_uni(*m1, (float) NUM2DBL(factor));
} else {
vec3 *vec = NULL;
vec = &VAL2VEC3(factor);
glm_scale(*m1, *vec);
}
return self;
}
|
#sizes([fovy]) ⇒ Hash
Returns the sizes of the near and far planes of this perspective projection. The return value has the following format:
{ near: [width, height], far: [width, height] }
If fovy
is omitted, it will be decomposed from the current matrix.
29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'ext/cglm/rb_cglm_cam.c', line 29
VALUE rb_cglm_cam_sizes(int argc, VALUE *argv, VALUE self) {
VALUE fovy = Qnil;
if (argc == 0) fovy = rb_cglm_cam_decomp_fovy(self);
else fovy = argv[0];
vec4 out;
glm_persp_sizes(VAL2MAT4(self), NUM2FLT(fovy), out);
VALUE n = rb_ary_new_from_args(2, DBL2NUM(out[0]), DBL2NUM(out[1]));
VALUE f = rb_ary_new_from_args(2, DBL2NUM(out[2]), DBL2NUM(out[3]));
VALUE dest = rb_hash_new();
rb_hash_aset(dest, ID2SYM(rb_intern("near")), n);
rb_hash_aset(dest, ID2SYM(rb_intern("far")), f);
return dest;
}
|
#swap_col!(col1, col2) ⇒ self
Swaps two matrix columns and returns self
.
203 204 205 206 |
# File 'ext/cglm/rb_cglm_mat4.c', line 203
VALUE rb_cglm_mat4_swap_col_self(VALUE self, VALUE col1, VALUE col2) {
glm_mat4_swap_col(VAL2MAT4(self), NUM2INT(col1), NUM2INT(col2));
return self;
}
|
#swap_row!(row1, row2) ⇒ self
Swaps two matrix rows and returns self
.
212 213 214 215 |
# File 'ext/cglm/rb_cglm_mat4.c', line 212
VALUE rb_cglm_mat4_swap_row_self(VALUE self, VALUE row1, VALUE row2) {
glm_mat4_swap_row(VAL2MAT4(self), NUM2INT(row1), NUM2INT(row2));
return self;
}
|
#to_a ⇒ Object
20 21 22 |
# File 'lib/cglm/mat4.rb', line 20 def to_a 4.times.map { |i| self[i].to_a } end |
#to_mat3(*args) ⇒ Object
54 55 56 57 58 59 60 |
# File 'ext/cglm/rb_cglm_mat4.c', line 54
VALUE rb_cglm_mat4_to_mat3(int argc, VALUE *argv, VALUE self) {
VALUE dest;
if (argc == 0) dest = MAT3_NEW(ALLOC_MAT3);
else dest = argv[0];
glm_mat4_pick3(VAL2MAT4(self), VAL2MAT3(dest));
return dest;
}
|
#to_quat(*args) ⇒ Object
95 96 97 98 99 100 101 |
# File 'ext/cglm/rb_cglm_mat4.c', line 95
VALUE rb_cglm_mat4_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_mat4_quat(VAL2MAT4(self), VAL2QUAT(dest));
return dest;
}
|
#to_transposed_mat3(*args) ⇒ Object
62 63 64 65 66 67 68 |
# File 'ext/cglm/rb_cglm_mat4.c', line 62
VALUE rb_cglm_mat4_to_transposed_mat3(int argc, VALUE *argv, VALUE self) {
VALUE dest;
if (argc == 0) dest = MAT3_NEW(ALLOC_MAT3);
dest = argv[0];
glm_mat4_pick3t(VAL2MAT4(self), VAL2MAT3(dest));
return dest;
}
|
#top ⇒ Numeric
72 73 74 75 76 |
# File 'ext/cglm/rb_cglm_cam.c', line 72
VALUE rb_cglm_cam_decomp_top(VALUE self) {
float top, bottom;
glm_persp_decomp_y(VAL2MAT4(self), &top, &bottom);
return DBL2NUM(top);
}
|
#top_and_bottom ⇒ Array
44 45 46 47 48 |
# File 'ext/cglm/rb_cglm_cam.c', line 44
VALUE rb_cglm_cam_decomp_top_and_bottom(VALUE self) {
float top, bottom;
glm_persp_decomp_y(VAL2MAT4(self), &top, &bottom);
return rb_ary_new_from_args(2, DBL2NUM(top), DBL2NUM(bottom));
}
|
#translate!(vec3) ⇒ self
99 100 101 102 103 104 105 106 |
# File 'ext/cglm/rb_cglm_affine.c', line 99
VALUE rb_cglm_translate_self(VALUE self, VALUE vec_v) {
mat4 *m1 = NULL;
vec3 *vec = NULL;
m1 = &VAL2MAT4(self);
vec = &VAL2VEC3(vec_v);
glm_translate(*m1, *vec);
return self;
}
|
#translate(vec3[, dest]) ⇒ dest | new Mat4
85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'ext/cglm/rb_cglm_affine.c', line 85
VALUE rb_cglm_translate(int argc, VALUE *argv, VALUE self) {
VALUE vec_v, dest_v;
rb_scan_args(argc, argv, "11", &vec_v, &dest_v);
if (NIL_P(dest_v)) dest_v = MAT4_NEW(ALLOC_MAT4);
mat4 *m1 = NULL, *dest = NULL;
vec3 *vec = NULL;
m1 = &VAL2MAT4(self);
vec = &VAL2VEC3(vec_v);
dest = &VAL2MAT4(dest_v);
glm_translate_to(*m1, *vec, *dest);
return dest_v;
}
|
#translate_x!(float) ⇒ self
109 110 111 112 113 114 |
# File 'ext/cglm/rb_cglm_affine.c', line 109
VALUE rb_cglm_translate_x_self(VALUE self, VALUE flt) {
mat4 *m1 = NULL;
m1 = &VAL2MAT4(self);
glm_translate_x(*m1, (float) NUM2DBL(flt));
return self;
}
|
#translate_y!(float) ⇒ Object
117 118 119 120 121 122 |
# File 'ext/cglm/rb_cglm_affine.c', line 117
VALUE rb_cglm_translate_y_self(VALUE self, VALUE flt) {
mat4 *m1 = NULL;
m1 = &VAL2MAT4(self);
glm_translate_y(*m1, (float) NUM2DBL(flt));
return self;
}
|
#translate_z!(float) ⇒ self
125 126 127 128 129 130 |
# File 'ext/cglm/rb_cglm_affine.c', line 125
VALUE rb_cglm_translate_z_self(VALUE self, VALUE flt) {
mat4 *m1 = NULL;
m1 = &VAL2MAT4(self);
glm_translate_z(*m1, (float) NUM2DBL(flt));
return self;
}
|
#transpose(*args) ⇒ Object
103 104 105 106 107 108 109 |
# File 'ext/cglm/rb_cglm_mat4.c', line 103
VALUE rb_cglm_mat4_transpose(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_mat4_transpose_to(VAL2MAT4(self), VAL2MAT4(dest));
return dest;
}
|
#transpose! ⇒ Object
111 112 113 114 |
# File 'ext/cglm/rb_cglm_mat4.c', line 111 VALUE rb_cglm_mat4_transpose_self(VALUE self) { glm_mat4_transpose(VAL2MAT4(self)); return self; } |
#uniform_scale? ⇒ Boolean
271 272 273 274 275 |
# File 'ext/cglm/rb_cglm_affine.c', line 271
VALUE rb_cglm_is_uniform_scale(VALUE self) {
mat4 *m;
m = &VAL2MAT4(self);
return glm_uniscaled(*m) ? Qtrue : Qfalse;
}
|
#unproject(pos, viewport[, dest]) ⇒ dest | new Vec3
Maps the specified position into the space represented by this matrix,
places it in dest
or a new Vec3 if dest
is omitted, and returns it.
NOTE: This method must calculate the inverse of the current matrix. If you already have the inverse handy, you should use #unproject_i for better performance.
If
self
is aprojection
matrix, then the result will be in view space.If
self
is aprojection * view
matrix, then the result will be in world space.If
self
is anprojection * view * model
matrix, then the result will be in object space.pos
is a Vec3 specifying the coordinates to unproject.viewport
is a Vec4 specifying the dimensions of the viewport in[x, y, width, height]
format.dest
is the Vec3 to place the results into, and will be created if omitted.
66 67 68 69 70 71 72 |
# File 'ext/cglm/rb_cglm_project.c', line 66
VALUE rb_cglm_project_unproject(int argc, VALUE *argv, VALUE self) {
VALUE pos, viewport, dest;
rb_scan_args(argc, argv, "21", &pos, &viewport, &dest);
if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
glm_unproject(VAL2VEC3(pos), VAL2MAT4(self), VAL2VEC4(viewport), VAL2VEC3(dest));
return dest;
}
|
#unproject_i(pos, viewport[, dest]) ⇒ dest | new Vec3
Maps the specified position into the space represented by this matrix,
places it in dest
or a new Vec3 if dest
is omitted, and returns it.
NOTE: This method assumes that
self
represents the inverse of a projection matrix. It's faster than calling #unproject assuming you already have an inverse matrix. If you don't have an inverse, you should just rely on #unproject (to save the overhead of the extra method call), but if you have or need the inverse for other computations, you can useunproject_i to save yourself the cost of the inversion.
If
self
is aninverse(projection)
matrix, then the result will be in view space.If
self
is aninverse(projection * view)
matrix, then the result will be in world space.If
self
is aninverse(projection * view * model)
matrix, then the result will be in object space.pos
is a Vec3 specifying the coordinates to unproject.viewport
is a Vec4 specifying the dimensions of the viewport in[x, y, width, height]
format.dest
is the Vec3 to place the results into, and will be created if omitted.
32 33 34 35 36 37 38 |
# File 'ext/cglm/rb_cglm_project.c', line 32
VALUE rb_cglm_project_unproject_i(int argc, VALUE *argv, VALUE self) {
VALUE pos, viewport, dest;
rb_scan_args(argc, argv, "21", &pos, &viewport, &dest);
if (NIL_P(dest)) dest = VEC3_NEW(ALLOC_VEC3);
glm_unprojecti(VAL2VEC3(pos), VAL2MAT4(self), VAL2VEC4(viewport), VAL2VEC3(dest));
return dest;
}
|