⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cboid.cpp

📁 这是一个用OPENGL和VC++作的人工智能程序,大家可以借鉴一下
💻 CPP
📖 第 1 页 / 共 2 页
字号:
      // test:  if this is OUR flock, skip it      if (i == flock_id) continue;#ifdef VISIBILITY_DEBUG   myprintf("   Testing to see if %x can see anybody in flock %d\n",this,i);#endif      // not our flock, so check it out      enemy = CFlock::ListOfFlocks[i]->GetFirstMember();      while (enemy != NULL) {      #ifdef VISIBILITY_DEBUG      myprintf("   looking at %x\n",enemy);#endif         // if this enemy is visible...         if ((dist = CanISee(enemy)) != INFINITY) {            // I can see it..increment counter            m_num_enemies_seen++;            // Test:  Closest enemy?            if (dist < m_dist_to_nearest_enemy) {                              // yes...save it off               m_dist_to_nearest_enemy = dist;               m_nearest_enemy = enemy;            }         }         // get next enemy in flock         enemy = enemy->GetNext();      }   }#ifdef VISIBILITY_DEBUG   myprintf("\n");   myprintf("   total enemies seen = %d\n",m_num_enemies_seen);   myprintf("   nearest enemy is %x at %f\n",m_nearest_enemy,m_dist_to_nearest_enemy);#endif   return (m_num_enemies_seen);}// SeeFriends.// Determines which flockmates a given flock boid can see.int CBoid::SeeFriends (CBoid *first_boid){   float dist;   CBoid *flockmate = first_boid;#ifdef BOID_DEBUG   myprintf("\nInside SeeFriends\n");#endif#ifdef VISIBILITY_DEBUG   myprintf("   Building visibilty list for %x...\n",this);#endif   // clear the existing visibility list of any holdover from last round   ClearVisibleList();   // now figure out who we can see   while (flockmate != NULL) {      // Test:  Within sight of this boid?#ifdef VISIBILITY_DEBUG      myprintf("   looking at %x\n",flockmate);#endif      if ((dist = CanISee(flockmate)) != INFINITY) {         // add it to the list         AddToVisibleList(flockmate);         // Test:  If this guy is closer than the current         // closest, make him the current closest         if (dist < m_dist_to_nearest_flockmate) {            m_dist_to_nearest_flockmate = dist;            m_nearest_flockmate = flockmate;         }      }      // next flockmate      flockmate = flockmate->GetNext();   }#ifdef VISIBILITY_DEBUG   myprintf("\n");   myprintf("   total flockmates seen = %d\n",m_num_flockmates_seen);   myprintf("   nearest flockmate is %x at %f\n",      m_nearest_flockmate, m_dist_to_nearest_flockmate);#endif   return (m_num_flockmates_seen);}// SteerToCenter.// Generates a vector to guide a flock boid towards// the "center of mass" of the flockmates he can see.vector CBoid::SteerToCenter (void){   vector center, change;#ifdef BOID_DEBUG   myprintf("\nInside SteerToCenter\n");#endif   // walk down the visibility list and sum up their position vectors   for (int i = 0; i < m_num_flockmates_seen; i++) {      if (VisibleFriendsList[i] != NULL) center += VisibleFriendsList[i]->m_pos;   }#ifdef BOID_DEBUG   myprintf("   perceived center before averaging = %f %f %f\n",center.x, center.y, center.z);   myprintf("   num_flockmates_seen = %d\n",m_num_flockmates_seen);#endif   // average the positions to get the perceived center of the flock   center /= m_num_flockmates_seen;#ifdef BOID_DEBUG   myprintf("   perceived center after averaging = %f %f %f\n",center.x, center.y, center.z);#endif   // now that we have the perceived center, computer a vector towards it   change = center - m_pos;   // Scale the change vector so we don't turn on a dime..   change.SetMagnitudeOfVector (MinUrgency);#ifdef BOID_DEBUG   myprintf("   final change vector from SteerToCenter = %f %f %f\n",      change.x, change.y, change.z);#endif   // return change vector   return (change);}// WorldBound.// Implements a world boundary so that flocks don't fly// infinitely far away from the camera, instead remaining // in a nice viewable area.  It does this by wrapping flock// boids around to the other side of the world, so (for example)// they move out the right and return on the left.// Returns:  nothing.void CBoid::WorldBound (void){   float maxX = CBox::WorldPtr->GetBoxWidth()/2;   float maxY = CBox::WorldPtr->GetBoxHeight()/2;   float maxZ = CBox::WorldPtr->GetBoxLength()/2;   float minX = -maxX;   float minY = -maxY;   float minZ = -maxZ;#ifdef BOID_DEBUG   myprintf("\nInside Worldbound\n");#endif   // test position of flock boid and    // 'warp' if they've strayed out of bounds   if (m_pos.x > maxX) {      m_pos.x = minX;   } else if (m_pos.x < minX) {      m_pos.x = maxX;      } else if (m_pos.y > maxY) {      m_pos.y = minY;   } else if (m_pos.y < minY) {      m_pos.y = maxY;      } else if (m_pos.z > maxZ) {      m_pos.z = minZ;   } else if (m_pos.z < minZ) {      m_pos.z = maxZ;   }}////////////////////////// miscellaneous methods////////////////////////// AccumulateChanges.// Adds vector values in changes into the accumumlator vector.// Returns:  magnitude of accumulator vector after adding changes.float CBoid::AccumulateChanges (vector &accumulator, vector changes){#ifdef BOID_DEBUG   myprintf("\nInside AccumulateChanges\n");#endif     // apply the change   accumulator += changes;   //accumulator.x += changes.x;   //accumulator.y += changes.y;   //accumulator.z += changes.z;   return (accumulator.length());}// AddToVisibleList.// Adds a boid to the list of visible boids.// This visibility list is regenerated for each boid each update cycle,// and acts much like a push-down queue; the latest boid added to the// list becomes the first one when the list is sequentially accessed.// Mostly I did this for speed reasons, as this allows for fast inserts// (and we don't delete from this list, we just rebuild it each update cycle).void CBoid::AddToVisibleList (CBoid *ptr){   // test:  do we see enough buddies already?   if (m_num_flockmates_seen < Max_Friends_Visible) {      // nope--we can add to this one to the list      VisibleFriendsList[m_num_flockmates_seen] = ptr;      // increment counter      m_num_flockmates_seen++;   }#ifdef VISIBILITY_DEBUG   int i;   myprintf("visibility list for %x after adding %x:\n",this,ptr);   for (i = 0; i < m_num_flockmates_seen; i++) {      if (VisibleFriendsList[i] != NULL) {         myprintf("VFL = %x\n",VisibleFriendsList[i]);      } else {         break;      }   }#endif}// ClearVisibleList.// Clears the visibility list.void CBoid::ClearVisibleList (void){   // walk down the list and clear each visible entry   for (int i = 0; i < Max_Friends_Visible; i++) {      VisibleFriendsList[i] = NULL;   }   // clear other visibility info   m_num_flockmates_seen       = 0;   m_nearest_flockmate         = NULL;   m_dist_to_nearest_flockmate = INFINITY;}// Determine whether a given invoking boid can see the boid in question.// Returns the distance to the boid.float CBoid::CanISee (CBoid *ptr){#ifdef VISIBILITY_DEBUG   myprintf("\n   Inside CanISee.\n");#endif   // Test:  if we're looking at ourselves, never mind   if (this == ptr) return (INFINITY);   // figure out distance   float dist = (m_pos.GetDist(m_pos, ptr->m_pos));#ifdef VISIBILITY_DEBUG   myprintf("   dist between %x and %x = %f\n",this,ptr,dist);#endif   // if we're using truth data, don't bother to check sighting   if (UseTruth) return (dist);   // not using truth, so check sighting   if (m_perception_range > dist) return (dist);   // fell through; can't see it   return (INFINITY);}// ComputeRPY.// Computes the roll/pitch/yaw of the flock boid based on its// latest velocity vector changes.  Roll/pitch/yaw are stored in// the "ang" data boid as follows://   pitch is about the x axis//   yaw is about the y axis//   roll is about the z axis//// All calculations assume a right-handed coordinate system://   +x = through the left side of the object//   +y = up//   +z = through the nose of the model//// All angles are computed in radians.//// NOTE:  This algorithm was generously provided by Christopher Kline, who originally//        developed it for *his* flocking applications.  Thanks Christopher!void CBoid::ComputeRPY (void){   float  roll, pitch, yaw;   // Determine the direction of the lateral acceleration.   vector lateralDir = (m_vel % (m_vel - m_oldvel)) % m_vel;   lateralDir.GetDirection();   // Set the lateral acceleration's magnitude. The magnitude is the vector   // projection of the appliedAcceleration vector onto the direction of the   // lateral acceleration).     float lateralMag = (m_vel - m_oldvel) * lateralDir;     // compute roll   if (lateralMag == 0) {      roll = 0.0f;     } else {      roll = (float) -atan2(GRAVITY, lateralMag) + HALF_PI;   }   // compute pitch   pitch = (float) -atan(m_vel.y / sqrt((m_vel.z*m_vel.z) + (m_vel.x*m_vel.x)));   // compute yaw   yaw = (float) atan2(m_vel.x, m_vel.z);   // store them   m_ang.x = pitch;   m_ang.y = yaw;   m_ang.z = roll;#ifdef BOID_DEBUG   myprintf("   roll = %f  pitch = %f  yaw = %f\n",roll, pitch, yaw);#endif}// SetNext.// Set the "next" pointer of an individual boid.void CBoid::SetNext (CBoid *ptr){   m_next = ptr;}// GetNext.// Returns the "next" pointer of the invoking boid.CBoid * CBoid::GetNext(){   return (m_next);}// SetPrev.// Set the "prev" pointer of an individual boid.void CBoid::SetPrev (CBoid *ptr){   m_prev = ptr;}// GetOrient.// Returns the orientation of the boid in question.vector * CBoid::GetOrient (void){   return (&m_ang);}// GetPos.// Returns the position of the boid in question.vector * CBoid::GetPos (void){   return (&m_pos);}// LinkOut.// Removes a boid from a list.void CBoid::LinkOut (){   // test location of boid   if ((m_next == NULL) && (m_prev == NULL)) {      SetNext(NULL);      SetPrev(NULL);   } else if (m_next == NULL) {      m_prev->SetNext(NULL);   } else if (m_prev == NULL) {            m_next->SetPrev(NULL);   } else {      m_prev->SetNext(m_next);      m_next->SetPrev(m_prev);   }}// PrintData// Dumps all data describing a given boid.void CBoid::PrintData (void){   myprintf("===================\n");   myprintf("Data for boid = %d @ %x\n", m_id,this);   myprintf(" perception_range = %f\n", m_perception_range);   myprintf(" pos x, y, z = %f %f %f\n", m_pos.x, m_pos.y, m_pos.z);   myprintf(" vel x, y, z = %f %f %f\n", m_vel.x, m_vel.y, m_vel.z);   myprintf(" roll, pitch, yaw = %f %f %f\n", m_ang.z, m_ang.x, m_ang.y);   myprintf(" speed                     = %f\n", m_speed);   myprintf(" num_flockmates_seen       = %d\n", m_num_flockmates_seen);   myprintf(" nearest_flockmate         = %x\n", m_nearest_flockmate);   myprintf(" dist_to_nearest_flockmate = %f\n", m_dist_to_nearest_flockmate);   myprintf(" num_enemies_seen          = %d\n", m_num_enemies_seen);   myprintf(" nearest_enemy             = %x\n", m_nearest_enemy);   myprintf(" dist_to_nearest_enemy     = %f\n", m_dist_to_nearest_enemy);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -