Shadowrun: Awakened 29 September 2011 - Build 871
Defines | Functions
apigeom.cpp File Reference
#include "machine.h"
#include "types.h"
#include "api.h"
#include "macros.h"
#include "vector.h"
Include dependency graph for apigeom.cpp:

Go to the source code of this file.

Defines

#define MyVNorm(a)   VNorm ((vector *) a)

Functions

static void adjust (apiflt *base, int xres, int yres, apiflt wx, apiflt wy, int xa, int ya, int x, int y, int xb, int yb)
void rt_heightfield (void *tex, vector ctr, int m, int n, apiflt *field, apiflt wx, apiflt wy)
void rt_landscape (void *tex, int m, int n, vector ctr, apiflt wx, apiflt wy)
void rt_polycylinder (void *tex, vector *points, int numpts, apiflt rad)
static void rt_sheightfield (void *tex, vector ctr, int m, int n, apiflt *field, apiflt wx, apiflt wy)
static void subdivide (apiflt *base, int xres, int yres, apiflt wx, apiflt wy, int x1, int y1, int x2, int y2)

Define Documentation

#define MyVNorm (   a)    VNorm ((vector *) a)

Definition at line 71 of file apigeom.cpp.

Referenced by rt_sheightfield().


Function Documentation

static void adjust ( apiflt base,
int  xres,
int  yres,
apiflt  wx,
apiflt  wy,
int  xa,
int  ya,
int  x,
int  y,
int  xb,
int  yb 
) [static]

Definition at line 207 of file apigeom.cpp.

Referenced by subdivide().

                                                      {
  apiflt d, v;
  
  if (base[x + (xres*y)]==0.0) { 

    d=(abs(xa - xb) / (xres * 1.0))*wx + (abs(ya - yb) / (yres * 1.0))*wy; 

    v=(base[xa + (xres*ya)] + base[xb + (xres*yb)]) / 2.0 +
       (((((rand() % 1000) - 500.0)/500.0)*d) / 8.0);

    if (v < 0.0) v=0.0; 
    if (v > (xres + yres)) v=(xres + yres);
    base[x + (xres * y)]=v; 
 } 
}
void rt_heightfield ( void *  tex,
vector  ctr,
int  m,
int  n,
apiflt field,
apiflt  wx,
apiflt  wy 
)

Definition at line 97 of file apigeom.cpp.

References rt_tri(), vector::x, vector::y, and vector::z.

                                                          {
  int xx,yy; 
  vector v0, v1, v2; 
  apiflt xoff, yoff, zoff;

  xoff=ctr.x - (wx / 2.0);
  yoff=ctr.z - (wy / 2.0);
  zoff=ctr.y;

  for (yy=0; yy<(n-1); yy++) { 
    for (xx=0; xx<(m-1); xx++) {
      v0.x=wx*(xx    )/(m*1.0) + xoff; 
      v0.y=field[(yy    )*m + (xx    )] + zoff;
      v0.z=wy*(yy    )/(n*1.0) + yoff;

      v1.x=wx*(xx + 1)/(m*1.0) + xoff; 
      v1.y=field[(yy    )*m + (xx + 1)] + zoff;
      v1.z=wy*(yy    )/(n*1.0) + yoff;

      v2.x=wx*(xx + 1)/(m*1.0) + xoff; 
      v2.y=field[(yy + 1)*m + (xx + 1)] + zoff;
      v2.z=wy*(yy + 1)/(n*1.0) + yoff;

      rt_tri(tex, v1, v0, v2);

      v0.x=wx*(xx    )/(m*1.0) + xoff;
      v0.y=field[(yy    )*m + (xx    )] + zoff;
      v0.z=wy*(yy    )/(n*1.0) + yoff;

      v1.x=wx*(xx    )/(m*1.0) + xoff;
      v1.y=field[(yy + 1)*m + (xx    )] + zoff;
      v1.z=wy*(yy + 1)/(n*1.0) + yoff;

      v2.x=wx*(xx + 1)/(m*1.0) + xoff;
      v2.y=field[(yy + 1)*m + (xx + 1)] + zoff;
      v2.z=wy*(yy + 1)/(n*1.0) + yoff;
 
      rt_tri(tex, v0, v1, v2);
    }
  } 
} /* end of heightfield */
void rt_landscape ( void *  tex,
int  m,
int  n,
vector  ctr,
apiflt  wx,
apiflt  wy 
)

Definition at line 250 of file apigeom.cpp.

References mission1::m, rt_sheightfield(), and subdivide().

Referenced by GetLandScape().

                                                  {
  int totalsize, x, y;
  apiflt * field; 

  totalsize=m*n;

  srand(totalsize);

  field=(apiflt *) malloc(totalsize*sizeof(apiflt));

  for (y=0; y<n; y++) {
    for (x=0; x<m; x++) {
       field[x + y*m]=0.0;
    }
  }

  field[0 + 0]=1.0 + (rand() % 100)/100.0;
  field[m - 1]=1.0 + (rand() % 100)/100.0;
  field[0     + m*(n - 1)]=1.0 + (rand() % 100)/100.0;
  field[m - 1 + m*(n - 1)]=1.0 + (rand() % 100)/100.0;

  subdivide(field, m, n, wx, wy, 0, 0, m-1, n-1);

  rt_sheightfield(tex, ctr, m, n, field, wx, wy);

  free(field);
}
void rt_polycylinder ( void *  tex,
vector points,
int  numpts,
apiflt  rad 
)

