bool CEntity::FBoxVisible(CEntity *pEntity, Vector *pvHit, unsigned char *ucBodyPart) { if (ucBodyPart) *ucBodyPart = 0; // don't look through water if (IsInWater() != pEntity->IsInWater()) return false; bool fVisible = false; traceresult_t tr; // Check direct Line to waist Vector vecLookerOrigin = GetGunPosition(); Vector vecTarget = pEntity->GetOrigin(); tr = TestLine(vecLookerOrigin, vecTarget, true, NULL); if (tr.fraction >= 1.0) { if (pvHit) *pvHit = tr.endpos; if (ucBodyPart) *ucBodyPart |= WAIST_VISIBLE; fVisible = true; } // Check direct Line to head vecTarget = pEntity->GetGunPosition(); tr = TestLine(vecLookerOrigin, vecTarget, true, NULL); if (tr.fraction >= 1.0) { if (pvHit) *pvHit = tr.endpos; if (ucBodyPart) *ucBodyPart |= HEAD_VISIBLE; fVisible = true; } if (fVisible) return true; // Nothing visible - check randomly other parts of body for (int i = 0; i < 5; i++) { vecTarget.x = RandomFloat(pEntity->GetAbsMin().x, pEntity->GetAbsMax().x); vecTarget.y = RandomFloat(pEntity->GetAbsMin().y, pEntity->GetAbsMax().y); vecTarget.z = RandomFloat(pEntity->GetAbsMin().z, pEntity->GetAbsMax().z); tr = TestLine(vecLookerOrigin, vecTarget, true, NULL); if (tr.fraction == 1.0) { // Return seen position if (pvHit) *pvHit = tr.endpos; if (ucBodyPart) *ucBodyPart |= CUSTOM_VISIBLE; return true; } } return false; // it's invisible }
// find the place to go for air when bot is underwater Vector CBotNav::AirGoal() { if (!m_pBot->IsInWater() && !m_pBot->IsInLava() && !m_pBot->IsInSlime()) return NULLVEC; // bot isn't underwater, don't bother Vector start = m_pBot->GetOrigin(), end = m_pBot->GetOrigin() + Vector(0, 0, 1000); // trace up until we hit solid traceresult_t tr = TestLine(start, end, true, NULL); end = tr.endpos; end.z -= 16; // lower a bit if (IsLiquid(end) || !PointBelongsToWorld(end)) return NULLVEC; // no enough space above water, fail // find the surface of the water while (end.z - start.z > 1) { // find the mid point Vector mid(start.x, start.y, (start.z + end.z) / 2); if (IsLiquid(mid)) { start.z = mid.z; // surface is ABOVE the mid point } else { end.z = mid.z; // surface is BELOW the mid point } } end.z += 16; // raise the point a bit to make sure bot will get air return end; // success! }
bool CEntity::FVisible(CEntity *pEntity) { // don't look through water if (IsInWater() != pEntity->IsInWater()) return false; return (TestLine(EyePosition(), pEntity->EyePosition(), true, pEntity).fraction >= 1.0); }
//========================================================= // FVisible - returns true if a line can be traced from // the caller's eyes to the target //========================================================= bool CEntity::FVisible(const Vector &vecDest) { // don't look through water if (IsLiquid(GetGunPosition()) != IsLiquid(vecDest)) return false; // check if line of sight to object is not blocked (i.e. visible) return (TestLine(EyePosition(), vecDest).fraction >= 1.0); }
// get the entity which blocks this link void CWorld::CLink::UpdateLinkEnt() { traceresult_t tr; // use a traceline to find the entity which blocks this link tr = TestLine(g_pServer->World()->m_pNodes[m_iSrcNode].MidPos(), g_pServer->World()->m_pNodes[m_iDestNode].MidPos(), false, NULL); m_pLinkEnt = tr.ent; // store away the entity }
void AddEmitSurfaceLights( const Vector &vStart, Vector lightBoxColor[6] ) { fltx4 fractionVisible; FourVectors vStart4, wlOrigin4; vStart4.DuplicateVector ( vStart ); for ( int iLight=0; iLight < *pNumworldlights; iLight++ ) { dworldlight_t *wl = &dworldlights[iLight]; // Should this light even go in the ambient cubes? if ( !( wl->flags & DWL_FLAGS_INAMBIENTCUBE ) ) continue; Assert( wl->type == emit_surface ); // Can this light see the point? wlOrigin4.DuplicateVector ( wl->origin ); TestLine ( vStart4, wlOrigin4, &fractionVisible ); if ( !TestSignSIMD ( CmpGtSIMD ( fractionVisible, Four_Zeros ) ) ) continue; // Add this light's contribution. Vector vDelta = wl->origin - vStart; float flDistanceScale = Engine_WorldLightDistanceFalloff( wl, vDelta ); Vector vDeltaNorm = vDelta; VectorNormalize( vDeltaNorm ); float flAngleScale = Engine_WorldLightAngle( wl, wl->normal, vDeltaNorm, vDeltaNorm ); float ratio = flDistanceScale * flAngleScale * SubFloat ( fractionVisible, 0 ); if ( ratio == 0 ) continue; for ( int i=0; i < 6; i++ ) { float t = DotProduct( g_BoxDirections[i], vDeltaNorm ); if ( t > 0 ) { lightBoxColor[i] += wl->intensity * (t * ratio); } } } }
/* ============ CastRay Returns the distance between the points, or -1 if blocked ============= */ vec_t CastRay (vec3_t p1, vec3_t p2) { int i; vec_t t; qboolean trace; trace = TestLine (p1, p2); if (!trace) return -1; // ray was blocked t = 0; for (i=0 ; i< 3 ; i++) t += (p2[i]-p1[i]) * (p2[i]-p1[i]); if (t == 0) t = 1; // don't blow up... return sqrt(t); }
void AddEmitSurfaceLights( const Vector &vStart, Vector lightBoxColor[6] ) { int iThread = 0; for ( int iLight=0; iLight < *pNumworldlights; iLight++ ) { dworldlight_t *wl = &dworldlights[iLight]; // Should this light even go in the ambient cubes? if ( !( wl->flags & DWL_FLAGS_INAMBIENTCUBE ) ) continue; Assert( wl->type == emit_surface ); // Can this light see the point? if ( TestLine( vStart, wl->origin, 0, iThread ) != CONTENTS_EMPTY ) continue; // Add this light's contribution. Vector vDelta = wl->origin - vStart; float flDistanceScale = Engine_WorldLightDistanceFalloff( wl, vDelta ); Vector vDeltaNorm = vDelta; VectorNormalize( vDeltaNorm ); float flAngleScale = Engine_WorldLightAngle( wl, wl->normal, vDeltaNorm, vDeltaNorm ); float ratio = flDistanceScale * flAngleScale; if ( ratio == 0 ) continue; for ( int i=0; i < 6; i++ ) { float t = DotProduct( g_BoxDirections[i], vDeltaNorm ); if ( t > 0 ) { lightBoxColor[i] += wl->intensity * (t * ratio); } } } }
void Test( void ) { int i; char buf[10]; /* create all the fundamental types */ for( i = DW_FT_MIN; i < DW_FT_MAX; ++i ) { FundamentalTypes[i] = DWFundamental( Client, itoa(i,buf,10), i, 2 ); } /* and let's get some constant versions of them */ for( i = DW_FT_MIN; i < DW_FT_MAX; ++i ) { ConstantFundamentalTypes[i] = DWModifier( Client, FundamentalTypes[i], DW_MOD_CONSTANT ); } ConstCharStar = DWPointer( Client, ConstantFundamentalTypes[DW_FT_SIGNED_CHAR], 0 ); TestMacInfo(); TestTypedef(); TestPointer(); TestString(); TestArray(); TestEnum(); TestStruct1(); TestStruct2(); TestStruct3(); TestSubroutineType(); TestLexicalBlock(); TestCommonBlock(); TestSubroutine(); TestLine(); TestAranges(); TestPubnames(); }
/******************************************************************************* * Compare functions to check for correctness * Use for testing only *******************************************************************************/ void write_test_screen() { // write RED lines (software) over the entire screen area // if we do hardware-accelerated lines and they fail, // the rest of the test will be harder to see int i; for(i = 0; i <= YRES-1; i++) { TestHLine(0, i, XRES-1, RED); } //each pair of lines (for horizontal/vertical) should have the same length //for horizontal lines, //test lines should start at both even and odd indexes //and have even and odd lengths //because they may be drawn incorrectly when drawing two pixels per cycle // even start pixel, even length TestHLine(100,100,100,LIME); TestHLine(100,101,100,LIME); TestHLine(100,102,100,LIME); TestHLine(100,103,100,LIME); TestHLine(100,104,100,LIME); WriteHLine(100,105,100,BLUE); WriteHLine(100,106,100,BLUE); WriteHLine(100,107,100,BLUE); WriteHLine(100,108,100,BLUE); WriteHLine(100,109,100,BLUE); // odd start pixel, even length TestHLine(101,120,100,LIME); TestHLine(101,121,100,LIME); TestHLine(101,122,100,LIME); TestHLine(101,123,100,LIME); TestHLine(101,124,100,LIME); WriteHLine(101,125,100,BLUE); WriteHLine(101,126,100,BLUE); WriteHLine(101,127,100,BLUE); WriteHLine(101,128,100,BLUE); WriteHLine(101,129,100,BLUE); // even start pixel, odd length TestHLine(100,140,101,LIME); TestHLine(100,141,101,LIME); TestHLine(100,142,101,LIME); TestHLine(100,143,101,LIME); TestHLine(100,144,101,LIME); WriteHLine(100,145,101,BLUE); WriteHLine(100,146,101,BLUE); WriteHLine(100,147,101,BLUE); WriteHLine(100,148,101,BLUE); WriteHLine(100,149,101,BLUE); // odd start pixel, odd length TestHLine(101,160,101,LIME); TestHLine(101,161,101,LIME); TestHLine(101,162,101,LIME); TestHLine(101,163,101,LIME); TestHLine(101,164,101,LIME); WriteHLine(101,165,101,BLUE); WriteHLine(101,166,101,BLUE); WriteHLine(101,167,101,BLUE); WriteHLine(101,168,101,BLUE); WriteHLine(101,169,101,BLUE); // test vertical lines TestVLine(200,200,100,LIME); TestVLine(201,200,100,LIME); TestVLine(202,200,100,LIME); TestVLine(203,200,100,LIME); TestVLine(204,200,100,LIME); WriteVLine(205,200,100,BLUE); WriteVLine(206,200,100,BLUE); WriteVLine(207,200,100,BLUE); WriteVLine(208,200,100,BLUE); WriteVLine(209,200,100,BLUE); // compare bresenham lines // should see a black line on top // and a purple line a few pixels below it // otherwise the hardware-accelerated line doesn't perfectly match WriteLine(240,340,440,440,MAGENTA); WriteLine(239,339,439,439,MAGENTA); TestLine(240,340,440,440,BLACK); TestLine(239,339,439,439,BLACK); TestLine(250,350,450,450,BLACK); TestLine(249,349,449,449,BLACK); WriteLine(250,350,450,450,MAGENTA); WriteLine(249,349,449,449,MAGENTA); // compare rectangles // should see WHITE rectangles above // and a LIME rectangles below // even to even WriteFilledRectangle(400, 250, 500, 300, LIME); TestFilledRectangle(400, 250, 500, 300, WHITE); // even to odd WriteFilledRectangle(600, 250, 701, 300, LIME); TestFilledRectangle(600, 250, 701, 300, WHITE); // odd to even TestFilledRectangle(401, 350, 500, 400, WHITE); WriteFilledRectangle(401, 350, 500, 400, LIME); // odd to odd TestFilledRectangle(601, 350, 701, 400, WHITE); WriteFilledRectangle(601, 350, 701, 400, LIME); // compare circles WriteCircle(500, 100, 50, LIME); TestCircle(500, 100, 50, WHITE); TestCircle(700, 100, 50, WHITE); WriteCircle(700, 100, 50, LIME); }
bool CBotNav::CantMoveForward(const Vector &move_angles) { // use some TraceLines to determine if anything is blocking the current // path of the bot. Vector v_forward, v_right, v_src, v_dest; traceresult_t tr; move_angles.AngleVectors(&v_forward, &v_right); v_src = m_pBot->EyePosition(); v_dest = v_src + v_forward * 40; // first do a trace from the bot's eyes forward... tr = TestLine(v_src, v_dest, false, m_pBot); // check if the trace hit something... if (tr.fraction < 1.0) { if (strncmp(tr.ent->GetClassname(), "func_door", 9) != 0) return true; } // bot's head is clear, check at shoulder level... // trace from the bot's shoulder left diagonal forward to the right shoulder... v_src = m_pBot->EyePosition() + Vector(0, 0, -16) - v_right * 16; v_dest = v_src + v_forward * 40; tr = TestLine(v_src, v_dest, false, m_pBot); // check if the trace hit something... if (tr.fraction < 1.0) { if (strncmp(tr.ent->GetClassname(), "func_door", 9) != 0) return true; } // bot's head is clear, check at shoulder level... // trace from the bot's shoulder right diagonal forward to the left shoulder... v_src = m_pBot->EyePosition() + Vector(0, 0, -16) + v_right * 16; v_dest = v_src + v_forward * 40; tr = TestLine(v_src, v_dest, false, m_pBot); // check if the trace hit something... if (tr.fraction < 1.0) { if (strncmp(tr.ent->GetClassname(), "func_door", 9) != 0) return true; } // Now check below Waist if (m_pBot->IsDucking()) { v_src = m_pBot->GetOrigin(); v_dest = v_src + v_forward * 40; tr = TestLine(v_src, v_dest, false, m_pBot); // check if the trace hit something... if (tr.fraction < 1.0) { if (strncmp(tr.ent->GetClassname(), "func_door", 9) != 0) return true; } } else { // Trace from the left Waist to the right forward Waist Pos v_src = m_pBot->GetOrigin() + Vector(0, 0, -17) + v_right * -16; v_dest = m_pBot->GetOrigin() + Vector(0, 0, -17) + v_right * 16 + v_forward * 40; tr = TestLine(v_src, v_dest, false, m_pBot); // check if the trace hit something... if (tr.fraction < 1.0) { if (strncmp(tr.ent->GetClassname(), "func_door", 9) != 0) return true; } // Trace from the left Waist to the right forward Waist Pos v_src = m_pBot->GetOrigin() + Vector(0, 0, -17) + v_right * 16; v_dest = m_pBot->GetOrigin() + Vector(0, 0, -17) + v_right * -16 + v_forward * 40; tr = TestLine(v_src, v_dest, false, m_pBot); // check if the trace hit something... if (tr.fraction < 1.0) { if (strncmp(tr.ent->GetClassname(), "func_door", 9) != 0) return true; } } return false; // bot can move forward, return false }