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:
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)
Respostas:
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
k
que 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.
fonte
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.
fonte