.:: Bots United ::.

.:: Bots United ::. (http://forums.bots-united.com/index.php)
-   General Bot Coding (http://forums.bots-united.com/forumdisplay.php?f=24)
-   -   code to get the illumination at any point on the map (http://forums.bots-united.com/showthread.php?t=9005)

KWo 20-03-2012 09:49

Re: code to get the illumination at any point on the map
 
Quote:

Originally Posted by Immortal_BLG (Post 64339)
About it I don't know, try to declare this function in bot_globals.cpp, but why you do not accept the declaration in a header file, how has offered Whistler?

Because I just don't know how to do it with a member of a class/namespace. :D

Quote:

Originally Posted by Immortal_BLG (Post 64339)
And into the account of classes and namespaces - you are free to make with a code all that you want, so you can simply remove this namespace....

If You can re-write that function so it doesn't need to be a member of namespace/class, it would be moreeasy for me to handle it. :)
Another thing I'm thinking of is - how much Your function consume the CPU power since it is a recursive function, which needs to be called for every 30 bots on the server (if there are 30 bots)?

Immortal_BLG 20-03-2012 10:56

Re: code to get the illumination at any point on the map
 
Quote:

Originally Posted by KWo (Post 64340)
Because I just don't know how to do it with a member of a class/namespace. :D

There is no difficult. Just cut code from utils.cpp and paste it to bot_globals.cpp.... :)

Quote:

Originally Posted by KWo (Post 64340)
If You can re-write that function so it doesn't need to be a member of namespace/class, it would be moreeasy for me to handle it. :)

Just remove:
Code:

namespace Light
{

// ...
}
And also "Light::" prefixes.

Quote:

Originally Posted by KWo (Post 64340)
Another thing I'm thinking of is - how much Your function consume the CPU power since it is a recursive function, which needs to be called for every 30 bots on the server (if there are 30 bots)?

Not cheked, but I think it is more faster then 30 fake illumination entities....

KWo 20-03-2012 11:01

Re: code to get the illumination at any point on the map
 
Quote:

Originally Posted by Immortal_BLG (Post 64341)
There is no difficult. Just cut code from utils.cpp and paste it to bot_globals.cpp.... :)

I believe You meant bot_globals.h (as Whistler wrote).

Immortal_BLG 20-03-2012 11:28

Re: code to get the illumination at any point on the map
 
Why? You said yourself that the functions that are defined in bot_globals.h, must be declared in the same file - bot_globals.cpp. But instead of it you can declare function "RecursiveLightPoint" in a header file bot_globals.h and ofcourse remove declaration from utils.cpp

KWo 20-03-2012 12:07

Re: code to get the illumination at any point on the map
 
I said - it is so for variables and functions, but I haven't had that case for a const (so I don't know if it needs or not to be done exactly the same way). My doubts are coming from lack of basic C++ knowledge. :)
Anyway I'll try to do something with it today evening.
Thanks again for all Your help.
Спасибо за совет! :)

KWo 20-03-2012 21:07

Re: code to get the illumination at any point on the map
 
OK. Still no luck. One thing I'm sure now. I have commented out in bot_globals.cpp this line:
const char *g_sz_cv_WPT_Folder;
and I've got similar error messages about text (0xaaaa), so that really means I do need somehow the declaration of the function RecursiveLightPoint.
I have checked and there are also other const (not only variables) - first added in bot_globals.h with "extern" prefix, then - without this prefix - in bot_globals.cpp. The problem for me is that template. I don't know how to correctly declare the function RecursiveLightPoint to pevent i.e. such error messages:

bot_globals.cpp|235|error: expected `,' or `...' before '*' token|
bot_globals.cpp|235|error: ISO C++ forbids declaration of `nodeType' with no type|
bot_globals.cpp|235|error: `const bool Light::RecursiveLightPoint(int)' should have been declared inside `Light'|
||=== Build finished: 3 errors, 0 warnings ===|


Currently in my code I've removed the function from util.cpp and in bot_globals.h it looks so:
Code:

