WPF 3D - Fit ModelVisual3D no campo da câmera de vista?
-
22-08-2019 - |
Pergunta
Eu tenho um cubóide que é dimensões são importados de XML assim que eu preciso ter certeza de que não importa qual o tamanho do modelo, a câmera sempre pode ver tudo isso. Isto é para fins de visualização. I vai provavelmente tornar uma legenda por cima mostrando a escala para maior clareza.
Eu acho que eu preciso de alguma função que vai me dizer se os ajustes ModelVisual3D dentro dos limites da FieldOfView
da câmera ou talvez o próprio Viewport3D.
Até agora eu tenho o callback estático (as propriedades de dimensão são DependencyProperty
s) quando dimensões propriedades mudam definir como abaixo. É muito bruto no momento, mas você começa a idéia que eu estou olhando. Os comentadas mostras seção mais ou menos o tipo de lógica que eu estou procurando
private static void OnCubeDimensionsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!valueSemaphore)
{
//while(mainModel.WillClip(mainCamera))
//{
// mainCamera.FieldOfView--;
//}
valueSemaphore = true;
double propertyValue = 0.0;
Product3D p = d as Product3D;
switch (e.Property.Name)
{
case "CubeHeight":
propertyValue = (double.Parse(e.NewValue.ToString()) / 100) * 8;
p.CubeHeight = propertyValue;
break;
case "CubeWidth":
propertyValue = (double.Parse(e.NewValue.ToString()) / 100) * 5.3;
p.CubeWidth = propertyValue;
break;
case "CubeDepth":
propertyValue = (double.Parse(e.NewValue.ToString()) / 100) * 2.6;
p.CubeDepth = propertyValue;
break;
}
valueSemaphore = false;
}
}
Se alguém sabe o que deve ir onde a seção comentou-out é eu ficaria eternamente grato.
Agradecemos antecipadamente.
Solução
O que você precisa para se apossar de é a extensão da projeção 2D do cubo sobre o plano da vista. Você pode então fazer uma verificação simples sobre os valores mínimo e máximo X e Y para ver se todo o cubo é visível.
Adicionando um fator de tolerância à medida vai cuidar de eventuais erros de arredondamento.
Copiei o que parece ser a seção relevante do código de aqui . Você pode então definir o tamanho da janela de exibição em conformidade.
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);
}
}
}
}