Como implementar aparelhos de conversão, escala e rotação para manipular as transformações de objetos 3D?

11

Estou desenvolvendo um editor 3D básico. Ele usa o OpenGL para renderizar um mundo 3D. No momento, minha cena é apenas algumas caixas de tamanhos diferentes e estou no estágio em que quero poder selecionar cada caixa e depois mover / escalar / girar para obter a transformação que desejar.

Como posso resolver o problema de implementar a renderização dos dispositivos dessas ferramentas (ou identificadores, ou como as pessoas costumam chamá-los) e também selecioná-los em cada eixo para realizar a alteração na transformação com o mouse? Para maior clareza: insira a descrição da imagem aqui

Até agora, minha pesquisa sugeriu que a abordagem mais limpa é ter uma caixa delimitadora alinhada por eixo por flecha no dispositivo e outra por quadrado (as que movem o objeto em um plano e não em um único eixo) e, em seguida, lançam um raio do mouse posição e ver o que ele colide. Mas isso ainda é um pouco abstrato demais para mim, eu gostaria de receber mais orientações sobre como esse algoritmo funcionaria (o pseudocódigo é mais que suficiente)

Grimshaw
fonte
1
Normalmente, você transmite o vídeo para o mundo com a posição do mouse e vê se atinge um dispositivo. Você também pode transformar o dispositivo no espaço da tela para detectar a colisão. Normalmente, você apenas distancia do raio para o tipo de segmento de linha. A rotação geralmente é feita como uma bola virtual. Veja Melax em Gems de programação de jogos 1. A tradução é basicamente um produto escalar, assim como a escala.
RandyGaul

Respostas:

9

Em algum momento do meu e-on, mantive os aparelhos da linha de produtos Vue .
Posso lhe dizer, você levará vários dias, em tempo integral.
A menos que você encontre alguma biblioteca ou uma maneira super inteligente, a maneira clássica é obter a coordenada do mouse na janela quando você clica. Se for uma coordenada relativa à janela de visualização, você pode simplesmente dividir xey pela largura e pela altura. obter um vetor (float 2d) no intervalo [0,1]. subtraia (0,5,0,5) a ele para entrar no intervalo [-0,5, 0,5] para x e y.
Então, você faz um raio a partir dessa coordenada usando xey simplesmente como o raio xey, e define z para a distância focal. Às vezes, a proporção é uma dor de cabeça nesta operação. Um pouco de brincadeira e erro de tentativa o consertarão.
Em seguida, é necessário verificar a interseção com seus elementos de aparelhos, ou você tem uma malha que você gerou ou modelou no liquidificador ou em outro DCC, ou peças de malha que podem se articular entre si ... Use essas partes de malha como um raio / consulta de interseção do triângulo.
Ou, se houver, raio / cilindro, raio / esfera, de acordo com a aparência e as peças do dispositivo.
Você precisa ter rotinas de interseção capazes de aplicar uma matriz de transformação na primitiva em que elas colidem . Extremamente importante porque seu dispositivo se traduzirá com o objeto que serve para mover, girará e será escalado com o inverso da distância da câmera, para manter um tamanho fixo na tela.
Então você tem a parte de interação, o mais fácil é pegar o delta do ponto quando o mouse foi o primeiro evento "mouse down" e a posição atual "Mouse move", em 2D puro, e usar esse delta como o movimento atual do eixo no espaço do mundo, multiplicado por alguns kque você decide empiricamente. De acordo com suas unidades internas versus pixel versus escala atual de zoom, etc.
A etapa final é simplesmente aplicar a matriz do dispositivo ao objeto manipulado, para que ele o siga.

Eu digo a você que é uma jornada bastante infernal para implementar, e se você estiver fazendo isso no seu tempo livre, espere mais de uma semana. Várias semanas se você estiver descobrindo completamente o campo. Mais de um mês se seus fins de semana estiverem ocupados com outras atividades :)

Eu sugiro que você baixe o Embree 2.0 da intel para fazer a consulta de interseção raio / triângulo para você, para que você não precise se preocupar em codificá-lo. Ou você pode copiar / colar, sem piedade, e adaptar o código do liquidificador ... Eu acho que eles mudaram para a licença Apache? Deve ser possível legalmente.

v.oddou
fonte
1
Muito obrigado pela resposta. É de fato útil. Eu sabia que não estava louco quando estava me sentindo oprimido por uma tarefa aparentemente fácil. Eu subestimo sua dificuldade e acabei preso ao mesmo problema por dias. Da próxima vez que for lidar com isso, certamente terei feito um bom plano. Obrigado
Grimshaw
0

Para manipulador-tradutor, eu uso o seguinte algoritmo:

1) Quando o mouse é pressionado, precisamos verificar se o raio cruza a seta. Por exemplo, consideramos a seta X. Construímos Ray no espaço do mundo (com base no perfil da câmera e na posição do mouse). Construímos um plano no qual o eixo x está: seu normal é igual a V cruz X cruz V, onde V - vetor do centro para a câmera, X - representa o eixo x. Em seguida, cruzamos o raio com o plano e, portanto, encontramos o ponto de interseção nas coordenadas do mundo. Em seguida, projetamos o segmento do eixo x e o ponto resultante de volta na tela, encontramos a distância entre o segmento projetado e o ponto projetado na tela. se tiver menos de alguns pixels, o mouse entrará no eixo. Também calculamos o vetor delta do espaço mundial entre o centro da seleção e nossa interseção.

Este procedimento é feito para 3 eixos, portanto, encontramos distâncias para todos os eixos. Encontre a distância mínima. então descobrimos com qual eixo o mouse se cruza.

2) Quando o mouse se move. sabemos por qual eixo o objeto se move (de 1). encontramos a interseção espacial mundial do raio com o plano (como em 1). Além disso, projetamos o ponto de interseção na linha em que o objeto se move. posição final do manipulador = interseção + delta.

push рор
fonte