CS 184: Computer Graphics and Imaging, Spring 2020

Final Project: Jenga Simulation

Katherine Lee, Ethan Yao, Winnie Zhang

Abstract

Jenga is a game that many people all know and love. From pulling out a single block from the tower to all the blocks falling down, the game itself demonstrates an interesting dynamic of a rigid body. Thus, our group decided to try to implement the rigid body dynamic for ourselves. Since Unity provides their own rigid body dynamic, we decided to first implement the game of Jenga using it in order to see how the blocks are supposed to interact with each other and the floor. By using multiple papers, we decided to represent the blocks as a group of particles. We tried two ways of doing this: creating the blocks from three particles and using a bounding box to create the particles within the block. Each method had its advantages and disadvantages, which will be discussed in more detail below. After these blocks were created, we then attempted to implement the rigid body dynamic. This was done by applying various forces to the body and making sure that the various particles stay together. This, however, proved to be more challenging then we initially anticipated due to some inconsistencies in Unity. We, sadly, were not able to completely implement the dynamics on to the block themselves.

Technical Approach

Game Mechanics

To start off our simulation, we decided to use Unity's built-in rigid body to see how the blocks are supposed to interact with each other. By using Unity's camera, we were able to give the user the ability to change how they view the game by using the WASD keys. We also changed the material of the block when the user used their mouse to hover over a block and select a block. This was done adding a collider box around the block and using a ray pointer starting from where the mouse is located; by using the ray pointer, the box collider was able to detect when the mouse was hovering over the block. This ray pointer is very similar to the rays discussed in class, since it uses the origin and direction to create a line from the mouse. Once the user selects a block, the user can then choose to move it in either the x, y, or z direction. In order to implement this section of the game, we just changed where the transform lays by 1 in either of those directions.

Particle Generation: Method 1

The first method used to generate the blocks was to create the block out of three particles. Each sphere was a prefab, and the particles were placed in a tower format during run-time. In order to form the blocks, each block had a parent particle. Thus, whenever anything needed to occur to the block, the parent sphere is first found.This made it easy to change the materials on the block, which made implementing the game mechanics relatively easy. Futhermore, the three particles were connected with a fixed joint, which prevented the block from falling apart. Since the block was only made out of 3 particles, it had a low computational cost. However, this also led to disadvantages. Since the block was so narrow and made out of only 3 particles, the tower could not be made very large. Furthermore, the tower was very sensitive to a block being pulled out, even if the tower was short.

Particle Generation: Method 2

The second method used to generate the blocks was to create the particles within a bounding box. Similar to the first method, the sphere was a prefab. However, the block was also a prefab in this method, which served to be the bounding box. Within this method, the spheres were generated within the bounding box, which created better and more detailed blocks. We were able to change the particle size while maintaining the size of the block. We could also model the force on an individual particle, rather than the parent particle from method 1. However, this method was computationally expensive, which led to some crashes if the particle size was too small.

Rigid Body Dynamics

In order to create the rigid body dynamic, we referenced the notes made by Carnegie Mellon. While they implemented the forces on a solid rigid body, we decided to implement it on particles due to another paper that discussed rigid body dynamics. It is also due to the fact that simulating the movement of a particle is very similar to simulating the movement of a rigid body. In order to simulate a rigid body, we had to create a state vector that was composed out of the translation of the body (x(t)), the rotational matrix (R(t)), the linear momentum (P(t)), and the angular momentum (L(t)). The linear momentum is described as M*v(t), and the derivative is equal to the total force acting on the body; the angular momentum is decribed to be I(t) * w(t), where I(t) is a 3x3 intertia tensor matrix, and w(t) is the angular velocity. Thus, by adding in the force of gravity, we were able to create a body of particles that fell.

In addition, for Method 2, we chose to implement an approach under taken by Muller, Macklin, Chentanez, and Kim in their paper Unified Particle Physics for Real-Time Applications. To summarize, this approach implemented a rigid body as a collection of particles, where each particle was affected by its own set of forces. In each simulation loop, we took each particle, and performed verlet based integration, as detailed in lecture. Then, we checked for collisions with the floor. Like in assignment 4, if a particle was found to be colliding with the floor (or was projected to under it) we would scoot it back out. Finally, in order to make sure the rigid body kept its shape, we implemented the methodology detailed in the paper. First, we calculated the covariance matrix. For every particle in the body, we calculated its distance to the current center of mass, and multiplied that vector by the transpose of the vector that represented the distance from the center of mass in the original matrix. Then, we found the polar decomposition of that matrix. This gave us a rotational part. We applied this matrix to the particle and got a new position, which helped keep the shape. In essence, this allowed us to not need to keep track of rotation stuff, which often requires concepts like quaternions.

Problems

One of the problems faced in method 1 was that the spheres would just fall to the ground. This was because the fixed joint was not added in to connect the particles together. Another issue faced was getting all three spheres to change material, which led to the creation of a parent particle. In the beginning, each sphere would either find the parent and a sibling or the two children. However, this caused bugs and was confusing to debug.

Method 2 was full of various bugs. Some of these can be attributed to Unity's weird non-determinism, which proved frustrating when debugging. Often times, a block which fell perfectly on one run would spaz out without hitting the ground in another. In terms of a debugging process, here are some of the bugs encountered. First, there was a critical error in the calculation of the polar decomposition initially. A block which fell would immediately fracture and quite literally explode. It turns out that there was a sneaky error in calculation - namely, instead of multiplying a matrices transpose by that matrix, it was reversed. Matrix multiplication isn't commutative. Another fundamental issue after solving the mystery of why blocks exploded was strange behavior with the total energy in the system. Blocks would often bounce nonsensically, windmilling off into space like rockets. An attempted fix for this was to keep track of the total energy of the system, and constrain the velocity of each particle if it was too high. However, this approach failed to provide useful results, in fact adding on to the weird errors, so it was ultimately ditched. An attempt at handling block to block collisions ended in the same fashion, as the imprecision of the collision just resulted in blocks flying wildly off into space. At least they kept their shape.

Lessons Learned

Through this project, we not only learned a lot about physics and how it effects the world around us, but we also learned about the difficultly of implementing these forces on a solid object. We had to discuss how to implement the blocks and how to detect when the blocks interacted with the floor or with each other. We also had to discuss how we would make the particles stay in a coherent shape as they fall to the ground.

Results

References

https://www.cs.cmu.edu/~baraff/sigcourse/notesd1.pdf

https://www.cs.cmu.edu/~baraff/sigcourse/notesd2.pdf

https://developer.nvidia.com/gpugems/gpugems3/part-v-physics-simulation/chapter-29-real-time-rigid-body-simulation-gpus

https://www.cs.drexel.edu/~david/Classes/Papers/MeshlessDeformations_SIG05.pdf

https://www.math.ucla.edu/~jteran/papers/WTF06.pdf url reflects the content

https://matthias-research.github.io/pages/publications/flex.pdf

Contributions

Katherine Lee implemented the game controls and helped implement the rigid body dynamics. Furthermore, she made the video in this website and the video in the milestone website.

Ethan Yao implemented the second method of the particle generation and also helped implement the rigid body dynamics. Futhermore, he helped make the websites.

Winnie Zhang implemented the first method of the particle generation and also helped implement the rigid body dynamics. Futhermore, she helped make the websites and slides.