Class: Mittsu::ParametricBufferGeometry

Inherits:
BufferGeometry show all
Defined in:
lib/mittsu/extras/geometries/parametric_buffer_geometry.rb

Constant Summary collapse

EPS =
0.00001

Instance Attribute Summary

Attributes inherited from BufferGeometry

#attributes, #bounding_box, #bounding_sphere, #draw_calls, #id, #name, #type, #uuid

Instance Method Summary collapse

Methods inherited from BufferGeometry

#[], #[]=, #add_draw_call, #apply_matrix, #center, #clone, #compute_bounding_box, #compute_bounding_sphere, #compute_offsets, #compute_tangents, #compute_vertex_normals, #dispose, #from_geometry, #keys, #merge, #normalize_normals, #reorder_buffers, #to_json

Methods included from EventDispatcher

#add_event_listener, #dispatch_event, #has_event_listener, #remove_event_listener

Constructor Details

#initialize(func, slices, stacks) ⇒ ParametricBufferGeometry

Returns a new instance of ParametricBufferGeometry.



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/mittsu/extras/geometries/parametric_buffer_geometry.rb', line 5

def initialize(func, slices, stacks)
  super()

  @type = 'ParametricBufferGeometry'

  @parameters = {
    func:   func,
    slices: slices,
    stacks: stacks
  }

  # buffers

  indices = []
  vertices = []
  normals = []
  uvs = []

  normal = Vector3.new

  p0 = Vector3.new
  p1 = Vector3.new

  pu = Vector3.new
  pv = Vector3.new

  # generate vertices, normals, and uvs

  slice_count = slices + 1

  for i in 0..stacks do
    v = i.to_f / stacks.to_f

    for j in 0..slices do
      u = j.to_f / slices.to_f

      # vertex
      func.call(u, v, p0)
      vertices += p0.elements

      # normal

      # approximate tangent vectors via finite differences
      if u - EPS >= 0
        func.call(u - EPS, v, p1)
        pu.sub_vectors(p0, p1)
      else
        func.call(u + EPS, v, p1)
        pu.sub_vectors(p1, p0)
      end

      if v - EPS >= 0
        func.call(u, v - EPS, p1)
        pv.sub_vectors(p0, p1)
      else
        func.call(u, v + EPS, p1)
        pv.sub_vectors(p1, p0)
      end

      # cross product of tangent vectors returns surface normal
      normal.cross_vectors(pu, pv).normalize
      normals += normal.elements

      # uv
      uvs << u << v
    end
  end

  for i in 0...stacks do
    for j in 0...slices do
      a = i * slice_count + j
      b = i * slice_count + j + 1
      c = (i + 1) * slice_count + j + 1
      d = (i + 1) * slice_count + j

      # faces one and two
      indices << a << b << d
      indices << b << c << d
    end
  end

  self[:index]    = BufferAttribute.new(indices, 1)
  self[:position] = BufferAttribute.new(vertices, 3)
  self[:normal]   = BufferAttribute.new(normals, 3)
  self[:uv]       = BufferAttribute.new(uvs, 2)
end