Implement the following 3 curve types:

    See the files for each curve inside Engine/src/animation.

  • Bezier

    They should be cubic beziers splined together with C0 continuity. You'll need at least four control points to make a single bezier curve. Adjacent Bezier curves share control points so that the last control point of one Bezier curve will be the first control point of another. In this way you can have two complete Bezier curves with only 7 control points and so on.

    Note: In the lecture slides, you were shown an adaptive recursive algorithm for creating Bezier curves as well as a straightforward method that simply samples at a consistent rate. The adaptive Bezier curve generation is not required (but is a bell of extra credit). Feel free to sample the curve at a constant rate to fulfill the project requirements.

  • Catmull-Rom

    Include endpoint interpolation.

    Keep in mind that it is possible to make parametric curves that "double back" on themselves (x is not monotonically increasing as a function of t), which is obviously not desirable. It must be possible to interpret the curves that your solution produces as a function of time, so you'll have to think about and solve this case when it occurs (for any curve).

  • B-spline

    Include endpoint interpolation.

  • Extend the existing Emitter Particle System:

    Animator can spawn particles, which are then acted upon by forces in the scene. Currently, it only responds to gravity (f=mg) and collisions with SphereColliders and PlaneColliders. Note that the system of forces is being solved with Euler's method. Find the class at Engine/scene/components/particlesystem.cpp.

  • Add viscous drag

    Viscous drag is a velocity-dependent force acting on each particle, always opposing it's motion (f = -k_drag * v). We've provided a UI slider for the drag constant; add the effect of this force to the particle system.

    Extend collision detection

    The system needs to detect and respond to collisions of particles with different primitives that can be added to your scene. It currently responds to PlaneColliders and SphereColliders. Extend this to support CylinderColliders.

    The cylinder collision should be "natural" - i.e. the particles colliding with the cylinder should reflect off at an angle dependent on the cylinder's normal at the point of collision, and the particle's incoming velocity direction. Keep in mind that a cylinder has a curved body as well as two flat endcaps. You may assume that particles are guaranteed to not originate from inside the collider (i.e., particles will only every collide with the "outside" surface of the cylinder).

    Note that when the cylinder collider is moved, the particle collision test should be with the cylinder's current position, not just its original position. Your particles should bounce off of the cylinder, and the restitution constant slider should properly control how much the normal component of the reflected velocity is attenuated.

  • Create a spring-based particle system:

    Another kind of particle system consists of a fixed number of particles that interact with each other in some way. Examples include a cloth, a field of grass, strands of hair, a deformable box, etc. We've provided a skeleton of such particle system to you, but this time you will have to implement collision detection and Euler's method, as well as any additional member variables and functions you will need. See Engine/scene/components/connectedparticlesystem.cpp.

  • Implement a spring force that interacts between the particles

    Use Hooke's spring law (with damping). See the lecture slides for the formula; you will want to use the 3D version. Springs can be attached between different pairs of particles, forming a 'mesh'. The sample solution implements a deformable cube in this way, where each particle is a vertex of the cube. The more connections a particle has, the more stable the mesh will be.

    We've also provided rendering code in glRenderer::Render(SceneObject&, ConnectedParticleSystem) and glRenderer::RenderDeformedMesh to handle drawing a wireframe mesh based on the particles as vertices. You may change the code there if you want to render your deformed mesh differently.

    You may also use springs in a different application if you wish: other interesting possibilities include using springs to simulate hair, cloth, or fur, or to deform a more complex mesh than a cube. Some of these options are listed in the Bells and Whistles below; if you implement them for this requirement, you may also earn extra credit.

    Note: You must solve the system of forces using Euler's method. If you want to implement more powerful methods of solving, such as Runge-Kutta (in Bells and Whistles), it must be an option that can be enabled and disabled.

  • Apply an additional force

    The most obvious force is gravity/constant force (f=mg). Other interesting possibilities include electromagnetic force, simulation of flocking behavior, and buoyant force. Similar as before, if the force you choose is complicated or novel (or listed in the Bells and Whistles), you may earn extra credit while simultaneously fulfilling this requirement.

  • Implement collision detection

    This system should also detect and respond to collisions of particles with different primitives that can be added to your scene. Like the emitter particle system, make this support SphereCollider, PlaneCollider, and CylinderCollider. The Restitution slider should once again attenuate the reflected velocity.

    Just like when working with individual particles, each particle should be separately considered for collision. If a particle/vertex comes into contact with a collider, then collision force is only applied to that single particle. Then, after implementing springs, this will propagate to the other neighboring particles via the connecting spring force.