raycast method

  1. @override
void raycast(
  1. Raycaster raycaster,
  2. List<Intersection> intersects
)
inherited

Get intersections between a casted Ray and this Line. Raycaster.intersectObject will call this method.

Implementation

@override
void raycast(Raycaster raycaster, List<Intersection> intersects) {
  final geometry = this.geometry!;
  final matrixWorld = this.matrixWorld;
  final threshold = raycaster.params["Line"]["threshold"];
  final drawRange = geometry.drawRange;

  // Checking boundingSphere distance to ray

  if (geometry.boundingSphere == null) geometry.computeBoundingSphere();

  _sphere.setFrom(geometry.boundingSphere!);
  _sphere.applyMatrix4(matrixWorld);
  _sphere.radius += threshold;

  if (raycaster.ray.intersectsSphere(_sphere) == false) return;

  //

  _inverseMatrix..setFrom(matrixWorld)..invert();
  _ray..copyFrom(raycaster.ray)..applyMatrix4(_inverseMatrix);

  final localThreshold = threshold / ((scale.x + scale.y + scale.z) / 3);
  final localThresholdSq = localThreshold * localThreshold;

  final vStart = Vector3.zero();
  final vEnd = Vector3.zero();
  final interSegment = Vector3.zero();
  final interRay = Vector3.zero();
  final step = type == "LineSegments" ? 2 : 1;

  final index = geometry.index;
  final attributes = geometry.attributes;
  final positionAttribute = attributes["position"];

  if (index != null) {
    final start = math.max<int>(0, drawRange["start"]!);
    final end = math.min<int>(
      index.count,
      (drawRange["start"]! + drawRange["count"]!),
    );

    for (int i = start, l = end - 1; i < l; i += step) {
      final a = index.getX(i)!;
      final b = index.getX(i + 1)!;

      vStart.fromBuffer(positionAttribute, a.toInt());
      vEnd.fromBuffer(positionAttribute, b.toInt());

      final distSq =
          _ray.distanceSqToSegment(vStart, vEnd, interRay, interSegment);

      if (distSq > localThresholdSq) continue;

      interRay.applyMatrix4(this.matrixWorld); //Move back to world space for distance calculation

      final distance = raycaster.ray.origin.distanceTo(interRay);

      if (distance < raycaster.near || distance > raycaster.far) continue;

      intersects.add(Intersection(
        distance: distance,
        // What do we want? intersection point on the ray or on the segment??
        // point: raycaster.ray.at( distance ),
        point: interSegment.clone()..applyMatrix4(this.matrixWorld),
        index: i,
        object: this
      ));
    }
  } else {
    final start = math.max<int>(0, drawRange["start"]!);
    final end = math.min<int>(
      positionAttribute.count,
      (drawRange["start"]! + drawRange["count"]!),
    );

    for (int i = start, l = end - 1; i < l; i += step) {
      vStart.fromBuffer(positionAttribute, i);
      vEnd.fromBuffer(positionAttribute, i + 1);

      final distSq =
          _ray.distanceSqToSegment(vStart, vEnd, interRay, interSegment);

      if (distSq > localThresholdSq) continue;

      interRay.applyMatrix4(this
          .matrixWorld); //Move back to world space for distance calculation

      final distance = raycaster.ray.origin.distanceTo(interRay);

      if (distance < raycaster.near || distance > raycaster.far) continue;

      intersects.add(Intersection(
        distance: distance,
        // What do we want? intersection point on the ray or on the segment??
        // point: raycaster.ray.at( distance ),
        point: interSegment.clone()..applyMatrix4(this.matrixWorld),
        index: i,
        object: this
      ));
    }
  }
}