<html>
<head><title>Assignment 4</title></head>
<body text="#000000" bgcolor="#ffffff" link="#0000ee" vlink="#551a8b" alink="#ff0000">
<center><IMG alt="cos426.jpg (39279 bytes)" src="../cos426.jpg"></center>
<center><h3>
<A href="../index.html">Computer Graphics, Spring 2007</a>
</h3></center>

<hr>
<center>
<h3>Assignment 4: Particle System</h3>
<h4>Due on Sunday, April 29 at 11:59 PM</h4>
</center>

<hr>
<h3>Overview</h3>
<blockquote>
In this assignment, you will implement a basic particle system. The
program will read in a scene file with particle commands and then 
draw particles as they move over time in an interactive viewer.

At its simplest, your program will be able to spawn particles, apply
forces such as gravity and drag to them, and bounce them off of
scene geometry. Once you have the basic system in place, you have a broad
selection of options to improve your system. You can choose to focus
on the rendering or the physics of the particles. Improved rendering
will allow for more convincing simulation of phenomena such as smoke,
fire, and sparks. Improved physics will allow simulation of rope and
cloth, or even flocks of birds or schools of fish.
</blockquote>


<hr>
<h3>Getting Started</h3>
<blockquote>

You should use the following skeleton code (<a
href="COS426_assignment4.zip">COS426_assignment4.zip</a>) as a starting point for
your assignment. We provide you with several files, but you
should mainly change <code>particle.cpp</code>.
<ul>
	<li><code>particleview.cpp</code>: interactive scene viewing program (similar to rayview.cpp).
	<li><code>particle.[h/cpp]</code>: core file for simulating and drawing particles.
        <li><code>R3Scene.[h/cpp]</code>: code to support reading and representing scenes (augmented to handle particles).
 	<li><code>R2</code>: code to support operations on 2D points, vectors, lines, segments, and images
	<li><code>R3</code>: code to support operations on 3D points, vectors, lines, segments, planes, and meshes.
	<li><code>jpeg</code>: code to read/write JPEG files
	<li><code>particleview.[vcproj/sln]</code>: Project file for Visual Studio .NET 2005 on Windows.</li>
	<li><code>Makefile</code>: Make file for Linux.</li>
</ul>

<p>After you copy the provided files to your diectory, the first thing
to do is compile the program. If you are developing on a Windows
machine and have Visual Studio .NET 2005 installed, use the provided
project files to build the program. If you are developing on a
UNIX/Linux machine, type <code>make</code> in the assignment4
directory. In either case, one executable will be created:
<code>particleview</code> (or <code>particleview.exe</code>).

<p>The skeleton code is able to read scene files (like in assignment 3)
augmented to support particle systems.  Specifically, the scene 
<a href="scnformat.html">file format</a> now supports three new commands:
<I>particle</I>, <I>particle_source</I>, and <I>particle_sink</I>.
We provide several <a href="../data/particles/">sample files</a> that 
you can use to get you started.  Of course, however, you should create
files of your own to demonstrate the features of your program.
</blockquote>

<hr>
<h3>How the Program Works</h3>
<blockquote>

When <code>particleview</code> is executed, it reads a scene file 
and spawns a window.  
<blockquote>
<code>% particleview in.scn</code>
</blockquote>
In the provided version of the program, the scene is drawn (with particles
shown as white points), but the particles are not animated.
Your job is to update the code to generate, update, and render particles 
at each time step of the simulation (in <code>GenerateParticles</code>, 
<code>UpdateParticles</code>, and <code>RenderParticles</code>).

<p>As in <code>meshview</code> and <code>rayview</code>,
<code>particleview</code> allows the camera to be moved interactively
with the mouse -- i.e., dragging with the left, middle, and right
mouse buttons down rotates, scales, and translates the scene,
respectively.  Also, hitting the 'P', 'F', and 'E' keys toggle drawing
particles, faces, and edges of the scene, respectively, 
and hitting the 'S' key saves an image of the window to a file.
Of course, you are welcome to create your own program
arguments, scene commands, and interactive commands - please 
provide documentation of them with your writeup.

<p>The particle system should be implemented in <code>particle.cpp</code>.
For every refresh of the window in <code>particleview.cpp</code>,
the <code>DrawParticles</code> function is called.
It reads the current time (in seconds since the start of the program)
and calls three functions: <code>UpdateParticles</code>, 
<code>GenerateParticles</code>, and <code>RenderParticles</code>.
<code>UpdateParticles</code> should update the position (and possibly
other parameters) of every particle at the current time.  
<code>GenerateParticles</code> should create new particles for
every particle source.  <code>RenderParticles</code> should use OpenGL
commands to draw every particle on the screen.  Shells are provided
for these three functions, but you must fill in the details.
</blockquote>

