04-01-2004 05:49
Here is a function that returns the time of the day in-game in a similar way to llGetWallclock(). After some discussion with Andrew about how the sun works, this is what I came up with. It works off of llGetTimeOfDay instead of llGetSunDirection.
CODE
`float GetGameWallclock() {    // Get the number of seconds since game midnight;    float   Seconds = llGetTimeOfDay();    // Convert this to an angle of the sun relative to the    // theoretical center of its orbit. (Assuming a 4 hour day).    float   Theta   = Seconds / 14400 * TWO_PI;    // Find the point on the sun's orbit it is currently at (theoretically).    vector  Sun     = <llCos(Theta), llSin(Theta), 0>;    // Shift this point to account for the earth being offset from    // the center of the sun's orbit.    Sun.x -= 0.70710678; // sqrt( 1/2 );    // Convert this point back to an angle (which is the angle of the    // sun relative to the earth.    float Phi   = llAtan2(Sun.y, Sun.x);    // Make sure this value is positive.    if (Phi < 0)        Phi += TWO_PI;    // Now convert back to a 24-hour day.    float GameSeconds = Phi / TWO_PI * 86400;    return GameSeconds;}`

Here is a version of the single prim clock, using this technique, to display game time:

CODE
`////////////////////////////////////////////// Single Prim Clock v2.1 Script (Game Time)//// Written by Xylor Baysklef/////////////////////////////////////////////////////////// CONSTANTS ///////////////////// These are the faces to show the clock on.integer HOUR_FACE   = 4;integer MINUTE_FACE = 0;integer AM_PM_FACE  = 2;// Texture type enumeration.integer WHITE_ON_BLACK  = 0;integer BLACK_ON_WHITE  = 1;integer TRANSPARENT     = 2;// This is the type of texture to display.integer DISPLAY_TYPE    = WHITE_ON_BLACK;list    HOUR_TEXTURES   = [            // White on Black            "7bc19746-de1b-b84c-9d2a-515d38c030ab",            // Black on White            "d9b1de36-44d6-c89b-7b7f-97cbc62d47a3",            // Transparent            "db0b0013-f0b5-70b3-5e40-8685d024a3a2" ];list    MINUTE_TEXTURES = [            // White on Black            "9bc9c4bb-8c20-b103-fd5d-60f1072a39b1", // 00-29            "e82c651f-47e9-7950-ea65-f496e1917dd4", // 30-59            // Black on White            "7d53ead7-e6a7-59c5-b98b-fe46d9f61818", // 00-29            "6ae5d6a8-a78f-b505-e950-fcb003a480bf", // 30-59            // Transparent            "34e55b37-1c59-4a09-38d1-4150ffa396a5", // 00-29            "2b660a82-8d91-c892-a076-45c4a86f0235"];// 30-59list    AM_PM_TEXTURES  = [            // White on Black            "13c95970-27a7-1a7a-cbc4-0e93f00361ba",            // Black on White            "b4d9d87e-36f8-7f4f-7d11-b7a2e973053b",            // Transparent            "f4ca9c46-3a46-6986-eb42-f497e9898d7a" ];///////////// END CONSTANTS ///////////////////////////// GLOBAL VARIABLES ////////////////////////// END GLOBAL VARIABLES ////////////UpdateTime() {    // Get the number of seconds since game midnight;    float   Seconds = llGetTimeOfDay();    // Convert this to an angle of the sun relative to the    // theoretical center of its orbit. (Assuming a 4 hour day).    float   Theta   = Seconds / 14400 * TWO_PI;    // Find the point on the sun's orbit it is currently at (theoretically).    vector  Sun     = <llCos(Theta), llSin(Theta), 0>;    // Shift this point to account for the earth being offset from    // the center of the sun's orbit.    Sun.x -= 0.70710678; // sqrt( 1/2 );    // Keep this for later, nice shortcut for estimation.    float   Magnitude = llVecMag(Sun);    // Convert this point back to an angle (which is the angle of the    // sun relative to the earth.    float Phi   = llAtan2(Sun.y, Sun.x);    // Make sure this value is positive.    if (Phi < 0)        Phi += TWO_PI;    // Now convert back to a 24-hour day.    float GameSeconds = Phi / TWO_PI * 86400;    // Figure out when the next game minute should occur (in game time seconds).    integer Minutes = llRound(GameSeconds / 60);    integer Hours   = Minutes / 60;    float NextMinute = (Minutes + 1) * 60;    // Work backwards now, converting this game time into 'real' time    // so we can set up a timer.    Phi = NextMinute / 86400 * TWO_PI;    // Figure out where the sun will be.    // Use the magnitude of the previous sun position, as a guide    // (Good approximation).    Sun = Magnitude * <llCos(Phi), llSin(Phi), 0>;    // Shift to move our center back.    Sun.x += 0.70710678;    // Calculate the angle the sun will make with the center of its orbit.    Theta = llAtan2(Sun.y, Sun.x);    // Make sure we are between 0 and TWO_PI    if (Theta < 0)        Theta += TWO_PI;    // Finally, convert to real seconds.    float NextMinuteReal = Theta / TWO_PI * 14400;    // Figure out how many real seconds until the next game minute.    float SecondsToNextMinute = NextMinuteReal - Seconds;    // Sanity check.    if (SecondsToNextMinute < 5) {        SecondsToNextMinute = 5;    }    llSetTimerEvent(SecondsToNextMinute);    // Now only keep the minutes of the current hour.    // (Normalize to 0-59).    Minutes %= 60;    Hours %= 24;    // Calculate if this is AM or PM.    integer AM_PM = Hours / 12;    // Normalize the hour to 0-11.    Hours %= 12;    // Calculate the hour grid positions.    integer xHourPos = Hours % 4;    integer yHourPos = Hours / 4;    // Calcualte the minute texture index.    integer MinuteTextureIndex = DISPLAY_TYPE * 2 + Minutes / 30;    // Normalize the minutes to 0-29.    Minutes %= 30;    // Calculate the minute grid positions.    integer xMinutePos = Minutes % 5;    integer yMinutePos = Minutes / 5;    // Update the minute texture.    key MinuteTexture = llList2Key(MINUTE_TEXTURES, MinuteTextureIndex);    llSetTexture(MinuteTexture, MINUTE_FACE);    // Now update the offsets to show the current time on the textures.    llOffsetTexture(-0.40 + 0.20 * xMinutePos, 0.45 - 0.10 * yMinutePos, MINUTE_FACE);    llOffsetTexture(-0.375 + 0.250 * xHourPos, 0.375 - 0.25 * yHourPos,  HOUR_FACE);    llOffsetTexture(0, 0.250 - 0.50 * AM_PM, AM_PM_FACE);}default {    state_entry() {        // First set up the correct texture scales, and rotations.        llScaleTexture(0.25, 0.25, HOUR_FACE);        llScaleTexture(0.20, 0.10, MINUTE_FACE);        llScaleTexture(1.00, 0.50, AM_PM_FACE);        llRotateTexture(PI_BY_TWO, HOUR_FACE);        llRotateTexture(0,         MINUTE_FACE);        llRotateTexture(-PI_BY_TWO,AM_PM_FACE);        // Show the hour and am/pm textures, since they don't change.        llSetTexture(llList2Key(HOUR_TEXTURES, DISPLAY_TYPE), HOUR_FACE);        llSetTexture(llList2Key(AM_PM_TEXTURES, DISPLAY_TYPE), AM_PM_FACE);        // Now just update the time, it will also start the timer.        UpdateTime();    }    on_rez(integer param) {        UpdateTime();    }    timer() {        // This will show the time, and adjust the timer event.        UpdateTime();    }}`

Xylor