예제 #1
0
파일: modify.cpp 프로젝트: paud/d2x-xl
void CMine::EditGeoFwd ()
{
  double x,y,z;
  double radius;
  vms_vector center,opp_center;
  int i;
/* calculate center of current side */
    center.x = center.y = center.z = 0;
    for (i = 0; i < 4; i++) {
		 int vertnum = Segments (Current ()->segment)->verts [side_vert [Current ()->side][i]];
      center.x += Vertices (vertnum)->x;
      center.y += Vertices (vertnum)->y;
      center.z += Vertices (vertnum)->z;
    }
   center.x /= 4;
   center.y /= 4;
   center.z /= 4;

// calculate center of opposite of current side
    opp_center.x = opp_center.y = opp_center.z = 0;
    for (i = 0; i < 4; i++) {
		 int vertnum = Segments (Current ()->segment)->verts [opp_side_vert [Current ()->side][i]];
      opp_center.x += Vertices (vertnum)->x;
      opp_center.y += Vertices (vertnum)->y;
      opp_center.z += Vertices (vertnum)->z;
    }
   opp_center.x /= 4;
   opp_center.y /= 4;
   opp_center.z /= 4;

// normalize vector
    x = center.x - opp_center.x;
    y = center.y - opp_center.y;
    z = center.z - opp_center.z;

// normalize direction
    radius = sqrt(x*x + y*y + z*z);

    if (radius > (F1_0/10)) {
      x /= radius;
      y /= radius;
      z /= radius;
    } else {
      vms_vector direction;
      CalcOrthoVector(direction,Current ()->segment,Current ()->side);
      x = (double)direction.x/(double)F1_0;
      y = (double)direction.y/(double)F1_0;
      z = (double)direction.z/(double)F1_0;
    }

// move on x, y, and z
	 theApp.SetModified (TRUE);
	 theApp.LockUndo ();
    MoveOn('X', (INT32) (x*move_rate));
    MoveOn('Y', (INT32) (y*move_rate));
    MoveOn('Z', (INT32) (z*move_rate));
	 theApp.UnlockUndo ();
}
예제 #2
0
파일: light.cpp 프로젝트: paud/d2x-xl
void CMine::CalcAverageCornerLight (bool bAll)
{
  int segnum,pt,i,vertnum,count,sidenum,uvnum;
  UINT16 max_brightness;

// smooth corner light by averaging all corners which share a vertex
theApp.SetModified (TRUE);
for (vertnum = 0; vertnum < VertCount (); vertnum++) {
	if (bAll || (*VertStatus (vertnum) & MARKED_MASK)) {
		max_brightness = 0;
		count = 0;
		// find all Segments () which share this point
		CDSegment *seg = Segments ();
		for (segnum = 0; segnum < SegCount (); segnum++, seg++) {
			for (pt = 0; pt < 8; pt++) {
				if (seg->verts[pt] == vertnum) {
					// add all the uvls for this point
					for (i = 0; i < 3; i++) {
						sidenum = point_sides[pt][i];
						uvnum = point_corners[pt][i];
						if ((seg->children[sidenum] < 0) || 
							 (seg->sides[sidenum].nWall < GameInfo ().walls.count)) {
							max_brightness = max(max_brightness,(UINT16)seg->sides[sidenum].uvls[uvnum].l);
							count++;
							}
						}
					}
				}
			}
		// now go back and set these light values
		if (count > 0) {
			theApp.SetModified (TRUE);
			//	max_brightness = min(max_brightness,0x8000L);
			CDSegment *seg = Segments ();
			for (segnum=0;segnum<SegCount ();segnum++, seg++) {
				for (pt=0;pt<8;pt++) {
					if (seg->verts[pt] == vertnum) {
						for (i=0;i<3;i++) {
							sidenum = point_sides[pt][i];
							uvnum = point_corners[pt][i];
							if ((seg->children[sidenum] < 0) || 
								 (seg->sides[sidenum].nWall < GameInfo ().walls.count)) {
								seg->sides[sidenum].uvls[uvnum].l = max_brightness;
								}
							}
						}
					}
				}
			}
		}
	}
}
예제 #3
0
파일: light.cpp 프로젝트: paud/d2x-xl
void CMine::AutoAdjustLight (double fLightScale, bool bAll, bool bCopyTexLights) 
{
	int			segnum;
	int			texture_num;
	int			sidenum;
	UINT32		brightness;
	CDSegment	*seg;
	CDSide		*side;

// clear all lighting on marked cubes
theApp.SetModified (TRUE);
theApp.LockUndo ();
if (bAll)
	memset (VertexColors (), 0, sizeof (MineData ().vertexColors));
for (segnum = SegCount (), seg = Segments (); segnum; segnum--, seg++)
	if (bAll || (seg->wall_bitmask & MARKED_MASK))
		for (sidenum=0, side = seg->sides;sidenum < MAX_SIDES_PER_SEGMENT; sidenum++, side++) {
			int i;
			for (i = 0; i < 4; i++) {
				side->uvls [i].l = 0;
				if (!bAll)
					memset (VertexColors (seg->verts [side_vert [sidenum][i]]), 0, sizeof (CDColor));
				}
			}

// Calculate cube side corner light values
// for each marked side in the level
// (range: 0 = min, 0x8000 = max)
for (segnum = 0, seg = Segments (); segnum < SegCount (); segnum++, seg++) {
	for (sidenum = 0, side = seg->sides; sidenum < 6; sidenum++, side++) {
		if (!(bAll || SideIsMarked (segnum, sidenum)))
			continue;
		if ((seg->children [sidenum] >= 0) && !VisibleWall (side->nWall))
			continue;
		if (bCopyTexLights)
			memset (LightColor (segnum, sidenum, false), 0, sizeof (CDColor));
		brightness = 0;
		texture_num = side->nBaseTex;
		if ((texture_num >= 0) && (texture_num < MAX_TEXTURES))
			brightness = max (brightness, LightWeight (texture_num));
		texture_num = side->nOvlTex & 0x3fff;
		if ((texture_num > 0) && (texture_num < MAX_TEXTURES))
			brightness = max (brightness, LightWeight (texture_num));
		if (brightness > 0)
			Illuminate (segnum, sidenum, (UINT32) (brightness * 2 * fLightScale), 1.0, bAll, bCopyTexLights);
		}
	}
theApp.UnlockUndo ();
}
예제 #4
0
파일: light.cpp 프로젝트: paud/d2x-xl
CDColor *CMine::LightColor (int i, int j, bool bUseTexColors) 
{ 
if (bUseTexColors && UseTexColors ()) {
	CDWall *pWall = SideWall (i, j);
	//if (!pWall || (pWall->type != WALL_TRANSPARENT)) 
		{	//always use a side color for transp. walls
		CDColor *pc;
		INT16 t = Segments (i)->sides [j].nOvlTex & 0x3fff;
		if ((t > 0) && (pc = GetTexColor (t)))
			return pc;
		if (pc = GetTexColor (Segments (i)->sides [j].nBaseTex, pWall && (pWall->type == WALL_TRANSPARENT)))
			return pc;
		}
	}	
return MineData ().lightColors [i] + j; 
}
예제 #5
0
파일: light.cpp 프로젝트: paud/d2x-xl
void CMine::SetCubeLight (double fLight, bool bAll, bool bDynCubeLights)
{
	long nLight = (long) (fLight * 65536); //24.0 * 327.68);
	CDSegment *seg;
	int	h, i, j, l, c, segnum;

theApp.SetModified (TRUE);
fLight /= 100.0;
for (segnum = SegCount (), seg = Segments (); segnum; segnum--, seg++) {
	if (bAll || (seg->wall_bitmask & MARKED_MASK)) {
		if (!bDynCubeLights)
			seg->static_light = nLight;
		else {
			l = 0;
			c = 0;
			for (j = 0; j < 6; j++) {
				for (i = 0; i < 4; i++) {
					h = (UINT16) seg->sides [j].uvls [i].l;
					if (h || ((seg->children [j] == -1) && !VisibleWall (seg->sides [j].nWall))) {
						l += h;
						c++;
						}
					}
				}
			seg->static_light = (FIX) (c ? fLight * ((double) l / (double) c) * 2 : nLight);
			}
		}
	}
}
예제 #6
0
void Track::GetPointLists(std::list< std::list<wxPoint> > &pointlists,
                          ViewPort &VP, const LLBBox &box )
{
    if( !IsVisible() || GetnPoints() == 0 ) return;
    Finalize();
//    OCPNStopWatch sw;
    Segments(pointlists, box, VP.view_scale_ppm);

#if 0
    if(GetnPoints() > 40000) {
        double t = sw.GetTime();
        double c = 0;
        for(std::list< std::list<wxPoint> >::iterator lines = pointlists.begin();
        lines != pointlists.end(); lines++) {
            if(lines->size() > 1)
                c += lines->size();
                continue;
        }
        printf("assemble time %f %f segments %f seg/ms\n", sw.GetTime(), c, c/t);
    }
#endif

    //    Add last segment, dynamically, maybe.....
    // we should not add this segment if it is not on the screen...
    if( IsRunning() ) {
        std::list<wxPoint> new_list;
        pointlists.push_back(new_list);
        AddPointToList(pointlists, TrackPoints.size()-1);
        wxPoint r;
        cc1->GetCanvasPointPix( gLat, gLon, &r );
        pointlists.back().push_back(r);
    }
}
예제 #7
0
int main(void)
{
DIO_voidInit();
SSD_voidInit();
p[0] = letterA;
p[1] = letterN;
p[2] = letterW;
p[3] = letterA;
p[4] = letterR;
DIO_u8WritePinVal(otpt_pin,0);  // output enable
DIO_u8WritePinVal(sh_clk,0);  // output enable


	while(1)
{

	Segments();
//for(u8 ii=0;ii<5;ii++)
//		{
//		DIO_u8WritePinVal(16,1);
//for(u8 i=0;i<50;i++)
//{
//		(*p[0])();
//}
//	DIO_u8WritePinVal(16,0);
//}
}
return 0;
}
예제 #8
0
파일: light.cpp 프로젝트: paud/d2x-xl
void CMine::UnlinkSeg (CDSegment *pSegment, CDSegment *pRoot)
{
#if 0
	INT16	prevSeg = pSegment->prevSeg;
	INT16	nextSeg = pSegment->nextSeg;
	INT16	thisSeg = pSegment - Segments ();

CBRK ((prevSeg >= 0) && (Segments (prevSeg)->nextSeg < 0));
if (prevSeg >= 0) {
	Segments () [prevSeg].nextSeg = nextSeg;
	pSegment->prevSeg = -1;
	}
if (nextSeg >= 0) {
	Segments () [nextSeg].prevSeg = prevSeg;
	pSegment->nextSeg = -1;
	}
#endif
}
예제 #9
0
파일: light.cpp 프로젝트: paud/d2x-xl
void CMine::ScaleCornerLight (double fLight, bool bAll) 
{
	int segnum,j,i;
	double scale;
	CDSegment *seg;

theApp.SetModified (TRUE);
scale = fLight / 100.0; // 100.0% = normal
for (segnum = 0, seg = Segments (); segnum < SegCount (); segnum++, seg++)
	if (bAll || (seg->wall_bitmask & MARKED_MASK))
		for (j = 0; j < 6; j++)
			for (i = 0; i < 4; i++) {
				fLight = ((double) ((UINT16) seg->sides [j].uvls [i].l)) * scale;
				fLight = min (fLight, 0x8000);
				fLight = max (fLight, 0);
				Segments (segnum)->sides[j].uvls[i].l = (UINT16) fLight;
				}
}
예제 #10
0
파일: light.cpp 프로젝트: paud/d2x-xl
void CMine::LinkSeg (CDSegment *pSegment, CDSegment *pRoot)
{
#if 0
	INT16	prevSeg = pRoot->prevSeg;
	INT16	nextSeg = pRoot->nextSeg;
	INT16 thisSeg = pSegment - Segments ();
	INT16 rootSeg = pRoot - Segments ();

if (prevSeg < 0) {
	pRoot->nextSeg = thisSeg;
	}
else {
	Segments () [prevSeg].nextSeg = thisSeg;
	pSegment->prevSeg = prevSeg;
	}
pRoot->prevSeg = thisSeg;
pSegment->nextSeg = rootSeg;
pSegment->rootSeg = rootSeg;
#endif
}
예제 #11
0
bool ReceiveBuffer::addSource( const size_t sourceIndex )
{
    assert( !_sourceBuffers.count( sourceIndex ));

    // TODO: This function must return false if the stream was already started!
    // This requires an full adaptation of the Stream library (DISCL-241)
    if ( _sourceBuffers.count( sourceIndex ))
        return false;

    _sourceBuffers[sourceIndex] = SourceBuffer();
    _sourceBuffers[sourceIndex].segments.push( Segments( ));
    return true;
}
예제 #12
0
파일: light.cpp 프로젝트: paud/d2x-xl
void CMine::SetSegmentChildNum (CDSegment *pRoot, INT16 segnum,INT16 recursion_level) 
{
	INT16			sidenum, child, nImprove = 0;
	UINT16		nWall;
	CDSegment	*seg = Segments () + segnum;
	CDSegment	*prevSeg = NULL;
	bool			bMarkChildren = false;

// mark each child if child number is lower
for (sidenum = 0; sidenum < MAX_SIDES_PER_SEGMENT; sidenum++) {
	// Skip if this is a door
	nWall = seg->sides [sidenum].nWall;
	// .. if there is a wall and its a door
	if ((nWall < GameInfo ().walls.count) && (Walls (nWall)->type == WALL_DOOR))
		continue;
	// mark segment if it has a child
	child = seg->children [sidenum];
	if ((child > -1) && (child < SegCount ()) && (recursion_level > seg->seg_number)) {
		if (seg->seg_number >= 0)
			++nImprove;
/*
		if (pRoot) {
			UnlinkSeg (seg, pRoot);
			LinkSeg (seg, pRoot);
			}
*/
		seg->seg_number = recursion_level;
		bMarkChildren = true;
		break;
		}
	}
//return if segment has no children or max recursion depth is reached
if (!bMarkChildren || (recursion_level == 1))
	return;

// check each side of this segment for more children
for (sidenum = 0; sidenum < MAX_SIDES_PER_SEGMENT; sidenum++) {
	// skip if there is a wall and its a door
	nWall = seg->sides [sidenum].nWall;
	if ((nWall < GameInfo ().walls.count) && (Walls (nWall)->type == WALL_DOOR))
		continue;
	// check child
	child = seg->children [sidenum];
	if ((child > -1) && (child < SegCount ()))
		SetSegmentChildNum (pRoot, child, recursion_level - 1);
	}
}
예제 #13
0
void SourceBuffer::push(const View view)
{
    _getQueue(view).push(Segments());
    ++_backFrameIndex[as_underlying_type(view)];
}
예제 #14
0
파일: modify.cpp 프로젝트: paud/d2x-xl
void CMine::RotateSelection (double angle, bool perpendicular) 
{
int nSegment = Current ()->segment;
int nSide = Current ()->side;
CDSegment *seg = Segments (nSegment);
vms_vector center,opp_center;
int i,pts [4];

switch (m_selectMode){
	case POINT_MODE:
	ErrorMsg("Cannot bend a point");
	break; /* can't spin a point */
	case LINE_MODE:
	ErrorMsg("Cannot bend a line");
	break; /* line spinning not supported */
	case SIDE_MODE:	// spin side around the opposite side
		theApp.SetModified (TRUE);
		theApp.LockUndo ();
		if (perpendicular) { // use lines 0 and 2
			pts [0] = 1;
			pts [1] = 2;
			pts [2] = 3;
			pts [3] = 0;
			} 
		else {             // use lines 1 and 3
			pts [0] = 0;
			pts [1] = 1;
			pts [2] = 2;
			pts [3] = 3;
			}
		// calculate center opp side line 0
		opp_center.x = (Vertices (seg->verts [opp_side_vert [nSide][pts [0]]])->x +
							 Vertices (seg->verts [opp_side_vert [nSide][pts [1]]])->x) / 2;
		opp_center.y = (Vertices (seg->verts [opp_side_vert [nSide][pts [0]]])->y +
							 Vertices (seg->verts [opp_side_vert [nSide][pts [1]]])->y) / 2;
		opp_center.z = (Vertices (seg->verts [opp_side_vert [nSide][pts [0]]])->z +
							 Vertices (seg->verts [opp_side_vert [nSide][pts [1]]])->z) / 2;
		// calculate center opp side line 2
		center.x = (Vertices (seg->verts [opp_side_vert [nSide][pts [2]]])->x +
						Vertices (seg->verts [opp_side_vert [nSide][pts [3]]])->x) / 2;
		center.y = (Vertices (seg->verts [opp_side_vert [nSide][pts [2]]])->y +
						Vertices (seg->verts [opp_side_vert [nSide][pts [3]]])->y) / 2;
		center.z = (Vertices (seg->verts [opp_side_vert [nSide][pts [2]]])->z +
						Vertices (seg->verts [opp_side_vert [nSide][pts [3]]])->z) / 2;
		// rotate points around a line
		for (i = 0; i < 4; i++)
			RotateVertex (Vertices (seg->verts [side_vert [nSide][i]]),
							  &center, &opp_center, angle);
		theApp.UnlockUndo ();	
		break;
	
	case CUBE_MODE:
		ErrorMsg("Cannot bend a cube");
		break; /* can't spin a point */
	
	case OBJECT_MODE:
		ErrorMsg("Cannot bend a object");
		break; /* can't spin a point */

	case BLOCK_MODE:
		ErrorMsg("Cannot bend a block");
		break; /* can't spin a point */
	}
}
예제 #15
0
파일: modify.cpp 프로젝트: paud/d2x-xl
void CMine::SizeItem (INT32 inc) 
{
	int nSegment = Current ()->segment;
	int nSide = Current ()->side;
	CDSegment *seg = Segments (nSegment);
	int i, j, point [4];

switch (m_selectMode) {
	case POINT_MODE:
		break;

	case LINE_MODE:
		point [0] = line_vert [side_line [Current ()->side][Current ()->line]][0];
		point [1] = line_vert [side_line [Current ()->side][Current ()->line]][1];
		SizeLine(seg,point [0],point [1],inc);
		break;

	case SIDE_MODE:
		theApp.SetModified (TRUE);
		theApp.LockUndo ();
		for (i = 0; i < 4; i++)
			point [i] = side_vert [Current ()->side][i];
		// enlarge the diagonals
		SizeLine(seg,point [0],point [2],(INT32) (inc*sqrt(2.0)));
		SizeLine(seg,point [1],point [3],(INT32) (inc*sqrt(2.0)));
		theApp.UnlockUndo ();
		break;

	case CUBE_MODE:
		// enlarge the diagonals
		theApp.SetModified (TRUE);
		theApp.LockUndo ();
		SizeLine(seg,0,6,(INT32) (inc*sqrt(3.0)));
		SizeLine(seg,1,7,(INT32) (inc*sqrt(3.0)));
		SizeLine(seg,2,4,(INT32) (inc*sqrt(3.0)));
		SizeLine(seg,3,5,(INT32) (inc*sqrt(3.0)));
		theApp.UnlockUndo ();
		break;

	case OBJECT_MODE:
		break;

	case BLOCK_MODE:
		theApp.SetModified (TRUE);
		vms_vector max_pt, min_pt, center, *verts;
		UINT8 *vstats;
		max_pt.x = -0x7fffffffL;
		max_pt.y = -0x7fffffffL;
		max_pt.z = -0x7fffffffL;
		min_pt.x =  0x7fffffffL;
		min_pt.y =  0x7fffffffL;
		min_pt.z =  0x7fffffffL;
		verts = Vertices ();
		vstats = VertStatus ();
		j = 0;
		for (i = VertCount (), j = 0; j < i; j++, verts++, vstats++)
			if (*vstats & MARKED_MASK) {
				max_pt.x = max (max_pt.x, verts->x);
				max_pt.y = max (max_pt.y, verts->y);
				max_pt.z = max (max_pt.z, verts->z);
				min_pt.x = min (min_pt.x, verts->x);
				min_pt.y = min (min_pt.y, verts->y);
				min_pt.z = min (min_pt.z, verts->z);
				}
		center.x = (max_pt.x + min_pt.x) / 2;
		center.y = (max_pt.y + min_pt.y) / 2;
		center.z = (max_pt.z + min_pt.z) / 2;
		double scale = ((double)(20*F1_0) + (double)inc)/(double)(20*F1_0);
		verts = Vertices ();
		vstats = VertStatus ();
		for (i = VertCount (), j = 0; j < i; j++, verts++, vstats++)
			if (*vstats & MARKED_MASK) {
				verts->x = center.x + (long) ((verts->x - center.x) * scale);
				verts->y = center.y + (long) ((verts->y - center.y) * scale);
				verts->z = center.z + (long) ((verts->z - center.z) * scale);
				}
	break;
	}
}
예제 #16
0
파일: modify.cpp 프로젝트: paud/d2x-xl
void CMine::MovePoints(int pt0, int pt1) 
{
	vms_vector *vector0,*vector1,delta;
	int point0,point1;
	double length;
	int point;
	int i;
	vms_vector *vect;

point0  = side_vert [Current ()->side][CURRENT_POINT(pt0)];
point1  = side_vert [Current ()->side][CURRENT_POINT(pt1)];
vector0 = Vertices (Segments (Current ()->segment)->verts [point0]);
vector1 = Vertices (Segments (Current ()->segment)->verts [point1]);
length  = CalcLength(vector0,vector1);
if (length >= F1_0) {
	delta.x = (FIX)(((double)(vector1->x - vector0->x) * (double)move_rate)/length);
	delta.y = (FIX)(((double)(vector1->y - vector0->y) * (double)move_rate)/length);
	delta.z = (FIX)(((double)(vector1->z - vector0->z) * (double)move_rate)/length);
	} 
else {
	delta.x = move_rate;
	delta.y = 0;
	delta.z = 0;
	}

switch (m_selectMode){
	case POINT_MODE:
		point = side_vert [Current ()->side][CURRENT_POINT(0)];
		vect  = Vertices (Segments (Current ()->segment)->verts [point]);
		vect->x += delta.x;
		vect->y += delta.y;
		vect->z += delta.z;
		theApp.SetModified (TRUE);
		break;

	case LINE_MODE:
		point = side_vert [Current ()->side][CURRENT_POINT(0)];
		vect  = Vertices (Segments (Current ()->segment)->verts [point]);
		vect->x += delta.x;
		vect->y += delta.y;
		vect->z += delta.z;
		point = side_vert [Current ()->side][CURRENT_POINT(1)];
		vect  = Vertices (Segments (Current ()->segment)->verts [point]);
		vect->x += delta.x;
		vect->y += delta.y;
		vect->z += delta.z;
		theApp.SetModified (TRUE);
		break;

	case SIDE_MODE:
		for (i = 0; i < 4; i++) {
			point = side_vert [Current ()->side][i];
			vect  = Vertices (Segments (Current ()->segment)->verts [point]);
			vect->x += delta.x;
			vect->y += delta.y;
			vect->z += delta.z;
			}
		theApp.SetModified (TRUE);
		break;

	case CUBE_MODE:
		for (i = 0; i < 8; i++) {
			vect = Vertices (Segments (Current ()->segment)->verts [i]);
			vect->x += delta.x;
			vect->y += delta.y;
			vect->z += delta.z;
			}
		theApp.SetModified (TRUE);
		break;

	case OBJECT_MODE:
		CurrObj ()->pos.x += delta.x;
		CurrObj ()->pos.y += delta.y;
		CurrObj ()->pos.z += delta.z;
		theApp.SetModified (TRUE);
		break;

	case BLOCK_MODE:
		bool bMoved = false;
		for (i = 0; i < MAX_VERTICES; i++) {
			if (*VertStatus (i) & MARKED_MASK) {
				Vertices (i)->x += delta.x;
				Vertices (i)->y += delta.y;
				Vertices (i)->z += delta.z;
				bMoved = true;
				}
			}
		theApp.SetModified (bMoved);
		break;
	}
}
예제 #17
0
파일: modify.cpp 프로젝트: paud/d2x-xl
void CMine::MoveOn (char axis,INT32 inc) 
{
int nSegment = Current ()->segment;
int nSide = Current ()->side;
int nPoint = Current ()->point;
int nLine = Current ()->line;
CDSegment *seg = Segments (nSegment);
INT16 i;

theApp.SetModified (TRUE);
switch (m_selectMode) {
	case POINT_MODE:
		switch (axis) {
			case 'X':
				Vertices (seg->verts [side_vert [nSide][nPoint]])->x += inc;
				break;
			case 'Y':
				Vertices (seg->verts [side_vert [nSide][nPoint]])->y += inc;
				break;
			case 'Z':
				Vertices (seg->verts [side_vert [nSide][nPoint]])->z += inc;
				break;
			}
		break;

	case LINE_MODE:
		switch (axis) {
			case 'X':
				Vertices (seg->verts [line_vert [side_line [nSide][nLine]][0]])->x += inc;
				Vertices (seg->verts [line_vert [side_line [nSide][nLine]][1]])->x += inc;
				break;
			case 'Y':
				Vertices (seg->verts [line_vert [side_line [nSide][nLine]][0]])->y += inc;
				Vertices (seg->verts [line_vert [side_line [nSide][nLine]][1]])->y += inc;
				break;
			case 'Z':
				Vertices (seg->verts [line_vert [side_line [nSide][nLine]][0]])->z += inc;
				Vertices (seg->verts [line_vert [side_line [nSide][nLine]][1]])->z += inc;
				break;
			}
		break;

	case SIDE_MODE:
		switch (axis) {
			case 'X':
			for (i = 0; i < 4; i++)
				Vertices (seg->verts [side_vert [nSide][i]])->x += inc;
			break;
		case 'Y':
			for (i = 0; i < 4; i++)
				Vertices (seg->verts [side_vert [nSide][i]])->y += inc;
			break;
		case 'Z':
			for (i = 0; i < 4; i++)
				Vertices (seg->verts [side_vert [nSide][i]])->z += inc;
			break;
		}
		break;

	case CUBE_MODE:
		switch (axis) {
			case 'X':
				for (i = 0; i < 8; i++)
					Vertices (seg->verts [i])->x += inc;
				for (i = 0; i < GameInfo ().objects.count; i++)
					if (Objects (i)->segnum == nSegment)
						Objects (i)->pos.x += inc;
				break;
			case 'Y':
				for (i = 0; i < 8; i++)
					Vertices (seg->verts [i])->y += inc;
				for (i = 0; i < GameInfo ().objects.count; i++) 
					if (Objects (i)->segnum == nSegment)
						Objects (i)->pos.y += inc;
				break;
			case 'Z':
				for (i = 0; i < 8; i++)
					Vertices (seg->verts [i])->z += inc;
				for (i = 0; i < GameInfo ().objects.count; i++) 
					if (Objects (i)->segnum == nSegment) 
						Objects (i)->pos.z += inc;
				break;
			}
	break;

	case OBJECT_MODE:
		switch (axis) {
			case 'X':
				CurrObj ()->pos.x += inc;
				break;
			case 'Y':
				CurrObj ()->pos.y += inc;
				break;
			case 'Z':
				CurrObj ()->pos.z += inc;
				break;
		}
	break;

	case BLOCK_MODE:
		CDObject *obj = Objects ();
		switch (axis) {
			case 'X':
				for (i = 0; i < MAX_VERTICES; i++)
					if (*VertStatus (i) & MARKED_MASK)
						Vertices (i)->x += inc;
				for (i = GameInfo ().objects.count; i; i--, obj++)
					if (obj->segnum >= 0)
						if (Segments (obj->segnum)->wall_bitmask & MARKED_MASK)
							obj->pos.x += inc;
				break;
			case 'Y':
				for (i = 0; i < MAX_VERTICES; i++)
					if (*VertStatus (i) & MARKED_MASK)
						Vertices (i)->y += inc;
				for (i = GameInfo ().objects.count; i; i--, obj++)
					if (obj->segnum >= 0)
						if (Segments (obj->segnum)->wall_bitmask & MARKED_MASK)
							obj->pos.y += inc;
				break;
			case 'Z':
				for (i = 0; i < MAX_VERTICES; i++)
					if (*VertStatus (i) & MARKED_MASK)
						Vertices (i)->z += inc;
				for (i = GameInfo ().objects.count; i; i--, obj++)
					if (obj->segnum >= 0)
						if (Segments (obj->segnum)->wall_bitmask & MARKED_MASK)
							obj->pos.z += inc;
				break;
		}
	break;
	}
}
예제 #18
0
파일: light.cpp 프로젝트: paud/d2x-xl
bool CMine::CalcSideLights (int segnum, int sidenum, vms_vector& source_center, 
									 vms_vector *source_corner, vms_vector& A, double *effect,
									 double fLightScale, bool bIgnoreAngle)
{
	CDSegment *seg = Segments (segnum);
// calculate vector between center of source segment and center of child
vms_vector B,center;
CalcCenter (center,segnum,sidenum);
B.x = center.x - source_center.x;
B.y = center.y - source_center.y;
B.z = center.z - source_center.z;

// calculate angle between vectors (use dot product equation)
if (!bIgnoreAngle) {
	double ratio,angle;
	double A_dot_B = (double)A.x * (double)B.x
						+ (double)A.y * (double)B.y
						+ (double)A.z * (double)B.z;
	double mag_A = my_sqrt( (double)A.x*(double)A.x
						+(double)A.y*(double)A.y
						+(double)A.z*(double)A.z);
	double mag_B = my_sqrt( (double)B.x*(double)B.x
						+(double)B.y*(double)B.y
						+(double)B.z*(double)B.z);
	if (mag_A == 0 || mag_B == 0)
		angle = (200.0 * M_PI)/180.0; // force a failure
	else {
		ratio = A_dot_B/(mag_A * mag_B);
		ratio = ((double)((int)(ratio*1000.0))) / 1000.0;
		if (ratio < -1.0 || ratio > (double)1.0)
			angle = (199.0 * M_PI)/180.0;  // force a failure
		else
			angle = acos(ratio);
		}
	// if angle is less than 110 degrees
	// then we found a match
	if (angle >= (180.0 * M_PI)/180.0)
		return false;
	}
int i, j;
for (j = 0; j < 4; j++) {
	vms_vector corner;
	int vertnum = side_vert[sidenum][j];
	int h = seg->verts[vertnum];
	corner.x = Vertices (h)->x;
	corner.y = Vertices (h)->y;
	corner.z = Vertices (h)->z;
	double length = 20.0 * m_lightRenderDepth;
	for (i = 0; i < 4; i++)
		length = min (length, CalcLength (source_corner + i, &corner) / F1_0);
	length /= 10.0 * m_lightRenderDepth / 6.0; // divide by 1/2 a cubes length so opposite side
	// light is recuded by 1/4
	effect [j] = 32;
	if (length > 1.0)//if (length < 20.0 * m_lightRenderDepth) // (roughly 4 standard cube lengths)
		effect [j] /= (length * length);
	effect [j] *= fLightScale;
//	else
//		effect [j] = 0;
	}
// if any of the effects are > 0, then increment the
// light for that side
return (effect [0] != 0 || effect [1] != 0 || effect [2] != 0 || effect [3] != 0);
}
예제 #19
0
파일: modify.cpp 프로젝트: paud/d2x-xl
void CMine::SpinSelection(double angle) 
{
	int nSegment = Current ()->segment;
	int nSide = Current ()->side;
	CDSegment *seg = Segments (nSegment);
	CDObject *obj;
	vms_vector center,opp_center;
	INT16 i;

#ifdef SPIN_RELATIVE
	double xspin,yspin,zspin;
	vms_vector rel [3];
#endif

/* calculate segment pointer */
switch (m_selectMode) {
	case POINT_MODE:
		ErrorMsg ("Cannot spin a point");
		break; /* can't spin a point */
	
	case LINE_MODE:
		ErrorMsg ("Cannot spin a line");
		break; /* line spinning not supported */
	
	case SIDE_MODE: // spin side around its center in the plane of the side
		// calculate center of current side
		theApp.SetModified (TRUE);
		center.x = center.y = center.z = 0;
		for (i = 0; i < 4; i++) {
			center.x += Vertices (seg->verts [side_vert [nSide][i]])->x;
			center.y += Vertices (seg->verts [side_vert [nSide][i]])->y;
			center.z += Vertices (seg->verts [side_vert [nSide][i]])->z;
			}
		center.x /= 4;
		center.y /= 4;
		center.z /= 4;
		// calculate orthogonal vector from lines which intersect point 0
		//       |x  y  z |
		// AxB = |ax ay az| = x(aybz-azby), y(azbx-axbz), z(axby-aybx)
		//       |bx by bz|
		struct vector {double x,y,z;};
		struct vector a,b,c;
		double length;
		INT16 vertnum1,vertnum2;

		vertnum1 = seg->verts [side_vert [nSide][0]];
		vertnum2 = seg->verts [side_vert [nSide][1]];
		a.x = (double)(Vertices (vertnum2)->x - Vertices (vertnum1)->x);
		a.y = (double)(Vertices (vertnum2)->y - Vertices (vertnum1)->y);
		a.z = (double)(Vertices (vertnum2)->z - Vertices (vertnum1)->z);
		vertnum1 = seg->verts [side_vert [nSide][0]];
		vertnum2 = seg->verts [side_vert [nSide][3]];
		b.x = (double)(Vertices (vertnum2)->x - Vertices (vertnum1)->x);
		b.y = (double)(Vertices (vertnum2)->y - Vertices (vertnum1)->y);
		b.z = (double)(Vertices (vertnum2)->z - Vertices (vertnum1)->z);
		c.x = a.y*b.z - a.z*b.y;
		c.y = a.z*b.x - a.x*b.z;
		c.z = a.x*b.y - a.y*b.x;
		// normalize the vector
		length = sqrt(c.x*c.x + c.y*c.y + c.z*c.z);
		c.x /= length;
		c.y /= length;
		c.z /= length;
		// set sign (since vert numbers for most sides don't follow right-handed convention)
		if (nSide!=1 && nSide!=5) {
			c.x = -c.x;
			c.y = -c.y;
			c.z = -c.z;
			}
		// set opposite center
		opp_center.x = center.x + (FIX)(0x10000L*c.x);
		opp_center.y = center.y + (FIX)(0x10000L*c.y);
		opp_center.z = center.z + (FIX)(0x10000L*c.z);
		/* rotate points around a line */
		for (i = 0; i < 4; i++) {
			RotateVertex(Vertices (seg->verts [side_vert [nSide][i]]),
			&center,&opp_center,angle);
			}
		break;


	case CUBE_MODE:	// spin cube around the center of the cube using screen's perspective
		// calculate center of current cube
		theApp.SetModified (TRUE);
		center.x = center.y = center.z = 0;
		for (i = 0; i < 8; i++) {
			center.x += Vertices (seg->verts [i])->x;
			center.y += Vertices (seg->verts [i])->y;
			center.z += Vertices (seg->verts [i])->z;
			}
		center.x /= 8;
		center.y /= 8;
		center.z /= 8;
		// calculate center of oppisite current side
		opp_center.x = opp_center.y = opp_center.z = 0;
		for (i = 0; i < 4; i++) {
			opp_center.x += Vertices (seg->verts [opp_side_vert [nSide][i]])->x;
			opp_center.y += Vertices (seg->verts [opp_side_vert [nSide][i]])->y;
			opp_center.z += Vertices (seg->verts [opp_side_vert [nSide][i]])->z;
			}
		opp_center.x /= 4;
		opp_center.y /= 4;
		opp_center.z /= 4;
		// rotate points about a point
		for (i = 0; i < 8; i++)
			RotateVertex(Vertices (seg->verts [i]),&center,&opp_center,angle);
		break;

	case OBJECT_MODE:	// spin object vector
		theApp.SetModified (TRUE);
		vms_matrix *orient;
		orient = (Current ()->object == GameInfo ().objects.count) ? &SecretOrient () : &CurrObj ()->orient;
		switch (nSide) {
			case 0:
				RotateVmsMatrix(orient,angle,'x');
				break;
			case 2:
				RotateVmsMatrix(orient,-angle,'x');
				break;
			case 1:
				RotateVmsMatrix(orient,-angle,'y');
				break;
			case 3:
				RotateVmsMatrix(orient,angle,'y');
				break;
			case 4:
				RotateVmsMatrix(orient,angle,'z');
				break;
			case 5:
				RotateVmsMatrix(orient,-angle,'z');
				break;
			}
#ifdef SPIN_RELATIVE
		// calculate angles to spin the side into the x-y plane
		// use points 0,1, and 2 of the side
		// make point0 the origin
		// and get coordinates of points 1 and 2 relative to point 0
		for (i=0;i<3;i++) {
			rel [i].x = vertices [seg->verts [side_vert [nSide][i]]].x - vertices [seg->verts [side_vert [nSide][0]]].x;
			rel [i].y = vertices [seg->verts [side_vert [nSide][i]]].y - vertices [seg->verts [side_vert [nSide][0]]].y;
			rel [i].z = vertices [seg->verts [side_vert [nSide][i]]].z - vertices [seg->verts [side_vert [nSide][0]]].z;
			}
		// calculate z-axis spin angle to rotate point1 so it lies in x-y plane
		zspin = (rel [1].x==rel [1].y) ? PI/4 : atan2(rel [1].y,rel [1].x);
		// spin all 3 points on z axis
		for (i=0;i<3;i++)
			RotateVmsVector(&rel [i],zspin,'z');
		// calculate y-axis spin angle to rotate point1 so it lies on x axis
		yspin = (rel [1].z==rel [1].x) ? PI/4 : atan2(rel [1].z,rel [1].x);
		// spin points 1 and 2 on y axis (don't need to spin point 0 since it is at 0,0,0)
		for (i=1;i<=2;i++)
			RotateVmsVector(&rel [i],yspin,'y');
		// calculate x-axis spin angle to rotate point2 so it lies in x-y plane
		xspin = (rel [2].z==rel [2].y) ? PI/4 : atan2(rel [2].z,rel [2].y);
		// spin points 2 on x axis (don't need to spin point 1 since it is on the x-axis
		RotateVmsVector(&rel [2],xspin,'x');
		RotateVmsMatrix(&obj->orient,zspin,'z');
		RotateVmsMatrix(&obj->orient,yspin,'y');
		RotateVmsMatrix(&obj->orient,xspin,'x');
		RotateVmsMatrix(&obj->orient,-xspin,'x');
		RotateVmsMatrix(&obj->orient,-yspin,'y');
		RotateVmsMatrix(&obj->orient,-zspin,'z');
#endif //SPIN_RELATIVE
		break;

	case BLOCK_MODE:
		theApp.SetModified (TRUE);
		// calculate center of current cube
		center.x = center.y = center.z = 0;
		for (i = 0; i < 8; i++) {
			center.x += Vertices (seg->verts [i])->x;
			center.y += Vertices (seg->verts [i])->y;
			center.z += Vertices (seg->verts [i])->z;
			}
		center.x /= 8;
		center.y /= 8;
		center.z /= 8;
		// calculate center of oppisite current side
		opp_center.x = opp_center.y = opp_center.z = 0;
		for (i = 0; i < 4; i++) {
			opp_center.x += Vertices (seg->verts [opp_side_vert [nSide][i]])->x;
			opp_center.y += Vertices (seg->verts [opp_side_vert [nSide][i]])->y;
			opp_center.z += Vertices (seg->verts [opp_side_vert [nSide][i]])->z;
			}
		opp_center.x /= 4;
		opp_center.y /= 4;
		opp_center.z /= 4;
		// rotate points about a point
		for (i=0;i<VertCount ();i++)
			if (*VertStatus (i) & MARKED_MASK)
				RotateVertex(Vertices (i),&center,&opp_center,angle);
		// rotate Objects () within marked cubes
		obj = Objects ();
		for (i = GameInfo ().objects.count; i; i--, obj++)
			if (Segments (obj->segnum)->wall_bitmask & MARKED_MASK)
				RotateVertex(&obj->pos, &center, &opp_center, angle);
		break;
	}
}
예제 #20
0
파일: modify.cpp 프로젝트: paud/d2x-xl
void CMine::EditGeoBack() 
{
  vms_vector center,opp_center;
  double x,y,z,radius;
  int i;

/* calculate center of current side */
  center.x = center.y = center.z = 0;
  for (i = 0; i < 4; i++) {
	 int vertnum = Segments (Current ()->segment)->verts [side_vert [Current ()->side][i]];
    center.x += Vertices (vertnum)->x;
    center.y += Vertices (vertnum)->y;
    center.z += Vertices (vertnum)->z;
  }
  center.x /= 4;
  center.y /= 4;
  center.z /= 4;

// calculate center of oppisite current side
  opp_center.x = opp_center.y = opp_center.z = 0;
  for (i = 0; i < 4; i++) {
	 int vertnum = Segments (Current ()->segment)->verts [opp_side_vert [Current ()->side][i]];
    opp_center.x += Vertices (vertnum)->x;
    opp_center.y += Vertices (vertnum)->y;
    opp_center.z += Vertices (vertnum)->z;
  }
  opp_center.x /= 4;
  opp_center.y /= 4;
  opp_center.z /= 4;

// normalize vector
  x = center.x - opp_center.x;
  y = center.y - opp_center.y;
  z = center.z - opp_center.z;

  // make sure distance is positive to prevent
  // cube from turning inside out
#if 1
  // defines line orthogonal to a side at a point
  UINT8 orthog_line [6][4] = {
    {8,6,1,3},
    {0,5,7,2},
    {3,1,6,8},
    {2,7,5,0},
    {4,9,10,11},
    {11,10,9,4}
  };
  CDSegment *seg;
  INT16 point0,point1;
  vms_vector *vector0,*vector1;
  bool ok_to_move;

  ok_to_move = TRUE;
  seg = Segments () + Current ()->segment;
  switch (m_selectMode) {
    case POINT_MODE:
      point0 = line_vert [orthog_line [Current ()->side][Current ()->point]][0];
      point1 = line_vert [orthog_line [Current ()->side][Current ()->point]][1];
      vector0 = Vertices (seg->verts [point0]);
      vector1 = Vertices (seg->verts [point1]);
      if (CalcLength(vector0,vector1) - move_rate < F1_0 / 4) {
	ok_to_move = FALSE;
      }
      break;
    case LINE_MODE:
      for (i=0;i<2;i++) {
	point0 = line_vert [orthog_line [Current ()->side][(Current ()->line+i)%4]][0];
	point1 = line_vert [orthog_line [Current ()->side][(Current ()->line+i)%4]][1];
	vector0 = Vertices (seg->verts [point0]);
	vector1 = Vertices (seg->verts [point1]);
	if (CalcLength(vector0,vector1) - move_rate < F1_0 / 4) {
	  ok_to_move = FALSE;
	}
      }
      break;
    case SIDE_MODE:
      for (i = 0; i < 4; i++) {
	point0 = line_vert [orthog_line [Current ()->side][i]][0];
	point1 = line_vert [orthog_line [Current ()->side][i]][1];
	vector0 = Vertices (seg->verts [point0]);
	vector1 = Vertices (seg->verts [point1]);
	if (CalcLength(vector0,vector1) - move_rate < F1_0 / 4) {
	  ok_to_move = FALSE;
	}
      }
      break;
  }
  if (ok_to_move == FALSE) {
    ErrorMsg("Too small to move in that direction");
    return;
  }
#endif

  radius = sqrt(x*x + y*y + z*z);
  if ((radius-move_rate) < F1_0 / 4) {
    if (m_selectMode == POINT_MODE
	|| m_selectMode == LINE_MODE
	|| m_selectMode == SIDE_MODE) {
      ErrorMsg("Cannot make cube any smaller\n"
	       "Cube must be greater or equal to 1.0 units wide.");
    }
  } else {

    // normalize direction
    if (radius > (F1_0/10)) {
      x /= radius;
      y /= radius;
      z /= radius;
    } else {
      vms_vector direction;
      CalcOrthoVector(direction,Current ()->segment,Current ()->side);
      x = (double)direction.x/(double)F1_0;
      y = (double)direction.y/(double)F1_0;
      z = (double)direction.z/(double)F1_0;
    }

// move on x, y, and z
	 theApp.SetModified (TRUE);
	 theApp.LockUndo ();
    MoveOn('X',(INT32) (-x*move_rate));
    MoveOn('Y',(INT32) (-y*move_rate));
    MoveOn('Z',(INT32) (-z*move_rate));
	 theApp.UnlockUndo ();
  }
theApp.SetModified (TRUE);
}
예제 #21
0
SourceBuffer::SourceBuffer()
{
    _getQueue(View::mono).push(Segments());
    _getQueue(View::left_eye).push(Segments());
    _getQueue(View::right_eye).push(Segments());
}
예제 #22
0
파일: light.cpp 프로젝트: paud/d2x-xl
void CMine::Illuminate (
	INT16 source_segnum, 
	INT16 source_sidenum, 
	UINT32 brightness, 
	double fLightScale, 
	bool bAll, bool 
	bCopyTexLights) 
{
CDSegment	*seg = Segments ();
CDSegment	*child_seg;
double		effect[4];
// find orthogonal angle of source segment
vms_vector A;

//fLightScale /= 100.0;
CalcOrthoVector (A,source_segnum,source_sidenum);
// remember to flip the sign since we want it to point inward
A.x = -A.x;
A.y = -A.y;
A.z = -A.z;

// calculate the center of the source segment
vms_vector source_center;
CalcCenter (source_center,source_segnum,source_sidenum);
if ((source_segnum == 911) && (source_sidenum == 3))
	A = A;
// mark those Segments () within N children of current cube

// set child numbers
//Segments ()[source_segnum].seg_number = m_lightRenderDepth;
int i;
for (i = SegCount (); i; i--, seg++)
	seg->seg_number = -1;
SetSegmentChildNum (NULL, source_segnum, m_lightRenderDepth);
CDColor *plc = LightColor (source_segnum, source_sidenum);
if (!plc->index) {
	plc->index = 255;
	plc->color.r =
	plc->color.g =
	plc->color.b = 1.0;
	}
if (UseTexColors () && bCopyTexLights) {
	CDColor	*psc = LightColor (source_segnum, source_sidenum, false);
	*psc = *plc;
	}
seg = Segments (source_segnum);
seg->seg_number = m_lightRenderDepth;
bool bWall = false; //FindWall (source_segnum, source_sidenum) != NULL;
// loop on child Segments ()
int child_segnum;
for (child_segnum=0, child_seg = Segments ();child_segnum<SegCount ();child_segnum++, child_seg++) {
	// skip if this is not viewable
	if (child_seg->seg_number < 0) 
		continue;
	// skip if not marked
//	if (!(bAll || (child_seg->wall_bitmask & MARKED_MASK)))
//		continue;
	// setup source corner vertex for length calculation later
	vms_vector source_corner[4];
	int j;
	for (j = 0; j < 4; j++) {
		int vertnum = side_vert [source_sidenum][j];
		int h = seg->verts [vertnum];
		source_corner[j].x = Vertices (h)->x;
		source_corner[j].y = Vertices (h)->y;
		source_corner[j].z = Vertices (h)->z;
		}
	// loop on child sides
	int child_sidenum;
	for (child_sidenum = 0; child_sidenum < 6; child_sidenum++) {
		// if side has a child..
		if (!(bAll || SideIsMarked (child_segnum, child_sidenum)))
			continue;
		if (child_seg->children[child_sidenum] >= 0) {
			UINT16 nWall = child_seg->sides[child_sidenum].nWall;
			// .. but there is no wall ..
			if (nWall >= GameInfo ().walls.count)
				continue;
				// .. or its not a door ..
			if (Walls (nWall)->type == WALL_OPEN)
				continue;
			}

//		CBRK (psc->index > 0);
		// if the child side is the same as the source side, then set light and continue
#ifdef _DEBUG
		CBRK (child_segnum == qqq1 && child_sidenum == qqq2);
#endif
		if (child_sidenum == source_sidenum && child_segnum == source_segnum) {
			uvl		*uvlP = child_seg->sides [child_sidenum].uvls;
			UINT32	vBr, lBr;

			theApp.SetModified (TRUE);
			int j;
			for (j = 0; j < 4; j++, uvlP++) {
				CDColor *pvc = VertexColors (child_seg->verts [side_vert [child_sidenum][j]]);
				vBr = (UINT16) uvlP->l;
				lBr = (UINT32) (brightness * fLightScale);
				BlendColors (plc, pvc, lBr, vBr);
				vBr += lBr;
				vBr = min (0x8000, vBr);
				uvlP->l = (UINT16) vBr;
				}
			continue;
			}

		// calculate vector between center of source segment and center of child
//		CBRK (child_segnum == 1 && child_sidenum == 2);
		if (CalcSideLights (child_segnum, child_sidenum, source_center, source_corner, A, effect, fLightScale, bWall)) {
				UINT32	vBr, lBr;	//vertex brightness, light brightness
				uvl		*uvlP = child_seg->sides [child_sidenum].uvls;

			theApp.SetModified (TRUE);
			int j;
			for (j = 0; j < 4; j++, uvlP++) {
				CDColor *pvc = VertexColors (child_seg->verts [side_vert [child_sidenum][j]]);
				if (child_seg->verts [side_vert [child_sidenum][j]] == 2368)
					j = j;
				vBr = (UINT16) uvlP->l;
				lBr = (UINT16) (brightness * effect [j] / 32);
				BlendColors (plc, pvc, lBr, vBr);
				vBr += lBr;
				vBr = min (0x8000, vBr);
				uvlP->l = (UINT16) vBr;
				}
			}
		}
	}
}
예제 #23
0
파일: light.cpp 프로젝트: paud/d2x-xl
bool CMine::CalcDeltaLights (double fLightScale, int force, int recursion_depth) 
{
	// initialize totals
CDSegment *srcseg, *childseg;
int source_segnum, child_segnum;
double effect[4];

GameInfo ().delta_lights.count = 0;
GameInfo ().dl_indices.count = 0;
bool bWall, bD2XLights = (level_version >= 15) && (GameInfo ().fileinfo_version >= 34);

fLightScale = 1.0; ///= 100.0;
for (source_segnum = 0, srcseg = Segments (); 
	  source_segnum < SegCount (); 
	  source_segnum++, srcseg++) {
	// skip if not marked unless we are automatically saving
	if  (!(srcseg->wall_bitmask & MARKED_MASK) && !force) 
		continue;
	// loop on all sides
	int source_sidenum;
	for (source_sidenum = 0; source_sidenum < 6; source_sidenum++) {
		INT16 tmapnum = srcseg->sides [source_sidenum].nBaseTex & 0x3fff;
		INT16 tmapnum2 = srcseg->sides [source_sidenum].nOvlTex & 0x3fff;
		INT16 trignum;
		bool bl1 = (bool) (IsLight (tmapnum) != -1);
		bool bl2 = (bool) (IsLight (tmapnum2) != -1);
		if (!(bl1 || bl2))
			continue;	// no lights on this side
		bool bCalcDeltas = false;
		// if the current side is a wall and has a light and is the target of a trigger
		// than can make the wall appear/disappear, calculate delta lights for it
		if ((bWall = (FindWall (source_segnum, source_sidenum) != NULL)) &&
			 ((trignum = FindTriggerTarget (0, source_segnum, source_sidenum)) >= 0)) {
			INT8 trigtype = Triggers (trignum)->type;
			bCalcDeltas =
				(trigtype == TT_ILLUSION_OFF) ||
				(trigtype == TT_ILLUSION_ON) ||
				(trigtype == TT_CLOSE_WALL) ||
				(trigtype == TT_OPEN_WALL) ||
				(trigtype == TT_LIGHT_OFF) ||
				(trigtype == TT_LIGHT_ON);
				 
			}
		if (!bCalcDeltas)
			bCalcDeltas = IsFlickeringLight (source_segnum, source_sidenum);
		if (!bCalcDeltas) {
			bool bb1 = IsBlastableLight (tmapnum);
			bool bb2 = IsBlastableLight (tmapnum2);
			if (bb1 == bb2)
				bCalcDeltas = bb1;	// both lights blastable or not
			else if (!(bb1 ? bl2 : bl1))	// i.e. one light blastable and the other texture not a non-blastable light 
				bCalcDeltas = true;
			}
		if (!bCalcDeltas) {	//check if light is target of a "light on/off" trigger
			int trignum = FindTriggerTarget (0, source_segnum, source_sidenum);
			if ((trignum >= 0) && (Triggers (trignum)->type >= TT_LIGHT_OFF))
				bCalcDeltas = true;
			}
		if (!bCalcDeltas)
			continue;
		// only set lights for textures which have a nOvlTex
		//if (tmapnum2 == 0)
		//	continue;

		INT16 srcwall = srcseg->sides [source_sidenum].nWall;
		if ((srcseg->children [source_sidenum] != -1) &&
			 ((srcwall >= GameInfo ().walls.count) || (Walls (srcwall)->type == WALL_OPEN)))
			continue;

//		if ((IsLight (tmapnum) == -1) && (IsLight (tmapnum2) == -1))
//			continue;
		if (GameInfo ().dl_indices.count >= MAX_DL_INDICES) {
			char szMsg [256];
			sprintf (szMsg, " Light tool: Too many dynamic lights at render depth %d", recursion_depth);
			DEBUGMSG (szMsg);
			return false;
			}

		vms_vector A,source_center;

		// get index number and increment total number of dl_indices
		int dl_index_num = (int)GameInfo ().dl_indices.count++;
		dl_index *pdli = DLIndex (dl_index_num);
		if (bD2XLights) {
			pdli->d2x.segnum = source_segnum;
			pdli->d2x.sidenum = source_sidenum;
			pdli->d2x.count = 0; // will be incremented below
			}
		else {
			pdli->d2.segnum = source_segnum;
			pdli->d2.sidenum = source_sidenum;
			pdli->d2.count = 0; // will be incremented below
			}
		pdli->d2.index = (INT16)GameInfo ().delta_lights.count;

		// find orthogonal angle of source segment
		CalcOrthoVector(A,source_segnum,source_sidenum);
		// remember to flip the sign since we want it to point inward
		A.x = -A.x;
		A.y = -A.y;
		A.z = -A.z;

		// calculate the center of the source segment
		CalcCenter(source_center,source_segnum,source_sidenum);

		// mark those Segments () within N children of current cube
		//(note: this is done once per light instead of once per segment
		//       even though some Segments () have multiple lights.
		//       This actually reduces the number of calls since most
		//       Segments () do not have lights)

		int h;
		for (h = 0; h < SegCount (); h++)
			Segments (h)->seg_number = -1;
		SetSegmentChildNum (srcseg, source_segnum, recursion_depth);
		srcseg->seg_number = recursion_depth;

		// setup source corner vertex for length calculation later
		vms_vector source_corner[4];
		int j;
		for (j = 0; j < 4; j++) {
			UINT8 vertnum = side_vert[source_sidenum][j];
			int h = srcseg->verts[vertnum];
			source_corner[j].x = Vertices (h)->x;
			source_corner[j].y = Vertices (h)->y;
			source_corner[j].z = Vertices (h)->z;
			}

		// loop on child Segments ()
		for (child_segnum = 0, childseg = Segments ();
			  child_segnum < SegCount ();
			  child_segnum++, childseg++) {
			if (childseg->seg_number < 0)
				continue;
			// loop on child sides
			int child_sidenum;
			for (child_sidenum = 0; child_sidenum < 6; child_sidenum++) {
				// if texture has a child..
#ifdef _DEBUG
			CBRK (source_segnum == 6 && source_sidenum == 2 &&
				child_segnum == 10 && child_sidenum == 1);
#endif
				if (childseg->children[child_sidenum] >= 0) {
					UINT16 nWall = childseg->sides[child_sidenum].nWall;
					// .. if there is no wall ..
					if (nWall >= GameInfo ().walls.count)
						continue;
					// .. or its not a door ..
					if (Walls (nWall)->type == WALL_OPEN) 
						continue; // don't put light because there is no texture here
					}
				// don't affect non-flickering light emitting textures (e.g. lava)
				tmapnum = childseg->sides [child_sidenum].nBaseTex;
				tmapnum2 = childseg->sides [child_sidenum].nOvlTex & 0x3fff;
				if (m_nNoLightDeltas == 1) {
					if (((IsLight (tmapnum) >= 0) || (IsLight (tmapnum2) >= 0))
						 && !IsFlickeringLight (child_segnum, child_sidenum))
						continue;
					}
				else if ((m_nNoLightDeltas == 2) && (IsLava (tmapnum) || IsLava (tmapnum2)))
					continue;
				// if the child side is the same as the source side, then set light and continue
				if (child_sidenum == source_sidenum && child_segnum == source_segnum) {
					if ((GameInfo ().delta_lights.count >= MAX_DELTA_LIGHTS) || 
						 (bD2XLights ? pdli->d2x.count == 8191 : pdli->d2.count == 255)) {
						char szMsg [256];
						sprintf (szMsg, " Light tool: Too many dynamic lights at render depth %d", recursion_depth);
						DEBUGMSG (szMsg);
						return false;
						}
					delta_light *dl = DeltaLights (GameInfo ().delta_lights.count++);
					dl->segnum = child_segnum;
					dl->sidenum = child_sidenum;
					dl->dummy = 0;
					dl->vert_light [0] =
					dl->vert_light [1] =
					dl->vert_light [2] =
					dl->vert_light [3] = (UINT8) min (32, 32 * fLightScale);
					if (bD2XLights)
						pdli->d2x.count++;
					else
						pdli->d2.count++;
					continue;
					}

				// calculate vector between center of source segment and center of child
#ifdef _DEBUG
					CBRK (child_segnum == qqq1 && child_sidenum == qqq2);
#endif
					if (CalcSideLights (child_segnum, child_sidenum, source_center, source_corner, A, effect, fLightScale, bWall)) {
						theApp.SetModified (TRUE);
						if ((GameInfo ().delta_lights.count >= MAX_DELTA_LIGHTS) || 
							 (bD2XLights ? pdli->d2x.count == 8191 : pdli->d2.count == 255)) {
							char szMsg [256];
							sprintf (szMsg, " Light tool: Too many dynamic lights at render depth %d", recursion_depth);
							DEBUGMSG (szMsg);
							return false;
							}
						delta_light *dl = DeltaLights (GameInfo ().delta_lights.count++);
						dl->segnum = child_segnum;
						dl->sidenum = child_sidenum;
						dl->dummy = 0;
						int iCorner;
						for (iCorner = 0; iCorner < 4; iCorner++)
							dl->vert_light [iCorner] = (UINT8) min(32, effect [iCorner]);
						if (bD2XLights)
							pdli->d2x.count++;
						else
							pdli->d2.count++;
						}
					}
				}
//			}
		}
	}
return true;
}
예제 #24
0
파일: trigger.cpp 프로젝트: paud/d2x-xl
CDTrigger *CMine::AddTrigger (UINT16 wallnum, INT16 type, BOOL bAutoAddWall) 
{
	INT16 flags;
	INT16 segnum, sidenum, trignum;
	static INT16 defWallTypes [NUM_TRIGGER_TYPES] = {
		WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_ILLUSION, 
		WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_OPEN, 
		WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_ILLUSION,
		WALL_OPEN, WALL_OPEN
		};
	static INT16 defWallTextures [NUM_TRIGGER_TYPES] = {
		0, 0, 0, 0, 426, 
		0, 0, 0, 0, 0, 
		0, 0, 0, 0, 426,
		0, 0
		};

// check if there's already a trigger on the current side
wallnum = FindTriggerWall (&trignum);
if (trignum != NO_TRIGGER) {
	ErrorMsg ("There is already a trigger on this side");
	return NULL;
	}
if (GameInfo ().triggers.count >= MAX_TRIGGERS) {
	ErrorMsg ("The maximum number of triggers has been reached.");
	return NULL;
	}
// if no wall at current side, try to add a wall of proper type
bool bUndo = theApp.SetModified (TRUE);
theApp.LockUndo ();
if (CurrSide ()->nWall >= GameInfo ().walls.count) {
	if (bAutoAddWall) {
		if (GameInfo ().walls.count >= MAX_WALLS) {
			ErrorMsg ("Cannot add a wall to this side,\nsince the maximum number of walls is already reached.");
			return NULL;
			}
		segnum = sidenum = -1;
		GetCurrent (segnum, sidenum);
		if (!AddWall (-1, -1, (Segments (segnum)->children [sidenum] < 0) ? WALL_OVERLAY : defWallTypes [type], 0, 0, -1, defWallTextures [type])) {
			ErrorMsg ("Cannot add a wall for this trigger.");
			theApp.ResetModified (bUndo);
			return NULL;
			}
		}
	else {
		ErrorMsg ("You must add a wall to this side before you can add a trigger.");
		return NULL;
		}
	}
// if D1, then convert type to flag value
if (file_type == RDL_FILE) {
	switch(type) {
		case TT_OPEN_DOOR:
			flags = TRIGGER_CONTROL_DOORS;
			break;
		case TT_MATCEN:
			flags = TRIGGER_MATCEN;
			break;
		case TT_EXIT:
			flags = TRIGGER_EXIT;
			break;
		case TT_SECRET_EXIT:
			flags = TRIGGER_SECRET_EXIT;
			break;
		case TT_ILLUSION_OFF:
			flags = TRIGGER_ILLUSION_OFF;
			break;
		case TT_ILLUSION_ON:
			flags = TRIGGER_ILLUSION_ON;
			break;
		case TT_ENERGY_DRAIN:
			flags = TRIGGER_ENERGY_DRAIN;
			break;
		case TT_SHIELD_DAMAGE:
			flags = TRIGGER_SHIELD_DAMAGE;
			break;
		default:
			flags = 0;
		}
	type = 0;
	}
else
	flags = 0;

trignum = (UINT16) GameInfo ().triggers.count;
// set new trigger data
InitTrigger (Triggers (trignum), type, flags);
// link trigger to the wall
Walls (wallnum)->trigger = (UINT8) trignum;
// update number of Triggers ()
GameInfo ().triggers.count++;
AutoLinkExitToReactor();
theApp.UnlockUndo ();
theApp.MineView ()->Refresh ();
return Triggers (trignum);
}