Class: CGLM::Frustum

Inherits:
Object
  • Object
show all
Defined in:
lib/cglm/frustum.rb,
ext/cglm/rb_cglm.c

Constant Summary collapse

LBN =

left bottom near

GLM_LBN
LTN =

left top near

GLM_LTN
RTN =

right top near

GLM_RTN
RBN =

right bottom near

GLM_RBN
LBF =

left bottom far

GLM_LBF
LTF =

left top far

GLM_LTF
RTF =

right top far

GLM_RTF
RBF =

right bottom far

GLM_RBF
LEFT =
GLM_LEFT
RIGHT =
GLM_RIGHT
BOTTOM =
GLM_BOTTOM
TOP =
GLM_TOP
NEAR =
GLM_NEAR
FAR =
GLM_FAR
CLIPSPACE_COORD_LBN =

left bottom near

VEC4_NEW(CSCOORD_LBN)
CLIPSPACE_COORD_LTN =

left top near

VEC4_NEW(CSCOORD_LTN)
CLIPSPACE_COORD_RTN =

right top near

VEC4_NEW(CSCOORD_RTN)
CLIPSPACE_COORD_RBN =

right bottom near

VEC4_NEW(CSCOORD_RBN)
CLIPSPACE_COORD_LBF =

left bottom far

VEC4_NEW(CSCOORD_LBF)
CLIPSPACE_COORD_LTF =

left top far

VEC4_NEW(CSCOORD_LTF)
CLIPSPACE_COORD_RTF =

right top far

VEC4_NEW(CSCOORD_RTF)
CLIPSPACE_COORD_RBF =

right bottom far

VEC4_NEW(CSCOORD_RBF)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(matrix = Mat4.identity) ⇒ Frustum

Returns a new instance of Frustum.



5
6
7
# File 'lib/cglm/frustum.rb', line 5

def initialize(matrix = Mat4.identity)
  @matrix = matrix
end

Instance Attribute Details

#matrixObject

Returns the value of attribute matrix.



3
4
5
# File 'lib/cglm/frustum.rb', line 3

def matrix
  @matrix
end

Class Method Details

.corners(inv_space[, dest]) ⇒ dest | new Hash

Extracts the view frustum corners using clip-space coordinates.

  • inv_space is the inverse of the Mat4 representing the space in which the 8 frustum corners are defined. If it's an (inverse(view * projection)) matrix, the result is in world space. If it's an (inverse(model * view * projection)) matrix, the result is in object space.

    • You probably want to extract planes in world space, so use (inverse(view * projection)) as inv_space.
  • dest is a Hash containing the following keys: :lbn, :ltn, :rtn, :rbn, :lbf, :ltf, :rtf, :rbf. Each value is a Vec4.

    • The dest hash, if created, is ordered such that you can index into the array of values with the Frustum class constants. For example, hash.values[Frustum::RTN].
    • If you know the index of a near coord, you can get its far coord by adding 4. For example, hash.values[Frustum::RTN + 4] == hash.values[Frustum::RTF].

Returns:

  • (dest | new Hash)


98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'ext/cglm/rb_cglm_frustum.c', line 98

