| 3805 | #endif |
| 3806 | |
| 3807 | void ImDrawList3D::SortedMoveToImGuiDrawList() { |
| 3808 | ImDrawList& draw_list = *ImGui::GetWindowDrawList(); |
| 3809 | |
| 3810 | const int tri_count = ZBuffer.Size; |
| 3811 | if (tri_count == 0) { |
| 3812 | // No triangles, just reset buffers and return |
| 3813 | ResetBuffers(); |
| 3814 | return; |
| 3815 | } |
| 3816 | |
| 3817 | // Build an array of (z, tri_idx) |
| 3818 | struct TriRef { |
| 3819 | double z; |
| 3820 | int tri_idx; |
| 3821 | }; |
| 3822 | TriRef* tris = (TriRef*)IM_ALLOC(sizeof(TriRef) * tri_count); |
| 3823 | for (int i = 0; i < tri_count; i++) { |
| 3824 | tris[i].z = ZBuffer[i]; |
| 3825 | tris[i].tri_idx = i; |
| 3826 | } |
| 3827 | |
| 3828 | // Sort by z (distance from viewer) |
| 3829 | ImQsort(tris, (size_t)tri_count, sizeof(TriRef), [](const void* a, const void* b) { |
| 3830 | double za = ((const TriRef*)a)->z; |
| 3831 | double zb = ((const TriRef*)b)->z; |
| 3832 | return (za < zb) ? -1 : (za > zb) ? 1 : 0; |
| 3833 | }); |
| 3834 | |
| 3835 | // Reserve space in the ImGui draw list |
| 3836 | draw_list.PrimReserve(IdxBuffer.Size, VtxBuffer.Size); |
| 3837 | |
| 3838 | // Copy vertices (no reordering needed) |
| 3839 | memcpy(draw_list._VtxWritePtr, VtxBuffer.Data, VtxBuffer.Size * sizeof(ImDrawVert)); |
| 3840 | unsigned int idx_offset = draw_list._VtxCurrentIdx; |
| 3841 | draw_list._VtxWritePtr += VtxBuffer.Size; |
| 3842 | draw_list._VtxCurrentIdx += (unsigned int)VtxBuffer.Size; |
| 3843 | |
| 3844 | // Maximum index allowed to not overflow ImDrawIdx |
| 3845 | unsigned int max_index_allowed = MaxIdx() - idx_offset; |
| 3846 | |
| 3847 | // Copy indices with triangle sorting based on distance from viewer |
| 3848 | ImDrawIdx* idx_out_begin = draw_list._IdxWritePtr; |
| 3849 | ImDrawIdx* idx_out = idx_out_begin; |
| 3850 | ImDrawIdx* idx_in = IdxBuffer.Data; |
| 3851 | for (int i = 0; i < tri_count; i++) { |
| 3852 | int tri_i = tris[i].tri_idx; |
| 3853 | int base_idx = tri_i * 3; |
| 3854 | unsigned int i0 = (unsigned int)idx_in[base_idx + 0]; |
| 3855 | unsigned int i1 = (unsigned int)idx_in[base_idx + 1]; |
| 3856 | unsigned int i2 = (unsigned int)idx_in[base_idx + 2]; |
| 3857 | |
| 3858 | // Check if after adding offset any of these indices exceed max_index_allowed |
| 3859 | if (i0 > max_index_allowed || i1 > max_index_allowed || i2 > max_index_allowed) |
| 3860 | continue; |
| 3861 | |
| 3862 | idx_out[0] = (ImDrawIdx)(i0 + idx_offset); |
| 3863 | idx_out[1] = (ImDrawIdx)(i1 + idx_offset); |
| 3864 | idx_out[2] = (ImDrawIdx)(i2 + idx_offset); |