diff --git a/INSTRUCTIONS.md b/INSTRUCTIONS.md new file mode 100644 index 0000000..c1cda32 --- /dev/null +++ b/INSTRUCTIONS.md @@ -0,0 +1,130 @@ +# Homework 4: L-systems + +For this assignment, you will design a set of formal grammar rules to create +a plant life using an L-system program. Once again, you will work from a +TypeScript / WebGL 2.0 base code like the one you used in homework 0. You will +implement your own set of classes to handle the L-system grammar expansion and +drawing. You will rasterize your L-system using faceted geometry. Feel free +to use ray marching to generate an interesting background, but trying to +raymarch an entire L-system will take too long to render! + +## Base Code +The provided code is very similar to that of homework 1, with the same camera and GUI layout. Additionally, we have provided you with a `Mesh` class that, given a filepath, will construct VBOs describing the vertex positions, normals, colors, uvs, and indices for any `.obj` file. The provided code also uses instanced rendering to draw a single square 10,000 times at different locations and with different colors; refer to the Assignment Requirements section for more details on instanced rendering. Farther down this README, we have also provided some example code snippets for setting up hash map structures in TypeScript. + +## Assignment Requirements +- __(15 points)__ Create a collection of classes to represent an L-system. You should have at least the following components to make your L-system functional: + - A `Turtle` class to represent the current drawing state of your L-System. It should at least keep track of its current position, current orientation, and recursion depth (how many `[` characters have been found while drawing before `]`s) + - A stack of `Turtle`s to represent your `Turtle` history. Push a copy of your current `Turtle` onto this when you reach a `[` while drawing, and pop the top `Turtle` from the stack and make it your current `Turtle` when you encounter a `]`. Note that in TypeScript, `push()` and `pop()` operations can be done on regular arrays. + - An expandable string of characters to represent your grammar as you iterate on it. + - An `ExpansionRule` class to represent the result of mapping a particular character to a new set of characters during the grammar expansion phase of the L-System. By making a class to represent the expansion, you can have a single character expand to multiple possible strings depending on some probability by querying a `Map`. + - A `DrawingRule` class to represent the result of mapping a character to an L-System drawing operation (possibly with multiple outcomes depending on a probability). + +- __(10 points)__ Set up the code in `main.ts` and `ShaderProgram.ts` to pass a collection of transformation data to the GPU to draw your L-System geometric components using __instanced rendering__. We will be using instanced rendering to draw our L-Systems because it is much more efficient to pass a single transformation for each object to be drawn rather than an entire collection of vertices. The provided base code has examples of passing a set of `vec3`s to offset the position of each instanced object, and a set of `vec4`s to change the color of each object. You should at least alter the following via instanced rendering (note that these can be accomplished with a single `mat4`): + - Position + - Orientation + - Scaling + +- __(55 points)__ Your L-System scene must have the following attributes: + - Your plant must grow in 3D (branches must not just exist in one plane) + - Your plant must have flowers, leaves, or some other branch decoration in addition to basic branch geometry + - Organic variation (i.e. noise or randomness in grammar expansion and/or drawing operations) + - The background should be a colorful backdrop to complement your plant, incorporating some procedural elements. + - A flavorful twist. Don't just make a basic variation of the example F[+FX]-FX from the slides! Create a plant that is unique to you. Make an alien tentacle monster plant if you want to! Play around with drawing operations; don't feel compelled to always make your branches straight lines. Curved forms can look quite visually appealing too. + +- __(10 points)__ Using dat.GUI, make at least three aspects of your L-System interactive, such as: + - The probability thresholds in your grammar expansions + - The angle of rotation in various drawing aspects + - The size or color or material of the plant components + - Anything else in your L-System expansion or drawing you'd like to make modifiable; it doesn't have to be these particular elements + +- __(10 points)__ Following the specifications listed +[here](https://github.com/pjcozzi/Articles/blob/master/CIS565/GitHubRepo/README.md), +create your own README.md, renaming the file you are presently reading to +INSTRUCTIONS.md. Don't worry about discussing runtime optimization for this +project. Make sure your README contains the following information: + - Your name and PennKey + - Citation of any external resources you found helpful when implementing this + assignment. + - A link to your live github.io demo (refer to the pinned Piazza post on + how to make a live demo through github.io) + - An explanation of the techniques you used to generate your L-System features. + Please be as detailed as you can; not only will this help you explain your work + to recruiters, but it helps us understand your project when we grade it! + +## Writing classes and functions in TypeScript +Example of a basic Turtle class in TypeScript (Turtle.ts) +``` +import {vec3} from 'gl-matrix'; + +export default class Turtle { + constructor(pos: vec3, orient: vec3) { + this.position = pos; + this.orientation = orient; + } + + moveForward() { + add(this.position, this.position, this.orientation * 10.0); + } +} +``` +Example of a hash map in TypeScript: +``` +let expansionRules : Map = new Map(); +expansionRules.set('A', 'AB'); +expansionRules.set('B', 'A'); + +console.log(expansionRules.get('A')); // Will print out 'AB' +console.log(expansionRules.get('C')); // Will print out 'undefined' +``` +Using functions as map values in TypeScript: +``` +function moveForward() {...} +function rotateLeft() {...} +let drawRules : Map = new Map(); +drawRules.set('F', moveForward); +drawRules.set('+', rotateLeft); + +let func = drawRules.get('F'); +if(func) { // Check that the map contains a value for this key + func(); +} +``` +Note that in the above case, the code assumes that all functions stored in the `drawRules` map take in no arguments. If you want to store a class's functions as values in a map, you'll have to refer to a specific instance of a class, e.g. +``` +let myTurtle: Turtle = new Turtle(); +let drawRules: Map = new Map(); +drawRules.set('F', myTurtle.moveForward.bind(myTurtle)); +let func = drawRules.get('F'); +if(func) { // Check that the map contains a value for this key + func(); +} +``` +TypeScript's `bind` operation sets the `this` variable inside the bound function to refer to the object inside `bind`. This ensures that the `Turtle` in question is the one on which `moveForward` is invoked when `func()` is called with no object. + +## Examples from previous years (Click to go to live demo) + +Andrea Lin: + +[![](andreaLin.png)](http://andrea-lin.com/Project3-LSystems/) + +Ishan Ranade: + +[![](ishanRanade.png)](https://ishanranade.github.io/homework-4-l-systems-IshanRanade/) + +Joe Klinger: + +[![](joeKlinger.png)](https://klingerj.github.io/Project3-LSystems/) + +Linshen Xiao: + +[![](linshenXiao.png)](https://githublsx.github.io/homework-4-l-systems-githublsx/) + +## Useful Resources +- [The Algorithmic Beauty of Plants](http://algorithmicbotany.org/papers/abop/abop-ch1.pdf) +- [OpenGL Instanced Rendering (Learn OpenGL)](https://learnopengl.com/Advanced-OpenGL/Instancing) +- [OpenGL Instanced Rendering (OpenGL-Tutorial)](http://www.opengl-tutorial.org/intermediate-tutorials/billboards-particles/particles-instancing/) + +## Extra Credit (Up to 20 points) +- For bonus points, add functionality to your L-system drawing that ensures geometry will never overlap. In other words, make your plant behave like a real-life plant so that its branches and other components don't compete for the same space. The more complex you make your L-system self-interaction, the more +points you'll earn. +- Any additional visual polish you add to your L-System will count towards extra credit, at your grader's discretion. For example, you could add animation of the leaves or branches in your vertex shader, or add falling leaves or flower petals. diff --git a/README.md b/README.md index c1cda32..12a909c 100644 --- a/README.md +++ b/README.md @@ -1,130 +1,69 @@ -# Homework 4: L-systems - -For this assignment, you will design a set of formal grammar rules to create -a plant life using an L-system program. Once again, you will work from a -TypeScript / WebGL 2.0 base code like the one you used in homework 0. You will -implement your own set of classes to handle the L-system grammar expansion and -drawing. You will rasterize your L-system using faceted geometry. Feel free -to use ray marching to generate an interesting background, but trying to -raymarch an entire L-system will take too long to render! - -## Base Code -The provided code is very similar to that of homework 1, with the same camera and GUI layout. Additionally, we have provided you with a `Mesh` class that, given a filepath, will construct VBOs describing the vertex positions, normals, colors, uvs, and indices for any `.obj` file. The provided code also uses instanced rendering to draw a single square 10,000 times at different locations and with different colors; refer to the Assignment Requirements section for more details on instanced rendering. Farther down this README, we have also provided some example code snippets for setting up hash map structures in TypeScript. - -## Assignment Requirements -- __(15 points)__ Create a collection of classes to represent an L-system. You should have at least the following components to make your L-system functional: - - A `Turtle` class to represent the current drawing state of your L-System. It should at least keep track of its current position, current orientation, and recursion depth (how many `[` characters have been found while drawing before `]`s) - - A stack of `Turtle`s to represent your `Turtle` history. Push a copy of your current `Turtle` onto this when you reach a `[` while drawing, and pop the top `Turtle` from the stack and make it your current `Turtle` when you encounter a `]`. Note that in TypeScript, `push()` and `pop()` operations can be done on regular arrays. - - An expandable string of characters to represent your grammar as you iterate on it. - - An `ExpansionRule` class to represent the result of mapping a particular character to a new set of characters during the grammar expansion phase of the L-System. By making a class to represent the expansion, you can have a single character expand to multiple possible strings depending on some probability by querying a `Map`. - - A `DrawingRule` class to represent the result of mapping a character to an L-System drawing operation (possibly with multiple outcomes depending on a probability). - -- __(10 points)__ Set up the code in `main.ts` and `ShaderProgram.ts` to pass a collection of transformation data to the GPU to draw your L-System geometric components using __instanced rendering__. We will be using instanced rendering to draw our L-Systems because it is much more efficient to pass a single transformation for each object to be drawn rather than an entire collection of vertices. The provided base code has examples of passing a set of `vec3`s to offset the position of each instanced object, and a set of `vec4`s to change the color of each object. You should at least alter the following via instanced rendering (note that these can be accomplished with a single `mat4`): - - Position - - Orientation - - Scaling - -- __(55 points)__ Your L-System scene must have the following attributes: - - Your plant must grow in 3D (branches must not just exist in one plane) - - Your plant must have flowers, leaves, or some other branch decoration in addition to basic branch geometry - - Organic variation (i.e. noise or randomness in grammar expansion and/or drawing operations) - - The background should be a colorful backdrop to complement your plant, incorporating some procedural elements. - - A flavorful twist. Don't just make a basic variation of the example F[+FX]-FX from the slides! Create a plant that is unique to you. Make an alien tentacle monster plant if you want to! Play around with drawing operations; don't feel compelled to always make your branches straight lines. Curved forms can look quite visually appealing too. - -- __(10 points)__ Using dat.GUI, make at least three aspects of your L-System interactive, such as: - - The probability thresholds in your grammar expansions - - The angle of rotation in various drawing aspects - - The size or color or material of the plant components - - Anything else in your L-System expansion or drawing you'd like to make modifiable; it doesn't have to be these particular elements - -- __(10 points)__ Following the specifications listed -[here](https://github.com/pjcozzi/Articles/blob/master/CIS565/GitHubRepo/README.md), -create your own README.md, renaming the file you are presently reading to -INSTRUCTIONS.md. Don't worry about discussing runtime optimization for this -project. Make sure your README contains the following information: - - Your name and PennKey - - Citation of any external resources you found helpful when implementing this - assignment. - - A link to your live github.io demo (refer to the pinned Piazza post on - how to make a live demo through github.io) - - An explanation of the techniques you used to generate your L-System features. - Please be as detailed as you can; not only will this help you explain your work - to recruiters, but it helps us understand your project when we grade it! - -## Writing classes and functions in TypeScript -Example of a basic Turtle class in TypeScript (Turtle.ts) -``` -import {vec3} from 'gl-matrix'; - -export default class Turtle { - constructor(pos: vec3, orient: vec3) { - this.position = pos; - this.orientation = orient; - } - - moveForward() { - add(this.position, this.position, this.orientation * 10.0); - } -} -``` -Example of a hash map in TypeScript: -``` -let expansionRules : Map = new Map(); -expansionRules.set('A', 'AB'); -expansionRules.set('B', 'A'); - -console.log(expansionRules.get('A')); // Will print out 'AB' -console.log(expansionRules.get('C')); // Will print out 'undefined' -``` -Using functions as map values in TypeScript: -``` -function moveForward() {...} -function rotateLeft() {...} -let drawRules : Map = new Map(); -drawRules.set('F', moveForward); -drawRules.set('+', rotateLeft); - -let func = drawRules.get('F'); -if(func) { // Check that the map contains a value for this key - func(); -} -``` -Note that in the above case, the code assumes that all functions stored in the `drawRules` map take in no arguments. If you want to store a class's functions as values in a map, you'll have to refer to a specific instance of a class, e.g. -``` -let myTurtle: Turtle = new Turtle(); -let drawRules: Map = new Map(); -drawRules.set('F', myTurtle.moveForward.bind(myTurtle)); -let func = drawRules.get('F'); -if(func) { // Check that the map contains a value for this key - func(); -} -``` -TypeScript's `bind` operation sets the `this` variable inside the bound function to refer to the object inside `bind`. This ensures that the `Turtle` in question is the one on which `moveForward` is invoked when `func()` is called with no object. - -## Examples from previous years (Click to go to live demo) - -Andrea Lin: - -[![](andreaLin.png)](http://andrea-lin.com/Project3-LSystems/) - -Ishan Ranade: - -[![](ishanRanade.png)](https://ishanranade.github.io/homework-4-l-systems-IshanRanade/) - -Joe Klinger: - -[![](joeKlinger.png)](https://klingerj.github.io/Project3-LSystems/) - -Linshen Xiao: - -[![](linshenXiao.png)](https://githublsx.github.io/homework-4-l-systems-githublsx/) - -## Useful Resources -- [The Algorithmic Beauty of Plants](http://algorithmicbotany.org/papers/abop/abop-ch1.pdf) -- [OpenGL Instanced Rendering (Learn OpenGL)](https://learnopengl.com/Advanced-OpenGL/Instancing) -- [OpenGL Instanced Rendering (OpenGL-Tutorial)](http://www.opengl-tutorial.org/intermediate-tutorials/billboards-particles/particles-instancing/) - -## Extra Credit (Up to 20 points) -- For bonus points, add functionality to your L-system drawing that ensures geometry will never overlap. In other words, make your plant behave like a real-life plant so that its branches and other components don't compete for the same space. The more complex you make your L-system self-interaction, the more -points you'll earn. -- Any additional visual polish you add to your L-System will count towards extra credit, at your grader's discretion. For example, you could add animation of the leaves or branches in your vertex shader, or add falling leaves or flower petals. +# L-systems Coral + +## Serena Gandhi (gserena) +## Link: https://gserena01.github.io/hw04-l-systems/ + +# Sample Images: + +Using Defaults: + +![image](https://user-images.githubusercontent.com/70620606/141114197-943c1a9b-8b4b-4fd5-955d-5a7ab70e2690.png) + +With Color and Decoration Size Change: + +![image](https://user-images.githubusercontent.com/70620606/141115420-030dba2a-7b8e-4824-b2ab-2fa850b5f5ec.png) + +With Iterations and Angle Change: + +![image](https://user-images.githubusercontent.com/70620606/141115687-21989520-a6ba-420d-b907-5d93a2c7465a.png) + +The Tool in Action: + +https://user-images.githubusercontent.com/70620606/141118237-24d21cf8-ae9f-4f39-bc3b-92cce27468b0.mp4 + + +# How It All Went Down: + +This project started with my inspiration, the coral. From here, I generated samples of my L-System grammar in the 2D L-System Visualizer (linked below) and in Houdini. Once my grammar was finalized, I moved on to coding. + +Admittedly, I had to start and re-start this project, but my final version used the following pipeline: + +First, I rendered out a single branch using the instanced shader. This helped me familiarize myself with instanced rendering, as well as ensure that, if my L-System is working properly, something will show up in my viewport. + +Then, I started working on my L-System. I created Turtle, Expansion Rule, and Drawing Rule classes, which were all used in conjunction in the L-System Class. The Turtle class recorded and altered the current position and orientation of the "turtle." The expansion rule classes expanded the grammar I described, using some randomness. The Drawing Rule class selected drawing rules based on the provided grammar, using some randomness. + +To start, I set my grammar to be two iterations of a simple "FF". This way, I could easily test whether my rules were working. Also, to start, I only included rotation in 2D. + +Once my grammar was properly working, I added 3D rotation and expanded the grammar to the current version. + +From here, I added the branch decoration and incorporated randomness in my grammar by adjusting each angle drawn by no more than 10 degrees in either direction (sampled on a curve, not uniformly, to ensure that larger angle changes are less common). I also added additional rules that could terminate the grammar with a branch decoration. + +Next, I worked on the background, adding the various colors and animating them on a sine curve. I also added stripes to my tree shader for a little extra fun! The stripes are made using the current color's inverse, for a little extra POP! + +Finally, I added the sand base and the gui elements to make my project a tool to make many corals! + +# Samples of L-System Using Tools: + +2D L-System Visualizer: + +![image](https://user-images.githubusercontent.com/60444726/138163560-f8537878-23f3-4a77-aae0-31b7e6201581.png) + +Houdini: + +![Screenshot 2021-10-20 200324](https://user-images.githubusercontent.com/60444726/138274074-d694a82b-69f7-44e3-a6fc-c970d17ae49c.png) + +# Reference Images: + +![image](https://user-images.githubusercontent.com/60444726/140631834-e2863c3f-1e70-4da8-9daa-1c8201c916e9.png) + +![image](https://user-images.githubusercontent.com/60444726/140631851-8845bd07-5ccd-40ed-b130-9c029304b2e5.png) + +![image](https://user-images.githubusercontent.com/60444726/140631854-348ce9c7-f722-4cbc-8ce8-d105a5965d84.png) + +# External Resources: + +Using Callback Functions: https://stackoverflow.com/questions/14471975/how-can-i-preserve-lexical-scope-in-typescript-with-a-callback-function + +L-System Visualizer: https://www.kevs3d.co.uk/dev/lsystems/ + +Color Palette: https://icolorpalette.com/color/ocean-blue diff --git a/package-lock.json b/package-lock.json index 095aa6c..f370cda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1743,7 +1743,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -1764,12 +1765,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1784,17 +1787,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -1911,7 +1917,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -1923,6 +1930,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1937,6 +1945,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1944,12 +1953,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -1968,6 +1979,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -2048,7 +2060,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -2060,6 +2073,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -2145,7 +2159,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -2181,6 +2196,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2200,6 +2216,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -2243,12 +2260,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, diff --git a/resources/base.mtl b/resources/base.mtl new file mode 100644 index 0000000..f231bdf --- /dev/null +++ b/resources/base.mtl @@ -0,0 +1,10 @@ +# Blender MTL File: 'None' +# Material Count: 1 + +newmtl None +Ns 500 +Ka 0.8 0.8 0.8 +Kd 0.8 0.8 0.8 +Ks 0.8 0.8 0.8 +d 1 +illum 2 diff --git a/resources/base.obj b/resources/base.obj new file mode 100644 index 0000000..a66ab5b --- /dev/null +++ b/resources/base.obj @@ -0,0 +1,285 @@ +# Blender v2.83.0 OBJ File: '' +# www.blender.org +mtllib base.mtl +o Sphere +v 0.000000 0.707107 -1.580931 +v 0.000000 0.382683 -2.065585 +v 0.327421 0.923880 -0.790465 +v 0.604996 0.707107 -1.460589 +v 0.790465 0.382683 -1.908352 +v 0.855593 -0.000000 -2.065585 +v 0.604996 0.923880 -0.604996 +v 1.117887 0.707107 -1.117887 +v 1.460589 0.382683 -1.460589 +v 1.580930 -0.000000 -1.580931 +v 0.790465 0.923880 -0.327422 +v 1.460589 0.707107 -0.604996 +v 1.908352 0.382683 -0.790465 +v 2.065585 -0.000000 -0.855593 +v 0.855593 0.923880 -0.000000 +v 1.580930 0.707107 -0.000000 +v 2.065585 0.382683 -0.000000 +v 2.235773 -0.000000 -0.000000 +v 0.790465 0.923880 0.327421 +v 1.460589 0.707107 0.604996 +v 1.908352 0.382683 0.790465 +v 2.065585 -0.000000 0.855593 +v 0.604996 0.923880 0.604995 +v 1.117886 0.707107 1.117886 +v 1.460589 0.382683 1.460589 +v 1.580930 -0.000000 1.580930 +v 0.327421 0.923880 0.790465 +v 0.604995 0.707107 1.460589 +v 0.790465 0.382683 1.908352 +v 0.855593 -0.000000 2.065585 +v -0.000000 0.923880 0.855593 +v -0.000001 0.707107 1.580930 +v -0.000001 0.382683 2.065585 +v -0.000001 -0.000000 2.235773 +v -0.327422 0.923880 0.790465 +v -0.604996 0.707107 1.460588 +v -0.790466 0.382683 1.908351 +v -0.855594 -0.000000 2.065584 +v -0.604996 0.923880 0.604995 +v -1.117887 0.707107 1.117885 +v -1.460590 0.382683 1.460588 +v -1.580931 -0.000000 1.580929 +v -0.790465 0.923880 0.327421 +v -1.460589 0.707107 0.604995 +v -1.908352 0.382683 0.790464 +v -2.065585 -0.000000 0.855592 +v -0.855593 0.923880 -0.000001 +v -1.580930 0.707107 -0.000001 +v -2.065585 0.382683 -0.000001 +v -2.235773 -0.000000 -0.000001 +v -0.790465 0.923880 -0.327422 +v -1.460588 0.707107 -0.604997 +v -1.908351 0.382683 -0.790466 +v -2.065584 -0.000000 -0.855595 +v -0.604995 0.923880 -0.604996 +v -1.117886 0.707107 -1.117887 +v -1.460588 0.382683 -1.460590 +v -1.580929 -0.000000 -1.580931 +v -0.327421 0.923880 -0.790465 +v -0.604995 0.707107 -1.460589 +v -0.790464 0.382683 -1.908352 +v -0.855592 -0.000000 -2.065585 +v -0.000000 1.000000 -0.000000 +v 0.000000 0.923880 -0.855593 +v 0.000001 -0.000000 -2.235773 +vt 0.750000 0.500000 +vt 0.750000 0.625000 +vt 0.687500 0.625000 +vt 0.687500 0.500000 +vt 0.750000 0.750000 +vt 0.750000 0.875000 +vt 0.687500 0.875000 +vt 0.687500 0.750000 +vt 0.718750 1.000000 +vt 0.625000 0.750000 +vt 0.625000 0.625000 +vt 0.656250 1.000000 +vt 0.625000 0.875000 +vt 0.625000 0.500000 +vt 0.562500 0.750000 +vt 0.562500 0.625000 +vt 0.593750 1.000000 +vt 0.562500 0.875000 +vt 0.562500 0.500000 +vt 0.500000 0.625000 +vt 0.500000 0.500000 +vt 0.500000 0.875000 +vt 0.500000 0.750000 +vt 0.531250 1.000000 +vt 0.437500 0.875000 +vt 0.437500 0.750000 +vt 0.437500 0.625000 +vt 0.468750 1.000000 +vt 0.437500 0.500000 +vt 0.375000 0.750000 +vt 0.375000 0.625000 +vt 0.406250 1.000000 +vt 0.375000 0.875000 +vt 0.375000 0.500000 +vt 0.343750 1.000000 +vt 0.312500 0.875000 +vt 0.312500 0.625000 +vt 0.312500 0.500000 +vt 0.312500 0.750000 +vt 0.250000 0.625000 +vt 0.250000 0.500000 +vt 0.250000 0.875000 +vt 0.250000 0.750000 +vt 0.281250 1.000000 +vt 0.187500 0.750000 +vt 0.187500 0.625000 +vt 0.218750 1.000000 +vt 0.187500 0.875000 +vt 0.187500 0.500000 +vt 0.125000 0.750000 +vt 0.125000 0.625000 +vt 0.156250 1.000000 +vt 0.125000 0.875000 +vt 0.125000 0.500000 +vt 0.062500 0.625000 +vt 0.062500 0.500000 +vt 0.062500 0.875000 +vt 0.062500 0.750000 +vt 0.093750 1.000000 +vt 0.000000 0.625000 +vt 0.000000 0.500000 +vt 0.000000 0.875000 +vt 0.000000 0.750000 +vt 0.031250 1.000000 +vt 1.000000 0.625000 +vt 1.000000 0.750000 +vt 0.937500 0.750000 +vt 0.937500 0.625000 +vt 1.000000 0.875000 +vt 0.968750 1.000000 +vt 0.937500 0.875000 +vt 1.000000 0.500000 +vt 0.937500 0.500000 +vt 0.875000 0.750000 +vt 0.875000 0.625000 +vt 0.906250 1.000000 +vt 0.875000 0.875000 +vt 0.875000 0.500000 +vt 0.812500 0.625000 +vt 0.812500 0.500000 +vt 0.812500 0.875000 +vt 0.812500 0.750000 +vt 0.843750 1.000000 +vt 0.781250 1.000000 +vn 0.1788 0.3998 -0.8990 +vn 0.0569 0.9566 -0.2859 +vn 0.1100 0.8260 -0.5529 +vn 0.0176 0.9959 -0.0886 +vn 0.3132 0.8260 -0.4687 +vn 0.0502 0.9959 -0.0751 +vn 0.5092 0.3998 -0.7621 +vn 0.1619 0.9566 -0.2424 +vn 0.4687 0.8260 -0.3132 +vn 0.0751 0.9959 -0.0502 +vn 0.7621 0.3998 -0.5092 +vn 0.2424 0.9566 -0.1619 +vn 0.8990 0.3998 -0.1788 +vn 0.2859 0.9566 -0.0569 +vn 0.5529 0.8260 -0.1100 +vn 0.0886 0.9959 -0.0176 +vn 0.2859 0.9566 0.0569 +vn 0.5529 0.8260 0.1100 +vn 0.0886 0.9959 0.0176 +vn 0.8990 0.3998 0.1788 +vn 0.4687 0.8260 0.3132 +vn 0.0751 0.9959 0.0502 +vn 0.7621 0.3998 0.5092 +vn 0.2424 0.9566 0.1619 +vn 0.0502 0.9959 0.0751 +vn 0.5092 0.3998 0.7621 +vn 0.1619 0.9566 0.2424 +vn 0.3132 0.8260 0.4687 +vn 0.1788 0.3998 0.8990 +vn 0.0569 0.9566 0.2859 +vn 0.1100 0.8260 0.5529 +vn 0.0176 0.9959 0.0886 +vn -0.1100 0.8260 0.5529 +vn -0.0176 0.9959 0.0886 +vn -0.1788 0.3998 0.8990 +vn -0.0569 0.9566 0.2859 +vn -0.3132 0.8260 0.4687 +vn -0.0502 0.9959 0.0751 +vn -0.5092 0.3998 0.7621 +vn -0.1619 0.9566 0.2424 +vn -0.7621 0.3998 0.5092 +vn -0.2424 0.9566 0.1619 +vn -0.4687 0.8260 0.3132 +vn -0.0751 0.9959 0.0502 +vn -0.8990 0.3998 0.1788 +vn -0.2859 0.9566 0.0569 +vn -0.5529 0.8260 0.1100 +vn -0.0886 0.9959 0.0176 +vn -0.5529 0.8260 -0.1100 +vn -0.0886 0.9959 -0.0176 +vn -0.8990 0.3998 -0.1788 +vn -0.2859 0.9566 -0.0569 +vn -0.4687 0.8260 -0.3132 +vn -0.0751 0.9959 -0.0502 +vn -0.7621 0.3998 -0.5092 +vn -0.2424 0.9566 -0.1619 +vn -0.5092 0.3998 -0.7621 +vn -0.1619 0.9566 -0.2424 +vn 0.0000 -1.0000 0.0000 +vn -0.3132 0.8260 -0.4687 +vn -0.0502 0.9959 -0.0751 +vn -0.0569 0.9566 -0.2859 +vn -0.1100 0.8260 -0.5529 +vn -0.0176 0.9959 -0.0886 +vn -0.1788 0.3998 -0.8990 +usemtl None +s off +f 65/1/1 2/2/1 5/3/1 6/4/1 +f 1/5/2 64/6/2 3/7/2 4/8/2 +f 2/2/3 1/5/3 4/8/3 5/3/3 +f 64/6/4 63/9/4 3/7/4 +f 5/3/5 4/8/5 8/10/5 9/11/5 +f 3/7/6 63/12/6 7/13/6 +f 6/4/7 5/3/7 9/11/7 10/14/7 +f 4/8/8 3/7/8 7/13/8 8/10/8 +f 9/11/9 8/10/9 12/15/9 13/16/9 +f 7/13/10 63/17/10 11/18/10 +f 10/14/11 9/11/11 13/16/11 14/19/11 +f 8/10/12 7/13/12 11/18/12 12/15/12 +f 14/19/13 13/16/13 17/20/13 18/21/13 +f 12/15/14 11/18/14 15/22/14 16/23/14 +f 13/16/15 12/15/15 16/23/15 17/20/15 +f 11/18/16 63/24/16 15/22/16 +f 16/23/17 15/22/17 19/25/17 20/26/17 +f 17/20/18 16/23/18 20/26/18 21/27/18 +f 15/22/19 63/28/19 19/25/19 +f 18/21/20 17/20/20 21/27/20 22/29/20 +f 21/27/21 20/26/21 24/30/21 25/31/21 +f 19/25/22 63/32/22 23/33/22 +f 22/29/23 21/27/23 25/31/23 26/34/23 +f 20/26/24 19/25/24 23/33/24 24/30/24 +f 23/33/25 63/35/25 27/36/25 +f 26/34/26 25/31/26 29/37/26 30/38/26 +f 24/30/27 23/33/27 27/36/27 28/39/27 +f 25/31/28 24/30/28 28/39/28 29/37/28 +f 30/38/29 29/37/29 33/40/29 34/41/29 +f 28/39/30 27/36/30 31/42/30 32/43/30 +f 29/37/31 28/39/31 32/43/31 33/40/31 +f 27/36/32 63/44/32 31/42/32 +f 33/40/33 32/43/33 36/45/33 37/46/33 +f 31/42/34 63/47/34 35/48/34 +f 34/41/35 33/40/35 37/46/35 38/49/35 +f 32/43/36 31/42/36 35/48/36 36/45/36 +f 37/46/37 36/45/37 40/50/37 41/51/37 +f 35/48/38 63/52/38 39/53/38 +f 38/49/39 37/46/39 41/51/39 42/54/39 +f 36/45/40 35/48/40 39/53/40 40/50/40 +f 42/54/41 41/51/41 45/55/41 46/56/41 +f 40/50/42 39/53/42 43/57/42 44/58/42 +f 41/51/43 40/50/43 44/58/43 45/55/43 +f 39/53/44 63/59/44 43/57/44 +f 46/56/45 45/55/45 49/60/45 50/61/45 +f 44/58/46 43/57/46 47/62/46 48/63/46 +f 45/55/47 44/58/47 48/63/47 49/60/47 +f 43/57/48 63/64/48 47/62/48 +f 49/65/49 48/66/49 52/67/49 53/68/49 +f 47/69/50 63/70/50 51/71/50 +f 50/72/51 49/65/51 53/68/51 54/73/51 +f 48/66/52 47/69/52 51/71/52 52/67/52 +f 53/68/53 52/67/53 56/74/53 57/75/53 +f 51/71/54 63/76/54 55/77/54 +f 54/73/55 53/68/55 57/75/55 58/78/55 +f 52/67/56 51/71/56 55/77/56 56/74/56 +f 58/78/57 57/75/57 61/79/57 62/80/57 +f 56/74/58 55/77/58 59/81/58 60/82/58 +f 6/4/59 10/14/59 14/19/59 18/21/59 22/29/59 26/34/59 30/38/59 34/41/59 38/49/59 42/54/59 46/56/59 50/72/59 54/73/59 58/78/59 62/80/59 65/1/59 +f 57/75/60 56/74/60 60/82/60 61/79/60 +f 55/77/61 63/83/61 59/81/61 +f 60/82/62 59/81/62 64/6/62 1/5/62 +f 61/79/63 60/82/63 1/5/63 2/2/63 +f 59/81/64 63/84/64 64/6/64 +f 62/80/65 61/79/65 2/2/65 65/1/65 diff --git a/resources/cylinder.mtl b/resources/cylinder.mtl new file mode 100644 index 0000000..f231bdf --- /dev/null +++ b/resources/cylinder.mtl @@ -0,0 +1,10 @@ +# Blender MTL File: 'None' +# Material Count: 1 + +newmtl None +Ns 500 +Ka 0.8 0.8 0.8 +Kd 0.8 0.8 0.8 +Ks 0.8 0.8 0.8 +d 1 +illum 2 diff --git a/resources/cylinder.obj b/resources/cylinder.obj new file mode 100644 index 0000000..f8857dc --- /dev/null +++ b/resources/cylinder.obj @@ -0,0 +1,140 @@ +# Blender v2.91.2 OBJ File: '' +# www.blender.org +mtllib cylinder.mtl +o Cylinder +v 0.000000 -1.000000 -0.250000 +v 0.000000 1.000000 -0.250000 +v 0.095671 -1.000000 -0.230970 +v 0.095671 1.000000 -0.230970 +v 0.176777 -1.000000 -0.176777 +v 0.176777 1.000000 -0.176777 +v 0.230970 -1.000000 -0.095671 +v 0.230970 1.000000 -0.095671 +v 0.250000 -1.000000 0.000000 +v 0.250000 1.000000 0.000000 +v 0.230970 -1.000000 0.095671 +v 0.230970 1.000000 0.095671 +v 0.176777 -1.000000 0.176777 +v 0.176777 1.000000 0.176777 +v 0.095671 -1.000000 0.230970 +v 0.095671 1.000000 0.230970 +v 0.000000 -1.000000 0.250000 +v 0.000000 1.000000 0.250000 +v -0.095671 -1.000000 0.230970 +v -0.095671 1.000000 0.230970 +v -0.176777 -1.000000 0.176777 +v -0.176777 1.000000 0.176777 +v -0.230970 -1.000000 0.095671 +v -0.230970 1.000000 0.095671 +v -0.250000 -1.000000 -0.000000 +v -0.250000 1.000000 -0.000000 +v -0.230970 -1.000000 -0.095671 +v -0.230970 1.000000 -0.095671 +v -0.176777 -1.000000 -0.176777 +v -0.176777 1.000000 -0.176777 +v -0.095671 -1.000000 -0.230970 +v -0.095671 1.000000 -0.230970 +vt 1.000000 0.500000 +vt 1.000000 1.000000 +vt 0.937500 1.000000 +vt 0.937500 0.500000 +vt 0.875000 1.000000 +vt 0.875000 0.500000 +vt 0.812500 1.000000 +vt 0.812500 0.500000 +vt 0.750000 1.000000 +vt 0.750000 0.500000 +vt 0.687500 1.000000 +vt 0.687500 0.500000 +vt 0.625000 1.000000 +vt 0.625000 0.500000 +vt 0.562500 1.000000 +vt 0.562500 0.500000 +vt 0.500000 1.000000 +vt 0.500000 0.500000 +vt 0.437500 1.000000 +vt 0.437500 0.500000 +vt 0.375000 1.000000 +vt 0.375000 0.500000 +vt 0.312500 1.000000 +vt 0.312500 0.500000 +vt 0.250000 1.000000 +vt 0.250000 0.500000 +vt 0.187500 1.000000 +vt 0.187500 0.500000 +vt 0.125000 1.000000 +vt 0.125000 0.500000 +vt 0.341844 0.471731 +vt 0.250000 0.490000 +vt 0.158156 0.471731 +vt 0.080294 0.419706 +vt 0.028269 0.341844 +vt 0.010000 0.250000 +vt 0.028269 0.158156 +vt 0.080294 0.080294 +vt 0.158156 0.028269 +vt 0.250000 0.010000 +vt 0.341844 0.028269 +vt 0.419706 0.080294 +vt 0.471731 0.158156 +vt 0.490000 0.250000 +vt 0.471731 0.341844 +vt 0.419706 0.419706 +vt 0.062500 1.000000 +vt 0.062500 0.500000 +vt 0.000000 1.000000 +vt 0.000000 0.500000 +vt 0.750000 0.490000 +vt 0.841844 0.471731 +vt 0.919706 0.419706 +vt 0.971731 0.341844 +vt 0.990000 0.250000 +vt 0.971731 0.158156 +vt 0.919706 0.080294 +vt 0.841844 0.028269 +vt 0.750000 0.010000 +vt 0.658156 0.028269 +vt 0.580294 0.080294 +vt 0.528269 0.158156 +vt 0.510000 0.250000 +vt 0.528269 0.341844 +vt 0.580294 0.419706 +vt 0.658156 0.471731 +vn 0.1951 0.0000 -0.9808 +vn 0.5556 0.0000 -0.8315 +vn 0.8315 0.0000 -0.5556 +vn 0.9808 0.0000 -0.1951 +vn 0.9808 0.0000 0.1951 +vn 0.8315 0.0000 0.5556 +vn 0.5556 0.0000 0.8315 +vn 0.1951 0.0000 0.9808 +vn -0.1951 0.0000 0.9808 +vn -0.5556 0.0000 0.8315 +vn -0.8315 0.0000 0.5556 +vn -0.9808 0.0000 0.1951 +vn -0.9808 0.0000 -0.1951 +vn -0.8315 0.0000 -0.5556 +vn 0.0000 1.0000 0.0000 +vn -0.5556 0.0000 -0.8315 +vn -0.1951 0.0000 -0.9808 +vn 0.0000 -1.0000 -0.0000 +usemtl None +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 6/5/2 5/6/2 +f 5/6/3 6/5/3 8/7/3 7/8/3 +f 7/8/4 8/7/4 10/9/4 9/10/4 +f 9/10/5 10/9/5 12/11/5 11/12/5 +f 11/12/6 12/11/6 14/13/6 13/14/6 +f 13/14/7 14/13/7 16/15/7 15/16/7 +f 15/16/8 16/15/8 18/17/8 17/18/8 +f 17/18/9 18/17/9 20/19/9 19/20/9 +f 19/20/10 20/19/10 22/21/10 21/22/10 +f 21/22/11 22/21/11 24/23/11 23/24/11 +f 23/24/12 24/23/12 26/25/12 25/26/12 +f 25/26/13 26/25/13 28/27/13 27/28/13 +f 27/28/14 28/27/14 30/29/14 29/30/14 +f 4/31/15 2/32/15 32/33/15 30/34/15 28/35/15 26/36/15 24/37/15 22/38/15 20/39/15 18/40/15 16/41/15 14/42/15 12/43/15 10/44/15 8/45/15 6/46/15 +f 29/30/16 30/29/16 32/47/16 31/48/16 +f 31/48/17 32/47/17 2/49/17 1/50/17 +f 1/51/18 3/52/18 5/53/18 7/54/18 9/55/18 11/56/18 13/57/18 15/58/18 17/59/18 19/60/18 21/61/18 23/62/18 25/63/18 27/64/18 29/65/18 31/66/18 diff --git a/resources/sphere.mtl b/resources/sphere.mtl new file mode 100644 index 0000000..f231bdf --- /dev/null +++ b/resources/sphere.mtl @@ -0,0 +1,10 @@ +# Blender MTL File: 'None' +# Material Count: 1 + +newmtl None +Ns 500 +Ka 0.8 0.8 0.8 +Kd 0.8 0.8 0.8 +Ks 0.8 0.8 0.8 +d 1 +illum 2 diff --git a/resources/sphere.obj b/resources/sphere.obj new file mode 100644 index 0000000..23173ba --- /dev/null +++ b/resources/sphere.obj @@ -0,0 +1,527 @@ +# Blender v2.83.0 OBJ File: '' +# www.blender.org +mtllib sphere.mtl +o Sphere +v 0.000000 0.353553 -0.353553 +v 0.000000 0.191342 -0.461940 +v 0.000000 -0.191342 -0.461940 +v 0.000000 -0.461940 -0.191342 +v 0.073223 0.461940 -0.176777 +v 0.135299 0.353553 -0.326641 +v 0.176777 0.191342 -0.426777 +v 0.191342 -0.000000 -0.461940 +v 0.176777 -0.191342 -0.426777 +v 0.135299 -0.353553 -0.326641 +v 0.073223 -0.461940 -0.176777 +v 0.135299 0.461940 -0.135299 +v 0.250000 0.353553 -0.250000 +v 0.326641 0.191342 -0.326641 +v 0.353553 -0.000000 -0.353553 +v 0.326641 -0.191342 -0.326641 +v 0.250000 -0.353553 -0.250000 +v 0.135299 -0.461940 -0.135299 +v 0.176777 0.461940 -0.073223 +v 0.326641 0.353553 -0.135299 +v 0.426777 0.191342 -0.176777 +v 0.461940 -0.000000 -0.191342 +v 0.426777 -0.191342 -0.176777 +v 0.326641 -0.353553 -0.135299 +v 0.176777 -0.461940 -0.073223 +v 0.191342 0.461940 -0.000000 +v 0.353553 0.353553 -0.000000 +v 0.461940 0.191342 -0.000000 +v 0.500000 -0.000000 -0.000000 +v 0.461940 -0.191342 -0.000000 +v 0.353553 -0.353553 -0.000000 +v 0.191342 -0.461940 -0.000000 +v 0.176777 0.461940 0.073223 +v 0.326641 0.353553 0.135299 +v 0.426777 0.191342 0.176777 +v 0.461940 -0.000000 0.191342 +v 0.426777 -0.191342 0.176777 +v 0.326641 -0.353553 0.135299 +v 0.176777 -0.461940 0.073223 +v 0.135299 0.461940 0.135299 +v 0.250000 0.353553 0.250000 +v 0.326641 0.191342 0.326641 +v 0.353553 -0.000000 0.353553 +v 0.326641 -0.191342 0.326641 +v 0.250000 -0.353553 0.250000 +v 0.135299 -0.461940 0.135299 +v 0.073223 0.461940 0.176777 +v 0.135299 0.353553 0.326641 +v 0.176777 0.191342 0.426777 +v 0.191342 -0.000000 0.461940 +v 0.176777 -0.191342 0.426777 +v 0.135299 -0.353553 0.326641 +v 0.073223 -0.461940 0.176777 +v -0.000000 0.461940 0.191342 +v -0.000000 0.353553 0.353553 +v -0.000000 0.191342 0.461940 +v -0.000000 -0.000000 0.500000 +v -0.000000 -0.191342 0.461940 +v -0.000000 -0.353553 0.353553 +v -0.000000 -0.461940 0.191342 +v -0.073223 0.461940 0.176777 +v -0.135299 0.353553 0.326640 +v -0.176777 0.191342 0.426776 +v -0.191342 -0.000000 0.461939 +v -0.176777 -0.191342 0.426776 +v -0.135299 -0.353553 0.326640 +v -0.073223 -0.461940 0.176777 +v -0.135299 0.461940 0.135299 +v -0.250000 0.353553 0.250000 +v -0.326641 0.191342 0.326640 +v -0.353553 -0.000000 0.353553 +v -0.326641 -0.191342 0.326640 +v -0.250000 -0.353553 0.250000 +v -0.135299 -0.461940 0.135299 +v -0.176777 0.461940 0.073223 +v -0.326641 0.353553 0.135299 +v -0.426777 0.191342 0.176776 +v -0.461940 -0.000000 0.191341 +v -0.426777 -0.191342 0.176776 +v -0.326641 -0.353553 0.135299 +v -0.176777 -0.461940 0.073223 +v -0.191342 0.461940 -0.000000 +v -0.353553 0.353553 -0.000000 +v -0.461940 0.191342 -0.000000 +v -0.500000 -0.000000 -0.000000 +v -0.461940 -0.191342 -0.000000 +v -0.353553 -0.353553 -0.000000 +v -0.191342 -0.461940 -0.000000 +v -0.176777 0.461940 -0.073223 +v -0.326641 0.353553 -0.135299 +v -0.426776 0.191342 -0.176777 +v -0.461939 -0.000000 -0.191342 +v -0.426776 -0.191342 -0.176777 +v -0.326641 -0.353553 -0.135299 +v -0.176777 -0.461940 -0.073223 +v -0.135299 0.461940 -0.135299 +v -0.250000 0.353553 -0.250000 +v -0.326640 0.191342 -0.326641 +v -0.353553 -0.000000 -0.353554 +v -0.326640 -0.191342 -0.326641 +v -0.250000 -0.353553 -0.250000 +v -0.135299 -0.461940 -0.135299 +v -0.073223 0.461940 -0.176777 +v -0.135299 0.353553 -0.326641 +v -0.176776 0.191342 -0.426777 +v -0.191341 -0.000000 -0.461940 +v -0.176776 -0.191342 -0.426777 +v -0.135299 -0.353553 -0.326641 +v -0.073223 -0.461940 -0.176777 +v -0.000000 0.500000 -0.000000 +v 0.000000 0.461940 -0.191342 +v 0.000000 -0.000000 -0.500000 +v 0.000000 -0.353553 -0.353553 +v 0.000000 -0.500000 -0.000000 +vt 0.750000 0.375000 +vt 0.750000 0.500000 +vt 0.687500 0.500000 +vt 0.687500 0.375000 +vt 0.750000 0.625000 +vt 0.750000 0.750000 +vt 0.687500 0.750000 +vt 0.687500 0.625000 +vt 0.750000 0.875000 +vt 0.718750 1.000000 +vt 0.687500 0.875000 +vt 0.718750 0.000000 +vt 0.750000 0.125000 +vt 0.687500 0.125000 +vt 0.750000 0.250000 +vt 0.687500 0.250000 +vt 0.656250 0.000000 +vt 0.625000 0.125000 +vt 0.625000 0.375000 +vt 0.625000 0.250000 +vt 0.625000 0.625000 +vt 0.625000 0.500000 +vt 0.625000 0.875000 +vt 0.625000 0.750000 +vt 0.656250 1.000000 +vt 0.562500 0.875000 +vt 0.562500 0.750000 +vt 0.562500 0.250000 +vt 0.562500 0.125000 +vt 0.562500 0.500000 +vt 0.562500 0.375000 +vt 0.562500 0.625000 +vt 0.593750 1.000000 +vt 0.593750 0.000000 +vt 0.500000 0.250000 +vt 0.500000 0.125000 +vt 0.500000 0.500000 +vt 0.500000 0.375000 +vt 0.500000 0.750000 +vt 0.500000 0.625000 +vt 0.531250 1.000000 +vt 0.500000 0.875000 +vt 0.531250 0.000000 +vt 0.468750 1.000000 +vt 0.437500 0.875000 +vt 0.468750 0.000000 +vt 0.437500 0.125000 +vt 0.437500 0.375000 +vt 0.437500 0.250000 +vt 0.437500 0.625000 +vt 0.437500 0.500000 +vt 0.437500 0.750000 +vt 0.375000 0.375000 +vt 0.375000 0.250000 +vt 0.375000 0.625000 +vt 0.375000 0.500000 +vt 0.375000 0.875000 +vt 0.375000 0.750000 +vt 0.375000 0.125000 +vt 0.406250 1.000000 +vt 0.406250 0.000000 +vt 0.312500 0.250000 +vt 0.312500 0.125000 +vt 0.312500 0.500000 +vt 0.312500 0.375000 +vt 0.312500 0.750000 +vt 0.312500 0.625000 +vt 0.343750 1.000000 +vt 0.312500 0.875000 +vt 0.343750 0.000000 +vt 0.250000 0.500000 +vt 0.250000 0.375000 +vt 0.250000 0.750000 +vt 0.250000 0.625000 +vt 0.281250 1.000000 +vt 0.250000 0.875000 +vt 0.281250 0.000000 +vt 0.250000 0.125000 +vt 0.250000 0.250000 +vt 0.218750 0.000000 +vt 0.187500 0.125000 +vt 0.187500 0.375000 +vt 0.187500 0.250000 +vt 0.187500 0.625000 +vt 0.187500 0.500000 +vt 0.187500 0.875000 +vt 0.187500 0.750000 +vt 0.218750 1.000000 +vt 0.125000 0.625000 +vt 0.125000 0.500000 +vt 0.125000 0.875000 +vt 0.125000 0.750000 +vt 0.125000 0.250000 +vt 0.125000 0.125000 +vt 0.125000 0.375000 +vt 0.156250 1.000000 +vt 0.156250 0.000000 +vt 0.062500 0.250000 +vt 0.062500 0.125000 +vt 0.062500 0.500000 +vt 0.062500 0.375000 +vt 0.062500 0.750000 +vt 0.062500 0.625000 +vt 0.093750 1.000000 +vt 0.062500 0.875000 +vt 0.093750 0.000000 +vt 0.000000 0.750000 +vt 0.000000 0.625000 +vt 0.031250 1.000000 +vt 0.000000 0.875000 +vt 0.031250 0.000000 +vt 0.000000 0.125000 +vt 0.000000 0.375000 +vt 0.000000 0.250000 +vt 0.000000 0.500000 +vt 0.968750 0.000000 +vt 1.000000 0.125000 +vt 0.937500 0.125000 +vt 1.000000 0.250000 +vt 1.000000 0.375000 +vt 0.937500 0.375000 +vt 0.937500 0.250000 +vt 1.000000 0.500000 +vt 1.000000 0.625000 +vt 0.937500 0.625000 +vt 0.937500 0.500000 +vt 1.000000 0.750000 +vt 1.000000 0.875000 +vt 0.937500 0.875000 +vt 0.937500 0.750000 +vt 0.968750 1.000000 +vt 0.875000 0.875000 +vt 0.875000 0.750000 +vt 0.875000 0.250000 +vt 0.875000 0.125000 +vt 0.875000 0.500000 +vt 0.875000 0.375000 +vt 0.875000 0.625000 +vt 0.906250 1.000000 +vt 0.906250 0.000000 +vt 0.812500 0.250000 +vt 0.812500 0.125000 +vt 0.812500 0.500000 +vt 0.812500 0.375000 +vt 0.812500 0.750000 +vt 0.812500 0.625000 +vt 0.843750 1.000000 +vt 0.812500 0.875000 +vt 0.843750 0.000000 +vt 0.781250 1.000000 +vt 0.781250 0.000000 +vn 0.1915 -0.1915 -0.9626 +vn 0.1632 0.5481 -0.8203 +vn 0.0388 0.9800 -0.1949 +vn 0.0388 -0.9800 -0.1949 +vn 0.1632 -0.5481 -0.8203 +vn 0.1915 0.1915 -0.9626 +vn 0.1098 0.8264 -0.5522 +vn 0.1098 -0.8264 -0.5522 +vn 0.1104 -0.9800 -0.1653 +vn 0.4647 -0.5481 -0.6954 +vn 0.5453 0.1915 -0.8161 +vn 0.3128 0.8264 -0.4681 +vn 0.3128 -0.8264 -0.4681 +vn 0.5453 -0.1915 -0.8161 +vn 0.4647 0.5481 -0.6954 +vn 0.1104 0.9800 -0.1653 +vn 0.4681 0.8264 -0.3128 +vn 0.4681 -0.8264 -0.3128 +vn 0.8161 -0.1915 -0.5453 +vn 0.6954 0.5481 -0.4647 +vn 0.1653 0.9800 -0.1104 +vn 0.1653 -0.9800 -0.1104 +vn 0.6954 -0.5481 -0.4647 +vn 0.8161 0.1915 -0.5453 +vn 0.5522 -0.8264 -0.1098 +vn 0.9626 -0.1915 -0.1915 +vn 0.8203 0.5481 -0.1632 +vn 0.1949 0.9800 -0.0388 +vn 0.1949 -0.9800 -0.0388 +vn 0.8203 -0.5481 -0.1632 +vn 0.9626 0.1915 -0.1915 +vn 0.5522 0.8264 -0.1098 +vn 0.1949 0.9800 0.0388 +vn 0.1949 -0.9800 0.0388 +vn 0.8203 -0.5481 0.1632 +vn 0.9626 0.1915 0.1915 +vn 0.5522 0.8264 0.1098 +vn 0.5522 -0.8264 0.1098 +vn 0.9626 -0.1915 0.1915 +vn 0.8203 0.5481 0.1632 +vn 0.6954 -0.5481 0.4647 +vn 0.8161 0.1915 0.5453 +vn 0.4681 0.8264 0.3128 +vn 0.4681 -0.8264 0.3128 +vn 0.8161 -0.1915 0.5453 +vn 0.6954 0.5481 0.4647 +vn 0.1653 0.9800 0.1104 +vn 0.1653 -0.9800 0.1104 +vn 0.3128 -0.8264 0.4681 +vn 0.5453 -0.1915 0.8161 +vn 0.4647 0.5481 0.6954 +vn 0.1104 0.9800 0.1653 +vn 0.1104 -0.9800 0.1653 +vn 0.4647 -0.5481 0.6954 +vn 0.5453 0.1915 0.8161 +vn 0.3128 0.8264 0.4681 +vn 0.1915 -0.1915 0.9626 +vn 0.1632 0.5481 0.8203 +vn 0.0388 0.9800 0.1949 +vn 0.0388 -0.9800 0.1949 +vn 0.1632 -0.5481 0.8203 +vn 0.1915 0.1915 0.9626 +vn 0.1098 0.8264 0.5522 +vn 0.1098 -0.8264 0.5522 +vn -0.0388 -0.9800 0.1949 +vn -0.1632 -0.5481 0.8203 +vn -0.1915 0.1915 0.9626 +vn -0.1098 0.8264 0.5522 +vn -0.1098 -0.8264 0.5522 +vn -0.1915 -0.1915 0.9626 +vn -0.1632 0.5481 0.8203 +vn -0.0388 0.9800 0.1949 +vn -0.5453 0.1915 0.8161 +vn -0.3128 0.8264 0.4681 +vn -0.3128 -0.8264 0.4681 +vn -0.5453 -0.1915 0.8161 +vn -0.4647 0.5481 0.6954 +vn -0.1104 0.9800 0.1653 +vn -0.1104 -0.9800 0.1653 +vn -0.4647 -0.5481 0.6954 +vn -0.4681 -0.8264 0.3128 +vn -0.8161 -0.1915 0.5453 +vn -0.6954 0.5481 0.4647 +vn -0.1653 0.9800 0.1104 +vn -0.1653 -0.9800 0.1104 +vn -0.6954 -0.5481 0.4647 +vn -0.8161 0.1915 0.5453 +vn -0.4681 0.8264 0.3128 +vn -0.8203 0.5481 0.1632 +vn -0.1949 0.9800 0.0388 +vn -0.1949 -0.9800 0.0388 +vn -0.8203 -0.5481 0.1632 +vn -0.9626 0.1915 0.1915 +vn -0.5522 0.8264 0.1098 +vn -0.5522 -0.8264 0.1098 +vn -0.9626 -0.1915 0.1915 +vn -0.1949 -0.9800 -0.0388 +vn -0.8203 -0.5481 -0.1632 +vn -0.9626 0.1915 -0.1915 +vn -0.5522 0.8264 -0.1098 +vn -0.5522 -0.8264 -0.1098 +vn -0.9626 -0.1915 -0.1915 +vn -0.8203 0.5481 -0.1632 +vn -0.1949 0.9800 -0.0388 +vn -0.4681 0.8264 -0.3128 +vn -0.4681 -0.8264 -0.3128 +vn -0.8161 -0.1915 -0.5453 +vn -0.6954 0.5481 -0.4647 +vn -0.1653 0.9800 -0.1104 +vn -0.1653 -0.9800 -0.1104 +vn -0.6954 -0.5481 -0.4647 +vn -0.8161 0.1915 -0.5453 +vn -0.3128 -0.8264 -0.4681 +vn -0.5453 -0.1915 -0.8161 +vn -0.4647 0.5481 -0.6954 +vn -0.1104 0.9800 -0.1653 +vn -0.1104 -0.9800 -0.1653 +vn -0.4647 -0.5481 -0.6954 +vn -0.5453 0.1915 -0.8161 +vn -0.3128 0.8264 -0.4681 +vn -0.0388 0.9800 -0.1949 +vn -0.0388 -0.9800 -0.1949 +vn -0.1632 -0.5481 -0.8203 +vn -0.1915 0.1915 -0.9626 +vn -0.1098 0.8264 -0.5522 +vn -0.1098 -0.8264 -0.5522 +vn -0.1915 -0.1915 -0.9626 +vn -0.1632 0.5481 -0.8203 +usemtl None +s off +f 3/1/1 112/2/1 8/3/1 9/4/1 +f 2/5/2 1/6/2 6/7/2 7/8/2 +f 111/9/3 110/10/3 5/11/3 +f 114/12/4 4/13/4 11/14/4 +f 113/15/5 3/1/5 9/4/5 10/16/5 +f 112/2/6 2/5/6 7/8/6 8/3/6 +f 1/6/7 111/9/7 5/11/7 6/7/7 +f 4/13/8 113/15/8 10/16/8 11/14/8 +f 114/17/9 11/14/9 18/18/9 +f 10/16/10 9/4/10 16/19/10 17/20/10 +f 8/3/11 7/8/11 14/21/11 15/22/11 +f 6/7/12 5/11/12 12/23/12 13/24/12 +f 11/14/13 10/16/13 17/20/13 18/18/13 +f 9/4/14 8/3/14 15/22/14 16/19/14 +f 7/8/15 6/7/15 13/24/15 14/21/15 +f 5/11/16 110/25/16 12/23/16 +f 13/24/17 12/23/17 19/26/17 20/27/17 +f 18/18/18 17/20/18 24/28/18 25/29/18 +f 16/19/19 15/22/19 22/30/19 23/31/19 +f 14/21/20 13/24/20 20/27/20 21/32/20 +f 12/23/21 110/33/21 19/26/21 +f 114/34/22 18/18/22 25/29/22 +f 17/20/23 16/19/23 23/31/23 24/28/23 +f 15/22/24 14/21/24 21/32/24 22/30/24 +f 25/29/25 24/28/25 31/35/25 32/36/25 +f 23/31/26 22/30/26 29/37/26 30/38/26 +f 21/32/27 20/27/27 27/39/27 28/40/27 +f 19/26/28 110/41/28 26/42/28 +f 114/43/29 25/29/29 32/36/29 +f 24/28/30 23/31/30 30/38/30 31/35/30 +f 22/30/31 21/32/31 28/40/31 29/37/31 +f 20/27/32 19/26/32 26/42/32 27/39/32 +f 26/42/33 110/44/33 33/45/33 +f 114/46/34 32/36/34 39/47/34 +f 31/35/35 30/38/35 37/48/35 38/49/35 +f 29/37/36 28/40/36 35/50/36 36/51/36 +f 27/39/37 26/42/37 33/45/37 34/52/37 +f 32/36/38 31/35/38 38/49/38 39/47/38 +f 30/38/39 29/37/39 36/51/39 37/48/39 +f 28/40/40 27/39/40 34/52/40 35/50/40 +f 38/49/41 37/48/41 44/53/41 45/54/41 +f 36/51/42 35/50/42 42/55/42 43/56/42 +f 34/52/43 33/45/43 40/57/43 41/58/43 +f 39/47/44 38/49/44 45/54/44 46/59/44 +f 37/48/45 36/51/45 43/56/45 44/53/45 +f 35/50/46 34/52/46 41/58/46 42/55/46 +f 33/45/47 110/60/47 40/57/47 +f 114/61/48 39/47/48 46/59/48 +f 46/59/49 45/54/49 52/62/49 53/63/49 +f 44/53/50 43/56/50 50/64/50 51/65/50 +f 42/55/51 41/58/51 48/66/51 49/67/51 +f 40/57/52 110/68/52 47/69/52 +f 114/70/53 46/59/53 53/63/53 +f 45/54/54 44/53/54 51/65/54 52/62/54 +f 43/56/55 42/55/55 49/67/55 50/64/55 +f 41/58/56 40/57/56 47/69/56 48/66/56 +f 51/65/57 50/64/57 57/71/57 58/72/57 +f 49/67/58 48/66/58 55/73/58 56/74/58 +f 47/69/59 110/75/59 54/76/59 +f 114/77/60 53/63/60 60/78/60 +f 52/62/61 51/65/61 58/72/61 59/79/61 +f 50/64/62 49/67/62 56/74/62 57/71/62 +f 48/66/63 47/69/63 54/76/63 55/73/63 +f 53/63/64 52/62/64 59/79/64 60/78/64 +f 114/80/65 60/78/65 67/81/65 +f 59/79/66 58/72/66 65/82/66 66/83/66 +f 57/71/67 56/74/67 63/84/67 64/85/67 +f 55/73/68 54/76/68 61/86/68 62/87/68 +f 60/78/69 59/79/69 66/83/69 67/81/69 +f 58/72/70 57/71/70 64/85/70 65/82/70 +f 56/74/71 55/73/71 62/87/71 63/84/71 +f 54/76/72 110/88/72 61/86/72 +f 64/85/73 63/84/73 70/89/73 71/90/73 +f 62/87/74 61/86/74 68/91/74 69/92/74 +f 67/81/75 66/83/75 73/93/75 74/94/75 +f 65/82/76 64/85/76 71/90/76 72/95/76 +f 63/84/77 62/87/77 69/92/77 70/89/77 +f 61/86/78 110/96/78 68/91/78 +f 114/97/79 67/81/79 74/94/79 +f 66/83/80 65/82/80 72/95/80 73/93/80 +f 74/94/81 73/93/81 80/98/81 81/99/81 +f 72/95/82 71/90/82 78/100/82 79/101/82 +f 70/89/83 69/92/83 76/102/83 77/103/83 +f 68/91/84 110/104/84 75/105/84 +f 114/106/85 74/94/85 81/99/85 +f 73/93/86 72/95/86 79/101/86 80/98/86 +f 71/90/87 70/89/87 77/103/87 78/100/87 +f 69/92/88 68/91/88 75/105/88 76/102/88 +f 77/103/89 76/102/89 83/107/89 84/108/89 +f 75/105/90 110/109/90 82/110/90 +f 114/111/91 81/99/91 88/112/91 +f 80/98/92 79/101/92 86/113/92 87/114/92 +f 78/100/93 77/103/93 84/108/93 85/115/93 +f 76/102/94 75/105/94 82/110/94 83/107/94 +f 81/99/95 80/98/95 87/114/95 88/112/95 +f 79/101/96 78/100/96 85/115/96 86/113/96 +f 114/116/97 88/117/97 95/118/97 +f 87/119/98 86/120/98 93/121/98 94/122/98 +f 85/123/99 84/124/99 91/125/99 92/126/99 +f 83/127/100 82/128/100 89/129/100 90/130/100 +f 88/117/101 87/119/101 94/122/101 95/118/101 +f 86/120/102 85/123/102 92/126/102 93/121/102 +f 84/124/103 83/127/103 90/130/103 91/125/103 +f 82/128/104 110/131/104 89/129/104 +f 90/130/105 89/129/105 96/132/105 97/133/105 +f 95/118/106 94/122/106 101/134/106 102/135/106 +f 93/121/107 92/126/107 99/136/107 100/137/107 +f 91/125/108 90/130/108 97/133/108 98/138/108 +f 89/129/109 110/139/109 96/132/109 +f 114/140/110 95/118/110 102/135/110 +f 94/122/111 93/121/111 100/137/111 101/134/111 +f 92/126/112 91/125/112 98/138/112 99/136/112 +f 102/135/113 101/134/113 108/141/113 109/142/113 +f 100/137/114 99/136/114 106/143/114 107/144/114 +f 98/138/115 97/133/115 104/145/115 105/146/115 +f 96/132/116 110/147/116 103/148/116 +f 114/149/117 102/135/117 109/142/117 +f 101/134/118 100/137/118 107/144/118 108/141/118 +f 99/136/119 98/138/119 105/146/119 106/143/119 +f 97/133/120 96/132/120 103/148/120 104/145/120 +f 103/148/121 110/150/121 111/9/121 +f 114/151/122 109/142/122 4/13/122 +f 108/141/123 107/144/123 3/1/123 113/15/123 +f 106/143/124 105/146/124 2/5/124 112/2/124 +f 104/145/125 103/148/125 111/9/125 1/6/125 +f 109/142/126 108/141/126 113/15/126 4/13/126 +f 107/144/127 106/143/127 112/2/127 3/1/127 +f 105/146/128 104/145/128 1/6/128 2/5/128 diff --git a/src/geometry/Mesh.ts b/src/geometry/Mesh.ts index c5591ce..76d22ca 100644 --- a/src/geometry/Mesh.ts +++ b/src/geometry/Mesh.ts @@ -1,7 +1,7 @@ -import {vec3, vec4} from 'gl-matrix'; -import Drawable from '../rendering/gl/Drawable'; -import {gl} from '../globals'; -import * as Loader from 'webgl-obj-loader'; +import { vec3, vec4 } from "gl-matrix"; +import Drawable from "../rendering/gl/Drawable"; +import { gl } from "../globals"; +import * as Loader from "webgl-obj-loader"; class Mesh extends Drawable { indices: Uint32Array; @@ -10,6 +10,12 @@ class Mesh extends Drawable { colors: Float32Array; uvs: Float32Array; center: vec4; + offsets: Float32Array; // Data for bufTranslate + + tCol1: Float32Array; // Data for bufTransform1 + tCol2: Float32Array; // Data for bufTransform2 + tCol3: Float32Array; // Data for bufTransform3 + tCol4: Float32Array; // Data for bufTransform4 objString: string; @@ -20,7 +26,7 @@ class Mesh extends Drawable { this.objString = objString; } - create() { + create() { let posTemp: Array = []; let norTemp: Array = []; let uvsTemp: Array = []; @@ -28,7 +34,6 @@ class Mesh extends Drawable { var loadedMesh = new Loader.Mesh(this.objString); - //posTemp = loadedMesh.vertices; for (var i = 0; i < loadedMesh.vertices.length; i++) { posTemp.push(loadedMesh.vertices[i]); if (i % 3 == 2) posTemp.push(1.0); @@ -42,9 +47,9 @@ class Mesh extends Drawable { uvsTemp = loadedMesh.textures; idxTemp = loadedMesh.indices; - // white vert color for now + // color white this.colors = new Float32Array(posTemp.length); - for (var i = 0; i < posTemp.length; ++i){ + for (var i = 0; i < posTemp.length; ++i) { this.colors[i] = 1.0; } @@ -59,6 +64,11 @@ class Mesh extends Drawable { this.generateUV(); this.generateCol(); + this.generateTransform1(); + this.generateTransform2(); + this.generateTransform3(); + this.generateTransform4(); + this.count = this.indices.length; gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.bufIdx); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); @@ -76,8 +86,34 @@ class Mesh extends Drawable { gl.bufferData(gl.ARRAY_BUFFER, this.uvs, gl.STATIC_DRAW); console.log(`Created Mesh from OBJ`); - this.objString = ""; // hacky clear + this.objString = ""; + } + + setInstanceVBOs( + col1s: Float32Array, + col2s: Float32Array, + col3s: Float32Array, + col4s: Float32Array, + colors: Float32Array + ) { + this.colors = colors; + this.tCol1 = col1s; + this.tCol2 = col2s; + this.tCol3 = col3s; + this.tCol4 = col4s; + + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufCol); + gl.bufferData(gl.ARRAY_BUFFER, this.colors, gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform1); + gl.bufferData(gl.ARRAY_BUFFER, this.tCol1, gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform2); + gl.bufferData(gl.ARRAY_BUFFER, this.tCol2, gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform3); + gl.bufferData(gl.ARRAY_BUFFER, this.tCol3, gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform4); + gl.bufferData(gl.ARRAY_BUFFER, this.tCol4, gl.STATIC_DRAW); } -}; +} export default Mesh; + diff --git a/src/geometry/Square.ts b/src/geometry/Square.ts index 5fdb8ba..a020345 100644 --- a/src/geometry/Square.ts +++ b/src/geometry/Square.ts @@ -8,6 +8,12 @@ class Square extends Drawable { colors: Float32Array; offsets: Float32Array; // Data for bufTranslate + tCol1: Float32Array; // Data for bufTransform1 + tCol2: Float32Array; // Data for bufTransform2 + tCol3: Float32Array; // Data for bufTransform3 + tCol4: Float32Array; // Data for bufTransform4 + + constructor() { super(); // Call the constructor of the super class. This is required. @@ -27,6 +33,12 @@ class Square extends Drawable { this.generateCol(); this.generateTranslate(); + this.generateTransform1(); + this.generateTransform2(); + this.generateTransform3(); + this.generateTransform4(); + + this.count = this.indices.length; gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.bufIdx); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); @@ -46,6 +58,32 @@ class Square extends Drawable { gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTranslate); gl.bufferData(gl.ARRAY_BUFFER, this.offsets, gl.STATIC_DRAW); } + + setInstanceTransformVBOs( + col1s: Float32Array, + col2s: Float32Array, + col3s: Float32Array, + col4s: Float32Array, + colors: Float32Array + ) { + this.colors = colors; + this.tCol1 = col1s; + this.tCol2 = col2s; + this.tCol3 = col3s; + this.tCol4 = col4s; + + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufCol); + gl.bufferData(gl.ARRAY_BUFFER, this.colors, gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform1); + gl.bufferData(gl.ARRAY_BUFFER, this.tCol1, gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform2); + gl.bufferData(gl.ARRAY_BUFFER, this.tCol2, gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform3); + gl.bufferData(gl.ARRAY_BUFFER, this.tCol3, gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform4); + gl.bufferData(gl.ARRAY_BUFFER, this.tCol4, gl.STATIC_DRAW); + } }; export default Square; + diff --git a/src/globals.ts b/src/globals.ts index cac5bf2..378fd2f 100644 --- a/src/globals.ts +++ b/src/globals.ts @@ -3,3 +3,24 @@ export var gl: WebGL2RenderingContext; export function setGL(_gl: WebGL2RenderingContext) { gl = _gl; } + + +export function readTextFile(file: string): string +{ + var text = ""; + var rawFile = new XMLHttpRequest(); + rawFile.open("GET", file, false); + rawFile.onreadystatechange = function () + { + if(rawFile.readyState === 4) + { + if(rawFile.status === 200 || rawFile.status == 0) + { + var allText = rawFile.responseText; + text = allText; + } + } + } + rawFile.send(null); + return text; +} \ No newline at end of file diff --git a/src/l-system/DrawingRule.ts b/src/l-system/DrawingRule.ts new file mode 100644 index 0000000..1a45402 --- /dev/null +++ b/src/l-system/DrawingRule.ts @@ -0,0 +1,23 @@ +class DrawingRule { + outputs: Array<[any, number]> = []; + + addOutput(oper : any, probability : number) { + this.outputs.push([oper, probability]); + } + + getOutput() : any { + let rand = Math.random(); + let probabilitySum : number = 0.0; + let i : number = 0; + while(i < this.outputs.length) { + probabilitySum += this.outputs[i][1]; + if (rand < probabilitySum) { + return this.outputs[i][0]; + } + i++; + } + return; + } + }; + +export default DrawingRule; \ No newline at end of file diff --git a/src/l-system/ExpansionRule.ts b/src/l-system/ExpansionRule.ts new file mode 100644 index 0000000..623e516 --- /dev/null +++ b/src/l-system/ExpansionRule.ts @@ -0,0 +1,22 @@ +class ExpansionRule { + outputs: Array<[string, number]> = []; + + addOutput(newString : string, probability : number) { + this.outputs.push([newString, probability]); + } + + getOutput() : string { + let rand = Math.random(); + let probabilitySum : number = 0.0; + let i : number = 0; + while(i < this.outputs.length) { + probabilitySum += this.outputs[i][1]; + if (rand < probabilitySum) { + return this.outputs[i][0]; + } + i++; + } + return; + } +}; +export default ExpansionRule; \ No newline at end of file diff --git a/src/l-system/L-System.ts b/src/l-system/L-System.ts new file mode 100644 index 0000000..b0b540e --- /dev/null +++ b/src/l-system/L-System.ts @@ -0,0 +1,320 @@ +import DrawingRule from "./DrawingRule"; +import ExpansionRule from "./ExpansionRule"; +import Turtle from "./Turtle"; +import Mesh from "../geometry/Mesh"; +import { readTextFile } from "../globals"; +import { vec3, mat4, quat, mat3, vec4 } from "gl-matrix"; +import OpenGLRenderer from "../rendering/gl/OpenGLRenderer"; + +class LSystem { + turtleStack: Array = []; + turtle: Turtle = new Turtle( + 15, + vec3.fromValues(50.0, 50.0, 0.0), + mat3.create() + ); + drawingRules: Map = new Map(); + expansionRules: Map = new Map(); + seed: string; + axioms: Array = []; + iterations: number = 2; + defaultAngle = 15; + scale = 1; + color1 = vec4.fromValues(255 / 255, 127.0 / 255.0, 80.0 / 255.0, 1.0); + color2 = vec4.fromValues(57 / 255.0, 217 /255.0, 222 / 255.0, 1.0); + + // Set up instanced rendering data arrays. + branchCols1: Array = []; + branchCols2: Array = []; + branchCols3: Array = []; + branchCols4: Array = []; + branchColorsBO: Array = []; + branchNum: number = 0; + + leafCols1: Array = []; + leafCols2: Array = []; + leafCols3: Array = []; + leafCols4: Array = []; + leafColorsBO: Array = []; + leafNum: number = 0; + + // import objs: + branch: Mesh = new Mesh( + readTextFile("resources/cylinder.obj"), + vec3.fromValues(0, 0, 0) + ); + + leaf: Mesh = new Mesh( + readTextFile("resources/sphere.obj"), + vec3.fromValues(0, 0, 0) + ); + + drawBranch: () => void; + setSeed: (s: string) => void; + pushTurtle: () => void; + popTurtle: () => void; + populateExpansionRules: () => void; + populateDrawingRules: () => void; + putBranch: (scale: vec3) => void; + putLeaf: () => void; + createMeshes: () => void; + drawTree: () => void; + expandGrammar: () => void; + makeTree: () => void; + + constructor(iters: number, angle: number, s: number, col1 : vec4, col2 : vec4) { + this.turtleStack = []; + this.turtle = new Turtle( + angle, + vec3.fromValues(50.0, 50.0, 0.0), + mat3.create() + ); + this.iterations = iters; + this.defaultAngle = angle; + this.scale = s; + this.color1 = col1; + this.color2 = col2; + + // define functions below to maintain context of "this" + + this.setSeed = (s: string) => { + this.seed = s; + }; + + this.pushTurtle = () => { + let newPos: vec3 = vec3.create(); + let newOrient: mat3 = mat3.create(); + let newTurtle: Turtle = new Turtle( + angle, + vec3.copy(newPos, this.turtle.position), + mat3.copy(newOrient, this.turtle.orientation) + ); + let newDepth: number = this.turtle.depth; + newTurtle.depth = newDepth; + this.turtleStack.push(newTurtle); + this.turtle.depth += 1; + }; + + this.popTurtle = () => { + if (this.turtle.depth > 0) { + let newTurtle: Turtle = this.turtleStack.pop(); + this.turtle.orientation = mat3.copy( + mat3.create(), + newTurtle.orientation + ); + this.turtle.position = vec3.copy(vec3.create(), newTurtle.position); + this.turtle.depth -= 1; + } + }; + + this.populateExpansionRules = () => { + let rule1: ExpansionRule = new ExpansionRule(); + rule1.addOutput("FF#-[-/-/FF#+*+*F^F#]+[+/+F/^F#]#", 0.9); // * is the same as \ in houdini here + rule1.addOutput("[-*^F]#", 0.1); + this.expansionRules.set("F", rule1); + + let rule2: ExpansionRule = new ExpansionRule(); + rule2.addOutput("++//&&[F]", 0.9); + rule2.addOutput("--**^^X#", 0.1); + this.expansionRules.set("X", rule2); + }; + + this.populateDrawingRules = () => { + let pushRule: DrawingRule = new DrawingRule(); + pushRule.addOutput(this.pushTurtle, 1.0); + this.drawingRules.set("[", pushRule); + + let popRule: DrawingRule = new DrawingRule(); + popRule.addOutput(this.popTurtle, 1.0); + this.drawingRules.set("]", popRule); + + let rotateLeftXRule: DrawingRule = new DrawingRule(); + rotateLeftXRule.addOutput(this.turtle.rotateLeftX, 0.9); + rotateLeftXRule.addOutput(this.turtle.rotateBigLeftX, 0.1); + this.drawingRules.set("+", rotateLeftXRule); + + let rotateRightXRule: DrawingRule = new DrawingRule(); + rotateRightXRule.addOutput(this.turtle.rotateRightX, 0.9); + rotateRightXRule.addOutput(this.turtle.rotateBigRightX, 0.1); + this.drawingRules.set("-", rotateRightXRule); + + let rotatePosYRule: DrawingRule = new DrawingRule(); + rotatePosYRule.addOutput(this.turtle.rotatePosY, 0.9); + rotatePosYRule.addOutput(this.turtle.rotateBigPosY, 0.1); + this.drawingRules.set("*", rotatePosYRule); + + let rotateNegYRule: DrawingRule = new DrawingRule(); + rotateNegYRule.addOutput(this.turtle.rotateNegY, 0.9); + rotateNegYRule.addOutput(this.turtle.rotateBigNegY, 0.1); + this.drawingRules.set("/", rotateNegYRule); + + let rotatePosZRule: DrawingRule = new DrawingRule(); + rotatePosZRule.addOutput(this.turtle.rotatePosZ, 0.9); + rotatePosZRule.addOutput(this.turtle.rotateBigPosZ, 0.1); + this.drawingRules.set("&", rotatePosZRule); + + let rotateNegZRule: DrawingRule = new DrawingRule(); + rotateNegZRule.addOutput(this.turtle.rotateNegZ, 0.9); + rotateNegZRule.addOutput(this.turtle.rotateBigNegZ, 0.1); + this.drawingRules.set("^", rotateNegZRule); + + let forwardRule: DrawingRule = new DrawingRule(); + forwardRule.addOutput(this.drawBranch, 1.0); + this.drawingRules.set("F", forwardRule); + + let leafRule: DrawingRule = new DrawingRule(); + leafRule.addOutput(this.putLeaf, 1.0); + this.drawingRules.set("#", leafRule); + }; + + this.putBranch = (scale: vec3) => { + // Calculate transformation + let transform: mat4 = mat4.create(); + let q: quat = quat.create(); + quat.fromMat3(q, this.turtle.orientation); + mat4.fromRotationTranslationScale( + transform, + q, + this.turtle.position, + scale + ); + for (let i = 0; i < 4; i++) { + this.branchCols1.push(transform[i]); + this.branchCols2.push(transform[4 + i]); + this.branchCols3.push(transform[8 + i]); + this.branchCols4.push(transform[12 + i]); + } + + this.branchColorsBO.push(this.color1[0] / 255.0); + this.branchColorsBO.push(this.color1[1] / 255.0); + this.branchColorsBO.push(this.color1[2] / 255.0); + this.branchColorsBO.push(1.0); + this.branchNum++; + }; + + this.putLeaf = () => { + this.turtle.smallMoveForward(); + + // Calculate transformation + let transform: mat4 = mat4.create(); + let q: quat = quat.create(); + let s : vec3 = vec3.scale(vec3.create(), vec3.fromValues(6.5, 6.5, 6.5), this.scale); + quat.fromMat3(q, this.turtle.orientation); + mat4.fromRotationTranslationScale( + transform, + q, + this.turtle.position, + s + ); + for (let i = 0; i < 4; i++) { + this.leafCols1.push(transform[i]); + this.leafCols2.push(transform[4 + i]); + this.leafCols3.push(transform[8 + i]); + this.leafCols4.push(transform[12 + i]); + } + + this.leafColorsBO.push(this.color2[0] / 255.0); + this.leafColorsBO.push(this.color2[1] / 255.0); + this.leafColorsBO.push(this.color2[2] / 255.0); + this.leafColorsBO.push(1.0); + this.leafNum++; + }; + + this.createMeshes = () => { + this.branch.create(); + }; + + this.drawTree = () => { + // reset everything + this.turtle.reset(); + this.branchNum = 0; + this.branchCols1 = []; + this.branchCols2 = []; + this.branchCols3 = []; + this.branchCols4 = []; + this.branchColorsBO = []; + this.branch.destroy(); + this.branch.create(); + + this.leafNum = 0; + this.leafCols1 = []; + this.leafCols2 = []; + this.leafCols3 = []; + this.leafCols4 = []; + this.leafColorsBO = []; + this.leaf.destroy(); + this.leaf.create(); + + // Draw based on grammar + let count = 0; + for (let i = 0; i < this.axioms[this.iterations].length; i++) { + let func = this.drawingRules + .get(this.axioms[this.iterations].charAt(i)) + .getOutput(); + if (func) { + func(); + count++; + } + } + + let bCol1: Float32Array = new Float32Array(this.branchCols1); + let bCol2: Float32Array = new Float32Array(this.branchCols2); + let bCol3: Float32Array = new Float32Array(this.branchCols3); + let bCol4: Float32Array = new Float32Array(this.branchCols4); + let bcolors: Float32Array = new Float32Array(this.branchColorsBO); + this.branch.setInstanceVBOs(bCol1, bCol2, bCol3, bCol4, bcolors); + this.branch.setNumInstances(this.branchNum); + + let lCol1: Float32Array = new Float32Array(this.leafCols1); + let lCol2: Float32Array = new Float32Array(this.leafCols2); + let lCol3: Float32Array = new Float32Array(this.leafCols3); + let lCol4: Float32Array = new Float32Array(this.leafCols4); + let lcolors: Float32Array = new Float32Array(this.leafColorsBO); + this.leaf.setInstanceVBOs(lCol1, lCol2, lCol3, lCol4, lcolors); + this.leaf.setNumInstances(this.leafNum); + }; + + this.expandGrammar = () => { + let currExpansion = this.seed; + // expanding the grammar + for (let i = 0; i < this.iterations; i++) { + let expandedString: string = ""; + for (let j = 0; j < currExpansion.length; j++) { + let currRule = this.expansionRules.get(currExpansion.charAt(j)); + if (currRule) { + expandedString += currRule.getOutput(); + } else { + expandedString += currExpansion.charAt(j); + } + } + currExpansion = expandedString; + this.axioms.push(expandedString); + } + }; + + this.makeTree = () => { + this.setSeed("FX"); + this.axioms = [this.seed]; + + this.populateExpansionRules(); + this.populateDrawingRules(); + + this.expandGrammar(); + + this.drawTree(); + }; + + this.drawBranch = () => { + this.turtle.moveForward(); + this.putBranch( + vec3.fromValues( + 6.5 - this.turtle.depth * 0.85, + 8.0, + 6.5 - this.turtle.depth * 0.85 + ) + ); + }; + } +} + +export default LSystem; diff --git a/src/l-system/Turtle.ts b/src/l-system/Turtle.ts new file mode 100644 index 0000000..c8c5f20 --- /dev/null +++ b/src/l-system/Turtle.ts @@ -0,0 +1,153 @@ +import { mat3, vec3, quat } from "gl-matrix"; + +// vec3 operations from: https://glmatrix.net/docs/module-vec3.html +const PI = 3.1415926535; + +class Turtle { + position: vec3 = vec3.fromValues(0.0, 0.0, 0.0); + orientation: mat3 = mat3.create(); + depth: number = 0; + angle : number = 15; + + getForward: () => vec3; + getRight: () => vec3; + getUp: () => vec3; + moveForward: () => void; + smallMoveForward: () => void; + rotateRightX: () => void; + rotateLeftX: () => void; + rotatePosY: () => void; + rotateNegY: () => void; + rotatePosZ: () => void; + rotateNegZ: () => void; + rotateBigRightX: () => void; + rotateBigLeftX: () => void; + rotateBigPosY: () => void; + rotateBigNegY: () => void; + rotateBigPosZ: () => void; + rotateBigNegZ: () => void; + rotate: (axis: vec3, angle: number) => void; + + constructor(a : number, pos: vec3, orient: mat3) { + this.position = pos; + this.orientation = orient; + this.depth = 0; + this.angle = a; + + this.getForward = () => { + return vec3.fromValues( + this.orientation[3], + this.orientation[4], + this.orientation[5] + ); + }; + + this.getRight = () => { + return vec3.fromValues( + this.orientation[6], + this.orientation[7], + this.orientation[8] + ); + }; + this.getUp = () => { + return vec3.fromValues( + this.orientation[0], + this.orientation[1], + this.orientation[2] + ); + }; + + this.moveForward = () => { + vec3.add( + this.position, + this.position, + vec3.scale(vec3.create(), this.getForward(), 10.0) + ); + }; + + this.smallMoveForward = () => { + vec3.add( + this.position, + this.position, + vec3.scale(vec3.create(), this.getForward(), 5.0) + ); + }; + + this.rotate = (axis: vec3, angle: number) => { + // pick random # + let rand = Math.random(); + // scale it to between -PI/2 and PI/2 + rand = (rand * PI) - (PI / 2); + // sample it on the sin curve + let offset = Math.sin(2.0 * rand); + // multiply value by 10 + offset = offset * 10.0; + + vec3.normalize(axis, axis); + let radians = (PI * (angle + offset)) / 180.0; + + let q: quat = quat.create(); + quat.setAxisAngle(q, axis, radians); + quat.normalize(q, q); + + let m: mat3 = mat3.create(); + mat3.fromQuat(m, q); + mat3.multiply(this.orientation, m, this.orientation); + }; + + this.rotateRightX = () => { + this.rotate(this.getUp(), -this.angle); + }; + + this.rotateLeftX = () => { + this.rotate(this.getUp(), this.angle); + }; + + this.rotatePosY = () => { + this.rotate(this.getForward(), this.angle); + }; + + this.rotateNegY = () => { + this.rotate(this.getForward(), -this.angle); + }; + + this.rotatePosZ = () => { + this.rotate(this.getRight(), this.angle); + }; + + this.rotateNegZ = () => { + this.rotate(this.getRight(), -this.angle); + }; + this.rotateBigRightX = () => { + this.rotate(this.getUp(), -this.angle * 2.0); + }; + + this.rotateBigLeftX = () => { + this.rotate(this.getUp(), this.angle * 2.0); + } + + this.rotateBigPosY = () => { + this.rotate(this.getForward(), this.angle * 2.0); + } + + this.rotateBigNegY = () => { + this.rotate(this.getForward(), -this.angle * 2.0); + } + + this.rotateBigPosZ = () => { + this.rotate(this.getRight(), this.angle * 2.0); + } + + this.rotateBigNegZ = () => { + this.rotate(this.getRight(), -this.angle * 2.0); + } + } + + reset() { + this.position = vec3.fromValues(50.0, 50.0, 0.0); + this.orientation = mat3.identity(this.orientation); + this.depth = 0; + } +} + +export default Turtle; diff --git a/src/main.ts b/src/main.ts index 932c78f..dde3a9b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,71 +1,121 @@ -import {vec3} from 'gl-matrix'; -import * as Stats from 'stats-js'; -import * as DAT from 'dat-gui'; -import Square from './geometry/Square'; -import ScreenQuad from './geometry/ScreenQuad'; -import OpenGLRenderer from './rendering/gl/OpenGLRenderer'; -import Camera from './Camera'; -import {setGL} from './globals'; -import ShaderProgram, {Shader} from './rendering/gl/ShaderProgram'; - -// Define an object with application parameters and button callbacks -// This will be referred to by dat.GUI's functions that add GUI elements. -const controls = { +import { vec3, mat4, vec4 } from "gl-matrix"; +import * as Stats from "stats-js"; +import * as DAT from "dat-gui"; +import Square from "./geometry/Square"; +import ScreenQuad from "./geometry/ScreenQuad"; +import OpenGLRenderer from "./rendering/gl/OpenGLRenderer"; +import Camera from "./Camera"; +import { setGL } from "./globals"; +import ShaderProgram, { Shader } from "./rendering/gl/ShaderProgram"; +import Mesh from "./geometry/Mesh"; +import LSystem from "./l-system/L-System"; +import { readTextFile } from "../src/globals"; + +var palette = { + color1: [255, 127.0, 80.0, 1.0], // branch + color2: [57, 217, 222, 1.0], // leaf }; +// controls: +let prevIters = 3; +let prevAngle = 15; +let prevScale = 1; +let prevColor1: vec4 = vec4.fromValues( + palette.color1[0], + palette.color1[1], + palette.color1[2], + 1.0 +); +let prevColor2: vec4 = vec4.fromValues( + palette.color2[0], + palette.color2[1], + palette.color2[2], + 1.0 +); + let square: Square; let screenQuad: ScreenQuad; let time: number = 0.0; +let branch: Mesh; +let matrix: mat4 = mat4.create(); +let coral: LSystem = new LSystem(4, 15, 1, prevColor1, prevColor2); +let base: Mesh = new Mesh( + readTextFile("resources/base.obj"), + vec3.fromValues(50, 50, 0) +); + +function putBase() { + base.create(); + + let base1 = [15, 0, 0, 0]; + let base2 = [0, 10, 0, 0]; + let base3 = [0, 0, 15, 0]; + let base4 = [50, 42, 0, 1]; + + let cols = [0.761, 0.698, 0.502, 1.0]; + + let bCol1: Float32Array = new Float32Array(base1); + let bCol2: Float32Array = new Float32Array(base2); + let bCol3: Float32Array = new Float32Array(base3); + let bCol4: Float32Array = new Float32Array(base4); + let bcolors: Float32Array = new Float32Array(cols); + base.setInstanceVBOs(bCol1, bCol2, bCol3, bCol4, bcolors); + base.setNumInstances(1); + +} + +// Define an object with application parameters and button callbacks +// This will be referred to by dat.GUI's functions that add GUI elements. +const controls = { + iterations: 3, + angle: 15, + decoration_scale: 1, + Generate: loadScene, +}; function loadScene() { - square = new Square(); - square.create(); + coral = new LSystem( + controls.iterations, + controls.angle, + controls.decoration_scale, + prevColor1, + prevColor2 + ); + coral.makeTree(); + + base = new Mesh( + readTextFile("resources/base.obj"), + vec3.fromValues(50, 50, 0) + ); + putBase(); + screenQuad = new ScreenQuad(); screenQuad.create(); - - // Set up instanced rendering data arrays here. - // This example creates a set of positional - // offsets and gradiated colors for a 100x100 grid - // of squares, even though the VBO data for just - // one square is actually passed to the GPU - let offsetsArray = []; - let colorsArray = []; - let n: number = 100.0; - for(let i = 0; i < n; i++) { - for(let j = 0; j < n; j++) { - offsetsArray.push(i); - offsetsArray.push(j); - offsetsArray.push(0); - - colorsArray.push(i / n); - colorsArray.push(j / n); - colorsArray.push(1.0); - colorsArray.push(1.0); // Alpha channel - } - } - let offsets: Float32Array = new Float32Array(offsetsArray); - let colors: Float32Array = new Float32Array(colorsArray); - square.setInstanceVBOs(offsets, colors); - square.setNumInstances(n * n); // grid of "particles" } function main() { // Initial display for framerate const stats = Stats(); stats.setMode(0); - stats.domElement.style.position = 'absolute'; - stats.domElement.style.left = '0px'; - stats.domElement.style.top = '0px'; + stats.domElement.style.position = "absolute"; + stats.domElement.style.left = "0px"; + stats.domElement.style.top = "0px"; document.body.appendChild(stats.domElement); // Add controls to the gui const gui = new DAT.GUI(); + gui.add(controls, "iterations", 1, 5).step(1); + gui.add(controls, "angle", 1, 20).step(1); + gui.add(controls, "decoration_scale", 0, 3).step(0.1); + gui.addColor(palette, "color1"); + gui.addColor(palette, "color2"); + gui.add(controls, "Generate"); // get canvas and webgl context - const canvas = document.getElementById('canvas'); - const gl = canvas.getContext('webgl2'); + const canvas = document.getElementById("canvas"); + const gl = canvas.getContext("webgl2"); if (!gl) { - alert('WebGL 2 not supported!'); + alert("WebGL 2 not supported!"); } // `setGL` is a function imported above which sets the value of `gl` in the `globals.ts` module. // Later, we can import `gl` from `globals.ts` to access it @@ -74,25 +124,78 @@ function main() { // Initial call to load scene loadScene(); - const camera = new Camera(vec3.fromValues(50, 50, 10), vec3.fromValues(50, 50, 0)); + const camera = new Camera( + vec3.fromValues(-60, 90, 15), + vec3.fromValues(50, 100, 0) + ); const renderer = new OpenGLRenderer(canvas); renderer.setClearColor(0.2, 0.2, 0.2, 1); - gl.enable(gl.BLEND); gl.blendFunc(gl.ONE, gl.ONE); // Additive blending const instancedShader = new ShaderProgram([ - new Shader(gl.VERTEX_SHADER, require('./shaders/instanced-vert.glsl')), - new Shader(gl.FRAGMENT_SHADER, require('./shaders/instanced-frag.glsl')), + new Shader(gl.VERTEX_SHADER, require("./shaders/instanced-vert.glsl")), + new Shader(gl.FRAGMENT_SHADER, require("./shaders/instanced-frag.glsl")), ]); const flat = new ShaderProgram([ - new Shader(gl.VERTEX_SHADER, require('./shaders/flat-vert.glsl')), - new Shader(gl.FRAGMENT_SHADER, require('./shaders/flat-frag.glsl')), + new Shader(gl.VERTEX_SHADER, require("./shaders/flat-vert.glsl")), + new Shader(gl.FRAGMENT_SHADER, require("./shaders/flat-frag.glsl")), ]); + function vec4Equals(a: vec4, b: vec4) { + return vec4.len(vec4.subtract(vec4.create(), a, b)) < 0.1; + } + // This function will be called every frame function tick() { + if ( + controls.iterations != prevIters || + controls.angle != prevAngle || + controls.decoration_scale != prevScale || + !vec4Equals( + prevColor1, + vec4.fromValues( + palette.color1[0], + palette.color1[1], + palette.color1[2], + 1.0 + ) + ) || + !vec4Equals( + prevColor2, + vec4.fromValues( + palette.color2[0], + palette.color2[1], + palette.color2[2], + 1.0 + ) + ) + ) { + prevIters = controls.iterations; + prevAngle = controls.angle; + prevScale = controls.decoration_scale; + prevColor1 = vec4.fromValues( + palette.color1[0], + palette.color1[1], + palette.color1[2], + 1.0 + ); + prevColor2 = vec4.fromValues( + palette.color2[0], + palette.color2[1], + palette.color2[2], + 1.0 + ); + coral = new LSystem( + controls.iterations, + controls.angle, + controls.decoration_scale, + prevColor1, + prevColor2 + ); + coral.makeTree(); + } camera.update(); stats.begin(); instancedShader.setTime(time); @@ -100,21 +203,23 @@ function main() { gl.viewport(0, 0, window.innerWidth, window.innerHeight); renderer.clear(); renderer.render(camera, flat, [screenQuad]); - renderer.render(camera, instancedShader, [ - square, - ]); + renderer.render(camera, instancedShader, [coral.branch, coral.leaf, base]); stats.end(); // Tell the browser to call `tick` again whenever it renders a new frame requestAnimationFrame(tick); } - window.addEventListener('resize', function() { - renderer.setSize(window.innerWidth, window.innerHeight); - camera.setAspectRatio(window.innerWidth / window.innerHeight); - camera.updateProjectionMatrix(); - flat.setDimensions(window.innerWidth, window.innerHeight); - }, false); + window.addEventListener( + "resize", + function () { + renderer.setSize(window.innerWidth, window.innerHeight); + camera.setAspectRatio(window.innerWidth / window.innerHeight); + camera.updateProjectionMatrix(); + flat.setDimensions(window.innerWidth, window.innerHeight); + }, + false + ); renderer.setSize(window.innerWidth, window.innerHeight); camera.setAspectRatio(window.innerWidth / window.innerHeight); diff --git a/src/rendering/gl/Drawable.ts b/src/rendering/gl/Drawable.ts index d5420f6..e93df14 100644 --- a/src/rendering/gl/Drawable.ts +++ b/src/rendering/gl/Drawable.ts @@ -1,4 +1,4 @@ -import {gl} from '../../globals'; +import { gl } from "../../globals"; abstract class Drawable { count: number = 0; @@ -9,6 +9,10 @@ abstract class Drawable { bufTranslate: WebGLBuffer; bufCol: WebGLBuffer; bufUV: WebGLBuffer; + bufTransform1: WebGLBuffer; + bufTransform2: WebGLBuffer; + bufTransform3: WebGLBuffer; + bufTransform4: WebGLBuffer; idxGenerated: boolean = false; posGenerated: boolean = false; @@ -16,18 +20,26 @@ abstract class Drawable { colGenerated: boolean = false; translateGenerated: boolean = false; uvGenerated: boolean = false; + transform1Generated: boolean = false; + transform2Generated: boolean = false; + transform3Generated: boolean = false; + transform4Generated: boolean = false; numInstances: number = 0; // How many instances of this Drawable the shader program should draw - abstract create() : void; + abstract create(): void; - destory() { + destroy() { gl.deleteBuffer(this.bufIdx); gl.deleteBuffer(this.bufPos); gl.deleteBuffer(this.bufNor); gl.deleteBuffer(this.bufCol); gl.deleteBuffer(this.bufTranslate); gl.deleteBuffer(this.bufUV); + gl.deleteBuffer(this.bufTransform1); + gl.deleteBuffer(this.bufTransform2); + gl.deleteBuffer(this.bufTransform3); + gl.deleteBuffer(this.bufTransform4); } generateIdx() { @@ -60,6 +72,24 @@ abstract class Drawable { this.bufUV = gl.createBuffer(); } + generateTransform1() { + this.transform1Generated = true; + this.bufTransform1 = gl.createBuffer(); + } + + generateTransform2() { + this.transform2Generated = true; + this.bufTransform2 = gl.createBuffer(); + } + generateTransform3() { + this.transform3Generated = true; + this.bufTransform3 = gl.createBuffer(); + } + generateTransform4() { + this.transform4Generated = true; + this.bufTransform4 = gl.createBuffer(); + } + bindIdx(): boolean { if (this.idxGenerated) { gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.bufIdx); @@ -102,6 +132,34 @@ abstract class Drawable { return this.uvGenerated; } + bindTrans1(): boolean { + if (this.transform1Generated) { + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform1); + } + return this.transform1Generated; + } + + bindTrans2(): boolean { + if (this.transform2Generated) { + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform2); + } + return this.transform2Generated; + } + + bindTrans3(): boolean { + if (this.transform3Generated) { + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform3); + } + return this.transform3Generated; + } + + bindTrans4(): boolean { + if (this.transform4Generated) { + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform4); + } + return this.transform4Generated; + } + elemCount(): number { return this.count; } @@ -113,6 +171,6 @@ abstract class Drawable { setNumInstances(num: number) { this.numInstances = num; } -}; +} export default Drawable; diff --git a/src/rendering/gl/ShaderProgram.ts b/src/rendering/gl/ShaderProgram.ts index fa9f450..e887dfe 100644 --- a/src/rendering/gl/ShaderProgram.ts +++ b/src/rendering/gl/ShaderProgram.ts @@ -1,6 +1,6 @@ -import {vec3, vec4, mat4, mat3} from 'gl-matrix'; -import Drawable from './Drawable'; -import {gl} from '../../globals'; +import { vec3, vec4, mat4, mat3 } from "gl-matrix"; +import Drawable from "./Drawable"; +import { gl } from "../../globals"; var activeProgram: WebGLProgram = null; @@ -16,7 +16,7 @@ export class Shader { throw gl.getShaderInfoLog(this.shader); } } -}; +} class ShaderProgram { prog: WebGLProgram; @@ -26,6 +26,10 @@ class ShaderProgram { attrCol: number; // This time, it's an instanced rendering attribute, so each particle can have a unique color. Not per-vertex, but per-instance. attrTranslate: number; // Used in the vertex shader during instanced rendering to offset the vertex positions to the particle's drawn position. attrUV: number; + attrTransform1: number; // Represents the columns of the transform matrix + attrTransform2: number; + attrTransform3: number; + attrTransform4: number; unifModel: WebGLUniformLocation; unifModelInvTr: WebGLUniformLocation; @@ -50,16 +54,22 @@ class ShaderProgram { this.attrPos = gl.getAttribLocation(this.prog, "vs_Pos"); this.attrCol = gl.getAttribLocation(this.prog, "vs_Col"); + this.attrNor = gl.getAttribLocation(this.prog, "vs_Nor"); this.attrTranslate = gl.getAttribLocation(this.prog, "vs_Translate"); this.attrUV = gl.getAttribLocation(this.prog, "vs_UV"); - this.unifModel = gl.getUniformLocation(this.prog, "u_Model"); + this.attrTransform1 = gl.getAttribLocation(this.prog, "vs_Transform1"); + this.attrTransform2 = gl.getAttribLocation(this.prog, "vs_Transform2"); + this.attrTransform3 = gl.getAttribLocation(this.prog, "vs_Transform3"); + this.attrTransform4 = gl.getAttribLocation(this.prog, "vs_Transform4"); + + this.unifModel = gl.getUniformLocation(this.prog, "u_Model"); this.unifModelInvTr = gl.getUniformLocation(this.prog, "u_ModelInvTr"); - this.unifViewProj = gl.getUniformLocation(this.prog, "u_ViewProj"); - this.unifCameraAxes = gl.getUniformLocation(this.prog, "u_CameraAxes"); - this.unifTime = gl.getUniformLocation(this.prog, "u_Time"); - this.unifEye = gl.getUniformLocation(this.prog, "u_Eye"); - this.unifRef = gl.getUniformLocation(this.prog, "u_Ref"); - this.unifUp = gl.getUniformLocation(this.prog, "u_Up"); + this.unifViewProj = gl.getUniformLocation(this.prog, "u_ViewProj"); + this.unifCameraAxes = gl.getUniformLocation(this.prog, "u_CameraAxes"); + this.unifTime = gl.getUniformLocation(this.prog, "u_Time"); + this.unifEye = gl.getUniformLocation(this.prog, "u_Eye"); + this.unifRef = gl.getUniformLocation(this.prog, "u_Ref"); + this.unifUp = gl.getUniformLocation(this.prog, "u_Up"); } use() { @@ -71,20 +81,20 @@ class ShaderProgram { setEyeRefUp(eye: vec3, ref: vec3, up: vec3) { this.use(); - if(this.unifEye !== -1) { + if (this.unifEye !== -1) { gl.uniform3f(this.unifEye, eye[0], eye[1], eye[2]); } - if(this.unifRef !== -1) { + if (this.unifRef !== -1) { gl.uniform3f(this.unifRef, ref[0], ref[1], ref[2]); } - if(this.unifUp !== -1) { + if (this.unifUp !== -1) { gl.uniform3f(this.unifUp, up[0], up[1], up[2]); } } setDimensions(width: number, height: number) { this.use(); - if(this.unifDimensions !== -1) { + if (this.unifDimensions !== -1) { gl.uniform2f(this.unifDimensions, width, height); } } @@ -159,6 +169,30 @@ class ShaderProgram { // TODO: Set up attribute data for additional instanced rendering data as needed + if (this.attrTransform1 != -1 && d.bindTrans1()) { + gl.enableVertexAttribArray(this.attrTransform1); + gl.vertexAttribPointer(this.attrTransform1, 4, gl.FLOAT, false, 0, 0); + gl.vertexAttribDivisor(this.attrTransform1, 1); // Advance 1 index in translate VBO for each drawn instance + } + + if (this.attrTransform2 != -1 && d.bindTrans2()) { + gl.enableVertexAttribArray(this.attrTransform2); + gl.vertexAttribPointer(this.attrTransform2, 4, gl.FLOAT, false, 0, 0); + gl.vertexAttribDivisor(this.attrTransform2, 1); // Advance 1 index in translate VBO for each drawn instance + } + + if (this.attrTransform3 != -1 && d.bindTrans3()) { + gl.enableVertexAttribArray(this.attrTransform3); + gl.vertexAttribPointer(this.attrTransform3, 4, gl.FLOAT, false, 0, 0); + gl.vertexAttribDivisor(this.attrTransform3, 1); // Advance 1 index in translate VBO for each drawn instance + } + + if (this.attrTransform4 != -1 && d.bindTrans4()) { + gl.enableVertexAttribArray(this.attrTransform4); + gl.vertexAttribPointer(this.attrTransform4, 4, gl.FLOAT, false, 0, 0); + gl.vertexAttribDivisor(this.attrTransform4, 1); // Advance 1 index in translate VBO for each drawn instance + } + d.bindIdx(); // drawElementsInstanced uses the vertexAttribDivisor for each "in" variable to // determine how to link it to each drawn instance of the bound VBO. @@ -171,14 +205,30 @@ class ShaderProgram { // by the GPU, thus being the same value for the first set of four vertices, // then advancing to a new value for the next four, then the next four, and // so on. - gl.drawElementsInstanced(d.drawMode(), d.elemCount(), gl.UNSIGNED_INT, 0, d.numInstances); + gl.drawElementsInstanced( + d.drawMode(), + d.elemCount(), + gl.UNSIGNED_INT, + 0, + d.numInstances + ); if (this.attrPos != -1) gl.disableVertexAttribArray(this.attrPos); if (this.attrNor != -1) gl.disableVertexAttribArray(this.attrNor); if (this.attrCol != -1) gl.disableVertexAttribArray(this.attrCol); - if (this.attrTranslate != -1) gl.disableVertexAttribArray(this.attrTranslate); + if (this.attrTranslate != -1) + gl.disableVertexAttribArray(this.attrTranslate); if (this.attrUV != -1) gl.disableVertexAttribArray(this.attrUV); + if (this.attrTransform1 != -1) + gl.disableVertexAttribArray(this.attrTransform1); + if (this.attrTransform2 != -1) + gl.disableVertexAttribArray(this.attrTransform2); + if (this.attrTransform3 != -1) + gl.disableVertexAttribArray(this.attrTransform3); + if (this.attrTransform4 != -1) + gl.disableVertexAttribArray(this.attrTransform4); } -}; +} export default ShaderProgram; + diff --git a/src/shaders/flat-frag.glsl b/src/shaders/flat-frag.glsl index 99362d2..b45e593 100644 --- a/src/shaders/flat-frag.glsl +++ b/src/shaders/flat-frag.glsl @@ -8,6 +8,46 @@ uniform float u_Time; in vec2 fs_Pos; out vec4 out_Col; +vec3 rgb(vec3 color) { + return vec3(color.x / 255.0, color.y / 255.0, color.z / 255.0); +} + void main() { - out_Col = vec4(0.5 * (fs_Pos + vec2(1.0)), 0.0, 1.0); + float yVal = fs_Pos.y; + float sinVal = sin(fs_Pos.x * 20.0 + u_Time / 75.0); + float dist = .2; + float start = .8; + + + // backdrop just in case of leaks + out_Col = vec4(rgb(vec3(242, 252, 255)), 1.0); + if(yVal < .05 * sinVal - start) { + out_Col = vec4(rgb(vec3(193, 242, 254)), 1.0); + } + if(yVal < .05 * sinVal + start) { + out_Col = vec4(rgb(vec3(144, 233, 255)), 1.0); + } + if(yVal < .05 * sinVal + (start - dist)) { + out_Col = vec4(rgb(vec3(95, 223, 255)), 1.0); + } + if(yVal < .05 * sinVal + (start - 2.0 * dist)) { + out_Col = vec4(rgb(vec3(46, 213, 255)), 1.0); + } + if(yVal < .05 * sinVal + (start - 3.0 * dist)) { + out_Col = vec4(rgb(vec3(0, 202, 252)), 1.0); + } + if(yVal < .05 * sinVal + (start - 4.0 * dist)) { + out_Col = vec4(rgb(vec3(0, 163, 204)), 1.0); + } + if(yVal < .05 * sinVal + (start - 5.0 * dist)) { + out_Col = vec4(rgb(vec3(0.0, 124.0, 155.0)), 1.0); + } + if(yVal < .05 * sinVal + (start - 6.0 * dist)) { + out_Col = vec4(rgb(vec3(0.0, 84.0, 106.0)), 1.0); + } + if(yVal < .05 * sinVal + (start - 7.0 * dist)) { + out_Col = vec4(rgb(vec3(0.0, 45.0, 57.0)), 1.0); + } + // muten by some factor + out_Col = vec4(vec3(out_Col / 1.5), 1.0); } diff --git a/src/shaders/instanced-frag.glsl b/src/shaders/instanced-frag.glsl index 72e7460..fa7b4a1 100644 --- a/src/shaders/instanced-frag.glsl +++ b/src/shaders/instanced-frag.glsl @@ -8,6 +8,11 @@ out vec4 out_Col; void main() { - float dist = 1.0 - (length(fs_Pos.xyz) * 2.0); - out_Col = vec4(dist) * fs_Col; + // for falloff: + // float dist = 1.0 - (length(fs_Pos.xyz) * 2.0); + // out_Col = vec4(dist) * fs_Col; + // sample y position on a sine curve + vec4 inverse = vec4(vec3(vec4(1.0) - fs_Col), 1.0); + float mixVal = sin(fs_Pos.y * 20.0); + out_Col = mix(inverse, fs_Col, 1.0 - mixVal); } diff --git a/src/shaders/instanced-vert.glsl b/src/shaders/instanced-vert.glsl index d8b8996..19e3851 100644 --- a/src/shaders/instanced-vert.glsl +++ b/src/shaders/instanced-vert.glsl @@ -10,20 +10,27 @@ in vec4 vs_Pos; // Non-instanced; each particle is the same quad drawn in a diff in vec4 vs_Nor; // Non-instanced, and presently unused in vec4 vs_Col; // An instanced rendering attribute; each particle instance has a different color in vec3 vs_Translate; // Another instance rendering attribute used to position each quad instance in the scene +in vec4 vs_Transform1; +in vec4 vs_Transform2; +in vec4 vs_Transform3; +in vec4 vs_Transform4; + in vec2 vs_UV; // Non-instanced, and presently unused in main(). Feel free to use it for your meshes. out vec4 fs_Col; out vec4 fs_Pos; +out vec4 fs_Nor; void main() { fs_Col = vs_Col; fs_Pos = vs_Pos; - vec3 offset = vs_Translate; - offset.z = (sin((u_Time + offset.x) * 3.14159 * 0.1) + cos((u_Time + offset.y) * 3.14159 * 0.1)) * 1.5; - - vec3 billboardPos = offset + vs_Pos.x * u_CameraAxes[0] + vs_Pos.y * u_CameraAxes[1]; + mat4 TransformMatrix = mat4(vs_Transform1, vs_Transform2, vs_Transform3, vs_Transform4); + fs_Nor = TransformMatrix * vs_Nor; + vec4 newPos = TransformMatrix * vs_Pos; - gl_Position = u_ViewProj * vec4(billboardPos, 1.0); + gl_Position = u_ViewProj * vec4(vec3(newPos), 1.0); } + +