Recentemente, estive pesquisando o SceneKit para OS X e notei que existem vários métodos de fábrica para criar formas geométricas, como:
Caixa, cápsula, cone, cilindro, avião, pirâmide, esfera, toro e tubo.
Estou interessado em adicionar essas formas primitivas ao meu renderizador, mas estou lutando para encontrar qualquer fonte razoável a partir da qual possa obter uma compreensão da geração processual. Existem vários recursos que detalham a teoria, mas faltam o código fonte apropriado para fazer o backup.
O SceneKit fornece métodos de fábrica que permitem definir dinamicamente os atributos de tais formas. No caso da caixa, você pode fornecer valores inteiros para o número de segmentos de largura, altura e profundidade nos quais cada face deve ser dividida.
Entendo a teoria, mas não tenho conhecimento para começar a subdividir as faces da geometria para obter o efeito desejado.
Os vértices para cada forma provavelmente são muito fáceis de gerar em loops simples. O que me surpreende é saber como criar as faces, ou melhor, as coordenadas de textura apropriadas para cada face. As normais podem ser calculadas por face, então estou bastante confiante de que poderia conseguir o que quero, é apenas saber por onde começar.
Alguém pode fornecer detalhes sobre geometria processual? O que eu realmente preciso é de algum código-fonte para obter algumas informações. Eu pesquisei alto e baixo para tutoriais, mas até agora vi apenas alguns sites ou blogs razoáveis. Quaisquer bons livros, tutoriais, blogs ou trabalhos de pesquisa serão apreciados.
Editar com base nos comentários
Eu deveria ter esclarecido que sei como criar vértices para formas básicas, a maioria delas provavelmente pode ser alcançada por loops simples. O que eu não entendo é como criar faces a partir da matriz gerada de vértices. Como crio uma faixa triangular, ou triângulos, a partir de uma matriz aparentemente não ordenada de vértices?
Suponho que, depois de ultrapassar esse ponto, eu possa criar os normais a partir de cada face. Embora ainda não tenha me aprofundado nisso, vi muitas referências a isso e tenho certeza de que será fácil de implementar.
Idealmente, eu gostaria de poder gerar geometria a partir de um determinado conjunto de propriedades, como a maneira que o SceneKit fornece. Dado que o SceneKit fez isso, e você pode fazer coisas semelhantes no Blender e Maya etc, presumo que não estou tentando implementar o impossível.
O aspecto final seria a aplicação de texturas. Novamente, isso não é algo que eu implementei, mas li e conheço os requisitos.
O principal problema aqui é que eu sei o que quero alcançar, mas estou lutando para decifrar como implementar as primitivas mencionadas acima. Eu esperava poder encontrar alguma aparência de conhecimento por meio do código-fonte, mas realmente não encontrei nada adequado até agora.
fonte
Respostas:
A maneira de gerar as arestas e as faces de uma forma primitiva como uma caixa, um cone e tudo o que você citou é gerá-las ao mesmo tempo em que cria os vértices. De fato, você deve criar os vértices de uma maneira lógica, para facilitar o cálculo das arestas e faces em conformidade.
Existem algoritmos que tomam como entrada um conjunto de pontos no espaço e calculam a chamada " triangulação do conjunto de pontos " sobre ele, mas o problema da triangulação do conjunto de pontos é NP-completo , de modo que é mais rápido criar bordas e faces conforme você avança, apenas calcula os vértices e deixa um algoritmo fazer o trabalho. Apenas informando que esta solução existe.
Além dessa solução ineficiente, acho que você só pode tratar os primitivos caso a caso, como nos exemplos a seguir.
Uma malha é vértices e faces . As arestas estão contidas na descrição das faces, a menos que sua malha contenha linhas que não compõem faces. Os vértices são tuplas de 3 coordenadas de ponto flutuante. As arestas são simplesmente pares de referências aos vértices, mas, novamente, você certamente não precisará deles. Digamos, por exemplo, que seus vértices estão em uma matriz indexada. Bem, suas bordas podem então ser pares de índices dessa matriz. As faces são trigêmeos de referências a vértices ou trigêmeos de índices no caso de matriz indexada .
Você deve ser capaz de contar os vértices, arestas e faces que compõem cada uma dessas formas primitivas, porque poder contá-las significa entender as propriedades do objeto, o que ajuda a criar o método com o qual você as construirá, usando loops e outras ferramentas como veremos.
Cone
Para um cone com n + 2 vértices, 3n arestas e 2n faces:
1) 2)
3)
4)
Resultado final:
Você também pode criar arestas e faces ao executar o loop que forma o círculo. Mesma complexidade, mesma coisa. Faça um vértice no círculo, armazene-o em sua matriz de vértices, adicione a aresta correspondente (par de índices) à matriz de pares de índices, se quiser, e finalmente adicione a face correspondente à sua matriz de trigêmeos de índices . Vá para o próximo vértice.
O cilindro e o tubo: não fazendo o mesmo trabalho duas vezes e quads
Novamente, para o tubo, ele começa com um vértice e um círculo que será o centro do disco superior ou inferior do cilindro:
Para vincular a parte superior e a inferior, você deve fazer quadriláteros entre pares de pares de vértices que se enfrentam. Então pense no futuro e por que não tornar-se uma função que cria duas faces triangulares em quatro vértices?
Feito. Observe que desta vez usamos o fato de que a mesma estrutura (círculo + centro) aparece duas vezes em um cilindro para usar um atalho. Não precisamos fazer todos os vértices, arestas e faces manualmente, ao contrário do cone onde era necessário.
Seguindo esse princípio de preguiça, também é possível fazer apenas um quarto do círculo e duplicá-lo, e novamente, fazer um círculo completo com transformações muito simples (válidas para qualquer círculo, também com o cone), mas isso é realmente um exagero para um forma não tão complexa.
Você sempre deve usar as propriedades geométricas dos objetos criados para simplificar sua criação . Ou seja, suas simetrias e invariantes .
Para um cilindro, apenas não faça o vértice base, apenas faça o círculo, duplique, traduza a cópia, faça os quadríceps, pronto.
A esfera e a cápsula: adicionando complexidade, ainda não são o mesmo trabalho duas vezes
Para criar uma cápsula, queremos criar uma esfera UV, dividi-la em duas metades, traduzir a primeira metade e depois vincular as duas com os lados das cápsulas.
Novamente, é possível criar apenas um oitavo (!!) da esfera, duplicá-lo e invertê-lo e, em seguida, duplicar e reverter o resultado, exceto em outro eixo, etc., para obter uma esfera completa, em 4 etapas (crie o oitavo , duplicar e reverter três vezes). Talvez exagere, mas menos do que no caso do círculo.
Uma simples esfera UV:
De fato, fazemos apenas metade dela (por exemplo), duplicamos essa metade, vire a cópia de cabeça para baixo e a traduzimos pelo comprimento da cápsula:
Vinculamos a metade superior e inferior:
O trabalho real (um tanto) árduo vem da trigonometria que entra na criação de uma esfera. O conjunto de todos os vértices pertencentes a uma esfera UV pode ser descrito como o conjunto de todos os pontos do formulário:
onde R é o raio da esfera e, para um certo número inteiro positivo mesmo N , temos a constante
θ = × π / N ,
k e n são números inteiros com k variando de 0 a 2N-1 e n varia de N / 2 a + N / 2 .
Para formar uma meia esfera ou um oitavo de uma esfera, você deve restringir o conjunto de valores tomados por k e n .
Se k fossem números reais e não apenas números inteiros, você obteria uma esfera inteira, não apenas os vértices em sua superfície. Então, o que fizemos aqui é rasterizar a equação da superfície do primitivo .
O toro temível : é fácil depois de tudo o que vimos!
Mais uma vez, mais trigonometria, mais vértices, mais quads, mais simetrias, mais invariantes ... mais geometria! Descubra a equação para a superfície de um toro, "rasterize-o" corretamente, simplifique o problema usando as simetrias (óbvias) do toro e, finalmente, faça um loop no conjunto de vértices que você acabou de definir e faça as arestas e faces à medida que ir!
Vejo? Completamente simples.
fonte