MCPcopy Create free account
hub / github.com/WolfireGames/overgrowth / checkSpheresInFrustum

Method checkSpheresInFrustum

Source/Graphics/camera.cpp:675–741  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

673#endif // defined(USE_SSE)
674
675void Camera::checkSpheresInFrustum(int count, float* where_x, float* where_y, float* where_z, float radius, float cull_distance_squared, uint32_t* is_visible_result) const {
676 const vec3 cam_pos = GetPos();
677 int i = 0;
678
679#if defined(USE_SSE)
680 // This loop exhausts all up to the last 0-3
681 const __m128 all_true = _mm_set1_ps((float)0xFFFFFFFF);
682 const __m128 neg_radius4 = _mm_set1_ps(-radius);
683
684 const __m128 cam_pos_x4 = _mm_set1_ps(cam_pos.x());
685 const __m128 cam_pos_y4 = _mm_set1_ps(cam_pos.y());
686 const __m128 cam_pos_z4 = _mm_set1_ps(cam_pos.z());
687 const __m128 cull_distance_squared4 = _mm_set1_ps(cull_distance_squared);
688
689 for (; i <= count - 4; i += 4) {
690 const __m128 where_x4 = _mm_load_ps(&where_x[i]);
691 const __m128 where_y4 = _mm_load_ps(&where_y[i]);
692 const __m128 where_z4 = _mm_load_ps(&where_z[i]);
693
694 __m128 inside = all_true;
695
696 __m128 distance_squared = simd_distance_squared(where_x4, where_y4, where_z4, cam_pos_x4, cam_pos_y4, cam_pos_z4);
697 __m128 is_in_view_distance = _mm_cmplt_ps(distance_squared, cull_distance_squared4);
698 inside = _mm_and_ps(inside, is_in_view_distance);
699
700 for (const auto& simdFrustumPlane : simdFrustumPlanes) {
701 const __m128& plane_n_x4 = simdFrustumPlane.normal_x;
702 const __m128& plane_n_y4 = simdFrustumPlane.normal_y;
703 const __m128& plane_n_z4 = simdFrustumPlane.normal_z;
704 __m128 n_dot_pos = simd_dot_product(where_x4, where_y4, where_z4, plane_n_x4, plane_n_y4, plane_n_z4);
705
706 __m128 plane_test = _mm_cmpgt_ps(_mm_add_ps(n_dot_pos, simdFrustumPlane.d), neg_radius4);
707 inside = _mm_and_ps(inside, plane_test);
708 }
709
710 _mm_store_ps((float*)&is_visible_result[i], inside);
711 }
712#endif // defined(USE_SSE)
713
714 for (; i < count; ++i) {
715 bool inside = true;
716
717 float center_to_cam[3] = {
718 where_x[i] - cam_pos.x(),
719 where_y[i] - cam_pos.y(),
720 where_z[i] - cam_pos.z(),
721 };
722 float distance_squared = center_to_cam[0] * center_to_cam[0] +
723 center_to_cam[1] * center_to_cam[1] +
724 center_to_cam[2] * center_to_cam[2];
725
726 if (distance_squared < cull_distance_squared) {
727 for (auto frustumPlane : frustumPlanes) {
728 float n_dot_pos =
729 frustumPlane[0] * where_x[i] +
730 frustumPlane[1] * where_y[i] +
731 frustumPlane[2] * where_z[i];
732 bool plane_test = n_dot_pos + frustumPlane[3] > -radius;

Callers 1

PreDrawCameraMethod · 0.80

Calls 5

simd_distance_squaredFunction · 0.85
simd_dot_productFunction · 0.85
xMethod · 0.45
yMethod · 0.45
zMethod · 0.45

Tested by

no test coverage detected