| 374 | } |
| 375 | |
| 376 | void Picker::PickSegments(std::shared_ptr<Visual> const& visual, char const* positions, |
| 377 | uint32_t vstride, IndexBuffer* ibuffer, Line3<float> const& line) |
| 378 | { |
| 379 | // Compute distances from the model-space segments to the line. |
| 380 | uint32_t const firstSegment = ibuffer->GetFirstPrimitive(); |
| 381 | uint32_t const numSegments = ibuffer->GetNumActivePrimitives(); |
| 382 | bool isIndexed = ibuffer->IsIndexed(); |
| 383 | IPType primitiveType = ibuffer->GetPrimitiveType(); |
| 384 | for (uint32_t i = firstSegment; i < firstSegment + numSegments; ++i) |
| 385 | { |
| 386 | // Get the vertex indices for the segment. |
| 387 | uint32_t v0, v1; |
| 388 | if (isIndexed) |
| 389 | { |
| 390 | ibuffer->GetSegment(i, v0, v1); |
| 391 | } |
| 392 | else if (primitiveType == IP_POLYSEGMENT_DISJOINT) |
| 393 | { |
| 394 | v0 = 2 * i; |
| 395 | v1 = v0 + 1; |
| 396 | } |
| 397 | else // primitiveType == IP_POLYSEGMENT_CONTIGUOUS |
| 398 | { |
| 399 | v0 = i; |
| 400 | v1 = v0 + 1; |
| 401 | } |
| 402 | |
| 403 | // Get the vertex positions. |
| 404 | auto p0 = *reinterpret_cast<Vector3<float> const*>(positions + static_cast<size_t>(v0) * vstride); |
| 405 | auto p1 = *reinterpret_cast<Vector3<float> const*>(positions + static_cast<size_t>(v1) * vstride); |
| 406 | |
| 407 | // Create the query segment in model space. |
| 408 | Segment3<float> segment(p0, p1); |
| 409 | |
| 410 | // Compute segment-line distance. |
| 411 | DCPQuery<float, Line3<float>, Segment3<float>> query; |
| 412 | auto result = query(line, segment); |
| 413 | if (result.distance <= mMaxDistance && mTMin <= result.parameter[0] && result.parameter[0] <= mTMax) |
| 414 | { |
| 415 | PickRecord record; |
| 416 | record.visual = visual; |
| 417 | record.primitiveType = primitiveType; |
| 418 | record.primitiveIndex = i; |
| 419 | record.vertexIndex[0] = static_cast<int32_t>(v0); |
| 420 | record.vertexIndex[1] = static_cast<int32_t>(v1); |
| 421 | record.vertexIndex[2] = -1; |
| 422 | record.t = result.parameter[0]; |
| 423 | record.bary[0] = 1.0f - result.parameter[1]; |
| 424 | record.bary[1] = result.parameter[1]; |
| 425 | record.bary[2] = 0.0f; |
| 426 | record.linePoint = HLift(result.closest[0], 1.0f); |
| 427 | record.primitivePoint = HLift(result.closest[1], 1.0f); |
| 428 | |
| 429 | #if defined (GTE_USE_VEC_MAT) |
| 430 | record.linePoint = record.linePoint * visual->worldTransform; |
| 431 | record.primitivePoint = record.primitivePoint * visual->worldTransform; |
| 432 | #else |
| 433 | record.linePoint = visual->worldTransform * record.linePoint; |
nothing calls this directly
no test coverage detected