class Mittsu::PointCloud

Attributes

geometry[RW]
material[RW]

Public Class Methods

new(geometry = Geometry.new, material = PointCloudMaterial.new(color: rand * 0xffffff)) click to toggle source
Calls superclass method Mittsu::Object3D::new
# File lib/mittsu/objects/point_cloud.rb, line 5
def initialize(geometry = Geometry.new, material = PointCloudMaterial.new(color: rand * 0xffffff))
  super()

  @type = 'PointCloud'

  @geometry = geometry
  @material = material

  @_inverse_matrix = Matrix4.new
  @_ray = Ray.new
end

Public Instance Methods

clone(object = PointCloud.new(@geometry, @material)) click to toggle source
Calls superclass method Mittsu::Object3D#clone
# File lib/mittsu/objects/point_cloud.rb, line 76
def clone(object = PointCloud.new(@geometry, @material))
  super(object)
end
raycast(raycaster, intersects) click to toggle source
# File lib/mittsu/objects/point_cloud.rb, line 17
def raycast(raycaster, intersects)
  threshold = raycaster.params[:point_cloud][:threshold]
  @_inverse_matrix.inverse(self.matrix_world)
  @_ray.copy(raycaster.ray).apply_matrix4(@_inverse_matrix)

  if !geometry.bounding_box.nil?
    return if @_ray.intersection_box?(geometry.bounding_box) == false
  end

  local_threshold = threshold / ((self.scale.x + self.scale.y + self.scale.z) / 3.0)
  position = Vector3.new

  if geometry.is_a?(BufferGeometry)
    attributes = geometry.attributes
    positions = attributes.position.array

    if !attributes[:index].nil?
      indices = attributes[:index][:array]
      offsets = geometry.compute_offsets

      if offsets.empty?
        offsets = [{
          start: 0,
          count: indices.length,
          index: 0
        }]
      end

      offsets.each do |offset|
        start = offset[:start]
        count = offset[:count]
        index = offset[:index]

        (start...start+count).each do |i|
          a = index + indices[i]
          position.from_array(positions, a * 3)
          test_point(position, a, local_threshold, raycaster, intersects)
        end
      end
    else
      point_count = positions.count / 3

      point_count.times do |i|
        position.set(
          positions[3 * i],
          positions[3 * i + 1],
          positions[3 * i + 2]
        )

        test_point(position, i, local_threshold, raycaster, intersects)
      end
    end
  else
    geometry.vertices.each_with_index do |vertex, i|
      test_point(vertex, i, local_threshold, raycaster, intersects)
    end
  end
end

Private Instance Methods

test_point(point, index, local_threshold, raycaster, intersects) click to toggle source
# File lib/mittsu/objects/point_cloud.rb, line 82
def test_point(point, index, local_threshold, raycaster, intersects)
  ray_point_distance = @_ray.distance_to_point(point)
  if ray_point_distance < local_threshold
    intersect_point = @_ray.closest_point_to_point(point)
    intersect_point.apply_matrix4(self.matrix_world)

    distance = raycaster.ray.origin.distance_to(intersect_point)
    intersects << {
      distance: distance,
      distance_to_ray: ray_point_distance,
      point: intersect_point.clone,
      index: index,
      face: nil,
      object: self
    }
  end
end