<hr>
<h3>What You Have to Do</h3>
<blockquote>
The assignment is worth 20 points. The following is a list of features that you may implement (listed roughly from easiest to hardest within each group). The number in front of the feature corresponds to how many points the feature is worth. The features in bold face are required. The other ones are optional.  

<ul>
<li>Particle sources:
<ul>
<li><b>(1)</b> Point sources.  Modify the GenerateParticles function to create particles for every source at every time step and add them to the scene. To get credit for this option, you must respect the source parameters for rate of generation and center position. 
<li><b>(1)</b> Nozzle sources.  Augment the previous option to support source parameters for particle source direction, angle cutoff, and speed.  
<li>(1) Solid sources. Augment the previous options to support generating particles in the interior of a shape specified as the second parameter of the <i>particle_source</i> command in the scene file.  The shape should be translated so that its origin is at the position of the source.  For each particle, you should pick a random point in the shape's interior volume (with the positions distributed uniformly).  To get one point for this option, you must support at least boxes, spheres, cylinders, and cones.  You can also get three additional points for supporting arbitrary meshes.  
<li>(1) Surface sources. Augment the previous options to support generating particles on the surface of a shape specified as the second parameter of the <i>particle_source</i> command in the scene file.  For each particle, you should pick a random point on the shape's surface (with the positions distributed uniformly with respect to surface area).  To get one point for this option, you must support at least boxes and spheres.  You can also get one additional point for each of cylinders, cones, and meshes, but for a maximum of 3 points total.  Remember that points must be distributed uniformly with respect to surface area on the shape to get credit.
<li>(2) Particles that generate particles. Augment the scene description to include a new type of particle that provides a source for other particles. Use your implementation to create a fireworks simulation. 
</ul>
</ul>

<ul>
<li>Particle simulation:
<ul>
<li><b>(1)</b> Particle lifetimes. Remove particles when their lifetimes expire.
<li><b>(1)</b> Global forces. Modify the UpdateParticles function to update the center position of every particle according to its velocity, its gravitational force, and a drag force determined by its drag coefficient using the simple forward Euler integration technique.
<li><b>(1)</b> Midpoint integration. Improve the accuracy of your simulation by implementing the midpoint integration scheme (second-order Runge Kutta).
<li>(2) Adaptive step sizes. Further improve the accuracy of your simulation by implementing the adaptive step size technique. You should be able to implement this technique without changing the global time step by taking multiple substeps for every particle during each time step.
</ul>
</ul>

<ul>
<li>Particle sinks:
<ul>
<li><b>(1)</b> Particle death. Remove particles that arrive at a sink (within some small distance).
<li><b>(1)</b> Point sinks. Modify the UpdateParticles function to apply a force that attracts all particles towards the positions of the particle sinks.  The magnitude of the force applied to each particle should be <i>force*1.0/ (ca + la*d + qa*d*d)</i>, where <i>force</i> indicated in the scene file (note that it can be negative), <i>d</i> is the distance from a particle to the sink position, and <i>ca, la, and qa</i> specify the attenuation of the force with distance.
<li>(1) Surface sinks.  Augment your code to handle sinks of arbitrary shapes (specified in the second parameter of the <i>source_sink</i> command).  The shape should be translated so that its origin is at the position of the source, and then the attenuation with distance should be computed based on the distance between each particle and the closest point on the shape's surface.  To get one point, you must handle at least boxes and spheres.  You can also get one additional point for each of cylinders, cones, and meshes, but for a maximum of 3 points total. 
</ul>
</ul>

<ul>
<li>Collision detection:
<ul>
<li><b>(2)</b> Particle-scene collisions.  Handle particle-surface collisions for obstacles specified in a scene file.  For each particle,  in each time step, you should use ray-surface interesection to determine whether the particle traveling along its current trajectory will collide with the static scene, and if so where and when.  When particles collide with a surface, they should bounce off in the specular reflection direction with a velocity scaled by the specular reflection coefficient of the collision point in the scene.  To get full credit, you must ensure that the particles never pass through a solid shape. 
<li>(2) Particle-particle collisions.  For each particle, in each time step, you should determine whether a collision will occur with other particles (within some distance tolerance), and if so where and when.  When particles collide, they should bounce off each other according to Newton's Second Law, taking into account momentums. 
</ul>
</ul>

