1 # SPDX-License-Identifier: GPL-2.0-or-later
6 from gpu_extras
.batch
import batch_for_shader
7 from mathutils
import Vector
10 if bpy
.app
.background
: # ignore north line in background mode
11 def north_update(self
, context
):
15 uniform mat4 u_ViewProjectionMatrix;
19 flat out vec2 v_StartPos;
24 vec4 pos = u_ViewProjectionMatrix * vec4(position, 1.0f);
26 v_StartPos = (pos / pos.w).xy;
34 flat in vec2 v_StartPos;
38 uniform vec2 u_Resolution;
42 vec4 vertPos_2d = v_VertPos / v_VertPos.w;
43 vec2 dir = (vertPos_2d.xy - v_StartPos.xy) * u_Resolution;
44 float dist = length(dir);
46 if (step(sin(dist / 5.0f), 0.0) == 1) discard;
52 shader
= gpu
.types
.GPUShader(vertex_shader
, fragment_shader
)
54 def draw_north_callback():
55 # ------------------------------------------------------------------
56 # Set up the compass needle using the current north offset angle
57 # less 90 degrees. This forces the unit circle to begin at the
58 # 12 O'clock instead of 3 O'clock position.
59 # ------------------------------------------------------------------
60 sun_props
= bpy
.context
.scene
.sun_pos_properties
62 color
= (0.2, 0.6, 1.0, 0.7)
64 angle
= -(sun_props
.north_offset
- math
.pi
/ 2)
65 x
= math
.cos(angle
) * radius
66 y
= math
.sin(angle
) * radius
68 coords
= Vector((x
, y
, 0)), Vector((0, 0, 0)) # Start & end of needle
70 batch
= batch_for_shader(
76 matrix
= bpy
.context
.region_data
.perspective_matrix
77 shader
.uniform_float("u_ViewProjectionMatrix", matrix
)
78 shader
.uniform_float("u_Resolution", (bpy
.context
.region
.width
, bpy
.context
.region
.height
))
79 shader
.uniform_float("u_Color", color
)
80 gpu
.state
.line_width_set(2.0)
86 def north_update(self
, context
):
88 if self
.show_north
and _handle
is None:
89 _handle
= bpy
.types
.SpaceView3D
.draw_handler_add(draw_north_callback
, (), 'WINDOW', 'POST_VIEW')
90 elif _handle
is not None:
91 bpy
.types
.SpaceView3D
.draw_handler_remove(_handle
, 'WINDOW')
93 context
.area
.tag_redraw()