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 (); }
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; } } } } } } } } }
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 (); }
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; }
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); } } } }
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); } }
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; }
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 }
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; } }
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 }
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; }
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); } }
void SourceBuffer::push(const View view) { _getQueue(view).push(Segments()); ++_backFrameIndex[as_underlying_type(view)]; }
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]]), ¢er, &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 */ } }
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; } }
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; } }
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; } }
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); }
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]]), ¢er,&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]),¢er,&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),¢er,&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, ¢er, &opp_center, angle); break; } }
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); }
SourceBuffer::SourceBuffer() { _getQueue(View::mono).push(Segments()); _getQueue(View::left_eye).push(Segments()); _getQueue(View::right_eye).push(Segments()); }
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; } } } } }
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; }
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); }