@@ -91,12 +91,10 @@ def refresh_rotation_matrix(self):
91
91
quaternion_from_angle_axis (phi , RIGHT , axis_normalized = True ),
92
92
quaternion_from_angle_axis (gamma , OUT , axis_normalized = True ),
93
93
)
94
- self .inverse_camera_rotation_matrix = rotation_matrix_transpose_from_quaternion (
95
- quat
96
- )
94
+ self .inverse_rotation_matrix = rotation_matrix_transpose_from_quaternion (quat )
97
95
98
96
def rotate (self , angle , axis = OUT , ** kwargs ):
99
- curr_rot_T = self .inverse_camera_rotation_matrix
97
+ curr_rot_T = self .inverse_rotation_matrix
100
98
added_rot_T = rotation_matrix_transpose (angle , axis )
101
99
new_rot_T = np .dot (curr_rot_T , added_rot_T )
102
100
Fz = new_rot_T [2 ]
@@ -182,22 +180,33 @@ class OpenGLRenderer:
182
180
def __init__ (self ):
183
181
# Measured in pixel widths, used for vector graphics
184
182
self .anti_alias_width = 1.5
185
-
186
183
self .num_plays = 0
187
184
self .skip_animations = False
188
-
189
185
self .camera = OpenGLCamera ()
186
+ self .pressed_keys = set ()
187
+
188
+ # Initialize shader map.
189
+ self .id_to_shader_program = {}
190
+
191
+ # Initialize texture map.
192
+ self .path_to_texture_id = {}
190
193
194
+ def init_scene (self , scene ):
195
+ self .partial_movie_files = []
196
+ self .file_writer = SceneFileWriter (
197
+ self ,
198
+ scene .__class__ .__name__ ,
199
+ )
200
+ self .scene = scene
191
201
if config ["preview" ]:
192
- self .window = Window ()
202
+ self .window = Window (self )
193
203
self .context = self .window .ctx
194
204
self .frame_buffer_object = self .context .detect_framebuffer ()
195
205
else :
196
206
self .window = None
197
207
self .context = moderngl .create_standalone_context ()
198
208
self .frame_buffer_object = self .get_frame_buffer_object (self .context , 0 )
199
209
self .frame_buffer_object .use ()
200
-
201
210
self .context .enable (moderngl .BLEND )
202
211
self .context .blend_func = (
203
212
moderngl .SRC_ALPHA ,
@@ -206,14 +215,6 @@ def __init__(self):
206
215
moderngl .ONE ,
207
216
)
208
217
209
- # Initialize shader map.
210
- self .id_to_shader_program = {}
211
-
212
- # Initialize texture map.
213
- self .path_to_texture_id = {}
214
-
215
- self .partial_movie_files = []
216
-
217
218
def update_depth_test (self , context , shader_wrapper ):
218
219
if shader_wrapper .depth_test :
219
220
self .context .enable (moderngl .DEPTH_TEST )
@@ -223,24 +224,24 @@ def update_depth_test(self, context, shader_wrapper):
223
224
def get_pixel_shape (self ):
224
225
return self .frame_buffer_object .viewport [2 :4 ]
225
226
226
- def refresh_perspective_uniforms (self , camera_frame ):
227
+ def refresh_perspective_uniforms (self , camera ):
227
228
pw , ph = self .get_pixel_shape ()
228
- fw , fh = camera_frame .get_shape ()
229
+ fw , fh = camera .get_shape ()
229
230
# TODO, this should probably be a mobject uniform, with
230
231
# the camera taking care of the conversion factor
231
232
anti_alias_width = self .anti_alias_width / (ph / fh )
232
233
# Orient light
233
- rotation = camera_frame . inverse_camera_rotation_matrix
234
- light_pos = camera_frame .light_source .get_location ()
234
+ rotation = camera . inverse_rotation_matrix
235
+ light_pos = camera .light_source .get_location ()
235
236
light_pos = np .dot (rotation , light_pos )
236
237
237
238
self .perspective_uniforms = {
238
- "frame_shape" : camera_frame .get_shape (),
239
+ "frame_shape" : camera .get_shape (),
239
240
"anti_alias_width" : anti_alias_width ,
240
- "camera_center" : tuple (camera_frame .get_center ()),
241
+ "camera_center" : tuple (camera .get_center ()),
241
242
"camera_rotation" : tuple (np .array (rotation ).T .flatten ()),
242
243
"light_source_position" : tuple (light_pos ),
243
- "focal_distance" : camera_frame .get_focal_distance (),
244
+ "focal_distance" : camera .get_focal_distance (),
244
245
}
245
246
246
247
def render_mobjects (self , mobs ):
@@ -347,12 +348,6 @@ def set_shader_uniforms(self, shader, shader_wrapper):
347
348
except KeyError :
348
349
pass
349
350
350
- def init_scene (self , scene ):
351
- self .file_writer = SceneFileWriter (
352
- self ,
353
- scene .__class__ .__name__ ,
354
- )
355
-
356
351
def play (self , scene , * args , ** kwargs ):
357
352
if len (args ) == 0 :
358
353
logger .warning ("Called Scene.play with no animations" )
@@ -389,7 +384,6 @@ def update_frame():
389
384
if self .window is not None :
390
385
self .window .swap_buffers ()
391
386
while self .animation_elapsed_time < frame_offset :
392
- # TODO: Just sleep?
393
387
update_frame ()
394
388
self .window .swap_buffers ()
395
389
@@ -429,3 +423,15 @@ def get_raw_frame_buffer_object_data(self, dtype="f1"):
429
423
dtype = dtype ,
430
424
)
431
425
return ret
426
+
427
+ # Returns offset from the bottom left corner in pixels.
428
+ def pixel_coords_to_space_coords (self , px , py , relative = False ):
429
+ pw , ph = config ["pixel_width" ], config ["pixel_height" ]
430
+ fw , fh = config ["frame_width" ], config ["frame_height" ]
431
+ fc = self .camera .get_center ()
432
+ if relative :
433
+ return 2 * np .array ([px / pw , py / ph , 0 ])
434
+ else :
435
+ # Only scale wrt one axis
436
+ scale = fh / ph
437
+ return fc + scale * np .array ([(px - pw / 2 ), (py - ph / 2 ), 0 ])
0 commit comments