Activity

Chanied

Circle and Static Shapes:
I updated the shape initialization to allow for easier polygon creation and allow for circles. Currently, only polygon-polygon and circle-polygon collisions work, as the circles borrow collision checks from polygons. Next update I will create a new lightweight check for circle-circle, as it does not need to be as complex as polygons.
Instead of manually adding points to create non-rectangle polygons, you can now specify the number of points as well as the width and height. This can create most simple polygons, but still leaves the option to specify points for more complex shapes.
Shapes can now be created as linear static, angular static, or both. Static prevents forces from other shapes applying that respective force. Instead, that force will be either converted to it’s non-static force type or applied to the non-static shape.
In the previous update, I said that it would be the last one due to flavortown ending. Turns out, flavortown got extended another month. Next update will probably be the real final update during flavortown, but follow the GitHub for future updates. In preparation for this final update, I added a trash button. For now, it just resets the environment back to its starting position.

Attachment
0
Chanied

Friction Calculations:
I reused the code that generates separating impulses to calculate friction. Since friction happens across surfaces, it uses the tangent to the normal. Static friction is used as a stopping force, and kinetic friction works as a slowing force. That means that static holds the object still while kinetic brings it closer to stopping. The forces are applied in the same way, and just add on to the velocities to be updated later.
Since this is the final update during Flavortown, I spent a lot of time fixing any bugs I could find as well as generally improving the engine. I made the separating vectors apply with the changed velocities to prevent race conditions. In addition to the large rectangle and small triangle, I also added some small squares. EPA now uses epsilons to better account for inaccuracies.
Continuing with my development in dev tools that pause and slow down time over the past few devlogs, I have created a tool to rewind time. While holding the Z key, all elements rendered are saved. After running the engine for a bit, you can hold M to enter rewind mode. Left and right arrow keys parse through individual frames, while up and down quickly move through them. Once M is released, the engine returns back to wherever it was before you started rewinding.

Attachment
0
Chanied

Impulse Calculations:
This final step applies velocities based on the original velocities and the collision to separate the shapes. It uses the MTV to establish a normal to base the direction of the collision off of. It then uses the contact point to calculate the relative velocity at that point as a combination of linear and angular velocity. It also calculates how aligned the relative velocity is with the the normal using the dot product. Only the amount of velocity that is aligned with the collision is counted. Once it has the needed information ready, it is able to calculate the base impulse, or strength of the collision in that same direction.
The applied forces are split into 2 parts: Linear and Angular. The linear force is the impulse multiplied by the inverse mass (1/mass) of that shape. This tells the shape how much it should react to the force (lighter shapes go faster). The angular force is the inverse inertia (1/inertia) multiplied by the cross product of the contact point and the impulse. The more misaligned the center of mass and contact point are to the normal, the more angular momentum the shape gets. All of these forces are saved to the object and applied at the same time later to prevent new velocities affecting further collision calculations in the same step.
The O key now slows down the step rate to allow for seeing issues and being able to easily pause on the problem frames.

Attachment
0
Chanied

Contact Points:
Using the Minimum Translation Vector, or MTV, we got from EPA, I am able to separate the shapes till they are near a collision rather than intersecting. Then, I scan all pairs of points on shape B for the closest line on shape A. The smallest distance is kept, but if there is a close second (within a set tolerance) it will keep both points. Then, it flips it to check all lines on shape B and points on A. If a significantly smaller distance is found, the previously found contact points are replaced. Otherwise, it will steal the second place distance if it was inside the tolerance. Then, the average of the two (if there were two) contact points is found. Instead of applying all forces in the next step on each contact point, it can be approximated at the average of the two points for efficiency and reliability.
When you hover over a shape, it now shows the number of that shape in the corner for debugging in addition to highlighting it. If holding shift, it will now highlight the closest point on that shape and display its index for further debugging.
I modified the pause functionality further to allow certain processes to continue even while paused. This includes shape highlighting, shape dragging, shape throwing (velocity is applied after unpause), and the new shape point highlighting.

Attachment
0
Chanied

EPA Algorithm:
The majority of this update was focused on the Expanding Polytype Algorithm.
The algorithim starts with the 3 point simplex that GJK terminated with (Cyan). It then iteratively finds the closes point on any line in the simplex (Yellow), and adds the GJK point furthest in that direction to the simplex. Once the GJK point it finds is already contained within the simplex, the original point it found on the line is the Minimum Translation Vector, or MTV. This represents the minimum distance that can be applied to the shapes to separate them. The MTV is the closest approximation to how the shapes moved since colliding and once applied allows for the contact points to be found. In some cases, an MTV can not be found. It will terminate early to save performance if the shapes are perfectly colliding or the same closest point is found twice in a row. Otherwise, it will terminate after a set number of attempts. The default attempts is 30, but it may need to be higher for complex shapes.
I split up the code to find a point using the Minkowski Difference from the code that sets and checks new GJK points. This allowed me to reuse the now general purpose code to generate points for EPA as well.
I added a new class dedicated to controlling the rendering and logging of debug information. Instead of commenting out lines that I don’t need anymore, but may need again in the future, this class controls what debug info is allowed to print or display. For now, it is vague categories and is hard on the eyes, but I plan to create functions to easily integrate these toggles with future code.
In addition to the debug toggles, I also allowed drawn lines and points to have configurable sizes. This allows for stacking lines and points of various colors and seeing both as well as the order they were created in.
Last update I enabled pausing physics calculations by holding the space key, and now I added the P key as a pause toggle.

Attachment
0
Chanied

GJK Algorithm:
I worked on porting my implementation of GJK over to the new Java physics engine.
I added a system of saving points and lines to be rendered each frame for debugging. To save these, I created new classes to save color data along with their respective points and lines. With the introduction of drawing specific data, I split the multi-threading synchronized lock into separate drawing data and object data locks.
I added keyboard input logging. It keeps track of when keys are pressed and released. So far, it is only used to pause the simulation using the space key. This was important for inspecting the data of individual frames to find errors. Soon, I plan to add more frame controlling keys to quickly recreate and debug issues.
With the help of the new debug tools, I was able to pause and inspect frames for what went wrong instead of attempting to make sense of hundreds of console debug lines.
GJK works off of a simple idea to determine collisions. Imagine a shape where a point was created from all possible combinations of shape A’s points subtracted from shape B’s points. If that new shape contained the coordinates (0,0), then the two shapes are colliding. However, calculating all of these (mostly interior) points is quite computationally expensive. Instead, you can find the points furthest in opposite directions to guarantee a perimeter point. In addition to that, by specifying the target direction (relative to the other found points and the origin) you can find whether the new shape contains the origin with only 3 points. Although does occasionally require a few iterations to create a working simplex, it is significantly more efficient.

Attachment
0
Chanied

Base engine:
I started porting my engine a little over a week before I decided to submit the file to flavor town.
I started off learning Java Swing and Jframe, as well as how to keep my code thread-safe. Once I had a solid base to transfer information back and forth between threads, I began working on a rendering system.

While working on the rendering, I also started defining the class for physics objects. To simplify functions and allow the return of both x and y coordinates from them, I created a Vector class that holds both coordinates and functions that use or modify coordinates.

To help test future collisions, I added the ability to move/throw shapes by dragging them.
Of the three stages of Collision (AABB, GJK, and EPA), so far I have completed AABB, or Axis Aligned Bounding Box. This is a lightweight check designed to identify objects that could not be touching. Currently, I’m working on implementing GJK and EPA to detect collisions between objects.

Attachment
0