City Explore
Tags: octograd2020, devgrad2020
Published: 2020-05-21 19:52:17

[Comment]: # (All of this is placeholder text. Use this format or any other format of your choosing to best describe your project and experience.)

[Note]: # (If you used the GitHub Student Developer Pack on your project, add the "#githubsdp" tag above. We’d also love to know which services you used and how you used it!)

## My Final Project
This project is designed to not only display the beautiful Cal Poly campus environment but also reflect a popular discussion topic nowadays- Coronavirus Crisis. It's done using OpenGL, C++, and an open-source tool - TinyObjLoader. I am excited to see how real-world remote sensing data enriches this interactive computer graphic project. To reduce the size of the raw data, the quality 3D obj mesh has to be compromised.

#Graphics Features#
1. Camera Control
2. Point Cloud to OBJ conversion
3. Vertex Color Enhancement
4. Cubemap/Skybox
5. Collision Detection
6. Terrain Detection
7. Hierarchical Models

## Link to Code
https://github.com/ChenxiXiao/CPE471/tree/master/SLO%20City%20Explore

[Note]: # (Our markdown editor supports pretty embeds. If you're sharing a GitHub repo, try this syntax: `{% github link_to_your_repo %}`)

## How I built it 
**Camera Control**
My original intent is let players to experience a virtual tour of the Cal Poly campus. Therefore I implemented a first-person-view camera where the player is placed in front of the camera in the direction towards target. The player is translated horizontally according to the keyboard update. Whenever the player presses one of the WASD keys, the camera's position will be updated accordingly. The Player's vertical offset is set by the terrain height. The player can use the mouse scroll to look around. Accordingly, the View matrix will be adjusted by the new "eye" and "lookAt" value.

**Point Cloud to OBJ conversion**
       
For the 3D campus scene, I discovered many ways to generate OBJ from Point Cloud data. The raw LiDAR data comes from a recent survey from the San Luis Obispo County. There is software like ArcGIS Pro, MeshLab, and Agisoft Metashape that perform such data processing and generates 3D spatial models. Through trials and errors, Agisoft Metashape Pro is able to write out vertex color (RGB) directly into the OBJ file, which comes handy later on. However, the counterpart is the exported mesh is blurred. Generating a "clean" mesh of the buildings and trees needs intensive effort. If time permitted, I would separate the entire mesh into a multi-mesh with buildings, terrain, trees, path, etc by restraining the shape based on basic geometric shapes.
![Mesh Overview](https://dev-to-uploads.s3.amazonaws.com/i/1tvi0613bn1p9wgxfaon.jpg)



**Vertex Color Enhancement**
Each vertex comes with X Y Z coordinates by default, some come with vertex color R G B value in addition. I modified the tinyOBJloader, Shape.cpp/h, and added a feature so it reads vertex color if there appears to be any, similar to how it reads vertex normal.
![OBJloader](https://dev-to-uploads.s3.amazonaws.com/i/0kk7kqqdsgogcixzj0kb.jpg)

**Cubemap/Skybox**
A Skybox consists of 6 2D pictures of the blue sky. Cube mapping enriches the background and makes the campus look more realistic. Future improvements could be replacing the pictures with a real scene of San Luis Obispo, where players can see Bishop mountain and the "P".

**Collision Detection**
My ideal collision detection would be between the player and the scene (trees, buildings). However, since the mesh comes with a single obj, computing collision planes for the entire landscape will be very expensive and challenging. Therefore my goal is to get through the campus safely without virus infection. The player has to detect the viruses and surgical mask. I check for overlap on both axes - X and Z. If there is a collision on both X-axis and the Z-axis, then return a collision. I set a radius for each virus due to its circular shape and computer a bounding box. When the player (a point) enters the sphere of the circle, then collision happened. If collides with viruses, the virus will follow the player to find a mask. When the player wears the mask, the virus can't get to him anymore.

**Terrain Detection**
Y and Z axis for the 3D campus mesh is reversed, therefore instead of using "Matrix->rotate()", I wrote my own rotation function which takes an angle and a vec3(x,y,z), modify the shape.mesh.positions value based on the rotation angle. After proper manual transformation, I saved an average height of the grid into a 2D array. I can get the corresponding height using the current X and Z value.

**Hierarchical Models**
I found a "Minecraft-styled" person in (multi-)Obj format from Turbosquid. I added texture mapping and basic hierarchical modeling. The player will rotate its feet based on the waist.



## Additional Thoughts / Feelings / Stories