[Bf-extensions-cvs] [085bc978] master: Sun Position: refactor and cleanup sun calculations
Damien Picard
noreply at git.blender.org
Sun Jan 8 02:53:07 CET 2023
Commit: 085bc978b7b0bc7135a63b2fdbf824976b36ce63
Author: Damien Picard
Date: Sat Jan 7 21:18:13 2023 +0100
Branches: master
https://developer.blender.org/rBA085bc978b7b0bc7135a63b2fdbf824976b36ce63
Sun Position: refactor and cleanup sun calculations
===================================================================
M sun_position/sun_calc.py
===================================================================
diff --git a/sun_position/sun_calc.py b/sun_position/sun_calc.py
index b1ae46dd..fc4e0452 100644
--- a/sun_position/sun_calc.py
+++ b/sun_position/sun_calc.py
@@ -2,32 +2,30 @@
import bpy
from bpy.app.handlers import persistent
-from mathutils import Euler
+from mathutils import Euler, Vector
import math
from math import degrees, radians, pi
import datetime
from .geo import parse_position
-class SunClass:
+class SunInfo:
"""
- SunClass is used for storing intermediate sun calculations.
+ Store intermediate sun calculations
"""
- class TazEl:
+ class TAzEl:
time = 0.0
azimuth = 0.0
elevation = 0.0
class CLAMP:
- elevation = 0.0
azimuth = 0.0
+ elevation = 0.0
az_start_sun = 0.0
az_start_env = 0.0
- sunrise = TazEl()
- sunset = TazEl()
- solar_noon = TazEl()
- rise_set_ok = False
+ sunrise = TAzEl()
+ sunset = TAzEl()
bind = CLAMP()
bind_to_sun = False
@@ -47,14 +45,14 @@ class SunClass:
sun_distance = 0.0
use_daylight_savings = False
-
-sun = SunClass()
+sun = SunInfo()
def sun_update(self, context):
update_time(context)
move_sun(context)
+
def parse_coordinates(self, context):
error_message = "ERROR: Could not parse coordinates"
sun_props = context.scene.sun_pos_properties
@@ -71,15 +69,10 @@ def parse_coordinates(self, context):
if sun_props.co_parser not in {'', error_message}:
sun_props.co_parser = ''
- at persistent
-def sun_handler(scene):
- update_time(bpy.context)
- move_sun(bpy.context)
-
def move_sun(context):
"""
- Cycle through all the selected objects and call set_sun_position and
+ Cycle through all the selected objects and call set_sun_location and
set_sun_rotations to place them in the sky
"""
addon_prefs = context.preferences.addons[__package__].preferences
@@ -101,11 +94,12 @@ def move_sun(context):
env_tex.texture_mapping.rotation.z = az
if sun_props.sun_object:
- sun.theta = math.pi / 2 - sun_props.hdr_elevation
- sun.phi = -sun_props.hdr_azimuth
+ theta = math.pi / 2 - sun_props.hdr_elevation
+ phi = -sun_props.hdr_azimuth
obj = sun_props.sun_object
- set_sun_position(obj, sun_props.sun_distance)
+ obj.location = get_sun_vector(theta, phi) * sun_props.sun_distance
+
rotation_euler = Euler((sun_props.hdr_elevation - pi/2,
0, -sun_props.hdr_azimuth))
@@ -124,28 +118,28 @@ def move_sun(context):
calc_sunrise_sunset(rise=True)
calc_sunrise_sunset(rise=False)
- get_sun_position(local_time, sun_props.latitude, sun_props.longitude,
- north_offset, zone, sun_props.month, sun_props.day, sun_props.year,
- sun_props.sun_distance)
+ az_north, theta, phi, azimuth, elevation = get_sun_coordinates(
+ local_time, sun_props.latitude, sun_props.longitude,
+ north_offset, zone, sun_props.month, sun_props.day, sun_props.year,
+ sun_props.sun_distance)
+ sun.azimuth = azimuth
+ sun.elevation = elevation
if sun_props.sky_texture:
sky_node = bpy.context.scene.world.node_tree.nodes.get(sun_props.sky_texture)
if sky_node is not None and sky_node.type == "TEX_SKY":
- locX = math.sin(sun.phi) * math.sin(-sun.theta)
- locY = math.sin(sun.theta) * math.cos(sun.phi)
- locZ = math.cos(sun.theta)
sky_node.texture_mapping.rotation.z = 0.0
- sky_node.sun_direction = locX, locY, locZ
- sky_node.sun_elevation = math.radians(sun.elevation)
- sky_node.sun_rotation = math.radians(sun.az_north)
+ sky_node.sun_direction = get_sun_vector(theta, phi)
+ sky_node.sun_elevation = math.radians(elevation)
+ sky_node.sun_rotation = math.radians(az_north)
# Sun object
if (sun_props.sun_object is not None
and sun_props.sun_object.name in context.view_layer.objects):
obj = sun_props.sun_object
- set_sun_position(obj, sun_props.sun_distance)
- rotation_euler = Euler((math.radians(sun.elevation - 90), 0,
- math.radians(-sun.az_north)))
+ obj.location = get_sun_vector(theta, phi) * sun_props.sun_distance
+ rotation_euler = Euler((math.radians(elevation - 90), 0,
+ math.radians(-az_north)))
set_sun_rotations(obj, rotation_euler)
# Sun collection
@@ -161,15 +155,16 @@ def move_sun(context):
time_increment = sun_props.time_spread
for obj in sun_objects:
- get_sun_position(local_time, sun_props.latitude,
- sun_props.longitude, north_offset, zone,
- sun_props.month, sun_props.day,
- sun_props.year, sun_props.sun_distance)
- set_sun_position(obj, sun_props.sun_distance)
+ az_north, theta, phi, azimuth, elevation = get_sun_coordinates(
+ local_time, sun_props.latitude,
+ sun_props.longitude, north_offset, zone,
+ sun_props.month, sun_props.day,
+ sun_props.year, sun_props.sun_distance)
+ obj.location = get_sun_vector(theta, phi) * sun_props.sun_distance
local_time -= time_increment
obj.rotation_euler = (
- (math.radians(sun.elevation - 90), 0,
- math.radians(-sun.az_north)))
+ (math.radians(elevation - 90), 0,
+ math.radians(-az_north)))
else:
# Analemma
day_increment = 365 / object_count
@@ -177,43 +172,61 @@ def move_sun(context):
for obj in sun_objects:
dt = (datetime.date(sun_props.year, 1, 1) +
datetime.timedelta(day - 1))
- get_sun_position(local_time, sun_props.latitude,
- sun_props.longitude, north_offset, zone,
- dt.month, dt.day, sun_props.year,
- sun_props.sun_distance)
- set_sun_position(obj, sun_props.sun_distance)
+ az_north, theta, phi, azimuth, elevation = get_sun_coordinates(
+ local_time, sun_props.latitude,
+ sun_props.longitude, north_offset, zone,
+ dt.month, dt.day, sun_props.year,
+ sun_props.sun_distance)
+ obj.location = get_sun_vector(theta, phi) * sun_props.sun_distance
day -= day_increment
obj.rotation_euler = (
- (math.radians(sun.elevation - 90), 0,
- math.radians(-sun.az_north)))
+ (math.radians(elevation - 90), 0,
+ math.radians(-az_north)))
+
+
+def day_of_year_to_month_day(year, day_of_year):
+ dt = (datetime.date(year, 1, 1) + datetime.timedelta(day_of_year - 1))
+ return dt.day, dt.month
+
+def month_day_to_day_of_year(year, month, day):
+ dt = datetime.date(year, month, day)
+ return dt.timetuple().tm_yday
+
def update_time(context):
sun_props = context.scene.sun_pos_properties
if sun_props.use_day_of_year:
- dt = (datetime.date(sun_props.year, 1, 1) +
- datetime.timedelta(sun_props.day_of_year - 1))
- sun.day = dt.day
- sun.month = dt.month
+ day, month = day_of_year_to_month_day(sun_props.year,
+ sun_props.day_of_year)
+ sun.day = day
+ sun.month = month
sun.day_of_year = sun_props.day_of_year
- if sun_props.day != dt.day:
- sun_props.day = dt.day
- if sun_props.month != dt.month:
- sun_props.month = dt.month
+ if sun_props.day != day:
+ sun_props.day = day
+ if sun_props.month != month:
+ sun_props.month = month
else:
- dt = datetime.date(sun_props.year, sun_props.month, sun_props.day)
- day_of_year = dt.timetuple().tm_yday
- if sun_props.day_of_year != day_of_year:
- sun_props.day_of_year = day_of_year
+ day_of_year = month_day_to_day_of_year(
+ sun_props.year, sun_props.month, sun_props.day)
sun.day = sun_props.day
sun.month = sun_props.month
sun.day_of_year = day_of_year
+ if sun_props.day_of_year != day_of_year:
+ sun_props.day_of_year = day_of_year
+
sun.year = sun_props.year
sun.longitude = sun_props.longitude
sun.latitude = sun_props.latitude
sun.UTC_zone = sun_props.UTC_zone
+ at persistent
+def sun_handler(scene):
+ update_time(bpy.context)
+ move_sun(bpy.context)
+
+
def format_time(the_time, daylight_savings, longitude, UTC_zone=None):
if UTC_zone is not None:
if daylight_savings:
@@ -256,8 +269,8 @@ def format_lat_long(lat_long, is_latitude):
return hh + "° " + mm + "' " + ss + '"' + coord_tag
-def get_sun_position(local_time, latitude, longitude, north_offset,
- utc_zone, month, day, year, distance):
+def get_sun_coordinates(local_time, latitude, longitude, north_offset,
+ utc_zone, month, day, year, distance):
"""
Calculate the actual position of the sun based on input parameters.
@@ -276,10 +289,10 @@ def get_sun_position(local_time, latitude, longitude, north_offset,
addon_prefs = bpy.context.preferences.addons[__package__].preferences
sun_props = bpy.context.scene.sun_pos_properties
- longitude *= -1 # for internal calculations
- utc_time = local_time + utc_zone # Set Greenwich Meridian Time
+ longitude *= -1 # for internal calculations
+ utc_time = local_time + utc_zone # Set Greenwich Meridian Time
- if latitude > 89.93: # Latitude 90 and -90 gives
+ if latitude > 89.93: # Latitude 90 and -90 gives
latitude =
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list