One option to consider is to place your feature points in a separate axes. The contents of different axes are drawn with childorder, even if the contents of each axes are drawn with depthsort.
It's a bit tricky though. Here's a really simplified version:
x = randn(1,1000);
y = randn(1,1000);
z = randn(1,1000);
scatter3(x,y,z,'.')
a1 = gca;
a2 = axes('Position',a1.Position, ...
'CameraPosition',a1.CameraPosition,'CameraTarget',a1.CameraTarget, ...
'XLim',a1.XLim,'YLim',a1.YLim,'ZLim',a1.ZLim);
scatter3(a2,x(12),y(12),z(12),120,'ro','filled')
a2.Visible = 'off';
a2.HandleVisibility = 'off';
linkprop([a1, a2], {'CameraPosition','CameraTarget','CameraUpVector', ...
'XLim','YLim','ZLim'})
So what's going on here? We're putting the axes a2 on top of a1, the axes that contains our point cloud. Then we're hiding all of the decorations of a2, so it looks like the children of a2 are just drawing in a1. The trick is that we need to keep two axes in synch. The simplest tool for that is the linkprop command, but it can be a little tricky to work with, and I probably missed some details there.
The other trick here is to set HandleVisibility to off on a2. The reason for that is to keep things like the rotate3d tool from seeing it. The HandleVisibility property lets you hide this axes from those types of tools.
Best Answer