/* eeshlo wrote a texture plugin for sunsky for blender, released the binary for 1 version of blender/python, then disappeared. Asshole. Written by Joseph Miller joseph c miller 2 at that gmail place Help with coords provided by subcomandante at yafaray IRC * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Copyright (c) 2000, Not a Number b.v. * This code is based at Ken Perlin's famous works... * */ #include #include #include "plugin.h" // see sunsky.cc for source extern void sunsky_get_rgb(float *red, float *green, float *blue, float sun_x_dir, float sun_y_dir, float sun_z_dir, float turb, float x_coord, float y_coord, float z_coord, float sun_intensity); /* * Copyright (c) 1999, Not a Number / NeoGeo b.v. * Adapted by :Predrag kurtovic 2.05.2000 */ /* ******************** GLOBAL VARIABLES ***************** */ /* Texture name */ char name[24]= "SunskyGPL"; /* Subtype names must be less than 15 characters */ #define NR_TYPES 2 char stnames[NR_TYPES][16]= {"Manual","SunByTime"}; /* Structure for buttons, * butcode name default min max 0 */ VarStruct varstr[]= { { LABEL, "SunskyGPL!",0, 0, 0, "Now GPL version released" }, {NUMSLI|FLO,"Turbidity", 4., 0., 12., "3-5 is normal day"}, //{NUMSLI|FLO,"Horz Bright", 1., -1., 1., "0.9-1.5 on normal day"}, //{NUMSLI|FLO,"Sun Width", 15., 0., 50., "width of solar region"}, {NUMSLI|FLO,"Sun Intens.", 15.0, 0., 40., "Glow intensity"}, //{NUMSLI|FLO,"Backscatter", 0., -5., 5., "Backscatter only used <0"}, {NUMSLI|FLO,"x=", 0.1, -1., 1., "Sun x position"}, {NUMSLI|FLO,"y=", 0.2, -1., 1., "Sun y position"}, {NUMSLI|FLO,"z=", 0.4, -1., 1., "Sun z position"}, { LABEL, "UseLatLon?",0, 0, 0, "Only set if want to be used" }, {NUMSLI|INT,"Year", 0, 0, 10000, "Year for SunByTime"}, {NUMSLI|INT,"Month", 0, 0, 12, "Month for SunByTime"}, {NUMSLI|INT,"Day", 0, 0, 31, "Day of Month for SunByTime"}, {NUMSLI|INT,"Hour", 0, 0, 24, "Hour of Day for SunByTime"}, {NUMSLI|INT,"Minute", 0, 0, 60, "Minute of Hour for SunByTime"}, {NUMSLI|INT,"Second", 0, 0, 60, "Second for SunByTime"}, {NUMSLI|FLO,"Lat", 46.5, -180.0, 180.0, "Latitude for SunByTime"}, {NUMSLI|FLO,"Lon", 6.5, -180.0, 180.0, "Longitude for SunByTime"} }; /* The cast struct is for input in the main doit function Varstr and Cast must have the same variables in the same order, INCLUDING dummy variables for label fields. */ typedef struct Cast { int labelvar1; float turbidity; //float horzbright; //float sundiskw; float sundiski; //float backscatter; float xcoord; float ycoord; float zcoord; int t_year; int t_month; int t_day; int t_hour; int t_minute; int t_second; float t_lat; float t_lon; } Cast; /* result: Intensity, R, G, B, Alpha, nor.x, nor.y, nor.z */ float result[8]; /* cfra: the current frame */ float cfra; int plugin_tex_doit(int, Cast*, float*, float*, float*); int ct_year; int ct_month; int ct_day; int ct_hour; int ct_minute; int ct_second; float ct_lat; float ct_lon; float sunsky_sv_x = 0; float sunsky_sv_y = 0; float sunsky_sv_z = 0; /* ******************** Fixed functions ***************** */ int plugin_tex_getversion(void) { return B_PLUGIN_VERSION; } void plugin_but_changed(int but) { } void plugin_init(void) { } /* this function should not be changed: */ void plugin_getinfo(PluginInfo *info) { info->name= name; info->stypes= NR_TYPES; info->nvars= sizeof(varstr)/sizeof(VarStruct); info->snames= stnames[0]; info->result= result; info->cfra= &cfra; info->varstr= varstr; info->init= plugin_init; info->tex_doit= (TexDoit) plugin_tex_doit; info->callback= plugin_but_changed; } /* ********************* the texture ******************** */ // from http://stackoverflow.com/questions/257717/position-of-the-sun-given-time-of-day-and-lat-long // I assume this is free to copy // this is directly copied and some must be changed from degrees to radians, be careful! void get_sun_position(float *x_vec, float *y_vec, float *z_vec, int year, int month, int day, int i_hour, int min, int sec, float lat, float lon) { float twopi = 2*M_PI; float deg2rad = M_PI / 180; int i; float hour = (float) i_hour; // convert day to relative to day of year, not day of month int month_days[] = {0,31,28,31,30,31,30,31,31,30,31,30}; for (i=0;i= 60; day += leapdays; // Get Julian date - 2400000 hour = hour + (float) min / 60.0 + (float) sec/3600.0; int delta = year - 1949; // what to do here? int leap = delta / 4; // former leapyears float jd = 32916.5 + (float) (delta * 365) + (float) leap + (float) day + hour/24.0; // The input to the Atronomer's almanach is the difference between // the Julian date and JD 2451545.0 (noon, 1 January 2000) float time = jd - 51545.0; // Ecliptic coordinates // mean longitude float mnlong = 280.460 + .9856474 * time; mnlong = fmod(mnlong,360.0); if ( mnlong < 0 ) { mnlong += 360.0; } // Mean anomaly float mnanom = 357.528 + .9856003 * time; mnanom = fmod(mnanom, 360.0); if ( mnanom < 0 ) { mnanom += 360.0; } mnanom *= deg2rad; // Ecliptic longitude and obliquity of ecliptic float eclong = mnlong + 1.915 * sin(mnanom) + 0.020 * sin(2*mnanom); eclong = fmod(eclong, 360.0); if ( eclong < 0 ) { eclong += 360; } float oblqec = 23.429 - 0.0000004 * time; eclong *= deg2rad; oblqec *= deg2rad; // Celestial coordinates // Right ascension and declination float num = cos(oblqec) * sin(eclong); float den = cos(eclong); float ra = atan(num/den); if ( den < 0 ) { ra += M_PI; } if ( den >= 0 && num < 0 ) { ra += twopi; } float dec = asin(sin(oblqec) * sin(eclong)); // local coordinates // Greenwich mean sidereal time float gmst = 6.697375 + .0657098242 * time + hour; gmst = fmod(gmst, 24.0); if ( gmst < 0 ) { gmst += 24.0; } // Local mean sidereal time float lmst = gmst + lon / 15.0; lmst = fmod(lmst, 24.0); if ( lmst < 0 ) { lmst += 24; } lmst = lmst * 15.0 * deg2rad; // hour angle float ha = lmst - ra; if ( ha < -M_PI ) { ha += twopi; } if ( ha > M_PI ) { ha -= twopi; } // Latitude to radians lat = lat * deg2rad; // Azimuth and elevation float el = asin(sin(dec) * sin(lat) + cos(dec) * cos(lat) * cos(ha)); float az = asin(-cos(dec) * sin(ha) / cos(el)); float elc = asin(sin(dec) / sin(lat)); if ( el >= elc ) { az = M_PI - az; } if ( el <= elc && ha > 0 ) { az += twopi; } // el = el / deg2rad; // az = az / deg2rad; // lat = lat / deg2rad; #define PI_OVER_180 0.01745329F *x_vec = -sin(el*PI_OVER_180)*cos(az*PI_OVER_180); *y_vec = sin(az*PI_OVER_180); *z_vec = cos(el*PI_OVER_180)*cos(az*PI_OVER_180); } /* return 0: One channel texture return 1: RGB texture return 2: Normals texture */ int plugin_tex_doit(int stype, Cast *cast, float *texvec, float *dxt, float *dyt) { float red, green, blue, x_coord, y_coord, z_coord, dist, sv_x, sv_y, sv_z; /* always return this value */ result[0] = 0.; x_coord = texvec[0]; y_coord = texvec[1]; z_coord = texvec[2]; if ( stype == 1 && cast->t_year > 0 && (cast->t_year != ct_year || cast->t_month != ct_month || cast->t_day != ct_day || cast->t_hour != ct_hour || cast->t_minute != ct_minute || cast->t_second != ct_second || cast->t_lat != ct_lat || cast->t_lon != ct_lon) ) { ct_year = cast->t_year; ct_month = cast->t_month; ct_day = cast->t_day; ct_hour = cast->t_hour; ct_minute = cast->t_minute; ct_second = cast->t_second; ct_lat = cast->t_lat; ct_lon = cast->t_lon; //get_sun_position(&sv_x, &sv_y, &sv_z, 2009, 9, 20, 10, 30, 30, 46.5, 6.5); get_sun_position(&sunsky_sv_x, &sunsky_sv_y, &sunsky_sv_z, cast->t_year, cast->t_month, cast->t_day, cast->t_hour, cast->t_minute, cast->t_second, cast->t_lat, cast->t_lon); fprintf(stderr, "set sun to x,y,z = %f,%f,%f\n", sunsky_sv_x, sunsky_sv_y, sunsky_sv_z); } if ( stype == 0 ) { sv_x = cast->xcoord; sv_y = cast->ycoord; sv_z = cast->zcoord; } else if ( stype == 1 ) { sv_x = sunsky_sv_x; sv_y = sunsky_sv_y; sv_z = sunsky_sv_z; } // for sunsky_get_rgb() see sunsky.cc near end of file // swapped y and z to change to camera view coordinates sunsky_get_rgb(&red, &green, &blue, sv_x, sv_y, sv_z, cast->turbidity, x_coord, z_coord, y_coord, log10(cast->sundiski)); //fprintf(stderr, "sun x,y,z = %f,%f,%f\n", sv_x, sv_y, sv_z); /* color? then return 1; * * this is r, g, b, a:#include "solpos00.h" */ result[1] = red; result[2] = green; result[3] = blue; result[4] = 1.0; return 1; }