示例#1
0
Tetra *MakeTetra(Face *f,Point3 *v[], int n)
{
 Plane p,Mp;
 boolean found=FALSE;
 double Radius=BIGNUMBER,  rad;
 Line Lc;
 int pind=0;
 Tetra *t;
 Point3 Center, c;
 int i;

 if(!CalcPlane(f->v[0],f->v[1],f->v[2],&p))
		Error("MakeTetra, Face with collinar vertices!\n",EXIT);

 CalcLineofCenter(f->v[0],f->v[1],f->v[2],&Lc);

 for(i=0;i<n;i++)
 {
  if((v[i]!=f->v[0]) &&
     (v[i]!=f->v[1]) &&
     (v[i]!=f->v[2]) &&
     RightSide(&p,v[i]) )
		{
		 CalcMiddlePlane(v[i],f->v[0],&Mp);
		 if(CalcLinePlaneInter(&Lc,&Mp,&c))
		      {
			rad=V3SquaredDistanceBetween2Points(&c, v[i]);

			if(!RightSide(&p,&c)) rad=-rad;
			if(rad==Radius) Error("MakeTetra, Five cocircular points!\n",EXIT);
			if(rad<Radius)
				{
				 found=TRUE;
				 Radius=rad;
				 Center=c;
				 pind=i;
				}
		      }
		}
 }

 if(!found) return NULL;

 t=BuildTetra(f,v[pind]);

 if(CheckFlag)	CheckTetra(t,v,n);

 if(StatFlag)
 {Point3 C;
  CalcSphereCenter(f->v[0], f->v[1], f->v[2], v[pind], &C);
  SI.Radius+=V3DistanceBetween2Points(&C, v[pind]);
 }

 return t;
}
示例#2
0
int InitGLObjects()										// Initialize Objects
{
	if (!ReadObject("Data/Object2.txt", &obj))			// Read Object2 Into obj
	{
		return FALSE;									// If Failed Return False
	}

	SetConnectivity(&obj);								// Set Face To Face Connectivity

	for (unsigned int i=0;i<obj.nPlanes;i++)			// Loop Through All Object Planes
		CalcPlane(obj, &(obj.planes[i]));				// Compute Plane Equations For All Faces

	return TRUE;										// Return True
}
Line *CalcLineofCenter(Point3 *p1, Point3 *p2, Point3 *p3, Line *l)
{
 Plane pl1,pl2,pl3;

  CalcMiddlePlane(p1,p2,&pl1);
  CalcMiddlePlane(p1,p3,&pl2);
  CalcPlane(p1,p2,p3,&pl3);

  CalcPlaneInter(&pl1,&pl2,&pl3,&(l->Lu));

  l->Lv=pl3.N;

  return l;
}
示例#4
0
Tetra *FirstTetra(Point3 *v[], int n)
{
 int i, MinIndex=0;
 double Radius, MinRadius=BIGNUMBER;

 Tetra *t;
 Plane p[3], Mp;
 Line Lc;
 Face f;
 Point3 c;

 boolean found=FALSE;

 f.v[0]=v[n/2-1];	/* The first point of the face is the	*/
			/* nearest to middle plane in negative	*/
			/* halfspace.				*/

			/* The 2nd point of the face is the	*/
			/* euclidean nearest to first point	*/
 for(i=n/2;i<n;i++)	/* that is in the positive halfspace	*/
    {
     Radius=V3SquaredDistanceBetween2Points(f.v[0], v[i]);
     if(Radius<MinRadius)
	{
	 MinRadius=Radius;
	 MinIndex=i;
	}
    }

 f.v[1]=v[MinIndex];
			/* The 3rd point is that with previous	*/
			/* ones builds the smallest circle.	*/

 CalcMiddlePlane(f.v[0],f.v[1], &(p[0]));

 MinRadius=BIGNUMBER;

 for(i=0;i<n;i++)
  if(v[i]!=f.v[0] && v[i]!=f.v[1])
   {
    CalcMiddlePlane(f.v[0], v[i],&(p[1]));
    if(CalcPlane(f.v[0],f.v[1],v[i],&(p[2])))
      if(CalcPlaneInter(&(p[0]), &(p[1]), &(p[2]), &c))
	{
	 Radius=V3DistanceBetween2Points(&c, f.v[0]);
	  if(Radius<MinRadius)
		{
		 MinRadius=Radius;
		 MinIndex=i;
		}
	}
   }

 f.v[2]=v[MinIndex];


 /* The first tetrahedron construction is analogous to normal */
 /* MakeTetra, only we dont limit search to an halfspace.     */

 MinRadius=BIGNUMBER;

 CalcPlane(f.v[0], f.v[1], f.v[2],&p[0]);
 CalcLineofCenter(f.v[0], f.v[1], f.v[2], &Lc);

 for(i=0;i<n;i++)
  if(v[i]!=f.v[0] && v[i]!=f.v[1] && v[i]!=f.v[2] )
   {
    CalcMiddlePlane(v[i], f.v[0], &Mp);
    if(CalcLinePlaneInter(&Lc, &Mp, &c))
	 {
	   Radius=V3SquaredDistanceBetween2Points(&c, v[i]);

	   if(MinRadius==Radius) Error("FirstTetra, Five cocircular points!\n",EXIT);
	   if(Radius<MinRadius)
		   {
		    found=TRUE;
		    MinRadius=Radius;
		    MinIndex=i;
		   }
	 }
   }

 if(!found) Error("FirstTetra, Planar dataset, unable to build first tetrahedron.\n",EXIT);

 if(!RightSide(&p[0],v[MinIndex]))	ReverseFace(&f);

 t=BuildTetra(&f, v[MinIndex]);

 CheckTetra(t,v,n);

 ReverseFace(t->f[0]); /* First Face in first Tetra   */
		       /* must be outward oriented    */
 return t;

}
static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec)
{
    int i, j;

    // Setting numvertexes to the same as numwalls is overly conservative,
    // but the extra vertices will be removed during the BSP building pass.
    numsides = numvertexes = numwalls;
    numlines = 0;

    sides = new side_t[numsides];
    memset (sides, 0, numsides*sizeof(side_t));

    vertexes = new vertex_t[numvertexes];
    numvertexes = 0;

    // First mark each sidedef with the sector it belongs to
    for (i = 0; i < numsectors; ++i)
    {
        if (bsec[i].wallptr >= 0)
        {
            for (j = 0; j < bsec[i].wallnum; ++j)
            {
                sides[j + bsec[i].wallptr].sector = sectors + i;
            }
        }
    }

    // Now copy wall properties to their matching sidedefs
    for (i = 0; i < numwalls; ++i)
    {
        char tnam[9];
        FTextureID overpic, pic;

        mysnprintf (tnam, countof(tnam), "BTIL%04d", LittleShort(walls[i].picnum));
        pic = TexMan.GetTexture (tnam, FTexture::TEX_Build);
        mysnprintf (tnam, countof(tnam), "BTIL%04d", LittleShort(walls[i].overpicnum));
        overpic = TexMan.GetTexture (tnam, FTexture::TEX_Build);

        walls[i].x = LittleLong(walls[i].x);
        walls[i].y = LittleLong(walls[i].y);
        walls[i].point2 = LittleShort(walls[i].point2);
        walls[i].cstat = LittleShort(walls[i].cstat);
        walls[i].nextwall = LittleShort(walls[i].nextwall);
        walls[i].nextsector = LittleShort(walls[i].nextsector);

        sides[i].SetTextureXOffset(walls[i].xpanning << FRACBITS);
        sides[i].SetTextureYOffset(walls[i].ypanning << FRACBITS);

        sides[i].SetTexture(side_t::top, pic);
        sides[i].SetTexture(side_t::bottom, pic);
        if (walls[i].nextsector < 0 || (walls[i].cstat & 32))
        {
            sides[i].SetTexture(side_t::mid, pic);
        }
        else if (walls[i].cstat & 16)
        {
            sides[i].SetTexture(side_t::mid, overpic);
        }
        else
        {
            sides[i].SetTexture(side_t::mid, FNullTextureID());
        }

        sides[i].TexelLength = walls[i].xrepeat * 8;
        sides[i].SetTextureYScale(walls[i].yrepeat << (FRACBITS - 3));
        sides[i].SetTextureXScale(FRACUNIT);
        sides[i].SetLight(SHADE2LIGHT(walls[i].shade));
        sides[i].Flags = WALLF_ABSLIGHTING;
        sides[i].RightSide = walls[i].point2;
        sides[walls[i].point2].LeftSide = i;

        if (walls[i].nextwall >= 0 && walls[i].nextwall <= i)
        {
            sides[i].linedef = sides[walls[i].nextwall].linedef;
        }
        else
        {
            sides[i].linedef = (line_t*)(intptr_t)(numlines++);
        }
    }

    // Set line properties that Doom doesn't store per-sidedef
    lines = new line_t[numlines];
    memset (lines, 0, numlines*sizeof(line_t));

    for (i = 0, j = -1; i < numwalls; ++i)
    {
        if (walls[i].nextwall >= 0 && walls[i].nextwall <= i)
        {
            continue;
        }

        j = int(intptr_t(sides[i].linedef));
        lines[j].sidedef[0] = (side_t*)(intptr_t)i;
        lines[j].sidedef[1] = (side_t*)(intptr_t)walls[i].nextwall;
        lines[j].v1 = FindVertex (walls[i].x, walls[i].y);
        lines[j].v2 = FindVertex (walls[walls[i].point2].x, walls[walls[i].point2].y);
        lines[j].frontsector = sides[i].sector;
        lines[j].flags |= ML_WRAP_MIDTEX;
        if (walls[i].nextsector >= 0)
        {
            lines[j].backsector = sectors + walls[i].nextsector;
            lines[j].flags |= ML_TWOSIDED;
        }
        else
        {
            lines[j].backsector = NULL;
        }
        P_AdjustLine (&lines[j]);
        if (walls[i].cstat & 128)
        {
            if (walls[i].cstat & 512)
            {
                lines[j].Alpha = FRACUNIT/3;
            }
            else
            {
                lines[j].Alpha = FRACUNIT*2/3;
            }
        }
        if (walls[i].cstat & 1)
        {
            lines[j].flags |= ML_BLOCKING;
        }
        if (walls[i].nextwall < 0)
        {
            if (walls[i].cstat & 4)
            {
                lines[j].flags |= ML_DONTPEGBOTTOM;
            }
        }
        else
        {
            if (walls[i].cstat & 4)
            {
                lines[j].flags |= ML_DONTPEGTOP;
            }
            else
            {
                lines[j].flags |= ML_DONTPEGBOTTOM;
            }
        }
        if (walls[i].cstat & 64)
        {
            lines[j].flags |= ML_BLOCKEVERYTHING;
        }
    }

    // Finish setting sector properties that depend on walls
    for (i = 0; i < numsectors; ++i, ++bsec)
    {
        SlopeWork slope;

        slope.wal = &walls[bsec->wallptr];
        slope.wal2 = &walls[slope.wal->point2];
        slope.dx = slope.wal2->x - slope.wal->x;
        slope.dy = slope.wal2->y - slope.wal->y;
        slope.i = long (sqrt ((double)(slope.dx*slope.dx+slope.dy*slope.dy))) << 5;
        if (slope.i == 0)
        {
            continue;
        }
        if ((bsec->floorstat & 2) && (bsec->floorheinum != 0))
        {   // floor is sloped
            slope.heinum = -LittleShort(bsec->floorheinum);
            slope.z[0] = slope.z[1] = slope.z[2] = -bsec->floorz;
            CalcPlane (slope, sectors[i].floorplane);
        }
        if ((bsec->ceilingstat & 2) && (bsec->ceilingheinum != 0))
        {   // ceiling is sloped
            slope.heinum = -LittleShort(bsec->ceilingheinum);
            slope.z[0] = slope.z[1] = slope.z[2] = -bsec->ceilingz;
            CalcPlane (slope, sectors[i].ceilingplane);
        }
        int linenum = int(intptr_t(sides[bsec->wallptr].linedef));
        int sidenum = int(intptr_t(lines[linenum].sidedef[1]));
        if (bsec->floorstat & 64)
        {   // floor is aligned to first wall
            P_AlignFlat (linenum, sidenum == bsec->wallptr, 0);
        }
        if (bsec->ceilingstat & 64)
        {   // ceiling is aligned to first wall
            P_AlignFlat (linenum, sidenum == bsec->wallptr, 0);
        }
    }
    for (i = 0; i < numlines; i++)
    {
        intptr_t front = intptr_t(lines[i].sidedef[0]);
        intptr_t back = intptr_t(lines[i].sidedef[1]);
        lines[i].sidedef[0] = front >= 0 ? &sides[front] : NULL;
        lines[i].sidedef[1] = back >= 0 ? &sides[back] : NULL;
    }
    for (i = 0; i < numsides; i++)
    {
        assert(sides[i].sector != NULL);
        sides[i].linedef = &lines[intptr_t(sides[i].linedef)];
    }
}
示例#6
0
Tetra *FastMakeTetra(Face *f, Point3 *v, int n, UG *G)
{
 Plane p;
 Tetra *t;
 float CellBoxRadius= 0.0,	/* Radius of Cell Box to scan for dd-nearest */
	BoxRadius,
	FaceRadius,
	MinRadius=BIGNUMBER;

 struct argGroup args;
 Line Lc;
 IntPoint3 vn,vp, start, end, inc;
 int Index=-1;
 boolean Found=FALSE;

 SI.MakeTetra++;

 UGResetMark(G);

 if(!CalcPlane(&(v[f->v[0]]),&(v[f->v[1]]),&(v[f->v[2]]),&p))
		Error("Faccia composta da tre punti allineati!!\n",EXIT);

 CalcLineofCenter(&(v[f->v[0]]),&(v[f->v[1]]),&(v[f->v[2]]),&Lc);

 FaceRadius=V3DistanceBetween2Points(&(Lc.Lu), &(v[f->v[0]]));

  args.f = f;
  args.Lc = &Lc;
  args.p = &p; 
  args.G = G;
 // printf("checkpoint 0\n");
 do
 {
  CellBoxRadius++;
  BoxRadius=CalcBox(f,v,&Lc,G,&vn,&vp, CellBoxRadius*FaceRadius);

  Found=ScanCellBox(&vn, &vp, v,&args,&Index, &MinRadius);
 }
 while(!Found && CellBoxRadius <= 1);
 //printf("checkpoint 1\n");
// printf("MinRadius = %f BoxRadius = %f\n",MinRadius, BoxRadius);
 if(Found && MinRadius>BoxRadius)
 {float oldMinRadius=MinRadius;

  SI.SecondBox++;
//  printf("f->v[0] = %d, f->v[1] = %d, f->v[2] = %d, sqrt(MinRadius) = %f\n",f->v[0],f->v[1],f->v[2], sqrt(MinRadius));
  BoxRadius=CalcBox(f,v,&Lc,G,&vn,&vp, sqrt(MinRadius));
 // printf("checkpoint 2\n");
//printf("vn->x = %d ,vn->y = %d, vn->z = %d, vp->x = %d, vp->y = %d, vp->z = %d, radius = %f\n",vn.x, vn.y, vn.z, vp.x, vp.y,vp.z,MinRadius);


  ScanCellBox(&vn, &vp, v, &args, &Index, &MinRadius);
   //printf("checkpoint 2.1\n");
  if(oldMinRadius>MinRadius) SI.UsefulSecondBox++;
 }
 
 if(!Found)
 {
  //printf("checkpoint 3\n");
  SI.EmptyBox++;
  CalcLastScan(G, &start, &end, &inc, &p);
  //printf("checkpoint 4\n"); 
  Found=MakeLastScan(&start, &end, &inc, v, &args, &Index,&MinRadius);
 }
 //printf("chekpoint 5\n");
 if(!Found) return NULL;
 if(MinRadius>0)
 {
  SI.MinRadius+=sqrt(MinRadius);
  SI.MinRadiusNum++;
 }


 t=BuildTetra(f,Index);
 if(StatFlag)
 {Point3 C;
  CalcSphereCenter(&(v[f->v[0]]),&(v[f->v[1]]),&(v[f->v[2]]),&(v[Index]),&C);
  SI.Radius+=V3DistanceBetween2Points(&C, &(v[Index]));
 }
 if(CheckFlag)  CheckTetra(t,v,n);

 return t;
}