<ul>
<li>Particle interaction:
<ul>
<li>(2) Particle attraction and repulsion. Augment your simulation to allow particles to apply simple attraction or repulsion forces to one another. The direction of the force should be along the vector between the particles, and the magnitude should diminish with the inverse squared distance.
<li>(2) Rope. Create a string of particles connected by springs. Fix the first particle in space, and determine the position of the remaining particles by their spring connections. Your simulation should be stable, which requires implementing adaptive time steps.
<li>(3) Cloth. Create a cloth surface in a manner similar to the rope, except in two dimensions. Create a 2D square of particles, and connect them using springs. Your simulation should be stable, which requires implementing adaptive time steps.
<li>(3) Flocking. Implement a system similar to <a href="http://www.red3d.com/cwr/boids/">Boids</a>. Make sure that your boids try to avoid geometry in the scene; you can accomplish this by allowing them to look a bit ahead of themselves by shooting a ray. Combined with rendering particles as animated geometry, you can make a reasonably convincing simulation of a flock of birds or a school of fish.
</ul>
</ul>

<ul>
<li>Scene animation:
<ul>
<li>(1) Animated camera. Augment <code>particleview.cpp</code> to move the camera automatically along a path specified with a Hermite, B-Spline, or Bezier curve.
<li>(1) Animated obstacles: Make a scene with a hierarchy of transformations (using <I>begin</I> and <I>end</I> commands) and then animate the scene by changing transformations as a function of time.  You can use this feature to create simple rotating parts like a spinning wheel, flapping wing, ceiling fan, etc.  You get an additional point if particles collide correctly with the animated scene elements.
</ul>
</ul>

<ul>
<li>Particle rendering:
<ul>
<li>(1) Materials. Modify the RenderParticles function to use OpenGL to render every particle with the material specified by m_id in the scene file.
<li>(1) Textures. Replace the code in RenderParticles to render a small square polygon centered at every particle position oriented towards the viewer and apply a texture (included as the last field of the material) when rendering the polygon.  You should be able to use this feature to generate interesting visual effects like snow flakes and smoke (with partially transparent textures).
<li>(1) Shapes. Support rendering of every particle with the geometric shape specified as its last parameter in the scene file.  The shape should be centered at the particle position and oriented according to the velocity vector of the particle (the last degree of rotational freedom - roll - can be set based on the "up" direction, but you get an additional point if you set it based on the curvature of the particle path).
<li>(1) Glow. Use the glEnable(GL_BLEND) and glBlend function so that overlapping particles add their colors in the framebuffer instead of overwriting each other. This can give the effect of glowing particles. 
<li>(1) Trails. Modify you particle rendering so that each particle leaves a trail behind it as it moves. You will have to remember previous positions for each particle and use GL_POINTS or GL_LINE_STRIP to achieve this effect. Try storing only the last K positions and fading out the color towards the end of the trail. 
<li>(1) Dynamic materials. Scale the material properties of every particle based on its velocity and/or lifetime.
<li>(2) Animated materials. Augment the scene description and parser to associate multiple materials with every particle and then cycle through them at regular time slices over the lifetime of the particle.  Combining this feature with textures, you should be able to get a reasonable approximation of fire. 
<li>(2) Responsive materials. Change the material properties of every particle based on its proximity to static shapes in the scene.
</ul>
</ul>

<ul>
<li>Interactive control:
<ul>
<li><b>(1)</b> Source control. Allow the user to click with the mouse to select a particle source.  Then, when a particle source is selected and the simulation is running, keyboard commands should allow the user to increase/decrease the rate of generated particles ("R" increases by 10% and "r" decreases by 10%).  Also support keyboard commands to increase/decrease the speed ("S" increases by 10% and "s" decreases by 10%), mass ("M" increases by 10% and "m" decreases by 10%), drag ("D" increases by 10% and "d" decreases by 10%), elasticity ("E" increases by 10% and "e" decreases by 10%), and lifetime ("L" increases by 10% and "l" decreases by 10%) of particles generated by the selected source.
<li>(1) Sink control. Allow the user to click with the mouse to select a particle sink.  Then, when a particle sink is selected and the simulation is running, keyboard commands should allow the user to increase/decrease the force associated with the sink ("F" increases by 10% and "f" decreases by 10%).
<li>(1) Source and sink dragging. Allow the user to move particle sources and sinks by selecting them and dragging with the mouse.
<li>(2) Rope or cloth manipulation. If implementing rope or cloth, allow the user to pick a point on the rope or cloth and drag it around. 
<li>(3) Graphical user interface. Use any GUI toolkit (e.g., <a href="http://www.cs.unc.edu/~rademach/glui/">glui</a>) to implement sliders to control parameters of sources and sinks as the simulation runs.  When the user selects a particle source and/or sink, the interface elements should change to provide sliders to adjust the parameters of that source or sink.  (note: this option is recommended)
</ul>
</ul>