namespace Light
{
//extern const mplane_t *lightplane (NULL);
//extern Vector lightspot;
  extern Color g_pointColor;

//  extern const bool RecursiveLightPoint (const nodeType *const node, const Vector &start, const Vector &end);

//      Color g_pointColor;
//
  template <typename nodeType, typename surfaceType>extern const  bool RecursiveLightPoint (const nodeType *const node, const Vector  &start, const Vector &end)
  {
      float front, back, frac;
      int side;
      mplane_t *plane;
      Vector mid;
      surfaceType *surf;
      int s, t, ds, dt;
      int i;
      mtexinfo_t *tex;
      color24 *lightmap;
      unsigned int scale;
      unsigned char maps;

      // Reliability check.
      assert (node != NULL);

      if (node->contents < 0)
        return false;  // didn't hit anything

      // Determine which side of the node plane our points are on
      // FIXME: optimize for axial
      plane = node->plane;
      front = DotProduct (start, plane->normal) - plane->dist;
      back = DotProduct (end, plane->normal) - plane->dist;
      side = front < 0.0f;

      // If they're both on the same side of the plane, don't bother to split just check the appropriate child
      if ((back < 0.0f) == side)
        return RecursiveLightPoint <nodeType, surfaceType>  (reinterpret_cast <nodeType *> (node->children[side]), start,  end);

      // calculate mid point
      frac = front / (front - back);
      mid = start + (end - start) * frac;

      // go down front side
      if (RecursiveLightPoint <nodeType, surfaceType>  (reinterpret_cast <nodeType *> (node->children[side]), start,  mid))
        return true;  // hit something

      // Blow it off if it doesn't split the plane...
      if ((back < 0.0f) == side)
        return false;  // didn't hit anything

      // check for impact on this node
  //  lightspot = mid;
  //  lightplane = plane;

      surf = reinterpret_cast <surfaceType *> (sv_worldmodel->surfaces) + node->firstsurface;
      for (i = 0; i < node->numsurfaces; ++i, ++surf)
      {
        if (surf->flags & SURF_DRAWTILED)
            continue;  // no lightmaps

        tex = surf->texinfo;

        // See where in lightmap space our intersection point is
        s = static_cast <int> (DotProduct (mid, Vector (tex->vecs[0])) + tex->vecs[0][3]);
        t = static_cast <int> (DotProduct (mid, Vector (tex->vecs[1])) + tex->vecs[1][3]);

        // Not in the bounds of our lightmap? punt...
        if (s < surf->texturemins[0] || t < surf->texturemins[1])
            continue;

        // assuming a square lightmap (FIXME: which ain't always the case),
        // lets see if it lies in that rectangle. If not, punt...
        ds = s - surf->texturemins[0];
        dt = t - surf->texturemins[1];

        if (ds > surf->extents[0] || dt > surf->extents[1])
            continue;

        if (surf->samples == NULL)
            return true;

        ds >>= 4;
        dt >>= 4;

        g_pointColor.Reset ();  // Reset point color.

        const int smax ((surf->extents[0] >> 4) + 1);
        const int tmax ((surf->extents[1] >> 4) + 1);
        const int size (smax * tmax);

        lightmap = surf->samples + dt * smax + ds;

        // Compute the lightmap color at a particular point
        for (maps = 0u; maps < MAXLIGHTMAPS && surf->styles[maps] != 255u; ++maps)
        {
            scale = d_lightstylevalue[surf->styles[maps]];

            g_pointColor.red += lightmap->r * scale;
            g_pointColor.green += lightmap->g * scale;
            g_pointColor.blue += lightmap->b * scale;

            lightmap += size;  // skip to next lightmap
        }

        g_pointColor.red >>= 8u;
        g_pointColor.green >>= 8u;
        g_pointColor.blue >>= 8u;

        return true;
      }

      // go down back side
      return RecursiveLightPoint <nodeType, surfaceType>  (reinterpret_cast <nodeType *> (node->children[!side]), mid,  end);
  }

  inline const bool IsSoftwareDrawingMode (void)
  {
      static const bool isSoftwareDrawingMode (IS_DEDICATED_SERVER () || GetModuleHandle ("sw.dll") != NULL);

      return isSoftwareDrawingMode;
  }

  inline const bool ActualRecursiveLightPoint (const Vector &start, const Vector &end)
  {
      return IsSoftwareDrawingMode () ?
        RecursiveLightPoint <mnode_t, msurface_t> (sv_worldmodel->nodes, start, end) :
        RecursiveLightPoint <GL_mnode_t, GL_msurface_t>  (reinterpret_cast <GL_mnode_t *> (sv_worldmodel->nodes), start,  end);
  }

  inline const unsigned char R_LightPoint (const Vector &p)
  {
  // Reliability check.
      if (sv_worldmodel == NULL)
        return 0u;

      if (sv_worldmodel->lightdata == NULL)
        return 255u;

      Vector end (p);

      end.z -= 2048.0f;

      return ActualRecursiveLightPoint (p, end) == false ? 0u : static_cast <unsigned char> (g_pointColor.GetAvg ());
  }
}