VALUE rb_cglm_frustum_singleton_corners(int argc, VALUE *argv, VALUE self) {
  VALUE mat, dest;
  rb_scan_args(argc, argv, "11", &mat, &dest);
  if (NIL_P(dest)) dest = rb_hash_new();
  vec4 corners[8];
  glm_frustum_corners(VAL2MAT4(mat), corners);

  #define HASH_GET_OR_SET(index, name)                     \
    VALUE name = rb_hash_aref(dest, SYMBOL(#name));        \
    if (NIL_P(name)) {                                     \
      name = VEC4_NEW(ALLOC_VEC4);                     \
      rb_hash_aset(dest, SYMBOL(#name), name);             \
    }                                                      \
    memcpy(&VAL2VEC4(name), &corners[index], sizeof(vec4));

    HASH_GET_OR_SET(GLM_LBN, lbn);
    HASH_GET_OR_SET(GLM_LTN, ltn);
    HASH_GET_OR_SET(GLM_RTN, rtn);
    HASH_GET_OR_SET(GLM_RBN, rbn);
    HASH_GET_OR_SET(GLM_LBF, lbf);
    HASH_GET_OR_SET(GLM_LTF, ltf);
    HASH_GET_OR_SET(GLM_RTF, rtf);
    HASH_GET_OR_SET(GLM_RBF, rbf);
  #undef HASH_GET_OR_SET

  return dest;
}

.corners_at(corners, split, far[, dest]) ⇒ dest | new Hash

Finds the corners of a plane which lies between the near and far planes of the frustum.

This will be helpful if you want to split a frustum, e.g. CSM/PSSM.

  • corners are the 8 corners of the frustum and follow the same format as is returned by corners.

  • split is the distance at which to calculate the 4 corners.

  • far is the far distance of the frustum.

  • dest is a Hash containing :lb, :lt, :rt, and :rb (all of which are Vec4's). If omitted, one will be created.

Returns:

  • (dest | new Hash)


191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'ext/cglm/rb_cglm_frustum.c', line 191

VALUE rb_cglm_frustum_singleton_corners_at(int argc, VALUE *argv, VALUE self) {
  VALUE corners_v, split, f, dest;
  rb_scan_args(argc, argv, "31", &corners_v, &split, &f, &dest);
  if (NIL_P(dest)) dest = rb_hash_new();
  vec4 corners[8];
  hash_to_corners(corners, corners_v);
  vec4 plane_corners[4];
  glm_frustum_corners_at(corners, NUM2FLT(split), NUM2FLT(f), plane_corners);

  #define HASH_GET_OR_SET(index, name)                     \
    VALUE name = rb_hash_aref(dest, SYMBOL(#name));        \
    if (NIL_P(name)) {                                     \
      name = VEC4_NEW(ALLOC_VEC4);                     \
      rb_hash_aset(dest, SYMBOL(#name), name);             \
    }                                                      \
    memcpy(&VAL2VEC4(name), &plane_corners[index], sizeof(vec4));

    HASH_GET_OR_SET(0, lb);
    HASH_GET_OR_SET(1, lt);
    HASH_GET_OR_SET(2, rt);
    HASH_GET_OR_SET(3, rb);
  #undef HASH_GET_OR_SET

  return dest;
}

.planes(space[, dest]) ⇒ dest | new Hash

Extracts the 6 view frustum planes into an hash of 6 Vec4's. If dest is omitted, a new Hash is allocated.

  • space is the Mat4 representing the space in which the 6 frustum planes are defined. If it's a projection matrix, the result is in view space. If it's a (view * projection) matrix, the result is in world space. If it's a (model * view * projection) matrix, the result is in object space.

  • dest is a Hash containing the following keys: :left, :right, :bottom, :top, :near, :far. Each value is a Vec4.

You probably want to extract planes in world space, so use (view * projection) as space.

Returns:

  • (dest | new Hash)


47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'ext/cglm/rb_cglm_frustum.c', line 47

VALUE rb_cglm_frustum_singleton_planes(int argc, VALUE *argv, VALUE self) {
  VALUE mat, dest;
  rb_scan_args(argc, argv, "11", &mat, &dest);
  if (NIL_P(dest)) dest = rb_hash_new();
  vec4 planes[6];
  glm_frustum_planes(VAL2MAT4(mat), planes);

  #define HASH_GET_OR_SET(index, name, str)                     \
    VALUE name = rb_hash_aref(dest, SYMBOL(str));        \
    if (NIL_P(name)) {                                     \
      name = VEC4_NEW(ALLOC_VEC4);                     \
      rb_hash_aset(dest, SYMBOL(str), name);             \
    }                                                      \
    memcpy(&VAL2VEC4(name), &planes[index], sizeof(vec4));

    HASH_GET_OR_SET(GLM_LEFT,   left, "left");
    HASH_GET_OR_SET(GLM_RIGHT,  right, "right");
    HASH_GET_OR_SET(GLM_BOTTOM, bottom, "bottom");
    HASH_GET_OR_SET(GLM_TOP,    top, "top");
    HASH_GET_OR_SET(GLM_NEAR,   n, "near");
    HASH_GET_OR_SET(GLM_FAR,    f, "far");
  #undef HASH_GET_OR_SET

  return dest;
}

.aabb(matr, corners[, dest]) ⇒ Object

Finds a bounding box for the frustum defined by corners relative to the givn matrix (e.g. a view matrix). Places the result in dest and returns dest, or a new AABB if dest is omitted.



164
165
166
167
168
169
170
171
172
# File 'ext/cglm/rb_cglm_frustum.c', line 164

VALUE rb_cglm_frustum_singleton_aabb(int argc, VALUE *argv, VALUE self) {
  VALUE matr, corners_v, dest;
  rb_scan_args(argc, argv, "21", &matr, &corners_v, &dest);
  if (NIL_P(dest)) dest = rb_funcall(rb_cAABB, rb_intern("new"), 0);
  vec4 corners[8];
  hash_to_corners(corners, corners_v);
  glm_frustum_box(corners, VAL2MAT4(matr), VAL2AABB(dest).corners);
  return dest;
}

Instance Method Details

#to_aabb(matr[, dest]) ⇒ Object

Same as calling #aabb with #corners as the first argument.



254
255
256
257
258
259
# File 'ext/cglm/rb_cglm_frustum.c', line 254

VALUE rb_cglm_frustum_to_aabb(int argc, VALUE *argv, VALUE self) {
  VALUE corners = rb_funcall(self, rb_intern("corners"), 0);
  VALUE split, f, dest;
  rb_scan_args(argc, argv, "21", &split, &f, &dest);
  return rb_funcall(rb_cFrustum, rb_intern("aabb"), 4, corners, split, f, dest);
}

#center([dest]) ⇒ dest | new Hash

Same as calling #center with #corners as the first argument.

Returns:

  • (dest | new Hash)


243
244
245
246
247
248
# File 'ext/cglm/rb_cglm_frustum.c', line 243

VALUE rb_cglm_frustum_center(int argc, VALUE *argv, VALUE self) {
  VALUE corners = rb_funcall(self, rb_intern("corners"), 0);
  VALUE dest;
  rb_scan_args(argc, argv, "01", &dest);
  return rb_funcall(rb_cFrustum, rb_intern("center"), 2, corners, dest);
}

#corners([dest]) ⇒ dest | new Hash

Same as calling corners with self.matrix.inverse as the first argument.

Returns:

  • (dest | new Hash)


232
233
234
235
236
237
# File 'ext/cglm/rb_cglm_frustum.c', line 232

VALUE rb_cglm_frustum_corners(int argc, VALUE *argv, VALUE self) {
  VALUE mat = rb_funcall(rb_ivar_get(self, rb_intern("@matrix")), rb_intern("inverse"), 0);
  VALUE dest;
  rb_scan_args(argc, argv, "01", &dest);
  return rb_funcall(rb_cFrustum, rb_intern("corners"), 2, mat, dest);
}

#to_aabb(matr[, dest]) ⇒ Object

Same as calling #aabb with #corners as the first argument.



254
255
256
257
258
259
# File 'ext/cglm/rb_cglm_frustum.c', line 254

VALUE rb_cglm_frustum_to_aabb(int argc, VALUE *argv, VALUE self) {
  VALUE corners = rb_funcall(self, rb_intern("corners"), 0);
  VALUE split, f, dest;
  rb_scan_args(argc, argv, "21", &split, &f, &dest);
  return rb_funcall(rb_cFrustum, rb_intern("aabb"), 4, corners, split, f, dest);
}

#planes([dest]) ⇒ dest | new Hash

Same as calling planes with self.matrix as the first argument.

Returns:

  • (dest | new Hash)


221
222
223
224
225
226
# File 'ext/cglm/rb_cglm_frustum.c', line 221

VALUE rb_cglm_frustum_planes(int argc, VALUE *argv, VALUE self) {
  VALUE mat = rb_ivar_get(self, rb_intern("@matrix"));
  VALUE dest;
  rb_scan_args(argc, argv, "01", &dest);
  return rb_funcall(rb_cFrustum, rb_intern("planes"), 2, mat, dest);
}