<p>By implementing all the required features, you get 10 points. There are many ways to get more points:
<ul>
	<li>implementing the optional features listed above;
	<li>(1) submitting one or more movies for the art contest, 
	<li>(2) winning the art contest.
</ul>

You should provide a working program with scripts to run it, along with short movies to demonstrate that your program works.  For each movie that you submit, you also have to submit the sequence of commands used to created it, otherwise it will not be considered valid.  
	
<p>It is possible to get more than 20 points. However, after 20 points, each point is divided by 2,
and after 22 points, each point is divided by 4. If your raw score is 19, your final score will be 19. If
the raw score is 23, you'll get 21.25. For a raw score of 26, you'll get 22.     

 <p>Extra credit points cannot replace the required features (bold items). 
Your final score will be calculated by adding 10 to the number of extra credit points you achieve, 
applying the above formula for diminishing returns, and then subtracting the number of required 
points that you missed.
</blockquote>

<hr>
<h3>What to Submit</h3>
<b>Note: The submission materials are slightly different from before</b><br>
<blockquote>

	You must <a href="../assignments.html#submit">submit</A><B> one 
	archive</B> (zip or tar file).  It needs to have the following directory structure inside the zip:
	<ul>
		<li>[your username]/     (i.e. cdecoro/)
			<ul>
				<li>source/
				<ul>
					<li>the complete source code, along with an updated Visual Studio project file (if you added any source files);
				</ul>
				<li>art/
				<ul>
					<li>the movies for the art contest (optional)
				</ul>
				<li>writeup/
				<ul>
					<li>assignment4.html, containing the writeup (see below)
					<li>all images and movies linked from assignment4.html.

				</ul>
				<li>script/
				<ul>
					<li>runparticle.[bat|sh], a test script that will run in this directory, and take all its inputs from this directory.
					<li>all input files for the test script
			</ul>

	</ul>
</ul>

	<p>The writeup should be a HTML document called <tt>assignment4.html</tt>.
You will use the writeup to demonstrate the effects of the features you have
implemented.  List each implemented feature in the format given above, and
along with the feature name, include a captured movie (or image if possible) that
demonstrates it.   The caption must indicate the regions of interest.  If it is
reasonable to demonstrate a feature with a picture, or multiple features in a single movie, 
you may do so.  

<p>Features that improve simuluation quality (e.g., midpoint integration and adaptive time steps)
will require a comparison of two or more movies.
Features that improve speed do not require a
picture, but should include a brief comparison of performance on a scene with
and without acceleration.

	<p>The included script must run the program with parameters and scenes that could generate all movies linked from the writeup.  It must run entirely in the script/ directory.  Please make sure that you include all input files.

</p>
	<p>NOTE: Please compress your art contest and writeup movies before submitting them (to save space).</p>
	<p>Should you choose to create a video, there are many options for video encoders available, however we have found that FFMPEG works well and runs on both Windows and linux. MEncoder is another option.</p>
	<p>Always remember the <A href="../assignments.html#Late Policy">late policy</A> and the <A href="../assignments.html#Collaboration Policy">collaboration policy</A>.
</blockquote>


<hr>
<h3>Hints</h3>
<blockquote>
	A few hints:
	<ul>
		<li>Do the simplest steps first and test/debug every step before going to the next one.
		<li>There are functions to manipulate 3D geometric primitives in <code>R3</code>. 
		<li><a href="mailto:cos426@cs.princeton.edu">Send mail</a> to the cos426 staff.        
		<li>The code should compile and link as-is (make sure to try it out before adding your own code!).  If you have problems linking to libjpeg, you can simply remove the -DUSE_JPEG flag from the makefile (or #undef USE_JPEG in your code) to disable JPEG support.
		<li>If you should happen stumble upon anything that you suspect is a bug in the framework code (we're not perfect either!) please mail the preceptor as soon as possible so that it can be corrected.
		<li>If you are stuck/confused/lost/having a problem, <b>meet with the preceptor.</b>  He is readily available most days of the week.
	</ul>
</blockquote>

<hr>
<h3>FAQ</h3>
<ul>
<li><b>How can I create a movie file from a sequence of stills?</b>
You can use the mencoder program, which is available free for download, and also on the cycleservers (wash.cs, rinse.cs, soak.cs, spin.cs) at /u/cdecoro/bin/mencoder.  A command line would look like the following:

<pre>
mencoder mf://*.jpg -mf w=640:h=480:fps=25:type=jpg -ovc lavc -lavcopts vcodec=mpeg4 -nosound -o movie.avi
</pre>
</ul>

<hr>


</body>
</html>