#endif

The line 235 from bot_globals.cpp looks so:
Code:

235: const bool Light::RecursiveLightPoint (const nodeType *const node, const Vector &start, const Vector &end);
236: Color Light::g_pointColor;

I need still some help with this. :(

Immortal_BLG 21-03-2012 03:25

Re: code to get the illumination at any point on the map
 
try:
in bot_globals.h:
Code:

#ifdef _LINUX
// Linux doesn't have this function so this emulates its functionality
inline void *GetModuleHandle(const char *name)
{
        void *handle;

        if( name == NULL )
        {
                // hmm, how can this be handled under linux....
                // is it even needed?
                return NULL;
        }

    if( (handle=dlopen(name, RTLD_NOW))==NULL)
    {
            // couldn't open this file
            return NULL;
    }

        // read "man dlopen" for details
        // in short dlopen() inc a ref count
        // so dec the ref count by performing the close
        dlclose(handle);
        return handle;
}
#endif
/*
=============================================================================

LIGHT SAMPLING

=============================================================================
*/
namespace Light
{
//extern const mplane_t *lightplane (NULL);
//extern Vector lightspot;
extern Color g_pointColor;

template <typename nodeType, typename surfaceType> static const bool RecursiveLightPoint (const nodeType *const node, const Vector &start, const Vector &end)
{
        float front, back, frac;
        int side;
        mplane_t *plane;
        Vector mid;
        surfaceType *surf;
        int s, t, ds, dt;
        int i;
        mtexinfo_t *tex;
        color24 *lightmap;
        unsigned int scale;
        unsigned char maps;

        // Reliability check.
        assert (node != NULL);

        if (node->contents < 0)
                return false;        // didn't hit anything

        // Determine which side of the node plane our points are on
        // FIXME: optimize for axial
        plane = node->plane;
        front = DotProduct (start, plane->normal) - plane->dist;
        back = DotProduct (end, plane->normal) - plane->dist;
        side = front < 0.0f;

        // If they're both on the same side of the plane, don't bother to split just check the appropriate child
        if ((back < 0.0f) == side)
                return RecursiveLightPoint <nodeType, surfaceType> (reinterpret_cast <nodeType *> (node->children[side]), start, end);

        // calculate mid point
        frac = front / (front - back);
        mid = start + (end - start) * frac;

        // go down front side       
        if (RecursiveLightPoint <nodeType, surfaceType> (reinterpret_cast <nodeType *> (node->children[side]), start, mid))
                return true;        // hit something

        // Blow it off if it doesn't split the plane...
        if ((back < 0.0f) == side)
                return false;        // didn't hit anything

        // check for impact on this node
//        lightspot = mid;
//        lightplane = plane;

        surf = reinterpret_cast <surfaceType *> (sv_worldmodel->surfaces) + node->firstsurface;
        for (i = 0; i < node->numsurfaces; ++i, ++surf)
        {
                if (surf->flags & SURF_DRAWTILED)
                        continue;        // no lightmaps

                tex = surf->texinfo;

                // See where in lightmap space our intersection point is
                s = static_cast <int> (DotProduct (mid, Vector (tex->vecs[0])) + tex->vecs[0][3]);
                t = static_cast <int> (DotProduct (mid, Vector (tex->vecs[1])) + tex->vecs[1][3]);

                // Not in the bounds of our lightmap? punt...
                if (s < surf->texturemins[0] || t < surf->texturemins[1])
                        continue;

                // assuming a square lightmap (FIXME: which ain't always the case),
                // lets see if it lies in that rectangle. If not, punt...
                ds = s - surf->texturemins[0];
                dt = t - surf->texturemins[1];

                if (ds > surf->extents[0] || dt > surf->extents[1])
                        continue;

                if (surf->samples == NULL)
                        return true;

                ds >>= 4;
                dt >>= 4;

                g_pointColor.Reset ();        // Reset point color.

                const int smax ((surf->extents[0] >> 4) + 1);
                const int tmax ((surf->extents[1] >> 4) + 1);
                const int size (smax * tmax);

                lightmap = surf->samples + dt * smax + ds;

                // Compute the lightmap color at a particular point
                for (maps = 0u; maps < MAXLIGHTMAPS && surf->styles[maps] != 255u; ++maps)
                {
                        scale = d_lightstylevalue[surf->styles[maps]];

                        g_pointColor.red += lightmap->r * scale;
                        g_pointColor.green += lightmap->g * scale;
                        g_pointColor.blue += lightmap->b * scale;

                        lightmap += size;        // skip to next lightmap
                }

                g_pointColor.red >>= 8u;
                g_pointColor.green >>= 8u;
                g_pointColor.blue >>= 8u;

                return true;
        }

        // go down back side
        return RecursiveLightPoint <nodeType, surfaceType> (reinterpret_cast <nodeType *> (node->children[!side]), mid, end);
}

inline const bool IsSoftwareDrawingMode (void)
{
        #ifdef _LINUX
                return true;        // Always software rendering mode....
        #else        // ifdef _LINUX
                static const bool isSoftwareDrawingMode (IS_DEDICATED_SERVER () || GetModuleHandle ("sw.dll") != NULL);

                return isSoftwareDrawingMode;
        #endif        // ifndef _LINUX
}
inline const bool ActualRecursiveLightPoint (const Vector &start, const Vector &end)
{
        return IsSoftwareDrawingMode () ?
                RecursiveLightPoint <mnode_t, msurface_t> (sv_worldmodel->nodes, start, end) :
                RecursiveLightPoint <GL_mnode_t, GL_msurface_t> (reinterpret_cast <GL_mnode_t *> (sv_worldmodel->nodes), start, end);
}

inline const unsigned char R_LightPoint (const Vector &p)
{
        // Reliability check.
        if (sv_worldmodel == NULL)
                return 0u;

        if (sv_worldmodel->lightdata == NULL)
                return 255u;

        Vector end (p);

        end.z -= 2048.0f;

        return ActualRecursiveLightPoint (p, end) == false ? 0u : static_cast <unsigned char> (g_pointColor.GetAvg ());
}
}

or even use the method of an "axe", as we in Russia love.... (without templates)
Code:

static const bool RecursiveLightPoint (const mnode_t *const node, const Vector &start, const Vector &end)
{
        float front, back, frac;
        int side;
        mplane_t *plane;
        Vector mid;
        msurface_t *surf;
        int s, t, ds, dt;
        int i;
        mtexinfo_t *tex;
        color24 *lightmap;
        unsigned int scale;
        unsigned char maps;

        // Reliability check.
        assert (node != NULL);

        if (node->contents < 0)
                return false;        // didn't hit anything

        // Determine which side of the node plane our points are on
        // FIXME: optimize for axial
        plane = node->plane;
        front = DotProduct (start, plane->normal) - plane->dist;
        back = DotProduct (end, plane->normal) - plane->dist;
        side = front < 0.0f;

        // If they're both on the same side of the plane, don't bother to split just check the appropriate child
        if ((back < 0.0f) == side)
                return RecursiveLightPoint (node->children[side], start, end);

        // calculate mid point
        frac = front / (front - back);
        mid = start + (end - start) * frac;

        // go down front side       
        if (RecursiveLightPoint (node->children[side], start, mid))
                return true;        // hit something

        // Blow it off if it doesn't split the plane...
        if ((back < 0.0f) == side)
                return false;        // didn't hit anything

        // check for impact on this node
//        lightspot = mid;
//        lightplane = plane;

        surf = sv_worldmodel->surfaces + node->firstsurface;
        for (i = 0; i < node->numsurfaces; ++i, ++surf)
        {
                if (surf->flags & SURF_DRAWTILED)
                        continue;        // no lightmaps

                tex = surf->texinfo;

                // See where in lightmap space our intersection point is
                s = static_cast <int> (DotProduct (mid, Vector (tex->vecs[0])) + tex->vecs[0][3]);
                t = static_cast <int> (DotProduct (mid, Vector (tex->vecs[1])) + tex->vecs[1][3]);

                // Not in the bounds of our lightmap? punt...
                if (s < surf->texturemins[0] || t < surf->texturemins[1])
                        continue;

                // assuming a square lightmap (FIXME: which ain't always the case),
                // lets see if it lies in that rectangle. If not, punt...
                ds = s - surf->texturemins[0];
                dt = t - surf->texturemins[1];

                if (ds > surf->extents[0] || dt > surf->extents[1])
                        continue;

                if (surf->samples == NULL)
                        return true;

                ds >>= 4;
                dt >>= 4;

                g_pointColor.Reset ();        // Reset point color.

                const int smax ((surf->extents[0] >> 4) + 1);
                const int tmax ((surf->extents[1] >> 4) + 1);
                const int size (smax * tmax);

                lightmap = surf->samples + dt * smax + ds;

                // Compute the lightmap color at a particular point
                for (maps = 0u; maps < MAXLIGHTMAPS && surf->styles[maps] != 255u; ++maps)
                {
                        scale = d_lightstylevalue[surf->styles[maps]];

                        g_pointColor.red += lightmap->r * scale;
                        g_pointColor.green += lightmap->g * scale;
                        g_pointColor.blue += lightmap->b * scale;

                        lightmap += size;        // skip to next lightmap
                }

                g_pointColor.red >>= 8u;
                g_pointColor.green >>= 8u;
                g_pointColor.blue >>= 8u;

                return true;
        }

        // go down back side
        return RecursiveLightPoint (node->children[!side], mid, end);
}
static const bool GL_RecursiveLightPoint (const GL_mnode_t *const node, const Vector &start, const Vector &end)
{
        float front, back, frac;
        int side;
        mplane_t *plane;
        Vector mid;
        GL_msurface_t *surf;
        int s, t, ds, dt;
        int i;
        mtexinfo_t *tex;
        color24 *lightmap;
        unsigned int scale;
        unsigned char maps;

        // Reliability check.
        assert (node != NULL);

        if (node->contents < 0)
                return false;        // didn't hit anything

        // Determine which side of the node plane our points are on
        // FIXME: optimize for axial
        plane = node->plane;
        front = DotProduct (start, plane->normal) - plane->dist;
        back = DotProduct (end, plane->normal) - plane->dist;
        side = front < 0.0f;

        // If they're both on the same side of the plane, don't bother to split just check the appropriate child
        if ((back < 0.0f) == side)
                return GL_RecursiveLightPoint (reinterpret_cast <GL_mnode_t *> (node->children[side]), start, end);

        // calculate mid point
        frac = front / (front - back);
        mid = start + (end - start) * frac;

        // go down front side       
        if (GL_RecursiveLightPoint (reinterpret_cast <GL_mnode_t *> (node->children[side]), start, mid))
                return true;        // hit something

        // Blow it off if it doesn't split the plane...
        if ((back < 0.0f) == side)
                return false;        // didn't hit anything

        // check for impact on this node
//        lightspot = mid;
//        lightplane = plane;

        surf = reinterpret_cast <GL_msurface_t *> (sv_worldmodel->surfaces) + node->firstsurface;
        for (i = 0; i < node->numsurfaces; ++i, ++surf)
        {
                if (surf->flags & SURF_DRAWTILED)
                        continue;        // no lightmaps

                tex = surf->texinfo;

                // See where in lightmap space our intersection point is
                s = static_cast <int> (DotProduct (mid, Vector (tex->vecs[0])) + tex->vecs[0][3]);
                t = static_cast <int> (DotProduct (mid, Vector (tex->vecs[1])) + tex->vecs[1][3]);

                // Not in the bounds of our lightmap? punt...
                if (s < surf->texturemins[0] || t < surf->texturemins[1])
                        continue;

                // assuming a square lightmap (FIXME: which ain't always the case),
                // lets see if it lies in that rectangle. If not, punt...
                ds = s - surf->texturemins[0];
                dt = t - surf->texturemins[1];

                if (ds > surf->extents[0] || dt > surf->extents[1])
                        continue;

                if (surf->samples == NULL)
                        return true;

                ds >>= 4;
                dt >>= 4;

                g_pointColor.Reset ();        // Reset point color.

                const int smax ((surf->extents[0] >> 4) + 1);
                const int tmax ((surf->extents[1] >> 4) + 1);
                const int size (smax * tmax);

                lightmap = surf->samples + dt * smax + ds;

                // Compute the lightmap color at a particular point
                for (maps = 0u; maps < MAXLIGHTMAPS && surf->styles[maps] != 255u; ++maps)
                {
                        scale = d_lightstylevalue[surf->styles[maps]];

                        g_pointColor.red += lightmap->r * scale;
                        g_pointColor.green += lightmap->g * scale;
                        g_pointColor.blue += lightmap->b * scale;

                        lightmap += size;        // skip to next lightmap
                }

                g_pointColor.red >>= 8u;
                g_pointColor.green >>= 8u;
                g_pointColor.blue >>= 8u;

                return true;
        }

        // go down back side
        return GL_RecursiveLightPoint (reinterpret_cast <GL_mnode_t *> (node->children[!side]), mid, end);
}
inline const bool ActualRecursiveLightPoint (const Vector &start, const Vector &end)
{
        return IsSoftwareDrawingMode () ?
                RecursiveLightPoint (sv_worldmodel->nodes, start, end) :
                GL_RecursiveLightPoint (reinterpret_cast <GL_mnode_t *> (sv_worldmodel->nodes), start, end);
}

But don't forget to remove all definitions of function RecursiveLightPoint from .cpp files FOR BOTH CASES....
Finally in bot_globals.cpp everything should be as so:
Code:

/*
=============================================================================

LIGHT SAMPLING

=============================================================================
*/
namespace Light
{
//const mplane_t *lightplane (NULL);
//Vector lightspot;
Color g_pointColor;
}


KWo 21-03-2012 22:10

Re: code to get the illumination at any point on the map
 
Finally I've got it compiling even with such code:
bot_globals.h
Code:

#include <com_model.h>
#include <pm_defs.h>

// KWo - 13.03.2012 - Thanks to Immortal_BLG for light code

#define  SURF_PLANEBACK      2
#define  SURF_DRAWSKY        4
#define  SURF_DRAWSPRITE    8
#define  SURF_DRAWTURB      0x10
#define  SURF_DRAWTILED      0x20
#define  SURF_DRAWBACKGROUND 0x40

#ifdef __linux__
// Linux doesn't have this function so this emulates its functionality
inline void *GetModuleHandle(const char *name)
{
  void *handle;

  if( name == NULL )
  {
      // hmm, how can this be handled under linux....
      // is it even needed?
      return NULL;
  }

    if( (handle=dlopen(name, RTLD_NOW))==NULL)
    {
            // couldn't open this file
            return NULL;
    }

  // read "man dlopen" for details
  // in short dlopen() inc a ref count
  // so dec the ref count by performing the close
  dlclose(handle);
  return handle;
}
#endif

struct GL_msurface_t
{
#define SURF_UNDERWATER      0x80  // ONLY FOR OpenGL!!!
//#define SURF_DONTWARP      0x100  // ONLY FOR OpenGL!!! (EXISTS?!?!?!?!?!??!?!?!?!?!?!??!)

/*off=0(0)*/  int        visframe;      // should be drawn when node is crossed
/*off=4(1)*/  mplane_t  *plane;        // pointer to shared plane
/*off=8(2)*/  int        flags;        // see SURF_* #defines

/*off=12(3)*/  int        firstedge;  // look up in model->surfedges[], negative numbers are backwards edges
/*off=16(4)*/  int        numedges;

/*off=20(5)*/  short      texturemins[2]; // smallest s/t position on the surface.
/*off=24(6)*/  short      extents[2];      // ?? s/t texture size, 1..256 for all non-sky surfaces

/*off=28(7)*/  int        light_s, light_t;  // gl lightmap coordinates
/*off=36(9)*/  struct glpoly_t  *polys;            // multiple if warped
/*off=40(10)*/  msurface_t  *texturechain;
/*off=44(11)*/  mtexinfo_t  *texinfo;

// lighting info
/*off=48(12)*/  int        dlightframe;  // last frame the surface was checked by an animated light
/*off=52(13)*/  int        dlightbits;      // dynamically generated. Indicates if the surface illumination
                        // is modified by an animated light.
/*off=56(14)*/  int        lightmaptexturenum;
/*off=60(15)*/  unsigned char      styles[MAXLIGHTMAPS]; // index into d_lightstylevalue[] for animated lights
                            // no one surface can be effected by more than 4
                            // animated lights.

/*off=64(16)*/  int        cached_light[MAXLIGHTMAPS];  // values currently used in lightmap
/*off=80(20)*/  qboolean  cached_dlight;            // true if dynamic light in cache

/*off=84(21)*/  color24      *samples;  // [numstyles*surfsize]

/*off=88(22)*/  decal_t      *pdecals;
};  // sizeof (GL_msurface_t) == 92 (23)
struct GL_mnode_t
{
  enum ChildrenType_t
  {
      ChildrenType_Front,
      ChildrenType_Back,

      ChildrenType_Total
  };

// common with leaf
/*! Off=0(0)*/  int        contents;      // 0, to differentiate from leafs
/*! Off=4(1)*/  int        visframe;      // node needs to be traversed if current

/*! Off=8(2)*/  Vector      mins, maxs;      // for bounding box culling

/*! Off=32(8)*/  mnode_t  *parent;

// node specific
/*! Off=36(9)*/  mplane_t  *plane;
/*! Off=40(10)*/  mnode_t  *children[ChildrenType_Total];

/*! Off=48(12)*/  unsigned short      firstsurface;
/*! Off=50(12.5)*/  unsigned short      numsurfaces;
};  // sizeof (GL_mnode_t) == 52 (13)

#define  MAX_LIGHTSTYLES  64
#define  MAX_LIGHTSTYLEVALUE  256

struct lightstyle_t
{
  int  length;
  char map[MAX_LIGHTSTYLES];
};

extern lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
extern int          d_lightstylevalue[MAX_LIGHTSTYLEVALUE];  // 8.8 fraction of base light value
extern model_t    *sv_worldmodel;  // Analog of sv.worldmodel.

struct Color
{
  int red;
  int green;
  int blue;

  inline      void        Reset  (void)      { red = green = blue = 0; }
  inline const unsigned int GetAvg (void) const { return (red + green + blue) / (sizeof (Color) / sizeof (int)); }
};

/*
=============================================================================

LIGHT SAMPLING

=============================================================================
*/


namespace Light
{
//extern const mplane_t *lightplane (NULL);
//extern Vector lightspot;
  extern Color g_pointColor;

//  extern const bool RecursiveLightPoint (const nodeType *const node, const Vector &start, const Vector &end);

//      Color g_pointColor;
//
  template <typename nodeType, typename surfaceType> extern const  bool RecursiveLightPoint (const nodeType *const node, const Vector  &start, const Vector &end)
  {
      float front, back, frac;
      int side;
      mplane_t *plane;
      Vector mid;
      surfaceType *surf;
      int s, t, ds, dt;
      int i;
      mtexinfo_t *tex;
      color24 *lightmap;
      unsigned int scale;
      unsigned char maps;

      // Reliability check.
      assert (node != NULL);

      if (node->contents < 0)
        return false;  // didn't hit anything

      // Determine which side of the node plane our points are on
      // FIXME: optimize for axial
      plane = node->plane;
      front = DotProduct (start, plane->normal) - plane->dist;
      back = DotProduct (end, plane->normal) - plane->dist;
      side = front < 0.0f;

      // If they're both on the same side of the plane, don't bother to split just check the appropriate child
      if ((back < 0.0f) == side)
        return RecursiveLightPoint <nodeType, surfaceType>  (reinterpret_cast <nodeType *> (node->children[side]), start,  end);

      // calculate mid point
      frac = front / (front - back);
      mid = start + (end - start) * frac;

      // go down front side
      if (RecursiveLightPoint <nodeType, surfaceType>  (reinterpret_cast <nodeType *> (node->children[side]), start,  mid))
        return true;  // hit something

      // Blow it off if it doesn't split the plane...
      if ((back < 0.0f) == side)
        return false;  // didn't hit anything

      // check for impact on this node
  //  lightspot = mid;
  //  lightplane = plane;

      surf = reinterpret_cast <surfaceType *> (sv_worldmodel->surfaces) + node->firstsurface;
      for (i = 0; i < node->numsurfaces; ++i, ++surf)
      {
        if (surf->flags & SURF_DRAWTILED)
            continue;  // no lightmaps

        tex = surf->texinfo;

        // See where in lightmap space our intersection point is
        s = static_cast <int> (DotProduct (mid, Vector (tex->vecs[0])) + tex->vecs[0][3]);
        t = static_cast <int> (DotProduct (mid, Vector (tex->vecs[1])) + tex->vecs[1][3]);

        // Not in the bounds of our lightmap? punt...
        if (s < surf->texturemins[0] || t < surf->texturemins[1])
            continue;

        // assuming a square lightmap (FIXME: which ain't always the case),
        // lets see if it lies in that rectangle. If not, punt...
        ds = s - surf->texturemins[0];
        dt = t - surf->texturemins[1];

        if (ds > surf->extents[0] || dt > surf->extents[1])
            continue;

        if (surf->samples == NULL)
            return true;

        ds >>= 4;
        dt >>= 4;

        g_pointColor.Reset ();  // Reset point color.

        const int smax ((surf->extents[0] >> 4) + 1);
        const int tmax ((surf->extents[1] >> 4) + 1);
        const int size (smax * tmax);

        lightmap = surf->samples + dt * smax + ds;

        // Compute the lightmap color at a particular point
        for (maps = 0u; maps < MAXLIGHTMAPS && surf->styles[maps] != 255u; ++maps)
        {
            scale = d_lightstylevalue[surf->styles[maps]];

            g_pointColor.red += lightmap->r * scale;
            g_pointColor.green += lightmap->g * scale;
            g_pointColor.blue += lightmap->b * scale;

            lightmap += size;  // skip to next lightmap
        }

        g_pointColor.red >>= 8u;
        g_pointColor.green >>= 8u;
        g_pointColor.blue >>= 8u;

        return true;
      }

      // go down back side
      return RecursiveLightPoint <nodeType, surfaceType>  (reinterpret_cast <nodeType *> (node->children[!side]), mid,  end);
  }

  inline const bool IsSoftwareDrawingMode (void)
  {
      static const bool isSoftwareDrawingMode (IS_DEDICATED_SERVER () || GetModuleHandle ("sw.dll") != NULL);

      return isSoftwareDrawingMode;
  }

  inline const bool ActualRecursiveLightPoint (const Vector &start, const Vector &end)
  {
      return IsSoftwareDrawingMode () ?
        RecursiveLightPoint <mnode_t, msurface_t> (sv_worldmodel->nodes, start, end) :
        RecursiveLightPoint <GL_mnode_t, GL_msurface_t>  (reinterpret_cast <GL_mnode_t *> (sv_worldmodel->nodes), start,  end);
  }

  inline const unsigned char R_LightPoint (const Vector &p)
  {
  // Reliability check.
      if (sv_worldmodel == NULL)
        return 0u;

      if (sv_worldmodel->lightdata == NULL)
        return 255u;

      Vector end (p);

      end.z -= 2048.0f;

      return ActualRecursiveLightPoint (p, end) == false ? 0u : static_cast <unsigned char> (g_pointColor.GetAvg ());
  }
}

bot_globals.cpp
Code:

lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
int          d_lightstylevalue[MAX_LIGHTSTYLEVALUE];  // 8.8 fraction of base light value
model_t    *sv_worldmodel (NULL);  // Analog of sv.worldmodel.

namespace Light
{
  Color g_pointColor;
  template <typename nodeType, typename surfaceType> const bool RecursiveLightPoint (const nodeType *const node, const Vector &start, const Vector &end);
}

The stupid message about wrong reference was coming from old compiled bot.cpp.obj, which wasn't changed by me long time, but it had already linked some references to the function defined first way (when it was compiling correctly for MS C++ Visual Express 2008). After that I was using all the time the "Rebuild" function (as usually), which should compile newer files only. If headers file were changed, all cpp should be compiled again, but it looks it didn't work correctly for MinGW. The "Clean" command helped. After that I did "Build" and it compiled the dll correctly (it is loading and light code is working for windows). I have to check how about cygwin and linux.
Thanks again for the patience for me. :)

