Skyrim Astronomy Sun position skse plugin bugs

fixing bugs
  • Author
  • Message
Offline
User avatar
*blah-blah-blah maniac*
Posts: 17427
Joined: 27 Dec 2011, 08:53
Location: Rather not to say

Re: Skyrim Astronomy Sun position skse plugin bugs

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.
_________________
i9-9900k, 64Gb RAM, RTX 3060 12Gb, Win7

Offline
Posts: 11
Joined: 28 Aug 2017, 20:14

Re: Skyrim Astronomy Sun position skse plugin bugs

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: Select all

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: Select all

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;
}

Offline
User avatar
*blah-blah-blah maniac*
Posts: 17427
Joined: 27 Dec 2011, 08:53
Location: Rather not to say

Re: Skyrim Astronomy Sun position skse plugin bugs

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.
_________________
i9-9900k, 64Gb RAM, RTX 3060 12Gb, Win7

Offline
User avatar
*blah-blah-blah maniac*
Posts: 17427
Joined: 27 Dec 2011, 08:53
Location: Rather not to say

Re: Skyrim Astronomy Sun position skse plugin bugs

Code: Select all

#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: Select all

float posY=r * sinSolarZenith * sinSolarAzimuth;
DirtyHack(EDirtyHack_SunPositionY, (void*)&posY);
and internally i'll check if sun have similar position +-0.1%.
_________________
i9-9900k, 64Gb RAM, RTX 3060 12Gb, Win7

Offline
User avatar
*blah-blah-blah maniac*
Posts: 17427
Joined: 27 Dec 2011, 08:53
Location: Rather not to say

Re: Skyrim Astronomy Sun position skse plugin bugs

Okay, i released new version with that function, check and test.
_________________
i9-9900k, 64Gb RAM, RTX 3060 12Gb, Win7

Offline
Posts: 11
Joined: 28 Aug 2017, 20:14

Re: Skyrim Astronomy Sun position skse plugin bugs

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).

Offline
User avatar
*blah-blah-blah maniac*
Posts: 17427
Joined: 27 Dec 2011, 08:53
Location: Rather not to say

Re: Skyrim Astronomy Sun position skse plugin bugs

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.
_________________
i9-9900k, 64Gb RAM, RTX 3060 12Gb, Win7

Offline
Posts: 11
Joined: 28 Aug 2017, 20:14

Re: Skyrim Astronomy Sun position skse plugin bugs

Ok, I tested the hack. Interestingly, it only works during sunrise and sunset. It does not work in the middle of the day.

Offline
User avatar
*blah-blah-blah maniac*
Posts: 17427
Joined: 27 Dec 2011, 08:53
Location: Rather not to say

Re: Skyrim Astronomy Sun position skse plugin bugs

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.
_________________
i9-9900k, 64Gb RAM, RTX 3060 12Gb, Win7

Offline
Posts: 11
Joined: 28 Aug 2017, 20:14

Re: Skyrim Astronomy Sun position skse plugin bugs

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?
Post Reply