Relative Objects - Demo 11¶
Purpose¶
Introduce relative objects, by making a small blue square that is defined relative to the left paddle, but offset some in the x direction. When the paddle on the left moves or rotates, the blue square moves with it, because it is defined relative to it.
How to Execute¶
On Linux or on MacOS, in a shell, type “python src/demo11/demo.py”. On Windows, in a command prompt, type “python src\demo11\demo.py”.
Move the Paddles using the Keyboard¶
Keyboard Input |
Action |
---|---|
w |
Move Left Paddle Up |
s |
Move Left Paddle Down |
k |
Move Right Paddle Down |
i |
Move Right Paddle Up |
d |
Increase Left Paddle’s Rotation |
a |
Decrease Left Paddle’s Rotation |
l |
Increase Right Paddle’s Rotation |
j |
Decrease Right Paddle’s Rotation |
UP |
Move the camera up, moving the objects down |
DOWN |
Move the camera down, moving the objects up |
LEFT |
Move the camera left, moving the objects right |
RIGHT |
Move the camera right, moving the objects left |
Description¶
Cayley Graph¶
In the graph below, all we have added is “Square space”, relative to paddle 1 space.
In the picture below, in 3D space, we see that the square has its own modelspace (as evidenced by the 3 arrows), and we are going to define its position and orientation relative to paddle 1.
Code¶
Define the geometry of the square in its own modelspace.
184square: Paddle = [
185 Vertex(x=-0.5, y=-0.5),
186 Vertex(x=0.5, y=-0.5),
187 Vertex(x=0.5, y=0.5),
188 Vertex(x=-0.5, y=0.5),
189]
Event Loop¶
234while not glfw.window_should_close(window):
...
Draw paddle 1, just as before.
253 glColor3f(paddle1.r, paddle1.g, paddle1.b)
254
255 glBegin(GL_QUADS)
256 for paddle1_vertex_in_model_space in paddle1.vertices:
257 paddle1_vertex_in_world_space: Vertex = paddle1_vertex_in_model_space.rotate(paddle1.rotation) \
258 .translate(translate_amount=paddle1.position)
259 paddle1_vertex_in_camera_space: Vertex = paddle1_vertex_in_world_space.translate(translate_amount=-camera.position_worldspace)
260 paddle1_vertex_in_ndc_space: Vertex = paddle1_vertex_in_camera_space.uniform_scale(scalar=1.0/10.0)
261 glVertex2f(paddle1_vertex_in_ndc_space.x, paddle1_vertex_in_ndc_space.y)
262 glEnd()
As a refresher, the author recommends reading the code from modelspace to worldspace from the bottom up, and from worldspace to NDC from top down.
Read from modelspace to world space, bottom up
Reset the coordinate system
Read from world space to camera space, knowing that camera transformations are implemented as the inverse of placing the camera space in world space.
Reset the coordinate system
Read camera-space to NDC
New part! Draw the square relative to the first paddle! Translate the square to the right by 2 units. We are dealing with a -1 to 1 world space, which later gets scaled down to NDC.
268 glColor3f(0.0, 0.0, 1.0)
269 glBegin(GL_QUADS)
270 for model_space in square:
271 paddle1space: Vertex = model_space.translate(Vertex(x=2.0, y=0.0))
272 world_space: Vertex = paddle1space.rotate(paddle1.rotation) \
273 .translate(paddle1.position)
274 camera_space: Vertex = world_space.translate(translate_amount=-camera.position_worldspace)
275 ndc_space: Vertex = camera_space.uniform_scale(scalar=1.0/10.0)
276 glVertex2f(ndc_space.x, ndc_space.y)
277 glEnd()
Towards that, we need to do all of the transformations to the square that we would to the paddle, and then do any extra transformations afterwards.
As such, read
Read paddle1space to world space, from bottom up
If we were to plot the square now, it would be in paddle 1’s space. We don’t want that, we want in to be moved in the X direction some units. Therefore
Read modelspace to paddle1space, from bottom up
Reset the coordinate system.
Now the square’s geometry will be in its own space!
Read from worldspace to camera-space, knowing that camera transformations are implemented as the inverse of placing the camera space in world space.
Reset the coordinate system
Read camera-space to NDC
Draw paddle 2 just like before.
283 glColor3f(paddle2.r, paddle2.g, paddle2.b)
284
285 glBegin(GL_QUADS)
286 for paddle2_vertex_model_space in paddle2.vertices:
287 paddle2_vertex_world_space: Vertex = paddle2_vertex_model_space.rotate(paddle2.rotation) \
288 .translate(paddle2.position)
289 paddle2_vertex_camera_space: Vertex = paddle2_vertex_world_space.translate(translate_amount=-camera.position_worldspace)
290 paddle2_vertex_ndc_space: Vertex = paddle2_vertex_camera_space.uniform_scale(scalar=1.0/10.0)
291 glVertex2f(paddle2_vertex_ndc_space.x, paddle2_vertex_ndc_space.y)
292 glEnd()