/cs123_final

Intro to Computer Graphics (CSCI1230) Final Project: Procedural Plant Generation using L-Systems

Primary LanguageC

████████╗██╗  ██╗███████╗    ██████╗ ██╗   ██╗███╗   ██╗ ██████╗ ███████╗ ██████╗ ███╗   ██╗ 
╚══██╔══╝██║  ██║██╔════╝    ██╔══██╗██║   ██║████╗  ██║██╔════╝ ██╔════╝██╔═══██╗████╗  ██║ 
   ██║   ███████║█████╗      ██║  ██║██║   ██║██╔██╗ ██║██║  ███╗█████╗  ██║   ██║██╔██╗ ██║ 
   ██║   ██╔══██║██╔══╝      ██║  ██║██║   ██║██║╚██╗██║██║   ██║██╔══╝  ██║   ██║██║╚██╗██║ 
   ██║   ██║  ██║███████╗    ██████╔╝╚██████╔╝██║ ╚████║╚██████╔╝███████╗╚██████╔╝██║ ╚████║ 
   ╚═╝   ╚═╝  ╚═╝╚══════╝    ╚═════╝  ╚═════╝ ╚═╝  ╚═══╝ ╚═════╝ ╚══════╝ ╚═════╝ ╚═╝  ╚═══╝ 
                                                                                             
 ██████╗ ███████╗    ██╗      ███████╗██╗   ██╗███████╗████████╗███████╗███╗   ███╗          
██╔═══██╗██╔════╝    ██║      ██╔════╝╚██╗ ██╔╝██╔════╝╚══██╔══╝██╔════╝████╗ ████║          
██║   ██║█████╗      ██║█████╗███████╗ ╚████╔╝ ███████╗   ██║   █████╗  ██╔████╔██║          
██║   ██║██╔══╝      ██║╚════╝╚════██║  ╚██╔╝  ╚════██║   ██║   ██╔══╝  ██║╚██╔╝██║          
╚██████╔╝██║         ███████╗ ███████║   ██║   ███████║   ██║   ███████╗██║ ╚═╝ ██║          
 ╚═════╝ ╚═╝         ╚══════╝ ╚══════╝   ╚═╝   ╚══════╝   ╚═╝   ╚══════╝╚═╝     ╚═╝          
                                                                                             
 ██████╗ ███████╗███╗   ██╗███████╗██████╗  █████╗ ████████╗███████╗██████╗                  
██╔════╝ ██╔════╝████╗  ██║██╔════╝██╔══██╗██╔══██╗╚══██╔══╝██╔════╝██╔══██╗                 
██║  ███╗█████╗  ██╔██╗ ██║█████╗  ██████╔╝███████║   ██║   █████╗  ██║  ██║                 
██║   ██║██╔══╝  ██║╚██╗██║██╔══╝  ██╔══██╗██╔══██║   ██║   ██╔══╝  ██║  ██║                 
╚██████╔╝███████╗██║ ╚████║███████╗██║  ██║██║  ██║   ██║   ███████╗██████╔╝                 
 ╚═════╝ ╚══════╝╚═╝  ╚═══╝╚══════╝╚═╝  ╚═╝╚═╝  ╚═╝   ╚═╝   ╚══════╝╚═════╝                  
                                                                                             
██████╗ ██╗      █████╗ ███╗   ██╗████████╗███████╗     █████╗ ███╗   ██╗██████╗             
██╔══██╗██║     ██╔══██╗████╗  ██║╚══██╔══╝██╔════╝    ██╔══██╗████╗  ██║██╔══██╗            
██████╔╝██║     ███████║██╔██╗ ██║   ██║   ███████╗    ███████║██╔██╗ ██║██║  ██║            
██╔═══╝ ██║     ██╔══██║██║╚██╗██║   ██║   ╚════██║    ██╔══██║██║╚██╗██║██║  ██║            
██║     ███████╗██║  ██║██║ ╚████║   ██║   ███████║    ██║  ██║██║ ╚████║██████╔╝            
╚═╝     ╚══════╝╚═╝  ╚═╝╚═╝  ╚═══╝   ╚═╝   ╚══════╝    ╚═╝  ╚═╝╚═╝  ╚═══╝╚═════╝             
                                                                                             