Definition at line 73 of file apigeom.cpp.

References rt_fcylinder(), rt_sphere(), vector::x, vector::y, and vector::z.

Referenced by GetPolyCylinder().

                                                                          {
  vector a;
  int i;

  if ((points == NULL) || (numpts == 0)) {
    return;
  }

  if (numpts > 0) {
    rt_sphere(tex, points[0], rad);
    
    if (numpts > 1) {
      for (i=1; i<numpts; i++) {
        a.x = points[i].x - points[i-1].x;
        a.y = points[i].y - points[i-1].y;
        a.z = points[i].z - points[i-1].z;
        
        rt_fcylinder(tex, points[i-1], a, rad);
        rt_sphere(tex, points[i], rad);
      }
    }
  }
}
static void rt_sheightfield ( void *  tex,
vector  ctr,
int  m,
int  n,
apiflt field,
apiflt  wx,
apiflt  wy 
) [static]

Definition at line 141 of file apigeom.cpp.

References mission1::m, MyVNorm, rt_stri(), rt_vector(), vector::x, vector::y, and vector::z.

Referenced by rt_landscape().

                                                          {
  vector * vertices;
  vector * normals;
  vector offset;
  apiflt xinc, yinc;
  int x, y, addr; 
   
  vertices = (vector *) malloc(m*n*sizeof(vector));
  normals = (vector *) malloc(m*n*sizeof(vector));

  offset.x = ctr.x - (wx / 2.0);
  offset.y = ctr.z - (wy / 2.0);
  offset.z = ctr.y;

  xinc = wx / ((apiflt) m);
  yinc = wy / ((apiflt) n);

  /* build vertex list */
  for (y=0; y<n; y++) { 
    for (x=0; x<m; x++) {
      addr = y*m + x;
      vertices[addr] = rt_vector(
        x * xinc + offset.x,
        field[addr] + offset.z,
        y * yinc + offset.y);
    }
  }

  /* build normals from vertex list */
  for (x=1; x<m; x++) {
    normals[x] = normals[(n - 1)*m + x] = rt_vector(0.0, 1.0, 0.0);
  }
  for (y=1; y<n; y++) {
    normals[y*m] = normals[y*m + (m-1)] = rt_vector(0.0, 1.0, 0.0);
  }
  for (y=1; y<(n-1); y++) {
    for (x=1; x<(m-1); x++) {
      addr = y*m + x;

      normals[addr] = rt_vector(
        -(field[addr + 1] - field[addr - 1]) / (2.0 * xinc), 
        1.0, 
        -(field[addr + m] - field[addr - m]) / (2.0 * yinc));

      MyVNorm(&normals[addr]);
    }
  }    

  /* generate actual triangles */
  for (y=0; y<(n-1); y++) {
    for (x=0; x<(m-1); x++) {
      addr = y*m + x;

      rt_stri(tex, vertices[addr], vertices[addr + 1 + m], vertices[addr + 1],
                   normals[addr], normals[addr + 1 + m], normals[addr + 1]);
      rt_stri(tex, vertices[addr], vertices[addr + m], vertices[addr + 1 + m],
                   normals[addr], normals[addr + m], normals[addr + 1 + m]);
    }
  }

  free(normals);
  free(vertices);
} /* end of smoothed heightfield */
static void subdivide ( apiflt base,
int  xres,
int  yres,
apiflt  wx,
apiflt  wy,
int  x1,
int  y1,
int  x2,
int  y2 
) [static]

Definition at line 224 of file apigeom.cpp.

References adjust().

Referenced by rt_landscape().

                                                  {
  long x,y;

  if (((x2 - x1) < 2) && ((y2 - y1) < 2)) { return; }

  x=(x1 + x2) / 2;
  y=(y1 + y2) / 2;

  adjust(base, xres, yres, wx, wy, x1, y1, x, y1, x2, y1);
  adjust(base, xres, yres, wx, wy, x2, y1, x2, y, x2, y2);
  adjust(base, xres, yres, wx, wy, x1, y2, x, y2, x2, y2);
  adjust(base, xres, yres, wx, wy, x1, y1, x1, y, x1, y2);

 
  if (base[x + xres*y]==0.0) {
    base[x + (xres * y)]=(base[x1 + xres*y1] + base[x2 + xres*y1] +
                          base[x2 + xres*y2] + base[x1 + xres*y2]   )/4.0;
  }
 
  subdivide(base, xres, yres, wx, wy, x1, y1 ,x ,y);
  subdivide(base, xres, yres, wx, wy, x, y1, x2, y);
  subdivide(base, xres, yres, wx, wy, x, y, x2, y2);
  subdivide(base, xres, yres, wx, wy, x1, y, x, y2);
}

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net