Immortal_BLG 22-03-2012 00:55

Re: code to get the illumination at any point on the map
 
Good news :)

just a question: have you tried to compile the function "RecursiveLightPoint" with the keyword "static" instead of "extern"? I'm just wondering whether the code from my last post is working or not.

BTW at the expense of function "GetModuleHandle". Once again I was wrong in my last post, because if there is no listen servers for LINUX, then the function "GetModuleHandle" for LINUX does not need, in addition, ".DLL" extension on LINUX, it does not exist, there ".SO".

So you should use: (without GetModuleHandle for LINUX)
Code:

inline const bool IsSoftwareDrawingMode (void)
{
        #ifdef _LINUX
                return true;        // Always software rendering mode....
        #else        // ifdef _LINUX
                static const bool isSoftwareDrawingMode (IS_DEDICATED_SERVER () || GetModuleHandle ("sw.dll") != NULL);

                return isSoftwareDrawingMode;
        #endif        // ifndef _LINUX
}


KWo 22-03-2012 08:06

Re: code to get the illumination at any point on the map
 
Quote:

Originally Posted by Immortal_BLG (Post 64348)
just a question: have you tried to compile the function "RecursiveLightPoint" with the keyword "static" instead of "extern"? I'm just wondering whether the code from my last post is working or not.

I was trying it when the code didn't want to compile. Later on - when I got it finally compiling - I was compiling it with that Your beloved method without templates. After that I went back to template and after compilation and successful loading dll (and working on windows) I didn't try again with static instead extern. I have focused to run my linux vmware test server, but yesterday that machine got crashed and I had to restore it from some my backup (11.2011). :D So finally I haven't had time yet to test if the cygwin compiled .so is loading and working or not. I'll try this today evening.


All times are GMT +2. The time now is 21:35.

Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.