Please use english language
It is currently 26 Feb 2020, 12:53

All times are UTC





Post new topic Reply to topic  [ 24 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
PostPosted: 22 Oct 2017, 18:23 
Offline
*blah-blah-blah maniac*
User avatar

Joined: 27 Dec 2011, 08:53
Posts: 14816
Location: Russia
But why you change distance to camera? Why not to keep it old? I don't get it.
Do you understand how stupid to put control over internal direction of sun inside enbseries sdk? Such hacks must be transparent and out of access anybody, except those who use them. I don't know what is fSunYExtreme, but in any game sun is direction based and you need to change direction of it, while length of directional vector (distance to camera) need to be 40, if i remember. Need some solution which compatible with any similar mods, but not confusing for users. My idea about config also wrong, cause config may stay while your mod can be removed. No idea really, you have more details about this, describe that i could understand, maybe code how you setup sun position will help me.

_________________
i5-4690k, 16Gb RAM, GTX 1060 6Gb, X-Fi Titanium, Win7 x128
I am INFP, not the brutal, godamnit.


Top
 Profile  
 
Tomoko
PostPosted: 23 Oct 2017, 18:16 
Offline

Joined: 28 Aug 2017, 20:14
Posts: 11
fSunYExtreme is the game setting used to set the distance of the sun from the camera along the y-axis. Like in the More Plausible South Side Sun mod (https://www.nexusmods.com/skyrim/mods/60937).

The sun in Skyrim is not direction based, it is position based using the xyz position from the camera. The 40 is not the total distance from the camera, it is just the distance along the y-axis.

Here is the source code to calculate the sun position that works similar to vanilla Skyrim. By default, Skyrim moves the sun along a curve that passes through these points:
sunrise - x: 400, y: 40, z: 0
midday - x: 0, y: 40, z: 400
sunset - x: -400, y: 40, z: 0
midnight - x: 0, y: 40, z: 400 (z is positive)

Code:
float* g_fSunAlphaTransTime = reinterpret_cast<float*>(0x01B117D8); // 0.5
float* g_fSunXExtreme = reinterpret_cast<float*>(0x01B117E4); // 400.0
float* g_fSunYExtreme = reinterpret_cast<float*>(0x01B117F0); // 40.0

float* g_sunriseBegin = reinterpret_cast<float*>(0x01B1175C);
float* g_sunriseEnd = reinterpret_cast<float*>(0x01B11760);
float* g_sunsetBegin = reinterpret_cast<float*>(0x01B11764);
float* g_sunsetEnd = reinterpret_cast<float*>(0x01B11768);

void CalculateSunPositionVanilla() {
   Sky* sky = GetSky(); // from SKSE
   Sun* sun = sky->sun;
   NiNode* sunNode = reinterpret_cast<NiNode*>(sun->m_refCount); // not named correctly in SKSE

   float gameHour = GetGameHour();
   float sunriseTime = (*g_sunriseBegin + *g_sunriseEnd - *g_fSunAlphaTransTime)/2;
   float sunsetTime = (*g_sunsetBegin + *g_sunsetEnd + *g_fSunAlphaTransTime)/2;

   float percent;
   if (gameHour >= sunriseTime && gameHour < sunsetTime) {
      percent = 1.0f - ((gameHour-sunriseTime)/(sunsetTime-sunriseTime))*2.0f;
   } else if (gameHour >= sunsetTime) {
      percent = ((gameHour-sunsetTime)/(24.0f-(sunsetTime-sunriseTime)))*2.0f - 1.0f;
   } else {//if (gameHour < sunriseTime) {
      percent = ((gameHour+24.0f-sunsetTime)/(24.0f-(sunsetTime-sunriseTime)))*2.0f - 1.0f;
   }

   sunNode->m_localTransform.pos.x = *g_fSunXExtreme * percent;
   sunNode->m_localTransform.pos.y = *g_fSunYExtreme;
   sunNode->m_localTransform.pos.z = abs(*g_fSunXExtreme) - abs(x);
}


And here's the code that I am using to calculate the sun position using latitude and day number. It's based on the forumla from this wikipedia entry:
https://en.wikipedia.org/wiki/Solar_azimuth_angle

Code:
void CalculateSunPosition(int dayNumber, float latitude) {
   Sky* sky = GetSky(); // from SKSE
   Sun* sun = sky->sun;
   NiNode* sunNode = reinterpret_cast<NiNode*>(sun->m_refCount); // not named correctly in SKSE

   float gameHour = GetGameHour();
   float solarZenith = 0.0f;
   float solarAzimuth = 0.0f;
   float axis = 23.439f;

   float JanDayNumber = dayNumber - 11.0f;
   if (JanDayNumber > 365.0f) JanDayNumber -= 365.0f;
   if (JanDayNumber < 1) JanDayNumber += 365f;

   latitude = toRadians(latitude);
   float sinLatitude = sin(latitude);
   float cosLatitude = cos(latitude);

   // Calculate declination
   float declination = -toRadians(axis) * cos(toRadians((360.0f / 365.0f) * (JanDayNumber + 10.0f)));
   float sinDeclination = sin(declination);
   float cosDeclination = cos(declination);

   // Calculate hour angle
   float hourAngle = toRadians(15.0f*(gameHour-12.0f));
   float cosHourAngle = cos(hourAngle);

   // Calculate solar zenith
   solarZenith = acos(sinLatitude*sinDeclination + cosLatitude*cosDeclination*cosHourAngle);
   float sinSolarZenith = sin(solarZenith);
   float cosSolarZenith = cos(solarZenith);

   // Calculate solar azimuth
   solarAzimuth = acos((sinDeclination*cosLatitude - cosHourAngle*cosDeclination*sinLatitude)/sinSolarZenith);
   if (hourAngle > 0) solarAzimuth = -solarAzimuth;
   solarAzimuth = -solarAzimuth + PI/2; // Convert to Skyrim coordinate system
   float sinSolarAzimuth = sin(solarAzimuth);
   float cosSolarAzimuth = cos(solarAzimuth);

   // Convert to xyz coordinates
   float r = *g_fSunXExtreme;
   sunNode->m_localTransform.pos.x = r * sinSolarZenith * cosSolarAzimuth;
   sunNode->m_localTransform.pos.y = r * sinSolarZenith * sinSolarAzimuth;
   sunNode->m_localTransform.pos.z = r * cosSolarZenith;
}


Top
 Profile  
 
PostPosted: 25 Oct 2017, 20:03 
Offline
*blah-blah-blah maniac*
User avatar

Joined: 27 Dec 2011, 08:53
Posts: 14816
Location: Russia
Well, im about to finish new version and one of the simplest things came to mind is to make exported function which allow set sun position and i'll compare object to such position and if close enough, detect it as sun. Of course shader must remain the same, its another trigger. In this case you should get path of game and load library d3d9.dll, grab from it function address (do not make mistake with system library d3d9.dll). Hope this will work.

_________________
i5-4690k, 16Gb RAM, GTX 1060 6Gb, X-Fi Titanium, Win7 x128
I am INFP, not the brutal, godamnit.


Top
 Profile  
 
PostPosted: 25 Oct 2017, 20:39 
Offline
*blah-blah-blah maniac*
User avatar

Joined: 27 Dec 2011, 08:53
Posts: 14816
Location: Russia
Code:
#define EDirtyHack_NONE                     0
#define EDirtyHack_SunPositionY               1

__declspec(dllexport) BOOL   DirtyHack(DWORD type, void *data)
{
   BOOL   res=FALSE;
   if (type==0) return TRUE;
   if (!data) return FALSE;

   if (type==EDirtyHack_SunPositionY)
   {
      float   *posY=(float*)data;
      //set global mod variables
      hack_SunPosY=*posY;
      hack_SunPosYCaptured=TRUE;
      res=TRUE;
   }

   return res;
}

//later and draw
      if (hack_SunPosYCaptured==TRUE)
      {
         if ((temp1._42 > hack_SunPosY*0.999f) && (temp1._42 < hack_SunPosY*1.001f))
         {
            issun=TRUE;
         } else
         {
            issun=FALSE;
         }
      }

This is internal code in new version, so you need to use getprocaddress to get that function (if exist), call it like this each frame (or each time you modify it):
Code:
float posY=r * sinSolarZenith * sinSolarAzimuth;
DirtyHack(EDirtyHack_SunPositionY, (void*)&posY);

and internally i'll check if sun have similar position +-0.1%.

_________________
i5-4690k, 16Gb RAM, GTX 1060 6Gb, X-Fi Titanium, Win7 x128
I am INFP, not the brutal, godamnit.


Top
 Profile  
 
PostPosted: 26 Oct 2017, 01:07 
Offline
*blah-blah-blah maniac*
User avatar

Joined: 27 Dec 2011, 08:53
Posts: 14816
Location: Russia
Okay, i released new version with that function, check and test.

_________________
i5-4690k, 16Gb RAM, GTX 1060 6Gb, X-Fi Titanium, Win7 x128
I am INFP, not the brutal, godamnit.


Top
 Profile  
 
PostPosted: 26 Oct 2017, 17:02 
Offline

Joined: 28 Aug 2017, 20:14
Posts: 11
Thank you for the hack. I have not tested it yet but after reading the posts again I think I figured out why we got confused.

What I was describing before was the sun object (NiNode and NiTriShape) and I think you were describing the sun directional light (NiDirectionalLight). The directional light works as you described where only the direction matters. Actually, if you have access to the directional light then it should have the same world position as the sun object. Maybe you can detect the sun using that? It's not as much of a hack, and is more compatible with other mods (such as More Plausible South Side Sun).


Top
 Profile  
 
PostPosted: 26 Oct 2017, 18:08 
Offline
*blah-blah-blah maniac*
User avatar

Joined: 27 Dec 2011, 08:53
Posts: 14816
Location: Russia
No, by the sun i mean exactly sun quad. It is strange that position based, but from d3d it is direction based, so game transform position to rotation. About directional light i don't remember if it have same direction as sun or not.

_________________
i5-4690k, 16Gb RAM, GTX 1060 6Gb, X-Fi Titanium, Win7 x128
I am INFP, not the brutal, godamnit.


Top
 Profile  
 
PostPosted: 28 Oct 2017, 17:27 
Offline

Joined: 28 Aug 2017, 20:14
Posts: 11
Ok, I tested the hack. Interestingly, it only works during sunrise and sunset. It does not work in the middle of the day.


Top
 Profile  
 
PostPosted: 28 Oct 2017, 20:43 
Offline
*blah-blah-blah maniac*
User avatar

Joined: 27 Dec 2011, 08:53
Posts: 14816
Location: Russia
No idea, this distance is checked every time of the day. Try to make some function or hotkey controlled tweaking, maybe sun going away from range somehow, for example matrix generated by game is not look at type. If it fails, you even can make table to detect which values are correct or think how matrix is done. Im going to another city for unknown time (hope week or less) and will not be able to answer.

_________________
i5-4690k, 16Gb RAM, GTX 1060 6Gb, X-Fi Titanium, Win7 x128
I am INFP, not the brutal, godamnit.


Top
 Profile  
 
PostPosted: 08 Nov 2017, 17:59 
Offline

Joined: 28 Aug 2017, 20:14
Posts: 11
Ok, I did more testing and printed the values of the sun to the console. It looks like it works only when the y value is greater than zero. It just happens that sunrise/sunset are the only times where the y value is above zero. I also tried forcing the y value to different values. It works during the day if I force the y value to a positive value, and does not work if it is a negative value.

Also, I'm not sure if I can reply to PMs yet?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 24 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group