//컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴 //Procedure GetWindDirVel //Author Robert Slater //Date Thu 16 Dec 1999 // //Description Returns the wind speed and direction at a given altitude // //Inputs Alt // //Returns Wind Heading and Speed // //------------------------------------------------------------------------------ void Atmosphere::GetWindDirVel (SLong alt, SWord& hdg, FP& speed) { if(!Save_Data.flightdifficulty [FD_WINDEFFECTS]) { hdg = 0; speed = 0; } else { if(alt > 914400) // 30,000 ft { hdg = SWord(diralt * 182.04); speed = 5148. * windalt; //from knotts... to vel*1000 } else { FP Dir0 = 182.04 * dir0; FP DirAlt = 182.04 * diralt; FP DeltaDir = DirAlt - Dir0; FP Fract = FP(alt) / 914411.0; FP fdir = Dir0 + Fract * DeltaDir; speed = ((1. - Fract) * wind0 + Fract * windalt) * 5148.; hdg = SWord(fdir); } } }
//컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴 //Procedure GetWindDirVel //Author Craig Beeston //Date Thu 10 Jun 1999 // //Description Returns the wind speed and direction at a given altitude // //Inputs Alt // //Returns Wind Heading and Speed // //------------------------------------------------------------------------------ Bool Atmosphere::GetWindDirVel (SLong alt, SWord& hdg, SLong& speed) { if(!Save_Data.flightdifficulty [FD_WINDEFFECTS]) { hdg = 0; speed = 0; return(TRUE); } if(alt > 914400) // 30,000 ft { hdg = SWord(diralt * 182.04); //DeadCode RJS 16Dec99 speed = (51 * windalt) / 10; speed = SLong(5148. * windalt); //RJS 16Dec99 return(TRUE); } //DeadCode RJS 16Dec99 SWord Dir0 = SWord(182.04 * dir0); //DeadCode RJS 16Dec99 SWord DirAlt = SWord(182.04 * diralt); //DeadCode RJS 16Dec99 //DeadCode RJS 16Dec99 SWord DeltaDir = DirAlt - Dir0; FP Dir0 = 182.04 * dir0; //RJS 16Dec99 FP DirAlt = 182.04 * diralt; //RJS 16Dec99 FP DeltaDir = DirAlt - Dir0; //RJS 16Dec99 FP Fract = FP(alt) / 914411.0; FP fdir = Dir0 + Fract * DeltaDir; FP fspeed = ((1. - Fract) * wind0 + Fract * windalt) * 5148.;//RJS 16Dec99 hdg = SWord(fdir); speed = SLong(fspeed); return(TRUE); }
//컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴 //Procedure GetWindDirVel //Author Craig Beeston //Date Thu 10 Jun 1999 // //Description Returns the wind speed and direction at a given altitude // //Inputs Alt // //Returns Wind Heading and Speed // //------------------------------------------------------------------------------ Bool Atmosphere::GetWindDirVel (SLong alt, SWord& hdg, SWord& speed) { //DeadCode CSB 13/06/99 /* TEST CODE CSB 11/06/99 */ hdg = SWord(182.04 * 270); //Fix This !!!! //DeadCode CSB 13/06/99 /* TEST CODE CSB 11/06/99 */ speed = 750; //Fix This !!!! //DeadCode CSB 13/06/99 /* TEST CODE CSB 11/06/99 */ return(TRUE); //Fix This !!!! if(!Save_Data.flightdifficulty [FD_WINDEFFECTS]) { hdg = 0; speed = 0; return(TRUE); } if(alt < 1036300) // 34,000 ft { hdg = SWord(dir0 * 182.04); speed = 0;//wind0; return(TRUE); } if(alt > 1066800) // 35,000 ft { hdg = SWord(diralt * 182.04); speed = (51 * windalt) / 10; return(TRUE); } SWord Dir0 = SWord(182.04 * dir0); SWord DirAlt = SWord(182.04 * diralt); SWord DeltaDir = DirAlt - Dir0; FP Fract = (alt - 1036300.0) / (1066800.0 - 1036300.0); FP fdir = Dir0 + Fract * DeltaDir; FP fspeed = Fract * windalt * 5.1; hdg = SWord(fdir); speed = SWord(fspeed); return(TRUE); }
//컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴 //Procedure GetWindDirVel //Author Craig Beeston //Date Thu 10 Jun 1999 // //Description Returns the wind speed and direction at a given altitude // //Inputs Alt // //Returns Wind Heading and Speed // //------------------------------------------------------------------------------ bool Atmosphere::GetWindDirVel (SLong alt, SWord& hdg, SWord& speed) { if (!Save_Data.flightdifficulty [FD_WINDEFFECTS]) { hdg = 0; speed = 0; return(true); } if (alt < 1036300) // 34,000 ft { hdg = SWord(dir0 * 182.04); speed = 0;//wind0; return(true); } if (alt > 1066800) // 35,000 ft { hdg = SWord(diralt * 182.04); speed = (51 * windalt) / 10; return(true); } SWord Dir0 = SWord(182.04 * dir0); SWord DirAlt = SWord(182.04 * diralt); SWord DeltaDir = DirAlt - Dir0; FP Fract = (alt - 1036300.0) / (1066800.0 - 1036300.0); FP fdir = Dir0 + Fract * DeltaDir; FP fspeed = Fract * windalt * 5.1; hdg = SWord(fdir); speed = SWord(fspeed); return(true); }
//컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴 //Procedure TouchedGround //Author Paul. //Date Wed 11 Sep 1996 // //Description // //Inputs // //Returns // //------------------------------------------------------------------------------ Bool Collide::TouchedGround( AirStrucPtr ac, ANGLES newpitch,ANGLES newroll, Collide::Pos& pos, SLong groundlevel, Bool isCrashed ) { ac->fly.pModel->GroundHeight = groundlevel; //RJS 15Apr99 //DEADCODE CSB 14/03/00 if(ac->fly.numinsag) //DEADCODE CSB 14/03/00 { //DEADCODE CSB 14/03/00 if(ac->World.Y < groundlevel + ac->classtype->deckshunt) //DEADCODE CSB 14/03/00 { //DEADCODE CSB 14/03/00 SWord maxang = ac->pitch; //DEADCODE CSB 14/03/00 pos = Collide::NOSE_TOUCH; //DEADCODE CSB 14/03/00 if(-SWord(ac->pitch) > maxang) //DEADCODE CSB 14/03/00 { //DEADCODE CSB 14/03/00 maxang = -SWord(ac->pitch); //DEADCODE CSB 14/03/00 pos = Collide::TAIL_TOUCH; //DEADCODE CSB 14/03/00 } //DEADCODE CSB 14/03/00 if(SWord(ac->roll) > maxang) //DEADCODE CSB 14/03/00 { //DEADCODE CSB 14/03/00 maxang = SWord(ac->roll); //DEADCODE CSB 14/03/00 pos = Collide::RIGHT_WING_TOUCH; //DEADCODE CSB 14/03/00 } //DEADCODE CSB 14/03/00 if(-SWord(ac->roll) > maxang) //DEADCODE CSB 14/03/00 { //DEADCODE CSB 14/03/00 maxang = -SWord(ac->roll); //DEADCODE CSB 14/03/00 pos = Collide::LEFT_WING_TOUCH; //DEADCODE CSB 14/03/00 } //DEADCODE CSB 14/03/00 return(TRUE); //DEADCODE CSB 14/03/00 } //DEADCODE CSB 14/03/00 else //DEADCODE CSB 14/03/00 { //DEADCODE CSB 14/03/00 pos = Collide::NOTTOUCHED; //DEADCODE CSB 14/03/00 return(FALSE); //DEADCODE CSB 14/03/00 } //DEADCODE CSB 14/03/00 } Bool retval = FALSE; SWord pitchdelta, rolldelta; COORDS3D coords; COORDS3D offset; COORDS3D PushedOffset; //RJS 12Aug97 UWord absroll = ac->roll; //RJS 14Apr99 AircraftAnimData* adptr = (AircraftAnimData*) ac->Anim; //RJS 15Apr99 LnchrType CTtocheck; pitchdelta = ac->pitch - newpitch; rolldelta = ac->roll - newroll; //First, are we upside down??? if((absroll > ACUPSIDEDOWNMIN) && (absroll < ACUPSIDEDOWNMAX))//RJS 14Apr99 { SLong biggestang = pitchdelta; CTtocheck = CT_BACK; if(-pitchdelta > biggestang) { biggestang = -pitchdelta; CTtocheck = CT_FRONT; } if(SWord(rolldelta - ANGLES_180Deg) > biggestang) { biggestang = SWord(rolldelta - ANGLES_180Deg); CTtocheck = CT_LEFT; } if(SWord(ANGLES_180Deg - rolldelta) > biggestang) { biggestang = SWord(ANGLES_180Deg - rolldelta); CTtocheck = CT_RIGHT; } SHAPE.GetContactPoint(ItemPtr(ac), CTtocheck, coords, offset, PushedOffset); if(coords.Y < groundlevel) { if(CTtocheck == CT_BACK) pos = Collide::TAIL_TOUCH; else if(CTtocheck == CT_FRONT) pos = Collide::NOSE_TOUCH; else if(CTtocheck == CT_LEFT) pos = Collide::LEFT_WING_TOUCH; else pos = Collide::RIGHT_WING_TOUCH; retval = TRUE; } } else { if((pitchdelta > ANGLES_5Deg) && (pitchdelta < ANGLES_15Deg) && (AbsAngle(rolldelta) > ANGLES_5Deg)) { CTtocheck = CT_LEFT; if(rolldelta > 0) CTtocheck = CT_RIGHT; SHAPE.GetContactPoint(ItemPtr(ac), CTtocheck, coords, offset, PushedOffset); if(coords.Y < groundlevel) { if(CTtocheck == CT_LEFT) if(ac->fly.pModel->GearTouched) pos = Collide::WHEEL_AND_WING_TOUCH; else pos = Collide::LEFT_WING_TOUCH; else if(ac->fly.pModel->GearTouched) pos = Collide::WHEEL_AND_WING_TOUCH; else pos = Collide::RIGHT_WING_TOUCH; retval = TRUE; } } else { CTtocheck = CT_WHLFRONT; if((adptr->acrpm <= 0) || (adptr->FRONT >= 254)) if(pitchdelta < -ANGLES_15Deg) CTtocheck = CT_FRONT; else CTtocheck = CT_BELLY; SWord maxroll = ANGLES_5Deg; if(CTtocheck == CT_WHLFRONT) maxroll += ANGLES_10Deg - pitchdelta; if(AbsAngle(rolldelta) > maxroll) if(rolldelta > 0) CTtocheck = CT_RIGHT; else CTtocheck = CT_LEFT; SHAPE.GetContactPoint(ItemPtr(ac), CTtocheck, coords, offset, PushedOffset); if(coords.Y < groundlevel) { if(CTtocheck == CT_WHLFRONT) pos = Collide::PROP_TOUCH; else if(CTtocheck == CT_FRONT) pos = Collide::NOSE_TOUCH; else if(CTtocheck == CT_BELLY) pos = Collide::LANDED_BELLY; else if(CTtocheck == CT_LEFT) pos = Collide::LEFT_WING_TOUCH; else pos = Collide::RIGHT_WING_TOUCH; retval = TRUE; } } } //#define PRINT_GROUND_COLLISION #ifdef PRINT_GROUND_COLLISION switch(CTtocheck) { case CT_WHLFRONT: PrintString(40, 2, "PROP "); break; case CT_FRONT: PrintString(40, 2, "NOSE "); break; case CT_BACK: PrintString(40, 2, "FIN "); break; case CT_LEFT: PrintString(40, 2, "LEFT_WING "); break; case CT_RIGHT: PrintString(40, 2, "RIGHT_WING"); break; case CT_BELLY: PrintString(40, 2, "BELLY "); break; } switch(pos) { //DEADCODE CSB 01/03/00 case Collide::NOTTOUCHED: PrintString(40, 3, "NOTTOUCHED "); break; //DEADCODE CSB 01/03/00 case Collide::LANDED_OK: PrintString(40, 3, "LANDED_OK "); break; case Collide::WHEEL_AND_WING_TOUCH: PrintString(40, 3, "WHEEL_&_WING"); break; case Collide::LANDED_BELLY: PrintString(40, 3, "LANDED_BELLY"); break; case Collide::PROP_TOUCH: PrintString(40, 3, "PROP_TOUCH "); break; case Collide::NOSE_TOUCH: PrintString(40, 3, "NOSE_TOUCH "); break; case Collide::LEFT_WING_TOUCH: PrintString(40, 3, "LEFT_WING "); break; case Collide::RIGHT_WING_TOUCH: PrintString(40, 3, "RIGHT_WING "); break; case Collide::TAIL_TOUCH: PrintString(40, 3, "TAIL_TOUCH "); break; } #endif //DEADCODE CSB 29/02/00 if( (pitchdelta<0?-pitchdelta:pitchdelta) < (rolldelta<0?-rolldelta:rolldelta) ) //DEADCODE CSB 29/02/00 { //DEADCODE CSB 29/02/00 //Dpitch gt Droll //DEADCODE CSB 29/02/00 //DEADCODE CSB 29/02/00 if ((ANGLES)(Angles)rolldelta>ACROLLANGLE) //DEADCODE CSB 29/02/00 { //DEADCODE CSB 29/02/00 SHAPE.GetContactPoint((itemptr )ac,CT_LEFT,coords,offset,PushedOffset);//RJS 12Aug97 //DEADCODE CSB 29/02/00 if((adptr->aclegsuspl > 0) || (adptr->aclegsuspr > 0)) //DEADCODE CSB 29/02/00 pos = Collide::WHEEL_AND_WING_TOUCH; //DEADCODE CSB 29/02/00 else //DEADCODE CSB 29/02/00 pos = Collide::LEFT_WING_TOUCH; //DEADCODE CSB 29/02/00 } //DEADCODE CSB 29/02/00 else //DEADCODE CSB 29/02/00 { //DEADCODE CSB 29/02/00 if ((ANGLES)(Angles)rolldelta<-ACROLLANGLE) //DEADCODE CSB 29/02/00 { //DEADCODE CSB 29/02/00 SHAPE.GetContactPoint((itemptr )ac,CT_RIGHT,coords,offset,PushedOffset);//RJS 12Aug97 //DEADCODE CSB 29/02/00 if((adptr->aclegsuspl > 0) || (adptr->aclegsuspr > 0)) //DEADCODE CSB 29/02/00 pos = Collide::WHEEL_AND_WING_TOUCH; //DEADCODE CSB 29/02/00 else //DEADCODE CSB 29/02/00 pos = Collide::RIGHT_WING_TOUCH; //DEADCODE CSB 29/02/00 } //DEADCODE CSB 29/02/00 else //DEADCODE CSB 29/02/00 { //DEADCODE CSB 29/02/00 if ( (!adptr->acleglowerl && !adptr->LEFTWHEEL) //RJS 19May99 //DEADCODE CSB 29/02/00 && (!adptr->acleglowerr && !adptr->RIGHTWHEEL) ) //RJS 19MaY99 //DEADCODE CSB 29/02/00 { //DEADCODE CSB 29/02/00 pos = Collide::LANDED_OK; //DEADCODE CSB 29/02/00 return FALSE; //DEADCODE CSB 29/02/00 } //DEADCODE CSB 29/02/00 else //DEADCODE CSB 29/02/00 { //DEADCODE CSB 29/02/00 SHAPE.GetContactPoint((itemptr )ac,CT_BELLY,coords,offset,PushedOffset);//RJS 12Aug97 //DEADCODE CSB 29/02/00 pos = Collide::LANDED_BELLY; //DEADCODE CSB 29/02/00 } //DEADCODE CSB 29/02/00 } //DEADCODE CSB 29/02/00 } //DEADCODE CSB 29/02/00 } //DEADCODE CSB 29/02/00 else //DEADCODE CSB 29/02/00 { //DEADCODE CSB 29/02/00 //Droll gt DPitch //DEADCODE CSB 29/02/00 //DEADCODE CSB 29/02/00 if ((ANGLES)(Angles)pitchdelta>ACPITCHANGLE) //DEADCODE CSB 29/02/00 { //DEADCODE CSB 29/02/00 SHAPE.GetContactPoint((itemptr )ac,CT_FRONT,coords,offset,PushedOffset);//RJS 12Aug97 //DEADCODE CSB 29/02/00 pos = Collide::NOSE_TOUCH; //DEADCODE CSB 29/02/00 } //DEADCODE CSB 29/02/00 else //DEADCODE CSB 29/02/00 { //DEADCODE CSB 29/02/00 if ((ANGLES)(Angles)pitchdelta<-ACPITCHANGLE) //DEADCODE CSB 29/02/00 { //DEADCODE CSB 29/02/00 SHAPE.GetContactPoint((itemptr )ac,CT_BACK,coords,offset,PushedOffset);//RJS 12Aug97 //DEADCODE CSB 29/02/00 pos = Collide::TAIL_TOUCH; //RJS 13Jan99 //DEADCODE CSB 29/02/00 } //DEADCODE CSB 29/02/00 else //DEADCODE CSB 29/02/00 { //DEADCODE CSB 29/02/00 if ( (!adptr->acleglowerl && !adptr->LEFTWHEEL) //RJS 19May99 //DEADCODE CSB 29/02/00 && (!adptr->acleglowerr && !adptr->RIGHTWHEEL) ) //RJS 19MaY99 //DEADCODE CSB 29/02/00 { //DEADCODE CSB 29/02/00 pos = Collide::LANDED_OK; //DEADCODE CSB 29/02/00 return FALSE; //DEADCODE CSB 29/02/00 } //DEADCODE CSB 29/02/00 else //DEADCODE CSB 29/02/00 { //DEADCODE CSB 29/02/00 if((adptr->ENGINELEFT != BS_DEAD) || (adptr->ENGINERIGHT != BS_DEAD)) //DEADCODE CSB 29/02/00 { //DEADCODE CSB 29/02/00 SHAPE.GetContactPoint((itemptr )ac,CT_BELLY,coords,offset,PushedOffset);//RJS 12Aug97 //DEADCODE CSB 29/02/00 pos = Collide::PROP_TOUCH; //DEADCODE CSB 29/02/00 } //DEADCODE CSB 29/02/00 else //DEADCODE CSB 29/02/00 { //DEADCODE CSB 29/02/00 SHAPE.GetContactPoint((itemptr )ac,CT_BELLY,coords,offset,PushedOffset);//RJS 12Aug97 //DEADCODE CSB 29/02/00 pos = Collide::LANDED_BELLY; //DEADCODE CSB 29/02/00 } //DEADCODE CSB 29/02/00 } //DEADCODE CSB 29/02/00 } //DEADCODE CSB 29/02/00 } //DEADCODE CSB 29/02/00 } SLong glevel; if(isCrashed) //RJS 02Jul98 { if(ac->World.Y <= ac->fly.pModel->GroundHeight) //RJS 24Aug98 retval = TRUE; } else { glevel = Land_Scape.GetGroundLevel(coords); //RJS 13Jan99 if(coords.Y <= glevel) //RJS 13Jan99 retval = TRUE; //RJS 13Jan99 } if (!retval) pos = Collide::NOTTOUCHED; return(retval); }
//컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴 //Procedure CheckTri //Author Paul. //Date Mon 1 Jun 1998 //------------------------------------------------------------------------------ bool CheckTri(int pntCnt,UByte* polyDef,PntDef* pntArray,int p0,int p1,int p2) { const bool INSIDE=false; const bool OUTSIDE=true; UByte i0=polyDef[p0]; UByte i1=polyDef[p1]; UByte i2=polyDef[p2]; PntDef& pt0=pntArray[i0]; PntDef& pt1=pntArray[i1]; PntDef& pt2=pntArray[i2]; SLong vi,vj,wi,wj; vi=SLong(pt1.x)-SLong(pt0.x); vj=SLong(pt1.z)-SLong(pt0.z); wi=SLong(pt1.x)-SLong(pt2.x); wj=SLong(pt1.z)-SLong(pt2.z); if (vi*wj>=wi*vj) return false; //failed on crossproduct test //check that no other active points in the poly are contained //within this new triangle for (int x=(p2+1)%pntCnt;x!=p0;++x%=pntCnt) { UByte it=polyDef[x]; if (it!=i0&&it!=i1&&it!=i2) { SWord ptx=pntArray[it].x; SWord ptz=pntArray[it].z; SWord x0,y0,x1,y1,x2,y2; x0=SWord(pt0.x)-ptx; y0=SWord(pt0.z)-ptz; //if the test point matches vertex 0 return false (inside) if (x0==0 && y0==0) return false; x1=SWord(pt1.x)-ptx; y1=SWord(pt1.z)-ptz; //if the test point matches vertex 1 return false (inside) if (x1==0 && y1==0) return false; x2=SWord(pt2.x)-ptx; y2=SWord(pt2.z)-ptz; //if the test point matches vertex 2 return false (inside) if (x2==0 && y2==0) return false; //if all points are to the left of the test point then no more //checks are required for this test point if (!(x0>0 && x1>0 && x2>0)) { if (x0>0 || x1>0 || x2>0) { SWord count; //if any of the triangle sides are horizontal and at the //same y as the test point then return false (inside) if //the test point lies between the sides endpoints if ((count=(y0==0)+(y1==0))==2 && (x0^x1)<0) return false; else if (count && (count=(y1==0)+(y2==0))==2 && (x1^x2)<0) return false; else if (count && (count=(y2==0)+(y0==0))==2 && (x2^x0)<0) return false; else if (!y0) { if ((y1^y2)<0) return false; } else if (!y1) { if ((y2^y0)<0) return false; } else if (!y2) { if ((y0^y1)<0) return false; } else { count=0; //test for intersection of segment v0->v1 if ((y0^y1)<0) { if ((x0^x1)<0) { SLong yiy0=SLong(-y0)<<16; SLong x1x0=SLong(x1-x0)<<16; SLong y1y0=SLong(y1-y0)<<16; SLong res=MULDIVSIN(yiy0,x1x0,y1y0)+(x0<<16); //point is classified as inside if it is on the line if (!((res+0x7F)&0xFFFFFF00)) return false; if (res>0) count++; //cross over detected } else count++; //cross over detected } if ((y1^y2)<0) { if ((x1^x2)<0) { SLong yiy1=SLong(-y1)<<16; SLong x2x1=SLong(x2-x1)<<16; SLong y2y1=SLong(y2-y1)<<16; SLong res=MULDIVSIN(yiy1,x2x1,y2y1)+(x1<<16); //point is classified as inside if it is on the line if (!((res+0x7F)&0xFFFFFF00)) return false; if (res>0) count++; //cross over detected } else count++; //cross over detected } //if count is 2 then there's no need to do the final //test because the test ray cannot intersect more than //2 sides of the triangle if (count!=2) { if ((y2^y0)<0) { if ((x2^x0)<0) { SLong yiy2=SLong(-y2)<<16; SLong x0x2=SLong(x0-x2)<<16; SLong y0y2=SLong(y0-y2)<<16; SLong res=MULDIVSIN(yiy2,x0x2,y0y2)+(x2<<16); //point is classified as inside if it is on the line if (!((res+0x7F)&0xFFFFFF00)) return false; if (res>0) count++; //cross over detected } else count++; //cross over detected } //even number of crossings means the point is outside //the triangle. odd number means the point is inside if (count&1) return false; } } } else if (x0==0 && x1==0) { if ((y0^y1)<0) return false; } else if (x1==0 && x2==0) { if ((y1^y2)<0) return false; } else if (x2==0 && x0==0) { if ((y2^y0)<0) return false; } } } } return true; }