{"id":23630673,"url":"https://github.com/lucastborges/animacao_camera","last_synced_at":"2025-11-08T07:30:36.849Z","repository":{"id":268914364,"uuid":"899038499","full_name":"LucasTBorges/Animacao_Camera","owner":"LucasTBorges","description":"Aplicação feita no Three.Js com câmeras de diferentes pontos de vista acompanhando um modelo ao longo de uma curva no espaço","archived":false,"fork":false,"pushed_at":"2024-12-19T16:44:09.000Z","size":7516,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-18T21:12:40.459Z","etag":null,"topics":["camera-control","threejs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LucasTBorges.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-05T14:05:18.000Z","updated_at":"2024-12-19T16:57:32.000Z","dependencies_parsed_at":"2024-12-19T17:47:41.501Z","dependency_job_id":null,"html_url":"https://github.com/LucasTBorges/Animacao_Camera","commit_stats":null,"previous_names":["lucastborges/animacao_camera"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucasTBorges%2FAnimacao_Camera","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucasTBorges%2FAnimacao_Camera/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucasTBorges%2FAnimacao_Camera/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucasTBorges%2FAnimacao_Camera/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LucasTBorges","download_url":"https://codeload.github.com/LucasTBorges/Animacao_Camera/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239550283,"owners_count":19657541,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["camera-control","threejs"],"created_at":"2024-12-28T02:37:35.704Z","updated_at":"2025-11-08T07:30:36.783Z","avatar_url":"https://github.com/LucasTBorges.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# Relatório Trabalho 1 - MATA65 (Computação Gráfica)\n## Introdução\nNeste repositório se localiza o produto final do trabalho que marca a conclusão da unidade 1 da disciplina MATA65 - Computação Gráfica na UFBA no semestre 2024.2, ministrada pelo professor [Antônio Apolinário](https://computacao.ufba.br/pt-br/antonio-lopes-apolinario-junior), responsável pelas especificações do trabalho. **Para executar a aplicação, é importante ter a pasta [Assets](https://github.com/LucasTBorges/Assets) na raíz do web server que está o executando.** A navegação da aplicação se dá a partir do index.html, localizado na pasta CodigoBase.\nNós fomos orientados a desenvolver uma aplicação utilizando a biblioteca [Three.js](https://threejs.org/) que nos permitisse visualizar um cenário sob dois pontos de vista simultaneamente: uma câmera estática e uma câmera que acompanha um agente representado por um modelo 3D percorrendo um circuito em loop pela cena.\nDentre os requisitos impostos, se encontravam:\n - Na visualização que acompanha o avatar pelo cenário, deve ser possível alternar entre as perspectivas de Primeira Pessoa, Terceira Pessoa e \"Drone Normal\".\n - O movimento da câmera deve ser suave e realista.\n - Deve ser possível pausar e reproduzir a execução da animação.\n## Modelos 3D\n\u003cimg src=\"./imgs/bookModel.png\" alt=\"Modelo 3D do cenário\" width=\"500\"/\u003e\n\u003cimg src=\"./imgs/passaro.png\" alt=\"Modelo 3D do avatar\" width=\"500\"/\u003e\n\nAs especificações do trabalho, localizadas neste mesmo repositório, dão liberdade criativa para a escolha dos modelos do avatar e do cenário. Dessa forma, escolhi, para o cenário, o modelo de um [feudo sobre um livro de fantasia medieval](https://sketchfab.com/3d-models/medieval-fantasy-book-06d5a80a04fc4c5ab552759e9a97d91a), disponível para download no SketchFab sob a publicação do usuário [Pixel](https://sketchfab.com/stefan.lengyel1). Para o avatar acompanhado pela câmera, optei pelo modelo de um [pássaro](https://sketchfab.com/3d-models/low-poly-bird-942ffdab96bb48a7bb1612b461386310), também disponível para download no SketchFab, sob a publicação do usuário [AlexFerrart3D](https://sketchfab.com/alexferrart3D).\n\n## Movimentação da Câmera\n\n**Translação:** A fim de traçar uma trajetória flúida para a câmera, decidi deslocá-la ao longo de uma [spline de Catmull-Rom](https://www.cs.cmu.edu/~fp/courses/graphics/asst5/catmullRom.pdf). Esta curva paramétrica, gerada a partir de uma lista de pontos no espaço, é uma spline interpolante, o que significa que os pontos definidos por mim farão parte da curva gerada, me dando mais controle sobre o circuito percorrido pela câmera. Por fim, já [existe uma implementação desta curva no Three.js](https://threejs.org/docs/#api/en/extras/curves/CatmullRomCurve3), o que foi mais um motivo para escolher essa abordagem no meu projeto.\n\n**Rotação:** Outra vantagem da utilização da spline de Catmull-Rom é o fato de que ela possui continuidade de classe $C^1$. Utilizar a tangente da curva para determinar a direção para a qual a câmera deve apontar em qualquer ponto me pareceu a escolha natural nessa situação.\n\n## Visualizações Simultâneas\n\n\u003cimg src=\"./imgs/moinho.png\" alt=\"Frame capturado durante a execução da animação\" width=\"500\"/\u003e\n\nCada frame da animação possui duas visualizações simultâneas da cena. A primeira, localizada na esquerda, é a visualização de uma [câmera que faz uso de projeção perspectiva](https://threejs.org/docs/#api/en/cameras/PerspectiveCamera) e acompanha o avatar percorrendo o cenário. A segunda, localizada na direita, é a visualização de uma [câmera ortográfica](https://threejs.org/docs/#api/en/cameras/OrthographicCamera) (faz uso de projeção paralela) que não sofre nenhuma tranformação durante a execução da aplicação.\nNa visualização da câmera ortográfica é possível visualizar alguns elementos não presentes na primeira visualização:\n - Um [Camera Helper](https://threejs.org/docs/#api/en/helpers/CameraHelper) referente à primeira visualização: segmentos de linha que auxiliam a visualizar o frustrum da câmera ativa.\n - Uma curva vermelha que descreve a trajetória da câmera na animação, cuja visualização pode ser desligada através da GUI.\n - Esferas ciano representando os pontos a partir dos quais a curva foi gerada. Como todas as esferas compartilham da mesma geometria e material, foi possível fazer uso da [InstancedMesh](https://threejs.org/docs/#api/en/objects/InstancedMesh) do Three.js ao invés de criar as malhas das esferas uma a uma e passar, de forma redundante, as mesmas informações de geometria e material toda vez. Essa escolha ainda otimiza a performance da aplicação pois diminui o número de draw calls realizadas. A visualização das esferas pode ser desligada através da GUI.\n\n## Diferentes Câmeras\n\n A especificação do trabalho indica que deve ser possível alternar entre as câmeras em Primeira Pessoa, Terceira Pessoa e \"Drone Normal\" através da GUI. Para além das três câmeras obrigatórias, minha aplicação também inclui a opção \"Cinematográfica\".\n\n---\n \n ### Primeira pessoa:\n \n \u003cimg src=\"./imgs/firstPerson.png\" alt=\"Visão em primeira pessoa\" width=\"350\"/\u003e\n \n  Câmera posicionada de forma a simular a experiência do pássaro, com a visão parcialmente obstruída pelo bico.\n\n---\n  \n ### Terceira Pessoa:\n \n\u003cimg src=\"./imgs/thirdPerson.png\" alt=\"Visão em terceira pessoa\" width=\"350\"/\u003e\n\nCâmera posicionada atrás e um pouco acima do pássaro.\n\n---\n\n### Drone Normal:\n\n\u003cimg src=\"./imgs/droneNormal.png\" alt=\"Visão de drone normal\" width=\"350\"/\u003e\n\nSimilar à visão em primeira pessoa, mas a visão não é obstruída por nenhuma parte do modelo do pássaro.\n\n---\n\n### Cinematográfica:\n\n\u003cimg src=\"./imgs/cinematica.png\" alt=\"Visão cinematográfica\" width=\"350\"/\u003e\n\nPosicionada a uma distância fixa do avatar, esta visão se diferencia das outras pois compartilha apenas as transformações de translação com o pássaro. Por não sofrer as mesmas transformações de rotação das outras câmeras, em alguns momentos veremos o pássaro de frente, em outros de lado e em outros de costas, a depender da direção para a qual o modelo está voltado. Entretanto, através da GUI, é possível controlar manualmente a rotação da câmera cinematográfica ao redor do pássaro. A intenção da inclusão dessa visão é facilitar a visualização das transformações de rotação aplicadas sobre o avatar durante o trajeto.\n\n---\n\nPara posicionar as câmeras com referência ao pássaro, utilizei [grupos](https://threejs.org/docs/?q=group#api/en/objects/Group) do Three.js para realizar o posicionamento no sistema de coordenadas local ao invés de no espaço do mundo. \nCriei um grupo para aplicar as tranformações de translação da animação e dentro dele criei um grupo para aplicar as transformações de rotação. No grupo de rotação incluí o modelo do pássaro e as câmeras de Primeira Pessoa, Terceira Pessoa e Drone Normal. No grupo pai, o grupo de translação, incluí a câmera cinematográfica. O resultado é que todas as câmeras e o modelo sofrem as transformações de translação acompanhando a spline ao longo da animação, mas as transformações de rotação (acompanhando a tangente da spline) não atingem a câmera cinematográfica, como pretendido.\n\n## Circuito\n\nA rota que tracei para o passáro foi formada pela interpolação de 12 pontos no cenário que determinei para que ela seguisse o seguinte percurso:\n\n 1. O pássaro começa passando por cima da cachoeira;\n 2. Em seguida, passa por debaixo da ponte com o pescador;\n 3. Sobrevoa os cervos;\n 4. Contorna o moinho de vento;\n 5. Passa por entre as torres mais altas do castelo e dá um \"mergulho\", saindo pelas portas da construção;\n 6. Vira a direita na casa com telhado cinza;\n 7. Sobrevoa as ovelhas;\n 8. Volta ao ponto inicial.\n\n## Modo Câmera Livre\n\nPara facilitar a montagem da curva, adicionei um modo de câmera livre à aplicação, acessível pela aba \"Câmera Livre\". Nela, faço uso dos [Fly Controls](https://threejs.org/docs/#examples/en/controls/FlyControls) do Three.js. Nesse modo, é possível navegar livremente pelo cenário. Assim, para montar o caminho, bastou navegar pela câmera livre até o local que eu achava apropriado para a adição de um ponto à minha lista de pontos e registrar a coordenada no espaço do mundo, que pode ser encontrada na janela de informações, habilitada através da interface gráfica.\n\n## GUI (Interface Gráfica)\n\n\u003cimg src=\"./imgs/gui.png\" alt=\"Interface gráfica gerada através da biblioteca lil-gui\" width=\"250\"/\u003e\n\nA interface para os controles da aplicação foi gerada com a biblioteca [lil-gui](https://lil-gui.georgealways.com/). Nem todos os controles estão disponíveis no modo de câmera livre, pois apenas alguns controles fazem sentido nesse modo.\n\n**Câmera:**\n - *Câmera*: Menu dropdown para selecionar a câmera ativa da visualização de perspectiva (PrimeiraPessoa, TerceiraPessoa, DroneNormal ou Cinematográfica).\n - *ÂnguloCâmera*: Visível apenas quando a câmera cinematográfica está selecionada, controla a rotação da câmera cinematográfica ao redor do pássaro.\n - *FOV*: Controla o campo de visão da câmera da visualização de perspectiva.\n - *Far*: Controla a distância do plano *far* de recorte da câmera (plano que limita o quão longe a câmera enxerga).\n\n**Animação:**\n - *Botão Play/Pause*: Retoma/Pausa a reprodução da animação.\n - *Velocidade*: Controla a velocidade da reprodução da animação.\n - *Reprodução*: Controla a posição da câmera na spline. Automaticamente atualizado durante a animação, mas pode ter seu valor modificado manualmente pelo usuário.\n\n**Outros:**\n - *Gravidade*: Controla a influência da orientação do pássaro em sua velocidade. Em 0, a velocidade é constante durante todo percurso, para qualquer outro valor, o pássaro fica mais rápido quando inclinado para baixo (quanto menor a coordenada y do vetor de direção, mais rápido). Essa funcionalidade torna a simulação um pouco mais realista e a diferença é mais perceptível no momento da animação no qual o pássaro \"dá um mergulho\" dentro do castelo.\n - *MostrarRota*: Checkbox que habilita/desabilita a visualização da curva que descreve a trajetória do grupo de translação.\n - *MostrarKeypoints*: Checkbox que habilita/desabilita a visualização das esferas que representam os pontos utilizados para gerar a spline.\n - *Informações*: Checkbox que habilita/desabilita a visualização da janela de debug, com algumas informações úteis durante o desenvolvimento sobre o estado atual da simulação.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucastborges%2Fanimacao_camera","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flucastborges%2Fanimacao_camera","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucastborges%2Fanimacao_camera/lists"}