Geração de geometria processual

10

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.

CaptainRedmuff
fonte
Você diz que seu problema está subdividindo a geometria, mas então você diz que tornar os vértices deve ser fácil e então diz que seu problema é como criar faces e depois diz que seu problema é o mapeamento de texturas. Qual é o seu problema? Você pode gerar as posições dos vértices? Você pode gerar as arestas e faces? Além disso, as coordenadas de textura dependem da sua textura e do que você deseja obter com ela; portanto, a pergunta sobre coordenadas de textura não é boa. Finalmente, a geração de primitivas é simplesmente sobre geometria e as pessoas raramente a chamam de "geometria processual", embora seja isso que é.
Jsala #
Eu entendo como criar a geometria para formas simples, como um cubo ou plano, é a criação das faces que não compreendo. Como crio os rostos de vários vértices? Traçar os pontos para formas mais complexas faz parte do problema, embora eu tenha um entendimento básico. Colá-los todos juntos em uma faixa triangular ou triângulos é o que estou lutando para envolver minha cabeça.
CaptainRedmuff
OK, obrigado pelos detalhes. Você pode editar sua pergunta para esclarecer. Tempo de atendimento!
Jsala #

Respostas:

11

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. Faça dois vértices separados.
  2. Faça um círculo em torno de um dos vértices (o vértice base), que está dentro de um plano perpendicular ao segmento entre os dois primeiros vértices. Espero que você possa fazer um círculo usando trigonometria, certo? Isso já é todos os vértices do cone. Isso também é um terço de todas as arestas (existem n arestas no círculo e 3n no total).
  3. Faça n arestas do vértice base aos n vértices no círculo. Você pode fazer metade das faces (que são n faces) ao fazer isso.
  4. Faça n arestas do vértice da ponta aos n vértices no círculo. Você pode fazer a outra metade das faces (que são n faces) ao fazer isso.

1) Dois vértices 2) e um círculo
3) e rostos
4) e rostos
Resultado final:resultado

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:

  1. Faça um vértice.
  2. Faça um círculo ao redor do vértice. Adicione arestas (se desejar arestas) entre os vértices sucessivos do círculo e entre o vértice central e cada vértice do círculo. Adicione faces entre cada trio de vértices feitos do vértice central e dois vértices sucessivos no círculo.
  3. Duplique tudo isso, traduza a cópia na direção perpendicular à base que você acabou de fazer, pelo comprimento do cilindro desejado.
  4. Vincule a parte superior e a inferior.

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:
esfera

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:
metades

Vinculamos a metade superior e inferior:
cápsula

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:

pontos

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.

jrsala
fonte
Uau. Obrigado por uma resposta tão detalhada e por tantos exemplos. Eu não tinha pensado na idéia de simplesmente gerar metade de uma esfera e espelhar os elementos simétricos. Muito obrigado por dedicar um tempo para escrever isso de uma maneira que eu possa entender facilmente e, com sorte, colocar em prática com facilidade.
CaptainRedmuff
De nada! Sinto muito, mas não havia código.
Jsala #
O esboço dos métodos era mais do que eu realmente precisava. Posso começar a elaborar um plano de ação a partir daí, pelo menos:] Suponho que você não tenha nenhuma informação sobre caixas / cubos com bordas chanfradas? docs.autodesk.com/3DSMAX/15/ENU/3ds-Max-Help/images/…
CaptainRedmuff