Welcome, dear Computer Graphics enjoyers!
In this blog, I will talk about some details of my implementation for CENG469 Computer Graphics II homework and the challenges I faced.
Curved Path Generation
I decided to start with this part as it seemed to be the easiest one. I implemented BezierCurve
class. Throughout the whole program, I keep one global instance of BezierCurve
class, which is instantiated with hardcoded control points at the beginning of the program. Each frame the t
parameter of the curve is increased by a hardcoded delta value. When the end of the curve is reached, we update the control points of the BezierCurve
class instance with the newly generated random control points, ensuring that the path is C1 continuous and stays in the scene bounds. The range of x
, y
and z
coordinates, in which the control points are generated, was found experimentally.
In the later stage of implementation – when I already aligned the model to the path – I faced the following problem: despite being C1 continuous, the path didn’t feel smooth. I minimized this by regenerating control points which are too close to each other.
Alignment and Rolling
The part I continued with was making Armadillo follow the path.
At each frame, Armadillo is translated by the current point of the curve. Then I aligned the gaze of Armadillo with the current tangent of the curve as described in the specification 11 of the homework text. However, I faced the following problem: while following the path, Armadillo gradually “falls” to one side:

The interesting part is that this issue wasn’t present when I was calculating right
vector as a cross-product of the tangent and the world’s up, in contrast with calculating right
as a cross-product of the tangent and the previous point’s up (the up vector calculated in the previous frame). Neither was this solution suitable as Armadillo was often flipping, while following the path.
I decided to combine these two solutions: using world’s up by default and prevUp
when the tangent and the world’s up are close to being parallel. This approach seemed to resolve the issue. Nevertheless, the ghost didn’t have this problem, so I used only prevUp
in the final implementation.
Alternating rolling motion was done using glm’s built-in quaternions.
Ghost
I designed ghost using five surfaces: four identical rotated surfaces and one concave bottom-surface (no holes in the mesh). Here are screenshots from MATLAB:


Each surface was rendered separately using the pipeline implemented in the template code.
s=t=1

s=t=2

s=t=3

s=t=5

s=t=10

s=t=25

s=t=50

s=t=100

Here is the final video showing all keyboard interactions:
Conclusion
In overall, it was a very satisfying experience. Many thanks to Oğuz Hocam and Kadir Hocam for such a great learning opportunity. The template code was very helpful.
Thanks for reading and see you in the upcoming homework!