Mostrando textos sobre a face de uma caixa com base na área visível ao aumentar / diminuir o zoom
Eu tenho um aplicativo 3D de amostra (criado usando a referência do 3DViewer de amostra Javafx) que possui uma tabela criada colocando Caixas e Painéis:
A tabela está centrada nas coordenadas wrt (0,0,0) e a câmera está na posição -z inicialmente.
Possui o zoom in / out com base na posição z da câmera do objeto. Ao ampliar / reduzir os limites do objeto, o InParent aumenta / diminui, ou seja, a área da face aumenta / diminui. Portanto, a idéia é colocar mais texto quando tivermos mais área (sempre confinada na face) e menos texto ou nenhum texto quando a área da face for muito menor. Eu sou capaz de fazer isso usando esta hierarquia de nós:
e redimensionar o painel (e gerenciar o vBox e o número de textos nele) conforme Box em cada zoom in / out.
Agora, o problema é que a tabela boundsInParent está fornecendo resultados incorretos (imagem da mesa mostrando a caixa delimitadora na parte superior) sempre que um texto for adicionado ao vBox somente pela primeira vez. Ao aumentar ou diminuir o zoom, a boundingBox está correta e não apaga.
Abaixo está a classe UIpane3D:
public class UIPane3D extends Pane
{
VBox textPane;
ArrayList<String> infoTextKeys = new ArrayList<>();
ArrayList<Text> infoTextValues = new ArrayList<>();
Rectangle bgCanvasRect = null;
final double fontSize = 16.0;
public UIPane3D() {
setMouseTransparent(true);
textPane = new VBox(2.0)
}
public void updateContent() {
textPane.getChildren().clear();
getChildren().clear();
for (Text textNode : infoTextValues) {
textPane.getChildren().add(textNode);
textPane.autosize();
if (textPane.getHeight() > getHeight()) {
textPane.getChildren().remove(textNode);
textPane.autosize();
break;
}
}
textPane.setTranslateY(getHeight() / 2 - textPane.getHeight() / 2.0);
bgCanvasRect = new Rectangle(getWidth(), getHeight());
bgCanvasRect.setFill(Color.web(Color.BURLYWOOD.toString(), 0.10));
bgCanvasRect.setVisible(true);
getChildren().addAll(bgCanvasRect, textPane);
}
public void resetInfoTextMap()
{
if (infoTextKeys != null || infoTextValues != null)
{
try
{
infoTextKeys.clear();
infoTextValues.clear();
} catch (Exception e){e.printStackTrace();}
}
}
public void updateInfoTextMap(String pKey, String pValue)
{
int index = -1;
boolean objectFound = false;
for (String string : infoTextKeys)
{
index++;
if(string.equals(pKey))
{
objectFound = true;
break;
}
}
if(objectFound)
{
infoTextValues.get(index).setText(pValue.toUpperCase());
}
else
{
if (pValue != null)
{
Text textNode = new Text(pValue.toUpperCase());
textNode.setFont(Font.font("Consolas", FontWeight.BLACK, FontPosture.REGULAR, fontSize));
textNode.wrappingWidthProperty().bind(widthProperty());
textNode.setTextAlignment(TextAlignment.CENTER);
infoTextKeys.add(pKey);
infoTextValues.add(textNode);
}
}
}
}
O código que é chamado no final depois de todas as manipulações:
public void refreshBoundingBox()
{
if(boundingBox != null)
{
root3D.getChildren().remove(boundingBox);
}
PhongMaterial blueMaterial = new PhongMaterial();
blueMaterial.setDiffuseColor(Color.web(Color.CRIMSON.toString(), 0.25));
Bounds tableBounds = table.getBoundsInParent();
boundingBox = new Box(tableBounds.getWidth(), tableBounds.getHeight(), tableBounds.getDepth());
boundingBox.setMaterial(blueMaterial);
boundingBox.setTranslateX(tableBounds.getMinX() + tableBounds.getWidth()/2.0);
boundingBox.setTranslateY(tableBounds.getMinY() + tableBounds.getHeight()/2.0);
boundingBox.setTranslateZ(tableBounds.getMinZ() + tableBounds.getDepth()/2.0);
boundingBox.setMouseTransparent(true);
root3D.getChildren().add(boundingBox);
}
Duas coisas:
BoundsInParent do table3D não é atualizado corretamente quando os textos são adicionados pela primeira vez.
Qual seria a maneira correta de colocar textos em nós 3D? Estou tendo que manipular muito para trazer os textos conforme necessário.
Código de compartilhamentoaqui.