COS 426:
|
|
COS 426 General | Assignment 5
In this assignment you will create various particle-systems in animated scenes.
As in the previous assignments, the program has two modes: (1) an GUI mode where you can choose a scene or adjust display parameters and (2) a "batch" mode where there is no GUI and the scene is specified in the URL. This section of the instructions are analogous those of the previous assignments, so by now this should be very familiar.
To get started, download this zip file and unzip it on your computer. Change to the subdirectory
cos426-assign5
and run the commandpython -m SimpleHTTPServer
(orpython -m http.server
for Python V3.0 and up) which will launch a web server on your computer, rooted at this directory. (See first assignment description about why we do this instead of opening the files directly.)Once you have started the local web server, direct your browser to
http://localhost:8000
. You should see the web page that links to the two different renderers.Using your favorite text/code editor, edit the file
ls js/student.js
in that directory and fill in your name and NetID. Reload the web page in your browser, and now your information should appear above the image.
batch.html?system=fountainBounce
. The scenes are specified in the file js/systemSettings.js
and the fountain scene (for example) is created by the method SystemSettings.fountainBounce
. Other parameters can also be set on the command line like width and height and texture etc.
The assignment is worth 12 points. The following is a list of features that you may implement. The number in front of the feature corresponds to how many points the feature is worth for the full implementation. Partial or partially-correct solutions will receive partial credit. The features in bold face are required. The other ones are optional. Refer to the examples web page for example output images as well as some implementation hints.
- Basic
- (1.0) Euler. Basic Euler integration. The provided code already updates positions based on velocities (to get you started). You need to update velocities based on gravity and attractors.
- (1.0) Sphere source. Emit particles from the surface of a sphere, with uniform probability over the entire surface. (The naive approach using a random latitude and longitude would emit more particles at the poles.)
- (1.0) Animated mesh source. Emit particles from a animated mesh by choosing a face at random and a random position within that face.
- (1.0) Damping. Add a damping force that is proportional to the negative velocity. The force has linear and quadratic terms, according to
F = -d1*V - d2*|V|*V
, whereV
is the velocity . To properly evaluate this feature, use the oscilator scene, which uses the sphere updater and initializer. As damping is increased (up to ~1 for the linear term, and much small for the quadratic one), less and less oscilations should happen until convergence in the middle.- (1.0) Uniform distribution on animated mesh. Change your code for the animated mesh to provide uniform probability distributed across the surface (as with the sphere above). You need to consider face areas.
- Collisions
- (1.0) Ground plane. This is needed in the fountain, for example. Implement two versions: one where the particles bounce, and the other where the ground plane is a sink (and the particles disappear).
- (1.0) Axis box. This is a box defined as minima/maxima in the x,y,z directions. Implement both the bounce and sink versions. You might want this for your own scene, for example to make a set of stairs.
- Cloth
- (1.0) Sphere collision. The cloth will drape over a sphere. Set the damping term to 0 so the cloth does not bounce off the sphere, but rather slide over its surface.
- (2.0) Spring system. You are given a 2D grid of particles. Add a spring force between every neighboring pair (neighbors are up, down, left, right).
- Other
- (1.0-3.0) Your system. Make your own cool particle system(s). It could include flocking, planets, spatial variation, strange attractors, more elaborate collision detection, different particle geometries, several time integration schemes, or any thing else you like. You could do several if you want. You can play around with making any kind of scene you want by modifying the function
createScene
for your system.- (1.0) Rendering. Play with rendering in any way you like. Perhaps make your particle's rendering style (color or size or anything) depend on its lifetime or location, etc.
- (3.0-6.0) Trails. Add a trail to each of the particles. This requires keeping a history particle location per particle, and rendering it in various ways. Using the existing framework, and the method suggested in the FAQ will grant you 3 points. For more credit, you should change the way the history particles are rendered (excluding changes in color and size, already supported by the framework). For example: controling its transparency, width and color according to age of a contiuously rendered trail will create effects that look like fireworks. Adding some randomness to the trail and breaking it up would look like sparkles. Motion blur effects are possible through thickening the trail, etc. Grading depends on the level of difficulty.
The translation filter is already implemented for you as an example. By implementing all the required features (in bold), you get 8 points. Full credit for this assignment is 12 points, so to complement the required features you may choose from the optional features listed above and participate in the art contest (which yields one point for participation and two for winning). It is possible to get more than 12 points for this assignment. The value of non-required features incurs diminishing returns after the first 4 points. For sums of non-required features (n>4), each point over 4 will accrue a value of 3/4 the previous point.
Your final score is based on the following factors:Final score will be rounded to the nearest 0.5. The formula in javascript is:
- r: your score on the required features (up to R = 8 points)
- n: your score on the non-required features (value diminishes when n > N = 4) .
- a: your participation in the art contest (1 point for participating, 1.5 for being selected for gallery, 2 for winning). You can make use of
customFilter()
- d: diminishing return factor (d = 3/4 in this assignment)
Math.round((Math.min(R, r) + Math.min(N, n) + d * (1 - Math.pow(d, Math.max(n - N, 0))) / (1 - d) + a) * 2.0) / 2.0
Score Calculator:
my score on the required features my score on the non-required features my score on the art contest total score
To implement the features listed above, you only need to edit the js filesinitializers.js
andupdaters.js
(and a little bit insystemSettings.js
if you make your own system). Before starting on that, we recommend you take a quick look at the other js files (especiallysystemSettings.js
andutils.js
) to get a sense of what does what. You are welcome to look at any of the other files, but it should not be necessary.
You should submit your solution via CS dropbox here. The submitted zip file should preserve the directory structure of the skeleton code we provided in the zip file above.
The
writeup.html
file should be an HTML document demonstrating the effects of the features you have implemented and would like scored.You should start from the the example
writeup.html
provided. At the top of that file are a list of features that you might implement, linking to the section where you talk about them. Please remove any features that you do not implement, but otherwise leave this header section in tact. When you include an image, also include a link to thebatch.html
command that creates that image, as in the last assignment. To save space, please submit images inpng
format.Note that you are expected to use good programming style at all times, including meaningful variable names, a comment or three describing what the code is doing, etc. Partial credit may not be assigned for code without comments. We have mostly tried to conform to the idiomatic JS style conventions.
As in the last assignment:
- Do the simplest operations first! Note, however, there are some dependencies, for example you need to handle mesh traversal before the other analysis and filtering operations.
- Look at the example page.
- Post a message to Piazza if you have questions.
- Take note of the late policy and the collaboration policy.
Here are some answers to frequently asked questions. Check back here occasionally, as we may add FAQs to this list:
How should I handle gravity? Is it attraction between two objects?
No. Gravity is simply a vector defined in the scene (in systemSettings.js). It is already fetched for you in the updater code.What other forces should I take into accout during the update?
Except gravity, you should only consider attractors (if they are present in the scene), damping (EulerUpdater only), and spring forces (ClothUpdater only).My attractors are not attracting as much as in the example page?
Yes. We have made them stronger for effect. We've used an attraction force that is about 50 times stronger than the one defined in the scene. Feel free to do the same.The vertices in the mesh animation scene don't seem to be on the mesh during the animation
Please note that the mesh may undergo some transformations (scaling, and translation) during rendering. These are defined in the scene (systemSettings.js, in the animationLoadFunction). You need to fetch these transformations and apply them yourself as well. In the horse animation, this means scaling down the mesh by 0.25.Where do I find d1 and d2, the linear and quadratic velocity damping coefficients?
They are too defined in the scene (systemSettings.js). The damping is a 3D vector, where its first element is d1, the second is d2, and the third isn't used. Note that during initialization, this term is already passed to the particles for you, and it is fetched for you during the update step. Access the "dampenings" array the same way you do "positions" - using the getElement function.How should I implement the Trails options?
you are, of course, free to implement it any way you want. The easiest way would probably be to add more particles that are "history" particles, and are handled differently.
In order to do that, you should:
1. In Emitter.prototype.update (particleEngine.js), multiply "toAdd" by the amount of history particles you would like to have per original particle. This will spawn a bunch of new particles for every particle that would have been spawned regularly.
2. add a "parents" and (if you think you need to) a "children" arrays to the particleAttributes structure. This can be done by adding "parents:1, children:1" to the _attributeInformation field, initialized in "function Emitter (opts)".
3. When initializing particles, form (doubly) connected linked lists using these new attribute(s). In other words, in the initializePositions function, spawn one particle with a parent of -1,the next particle will have the first one as parent. This continues according to the toSpawn array, until the desired history length. (If you're using children, each particle's child field will hold the value in the next position in toSpawn, and the last particle will have a child of -1).
4. During the update step, update the roots of each linked-list (the ones that have -1 parents) normally, and update each other particle to the position of it's parent (in the right order of course).
5. Please note that for performance, the order of the particles is changed during the simulation, which would change the indices and make the parent/child pointers incorrect. To prevent that, disable the use of sortParticles.
That's it!
Other notes:
- The desired history length would be most convenient to control from the scene definition in systemSettings.js. To enable this control, you need to add it to the systemSetting.js file as another field. This will add it to InputSettings. In main.js be sure to pass it to the Emitter. In the Emitter, add it as well (in "function Emitter (opts)"), and then pass it as an extra argument in the initialize and update functions of the Emitter.