Class: Mittsu::CylinderGeometry

Inherits:
Geometry
  • Object
show all
Defined in:
lib/mittsu/extras/geometries/cylinder_geometry.rb

Constant Summary

Constants included from OpenGLGeometryLike

OpenGLGeometryLike::CONST_BUFFER_NAMES

Instance Attribute Summary

Attributes inherited from Geometry

#bounding_box, #bounding_sphere, #colors, #dynamic, #face_vertex_uvs, #faces, #groups, #has_tangents, #id, #initted, #line_distances, #morph_colors, #morph_normals, #morph_targets, #name, #skin_indices, #skin_weights, #type, #uuid, #vertices

Attributes included from OpenGLGeometryLike

#custom_attributes_list, #face_count, #faces3, #initted_arrays, #line_count, #morph_normals_arrays, #morph_normals_buffers, #morph_targets_arrays, #morph_targets_buffers, #num_morph_normals, #num_morph_targets, #num_vertices, #particle_count, #renderer, #type_array, #vertex_array_object

Instance Method Summary collapse

Methods inherited from Geometry

#apply_matrix, #center, #clone, #compute_bounding_box, #compute_bounding_sphere, #compute_face_normals, #compute_line_distances, #compute_morph_normals, #compute_tangents, #compute_vertex_normals, #create_line_buffers, #create_particle_buffers, #dispose, #from_buffer_geometry, #init_geometry_groups, #init_line_buffers, #init_particle_buffers, #merge, #merge_mesh, #merge_vertices, #set_line_buffers, #set_particle_buffers, #to_json

Methods included from OpenGLGeometryLike

#bind_vertex_array_object, #update_other_buffers, #update_vertex_buffer

Methods included from EventDispatcher

#add_event_listener, #dispatch_event, #has_event_listener, #remove_event_listener

Constructor Details

#initialize(radius_top = 20.0, radius_bottom = 20.0, height = 100.0, radial_segments = 8, height_segments = 1, open_ended = false, theta_start = 0.0, theta_length = (::Math::PI * 2.0)) ⇒ CylinderGeometry

Returns a new instance of CylinderGeometry.



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
91
92
93
94
95
96
97
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/mittsu/extras/geometries/cylinder_geometry.rb', line 6

def initialize(radius_top = 20.0, radius_bottom = 20.0, height = 100.0, radial_segments = 8, height_segments = 1, open_ended = false, theta_start = 0.0, theta_length = (::Math::PI * 2.0))
  super()

  @type = 'CylinderGeometry'

  @parameters = {
    radius_top:      radius_top,
    radius_bottom:   radius_bottom,
    height:          height,
    radial_segments: radial_segments,
    height_segments: height_segments,
    open_ended:      open_ended,
    theta_start:     theta_start,
    theta_length:    theta_length
  }

  height_half = height / 2.0

  index_rows = []
  uv_rows = []

  for y in 0..height_segments do
    index_row = []
    uv_row = []

    v = y.to_f / height_segments.to_f
    radius = v * (radius_bottom - radius_top) + radius_top

    for x in 0..radial_segments do
      u = x.to_f / radial_segments

      vertex = Vector3.new
      vertex.x = radius * ::Math.sin(u * theta_length + theta_start)
      vertex.y = -v * height + height_half
      vertex.z = radius * ::Math.cos(u * theta_length + theta_start)

      @vertices << vertex

      index_row << (vertices.length - 1)
      uv_row << Vector2.new(u, 1.0 - v)
    end

    index_rows << index_row
    uv_rows << uv_row
  end

  tan_theta = (radius_bottom - radius_top) / height

  na = nil
  nb = nil

  for x in 0...radial_segments do
    if radius_top != 0
      na = @vertices[index_rows[0][x]].clone
      nb = @vertices[index_rows[0][x + 1]].clone
    else
      na = @vertices[index_rows[1][x]].clone
      nb = @vertices[index_rows[1][x + 1]].clone
    end

    na.y = ::Math.sqrt(na.x * na.x + na.z * na.z) * tan_theta
    na.normalize

    nb.y = ::Math.sqrt(nb.x * nb.x + nb.z * nb.z) * tan_theta
    nb.normalize

    for y in 0...height_segments do
      v1 = index_rows[y][x]
      v2 = index_rows[y + 1][x]
      v3 = index_rows[y + 1][x + 1]
      v4 = index_rows[y][x + 1]

      n1 = na.clone
      n2 = na.clone
      n3 = nb.clone
      n4 = nb.clone

      uv1 = uv_rows[y][x].clone
      uv2 = uv_rows[y + 1][x].clone
      uv3 = uv_rows[y + 1][x + 1].clone
      uv4 = uv_rows[y][x + 1].clone

      @faces << Face3.new(v1, v2, v4, [n1, n2, n4])
      @face_vertex_uvs[0] << [uv1, uv2, uv4]

      @faces << Face3.new(v2, v3, v4, [n2.clone, n3, n4.clone])
      @face_vertex_uvs[0] << [uv2.clone, uv3, uv4.clone]
    end
  end

  # top cap

  if !open_ended && radius_top > 0.0
    @vertices << Vector3.new(0, height_half, 0)

    for x in 0...radial_segments do
      v1 = index_rows[0][x]
      v2 = index_rows[0][x + 1]
      v3 = @vertices.length - 1

      n1 = Vector3.new(0, 1, 0)
      n2 = Vector3.new(0, 1, 0)
      n3 = Vector3.new(0, 1, 0)

      uv1 = uv_rows[0][x].clone
      uv2 = uv_rows[0][x + 1].clone
      uv3 = Vector2.new(uv2.x, 0)

      @faces << Face3.new(v1, v2, v3, [n1, n2, n3])
      @face_vertex_uvs[0] << [uv1, uv2, uv3]
    end
  end

  # bottom cap

  if !open_ended && radius_bottom > 0.0
    @vertices << Vector3.new(0, -height_half, 0)

    for x in 0...radial_segments do
      v1 = index_rows[height_segments][x + 1]
      v2 = index_rows[height_segments][x]
      v3 = @vertices.length - 1

      n1 = Vector3.new(0, -1, 0)
      n2 = Vector3.new(0, -1, 0)
      n3 = Vector3.new(0, -1, 0)

      uv1 = uv_rows[height_segments][x].clone
      uv2 = uv_rows[height_segments][x + 1].clone
      uv3 = Vector2.new(uv2.x, 0)

      @faces << Face3.new(v1, v2, v3, [n1, n2, n3])
      @face_vertex_uvs[0] << [uv1, uv2, uv3]
    end
  end

  compute_face_normals
end