███╗   ██╗ ██████╗ ██████╗ ███╗   ███╗ █████╗ ██╗         ███╗   ███╗ █████╗ ██████╗ ███████╗
████╗  ██║██╔═══██╗██╔══██╗████╗ ████║██╔══██╗██║         ████╗ ████║██╔══██╗██╔══██╗██╔════╝
██╔██╗ ██║██║   ██║██████╔╝██╔████╔██║███████║██║         ██╔████╔██║███████║██████╔╝███████╗
██║╚██╗██║██║   ██║██╔══██╗██║╚██╔╝██║██╔══██║██║         ██║╚██╔╝██║██╔══██║██╔═══╝ ╚════██║
██║ ╚████║╚██████╔╝██║  ██║██║ ╚═╝ ██║██║  ██║███████╗    ██║ ╚═╝ ██║██║  ██║██║     ███████║
╚═╝  ╚═══╝ ╚═════╝ ╚═╝  ╚═╝╚═╝     ╚═╝╚═╝  ╚═╝╚══════╝    ╚═╝     ╚═╝╚═╝  ╚═╝╚═╝     ╚══════╝
                                                                                             

This project was made by Jiajie Chen, Joseph Bellavia, and Will Thompson.
(jc124, jbellavi, wcthomps)
We worked very hard on this project.
Please let us pass the class.


       =================== TEXTURE MAPS ======================
Texture map coordinates (u,v) are computed for each vertex by the CPU.
Once computed, they are passed the the vertex and fragment shaders which
interpolate the (u, v) coordinates of each fragment.  A lookup is performed
on the texture Sampler2D and the base color is assigned to the fragment.
This color is then adjusted based on lighting and normal maps.


       =================== NORMAL MAPS =======================
Normal map coordinates (u,v) are always lined up with texture map
coordinates to prevent these two from separating, which would cause the two
maps to display at different intervals, which would be undesirable.  The lookup
is performed in the same way as the texture map lookup.  Once it has been looked up,
the three channels (rgb) are treated as (xyz) values which will be used to
adjust the normal used for lighting calculation at that fragment.

In order to adjust the normal, the shader must first compute two tangents to
the surface and the actual surface normal for the fragment, all of which are
mutually perpendicular to each other.  This set of normals and tangents, along
with the xyz on the normal map are then used to determine the value of the
normal after adjustment.  After the normal has been adjusted, lighting calculations
are performed using this new normal, which has been perturbed according to the rules
above.


       ==================== L-SYSTEMS ========================
We extended CS123XmlSceneParser to handle 'lsystem' blocks that represent the rules and the axiom of an LSystem.
The LSystem info is given to a LSystemGenerator to handle the LSystem materials, and generate iterations of the LSystem after rewriting.

LSystem Rules:
F, X: move forward & draw
f: move forward 
+: rotate clockwise about up axis (defaults to object z-axis in our scene)
-: rotate ccw about up axis 
&: rotate clockwise about left axis (defaults to object x-axis)
^: rotate ccw about left axis
\: rotate clockwise about heading axis (defaults to object y-axis) 
/: rotate ccw about heading axis
|: rotate 180 about up
": increase state length
`: decrease state length
!: increase state width
~: decrease state width
,: use next material if available 
.: use previous material if available 
[: push state onto stack
]: pop state from stack


Once the rules for an LSystem are generated, we pass them to a special shape type (does not actually extend the base shape class) LShape. An LShape parses the rules and builds the geometry on the fly. Whenever the command to add geometry with the current parameters is encountered, the triangles for a custom shape (cylinder with a rounded end) are added to a cumlative vector of triangles and transformed as per the current state. A CFM is used to keep track of the relative position of each 'state' and is applied to the triangles before being stored. The LShape is backed by OpenGLShapes representing the geometry of each material in the structure (branches and leaves, for example). After parsing and building up triangle arrays, the LShape prepares it's individual shapes for rendering by packing the triangle data into vertex buffers for each material-subshape. The rendering is handled in SceneviewScene as in the projects. 

We keep a cache of completed rulesets to precomputed shapes to avoid recomputing complex geometry. 




       ====================== CAMERA =========================

We implemented a POVCamera, which is contraollable by mouse and keyboard.
POVCamera allows the user to control the camera angle with their mouse, and the camera position with their arrow keys.
POVCamera is set up with the scene's camera data. It is used to view a given scene.
We make it so the up vector is always on the positive y axis, so it remains upright.
We also make sure movement is constrained to the xy plane, to avoid going out of distance.
In our main scene file (loaded automatically), pressing the '[' amd ']' keys will increase the allowed lsystem depth (each system is capped with its own max).