def __init__( self, default_matcap: core.Texture, *, render_node: core.NodePath = None, light_dir: core.Vec3 = None, hueshift: core.Vec3 = None, ): self._default_matcap = default_matcap if render_node is None: render_node = base.render if light_dir is None: self._light_dir = core.PTA_float(core.Vec3(-1).normalized()) else: self._light_dir = core.PTA_float(light_dir.normalized()) if hueshift is None: hueshift = core.Vec3(0) self._hueshift = hueshift self._render_node = render_node # Do not force power-of-two textures core.Texture.set_textures_power_2(core.ATS_none) # Matcap Shader self._recompile_matcap()
def light_dir(self, value: core.Vec3) -> None: for i, j in enumerate(value.normalized()): self._light_dir[i] = j self._recompile_matcap()
def closest_object_intersecting_line( self, point: core.Point3, direction: core.Vec3 ): normalized_direction = direction.normalized() normal_2d_length = core.Vec2( normalized_direction.x, normalized_direction.y ).length() closest_object = None closest_part: str = None closest_distance_squared = ( constants.REALLY_BIG_NUMBER * constants.REALLY_BIG_NUMBER ) closest_hit: core.Point3 = None part = self._sector.part_for_direction(normalized_direction) if part == map_objects.EditorSector.FLOOR_PART: hit = self._sector.floor_plane.intersect_line(point, normalized_direction) else: hit = self._sector.ceiling_plane.intersect_line(point, normalized_direction) if hit is not None and self._sector.point_in_sector(hit.xy): closest_object = self._sector closest_part = part closest_hit = hit closest_distance_squared = (hit - point).length_squared() for editor_wall in self._sector.walls: intersection = editor_wall.intersect_line(point, normalized_direction) if intersection is not None: hit, distance_squared = self._hit_3d_and_squared_distance_from_hit_2d( intersection, point, normal_2d_length, normalized_direction ) if hit is not None: if distance_squared < closest_distance_squared: part = editor_wall.get_part_at_point(hit) closest_hit = hit closest_distance_squared = distance_squared closest_object = editor_wall closest_part = part for editor_sprite in self._sector.sprites: intersection = editor_sprite.intersect_line(point, direction) if intersection is not None: hit, distance_squared = self._hit_3d_and_squared_distance_from_hit_2d( intersection, point, normal_2d_length, normalized_direction ) if hit is not None: distance_squared -= self._SPRITE_BIAS_SQUARED if distance_squared < closest_distance_squared: part = editor_sprite.get_part_at_point(hit) if part is not None: closest_hit = hit closest_distance_squared = distance_squared closest_object = editor_sprite closest_part = part markers = ( self._sector.markers + self._sector.floor_z_motion_markers + self._sector.ceiling_z_motion_markers ) for editor_marker in markers: if editor_marker is None: continue intersection = editor_marker.intersect_line(point, direction) if intersection is not None: hit, distance_squared = self._hit_3d_and_squared_distance_from_hit_2d( intersection, point, normal_2d_length, normalized_direction ) if hit is not None: distance_squared -= self._SPRITE_BIAS_SQUARED if distance_squared < closest_distance_squared: part = editor_marker.get_part_at_point(hit) if part is not None: closest_hit = hit closest_distance_squared = distance_squared closest_object = editor_marker closest_part = part return closest_object, closest_part, closest_hit