WPF 3D - Определите, обрезается ли ModelVisual3D внутри его Viewport3D
У меня есть рендеринг куба внутри Viewport3D
и мне нужно знать способ узнать, виден ли ВСЕ куб для пользователя.
Изменить: Просто чтобы прояснить, я не говорю об отсечении из-за расстояния ближней / дальней плоскости здесь. Я имею в виду, что куб должен быть высоким или широким, чтобы поместиться в поле зрения камеры.
Любая помощь будет высоко ценится!
Заранее спасибо.
3 ответа
Я не могу предложить решение, но я могу, возможно, указать вам правильное направление.
То, что вам нужно, - это степень 2D-проекции куба на плоскость вида. Затем вы можете просто проверить минимальное и максимальное значения X & Y, чтобы увидеть, виден ли весь куб.
Добавление допускового коэффициента в степень позволит устранить любые ошибки округления.
РЕДАКТИРОВАТЬ: я только что сделал поиск Google для "2D проекция WPF", и эта ссылка пришла. Похоже, это адрес того, что вы хотите.
ДОПОЛНИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ: Я скопировал соответствующий раздел кода по ссылке выше здесь.
public static Rect Get2DBoundingBox(ModelVisual3D mv3d)
{
bool bOK;
Matrix3D m = MathUtils.TryWorldToViewportTransform(vpv, out bOK);
bool bFirst = true;
Rect r = new Rect();
if (mv3d.Content is GeometryModel3D)
{
GeometryModel3D gm3d = (GeometryModel3D) mv3d.Content;
if (gm3d.Geometry is MeshGeometry3D)
{
MeshGeometry3D mg3d = (MeshGeometry3D)gm3d.Geometry;
foreach (Point3D p3d in mg3d.Positions)
{
Point3D pb = m.Transform(p3d);
Point p2d = new Point(pb.X, pb.Y);
if (bFirst)
{
r = new Rect(p2d, new Size(1, 1));
bFirst = false;
}
else
{
r.Union(p2d);
}
}
}
}
return r;
}
Я могу думать о чем-то похожем на это:
Проверьте ближайшую точку куба, связанную с камерой, и убедитесь, что она отсечена от ближней плоскости отсечения. Ближайшая точка от камеры, о которой я могу думать, - это одна из точек, составляющих куб. Поэтому вы должны проверить каждую из 6 точек куба и проверить, не обрезаны ли они. Если ни один из них не является, тогда ваш куб, если он полностью виден, О, и, очевидно, вы должны проверить также и дальнюю плоскость отсечения.
Код прост:
for each point of cube do
if !(point is in farClippingPlane and nearClippingPlane)
return false;
end if
end for
return true