Author Topic: Dynamic Area Lighting  (Read 407 times)

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Dynamic Area Lighting
« on: May 01, 2012, 05:10:52 pm »


               I've gone with the assumption that dynamic area lighting doesn't work. So recently came up with a system that uses both events on placeables as well as the AID framework toa chieve the same thing - lighting of torches int eh area, enabling a player to pull them off the wall etc....

However... after I did all that work, I found the SetTileSourceLightColor function, and thought that perhaps it does work. Anyone have any experience with turning lights off (black) and on (any other color) with this method? The lexicon says it is problematic (which is the word I'd use when discussing lights and placeables) so I'm not eager to even try it. But if anyone else has had good results with this, I would like to know.
               
               

               
            

Legacy_Leurnid

  • Sr. Member
  • ****
  • Posts: 473
  • Karma: +0/-0
Dynamic Area Lighting
« Reply #1 on: May 01, 2012, 05:41:06 pm »


               http://nwvault.ign.c...s.Detail&id=501

I can't really help, but the script there is using some dynamic lighting, and works well enough. Maybe that could help (or not).
               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Dynamic Area Lighting
« Reply #2 on: May 01, 2012, 05:50:36 pm »


               Thank you. Interesting script. That script however changes tile lighting.

I should have been clearer. I am interested in the torches etc... built into the tileset, and controllign their lighting. Those are called source lights.
               
               

               
            

Legacy_Leurnid

  • Sr. Member
  • ****
  • Posts: 473
  • Karma: +0/-0
Dynamic Area Lighting
« Reply #3 on: May 01, 2012, 06:15:17 pm »


               The first comment suggests trying change TILE_MAIN_LIGHT to TILE_SOURCE_LIGHT, which would effect tileset torches.

Placeable torches though... egads, my head hurts!
               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Dynamic Area Lighting
« Reply #4 on: May 01, 2012, 06:38:28 pm »


               Heh. yeah using placeables in the way that I am can make your head hurt. I wish the vanilla toolset itself was scriptable, so that you could create little utilities on the fly. It would make building complex things much much easier. I have a tendency to do a lot of dynamic stuff with placeables (and creatures) which requires precise positioning. If you use a rope on a climb point for example the position of the rope placeable that shows up needs to be carefully positioned so that it looks right. In this case, the flame vfx needs to be in the right place on the tile model - just over the sconce. I've been recording the position and then setting it as local data on the interactive object (usually an invisible one) whioch allows me to create a position vector via script for the dynamically crated object(s). But its tedious. I originally tried leaving waypoints for this in the game and using their locations/positions via script, but  it didn't lessen my work significantly to do it this way while it soon became a mess of waypoints everywhere that was harder to manage.

Someday I'll figure out how to write a script which analyzes the situation and positions everything dynamically, but that likely won't work in NWN. I'm not aware of any script hooks into the model which allow you to position things relative to the model's bones, or nodes or whatever.
               
               

               


                     Modifié par henesua, 01 mai 2012 - 05:44 .
                     
                  


            

Legacy_Fester Pot

  • Hero Member
  • *****
  • Posts: 1698
  • Karma: +0/-0
Dynamic Area Lighting
« Reply #5 on: May 01, 2012, 06:39:49 pm »


               I was never able to get the torches to go off, once they were turned on.

Turning off the tile specific torch light in the Toolset by making those colors black, then firing them via a script to turn them on, worked great.

Once lit, attempting to turn them off via a script wouldn't happen. TILE_SOURCE_LIGHT_COLOR_BLACK did not douse the tileset specific torch flame.

void SetTileLight()
{

   // Set lighting below entrance shaft.
   object   oTile1    = GetObjectByTag("THKLIGHT1");
   object   oTile2    = GetObjectByTag("THKLIGHT2");
   object   oTile3    = GetObjectByTag("THKLIGHT3");
   object   oTile4    = GetObjectByTag("THKLIGHT4");
   object   oTile5    = GetObjectByTag("THKLIGHT5");
   object   oTile6    = GetObjectByTag("THKLIGHT6");

   object   oArea1    = GetArea(oTile1);
   object   oArea2    = GetArea(oTile2);
   object   oArea3    = GetArea(oTile3);
   object   oArea4    = GetArea(oTile4);
   object   oArea5    = GetArea(oTile5);
   object   oArea6    = GetArea(oTile6);

   location locTile1  = GetLocation(oTile1);
   location locTile2  = GetLocation(oTile2);
   location locTile3  = GetLocation(oTile3);
   location locTile4  = GetLocation(oTile4);
   location locTile5  = GetLocation(oTile5);
   location locTile6  = GetLocation(oTile6);

   vector   vecTile1  = GetPositionFromLocation(locTile1);
   vector   vecTile2  = GetPositionFromLocation(locTile2);
   vector   vecTile3  = GetPositionFromLocation(locTile3);
   vector   vecTile4  = GetPositionFromLocation(locTile4);
   vector   vecTile5  = GetPositionFromLocation(locTile5);
   vector   vecTile6  = GetPositionFromLocation(locTile6);


   float    facTile1  = GetFacingFromLocation(locTile1);
   float    facTile2  = GetFacingFromLocation(locTile2);
   float    facTile3  = GetFacingFromLocation(locTile3);
   float    facTile4  = GetFacingFromLocation(locTile4);
   float    facTile5  = GetFacingFromLocation(locTile5);
   float    facTile6  = GetFacingFromLocation(locTile6);

   vecTile1.x /= 10.0;
   vecTile1.y /= 10.0;

   vecTile2.x /= 10.0;
   vecTile2.y /= 10.0;

   vecTile3.x /= 10.0;
   vecTile3.y /= 10.0;

   vecTile4.x /= 10.0;
   vecTile4.y /= 10.0;

   vecTile5.x /= 10.0;
   vecTile5.y /= 10.0;

   vecTile6.x /= 10.0;
   vecTile6.y /= 10.0;

   locTile1 = Location(oArea1, vecTile1, facTile1);
   locTile2 = Location(oArea2, vecTile2, facTile2);
   locTile3 = Location(oArea3, vecTile3, facTile3);
   locTile4 = Location(oArea4, vecTile4, facTile4);
   locTile5 = Location(oArea5, vecTile5, facTile5);
   locTile6 = Location(oArea5, vecTile6, facTile6);

   int nColor;
   if      (GetIsDawn()) nColor = TILE_SOURCE_LIGHT_COLOR_PALE_DARK_ORANGE;
   else if (GetIsDay())  nColor = TILE_SOURCE_LIGHT_COLOR_BLACK;
   else if (GetIsDusk()) nColor = TILE_SOURCE_LIGHT_COLOR_PALE_DARK_BLUE;
   else                  nColor = TILE_SOURCE_LIGHT_COLOR_PALE_DARK_BLUE;

   SetTileSourceLightColor(locTile1, nColor, nColor);
   SetTileSourceLightColor(locTile2, nColor, nColor);
   SetTileSourceLightColor(locTile3, nColor, nColor);
   SetTileSourceLightColor(locTile4, nColor, nColor);
   SetTileSourceLightColor(locTile5, nColor, nColor);
   SetTileSourceLightColor(locTile6, nColor, nColor);


   RecomputeStaticLighting(oArea1);
   RecomputeStaticLighting(oArea2);
   RecomputeStaticLighting(oArea3);
   RecomputeStaticLighting(oArea4);
   RecomputeStaticLighting(oArea5);
   RecomputeStaticLighting(oArea6);

}


In the end, I had to go the route of placeable torches on the wall that were useable, so the player could place a torch, douse a burning torch or ignite a torch, driven through conversation options.

FP!
               
               

               


                     Modifié par Fester Pot, 01 mai 2012 - 05:43 .
                     
                  


            

Legacy_Leurnid

  • Sr. Member
  • ****
  • Posts: 473
  • Karma: +0/-0
Dynamic Area Lighting
« Reply #6 on: May 01, 2012, 07:38:12 pm »


               I don't know if everybody has this issue, but on my current PC, any light sources have an obnoxious 'hotspot' at the light source, even when it is supposed to be a subtle glow. I have taken to using the non-light-emitting candles and flames, and using tile lighting for the actual illumination of to get around that annoyance. I don't recall that being a problem on my old machine, so I am blaming it on nuances of my graphics card.
               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Dynamic Area Lighting
« Reply #7 on: May 01, 2012, 08:33:39 pm »


               Leurnid,
Thats an issue with most placeable light sources. When I can I avoid using those. If you can, it is best to use the non-light emitting placeables and to apply a light vfx via script as a permanent visual effect. Unfortunately not all placeables can emit light in this way. The kind that look like VFXs - such as Project Q's flames - do not seem to take a light effect like this. Perhaps they lack the right kind of mesh. I dunno. And they make this all more complicated. Thankfully they are rare.

So anyway, my recommendation for you in most cases is to apply a light VFX via script rather than adjust tile lighting. You'll get a much better looking result. I do this with dynamically spawned campfires (which also have a dynamic looping sound effect that I am proud of '<img'> ), player placeable candles and lanterns, and non-dynamic placeables (those placed by me in the toolset) are placed in the "off" state, and have a Use event which can switch them on during which the light effect is applied or off which clears all light effects.

For the later it is possible to have the placeable automatically switch itself on as well rather than rely on a player. But that would require you to set up a framework that responds to placeable spawn or area enter or the like. Since placeables do not "spawn" that can be a little tricky, but there are many ways to solve it. You could also create two kinds of placeable prefabs - one that is placed on, the other that is placed off.

FP,
Thanks for that! It looks like we came up with different methods to solve the same thing. it would be useful to compare notes I think.

I am using the placeable's OnUse event of a torch/lantern placeable to turn it on or off. For other options rather than using a conversation, I've hooked into the AID framework and can add commands to each object: examine (provides more info and a list of other commands), light/extinguish, take, push/pull (secret doors need toggles!) etc.... I haven't come up with any other yet.

So far I have two kinds of placeables that operate this way. The main kind works as above. The other kind is a player item that when dropped on the ground becomes a placeable (lanterns and candles) which emits light. These item/placeables are taken when "used" just as a typical item would be. And they are consumable just as their item equivalents are. I have not yet them the ability to turn on or off, because the candle placeable that I am using doesn't have an off state. Until I have a candle placeable with two states and also has an identical holdable model, I think I'm just gonna stick with what I have. This means that gusts of wind simply destroy placed candles rather than blowing them out.

Disclosure: yes, I became obsessed with lighting, and light emitting items, and perception of light by creatures last year and so hopefully this is the last "light" feature that I will roll into Arnheim.
               
               

               
            

Legacy_Leurnid

  • Sr. Member
  • ****
  • Posts: 473
  • Karma: +0/-0
Dynamic Area Lighting
« Reply #8 on: May 01, 2012, 08:59:34 pm »


               Digging a bit more, I found this for dealing with placeable lights:


//::///////////////////////////////////////////////
//:: Name n_am_ou_lswitch
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
     Turns all lights (tag "am_light") in area on/off. If
     these are light objects (like a chandelier); set this int
     Properties/Advanced/Variables of the light object:
     IS_STANDARD_LIGHT int 1
*/
//:://////////////////////////////////////////////
//:: Created By: nereng
//:: Created On: 14/11/2004
//:://////////////////////////////////////////////
void main()
{
    object oArea = GetArea(OBJECT_SELF);
    object oObject = GetFirstObjectInArea(oArea);
    effect eLight = EffectVisualEffect(VFX_DUR_LIGHT_WHITE_20);

    if (GetLocalInt(OBJECT_SELF,"NW_L_AMION") == 0) //It's off; lights on!
    {
        ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE);
        SetLocalInt(OBJECT_SELF,"NW_L_AMION",1);

        // Loop all objects in the area
        while(GetIsObjectValid(oObject))
        {
            if (GetTag(oObject) == "am_light")
            {
                if (GetLocalInt(oObject, "IS_STANDARD_LIGHT") == 1)
                {
                //* If this is a standard lightsource, like a chandelier
                AssignCommand(oObject, ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE));
                SetPlaceableIllumination(oObject, TRUE);
                }

                ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLight, oObject);
            }

        oObject = GetNextObjectInArea(oArea);
        }

        DelayCommand(0.6,RecomputeStaticLighting(GetArea(OBJECT_SELF)));
    }
    else //It's on; lights off!
    {
        ActionPlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE);
        SetLocalInt(OBJECT_SELF,"NW_L_AMION",0);

        while(GetIsObjectValid(oObject)) //check all objects
        {
            if (GetTag(oObject) == "am_light")
            {
                if (GetLocalInt(oObject, "IS_STANDARD_LIGHT") == 1)
                {
                //* If this is a standard lightsource, like a candelabra
                AssignCommand(oObject, ActionPlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE));
                SetPlaceableIllumination(oObject, FALSE);
                }

                effect eEffect = GetFirstEffect(oObject);
                while (GetIsEffectValid(eEffect) == TRUE)
                    {
                    if (GetEffectType(eEffect) == EFFECT_TYPE_VISUALEFFECT)
                        RemoveEffect(oObject, eEffect);
                    eEffect = GetNextEffect(oObject);
                    }
            }

        oObject = GetNextObjectInArea(oArea);
        }
        DelayCommand(0.6,RecomputeStaticLighting(GetArea(OBJECT_SELF)));
    }

}