raycast method
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
));
}
}
}