예제 #1
0
void TriggerHitCircle::Collide(const CollisionEvent& coll)
{
   Ball * const pball = coll.m_ball;

   if ((m_ObjType < eTrigger) || // triggers and kickers
      (!pball->m_vpVolObjs)) return;

   const int i = FindIndexOf(*(pball->m_vpVolObjs), m_obj); // if -1 then not in objects volume set (i.e not already hit)

   if ((!coll.m_hitflag) == (i < 0))                 // Hit == NotAlreadyHit
   {
      pball->m_pos += STATICTIME * pball->m_vel;     //move ball slightly forward

      if (i < 0)
      {
         pball->m_vpVolObjs->push_back(m_obj);
         ((Trigger*)m_obj)->TriggerAnimationHit();
         ((Trigger*)m_obj)->FireGroupEvent(DISPID_HitEvents_Hit);
      }
      else
      {
         pball->m_vpVolObjs->erase(pball->m_vpVolObjs->begin() + i);
         ((Trigger*)m_obj)->TriggerAnimationUnhit();
         ((Trigger*)m_obj)->FireGroupEvent(DISPID_HitEvents_Unhit);
      }
   }
}
예제 #2
0
long XStrList::Add( const UtilStr& inStr ) {
	bool doAdd = true;
	
	if ( mStrListOption != cDuplicatesAllowed ) 
		doAdd = FindIndexOf( inStr ) == 0;
	
	if ( doAdd )
		return mStrings.Add( new UtilStr( inStr ) );
	else
		return 0;
}
예제 #3
0
long XStrList::Add( const char* inStr ) {
	UtilStr* s		= new UtilStr( inStr );
	bool 	doAdd	= true;
	
	if ( mStrListOption != cDuplicatesAllowed ) 
		doAdd = FindIndexOf( *s ) == 0;
	
	if ( doAdd ) 
		return mStrings.Add( s );
	else {
		delete s;
		return 0;
	}
}
예제 #4
0
void Hit3DPoly::Collide(const CollisionEvent& coll)
{
   Ball * const pball = coll.m_ball;
   const Vertex3Ds& hitnormal = coll.m_hitnormal;

   if (m_ObjType != eTrigger)
   {
      const float dot = -(hitnormal.Dot(pball->m_vel));

      pball->Collide3DWall(m_normal, m_elasticity, m_elasticityFalloff, m_friction, m_scatter);

      if (m_obj && m_fe && dot >= m_threshold)
      {
          if (m_ObjType == ePrimitive)
          {
             m_obj->m_currentHitThreshold = dot;
             FireHitEvent(pball);
          }
          else if (m_ObjType == eHitTarget && ((HitTarget*)m_obj)->m_d.m_isDropped == false)
          {
             ((HitTarget*)m_obj)->m_hitEvent = true;
             m_obj->m_currentHitThreshold = dot;
             FireHitEvent(pball);
          }
      }
   }
   else // trigger:
   {
      if (!pball->m_vpVolObjs) return;

      const int i = FindIndexOf(*(pball->m_vpVolObjs), m_obj); // if -1 then not in objects volume set (i.e not already hit)

      if ((!coll.m_hitflag) == (i < 0)) // Hit == NotAlreadyHit
      {
         pball->m_pos += STATICTIME * pball->m_vel;      //move ball slightly forward

         if (i < 0)
         {
            pball->m_vpVolObjs->push_back(m_obj);
            ((Trigger*)m_obj)->FireGroupEvent(DISPID_HitEvents_Hit);
         }
         else
         {
            pball->m_vpVolObjs->erase(pball->m_vpVolObjs->begin() + i);
            ((Trigger*)m_obj)->FireGroupEvent(DISPID_HitEvents_Unhit);
         }
      }
   }
}
예제 #5
0
bool IsEdgeInTrail(int cityX, int cityY, int *path)
    {
      int lastIndex = n - 1;
      int idx = FindIndexOf(cityX, path);

      if (idx == 0 && path[1] == cityY) return true;
      else if (idx == 0 && path[lastIndex] == cityY) return true;
      else if (idx == 0) return false;
      else if (idx == lastIndex && path[lastIndex - 1] == cityY) return true;
      else if (idx == lastIndex && path[0] == cityY) return true;
      else if (idx == lastIndex) return false;
      else if (path[idx - 1] == cityY) return true;
      else if (path[idx + 1] == cityY) return true;
      else return false;
    }
예제 #6
0
long XStrList::FindIndexOf( const UtilStr& inStr ) const {
	int			i = 1;
	UtilStr*	str;
	bool		caseSens	= mStrListOption != cNoDuplicates_CaseInsensitive;
	
	if ( mStrings.mCompFcn ) {
		i = mStrings.FetchPredIndex( &inStr ) + 1;
		if ( mStrings.Fetch( i, (void**) &str ) ) {
			if ( str -> compareTo( &inStr, caseSens ) == 0 )
				return i;
		} }
	else
		return FindIndexOf( inStr.getCStr() );
	
	return 0;
}
예제 #7
0
int *CreateRandomPath(const int start)
{
	vector <int> trail; // wektor opisuj�cy losow� �cie�k�

	for(int i=0;i<n;i++) trail.push_back(i); // wrzucenie do wektora �cie�ki od 0 do n-1

	random_shuffle(trail.begin(),trail.end()); // wymieszanie losowe warto�ci wektora (�cie�ki)

	int temp = FindIndexOf(start,&trail[0]); // Szuka indeks w kt�rym znajduje si� warto�� 'start'
	
	swap(trail[0],trail[temp]);

	int *tab = new int[n];

	for(int i=0;i<n;i++) 
		tab[i] = trail[i];

	return tab; // zwraca adres pocz�tkowy wektora i przypisuje do jakiej� tablicy int
}
예제 #8
0
float Hit3DPoly::HitTest(const Ball * const pball, const float dtime, CollisionEvent& coll) const
{
   if (!m_fEnabled) return -1.0f;

   const float bnv = m_normal.Dot(pball->m_vel);  //speed in Normal-vector direction

   if ((m_ObjType != eTrigger) && (bnv > C_LOWNORMVEL)) // return if clearly ball is receding from object
      return -1.0f;

   // Point on the ball that will hit the polygon, if it hits at all
   Vertex3Ds hitPos = pball->m_pos - pball->m_radius * m_normal; // nearest point on ball ... projected radius along norm

   const float bnd = m_normal.Dot(hitPos - m_rgv[0]); // distance from plane to ball

   bool bUnHit = (bnv > C_LOWNORMVEL);
   const bool inside = (bnd <= 0.f);                // in ball inside object volume

   const bool rigid = (m_ObjType != eTrigger);
   float hittime;
#ifdef NEW_PHYSICS
   bool isContact = false;
#endif
   if (rigid) //rigid polygon
   {
      if (bnd < -pball->m_radius/**2.0f*/) return -1.0f; // (ball normal distance) excessive penetration of object skin ... no collision HACK //!! *2 necessary?

      if (bnd <= (float)PHYS_TOUCH)
      {
#ifdef NEW_PHYSICS
          if (fabsf(bnv) <= C_CONTACTVEL)
          {
              hittime = 0;
              isContact = true;
          }
          else if (inside)
              hittime = 0;                          // zero time for rigid fast bodies
          else
              hittime = bnd / -bnv;
#else
          if (inside || (fabsf(bnv) > C_CONTACTVEL) // fast velocity, return zero time
                                                    //zero time for rigid fast bodies
              || (bnd <= (float)(-PHYS_TOUCH)))     // slow moving but embedded
              hittime = 0;
          else
              hittime = bnd*(float)(1.0/(2.0*PHYS_TOUCH)) + 0.5f;	// don't compete for fast zero time events
#endif
      }
      else if (fabsf(bnv) > C_LOWNORMVEL)           // not velocity low?
          hittime = bnd / -bnv;                     // rate ok for safe divide 
      else
          return -1.0f;                             // wait for touching
   }
   else //non-rigid polygon
   {
      if (bnv * bnd >= 0.f)                         // outside-receding || inside-approaching
      {
         if (//(m_ObjType != eTrigger) ||             // not a trigger? // always false due to rigid test
            (!pball->m_vpVolObjs) ||                // temporary ball
            // if trigger, then check:
            (fabsf(bnd) >= pball->m_radius*0.5f) ||	// not too close ... nor too far away
            (inside != (FindIndexOf(*(pball->m_vpVolObjs), m_obj) < 0))) // ...ball outside and hit set or ball inside and no hit set
            return -1.0f;

         hittime = 0;
         bUnHit = !inside;	// ball on outside is UnHit, otherwise it's a Hit
      }
      else
         hittime = bnd / (-bnv);
   }

   if (infNaN(hittime) || hittime < 0 || hittime > dtime) return -1.0f;	// time is outside this frame ... no collision

   hitPos += hittime * pball->m_vel;     // advance hit point to contact

   // Do a point in poly test, using the xy plane, to see if the hit point is inside the polygon
   //this need to be changed to a point in polygon on 3D plane

   float x2 = m_rgv[0].x;
   float y2 = m_rgv[0].y;
   bool hx2 = (hitPos.x >= x2);
   bool hy2 = (hitPos.y <= y2);
   int crosscount = 0;	// count of lines which the hit point is to the left of
   for (int i = 0; i < m_cvertex; i++)
   {
      const float x1 = x2;
      const float y1 = y2;
      const bool hx1 = hx2;
      const bool hy1 = hy2;

      const int j = (i < m_cvertex - 1) ? (i + 1) : 0;
      x2 = m_rgv[j].x;
      y2 = m_rgv[j].y;
      hx2 = (hitPos.x >= x2);
      hy2 = (hitPos.y <= y2);

      if ((y1 == y2) ||
         (hy1 && hy2) || (!hy1 && !hy2) || // if out of y range, forget about this segment
         (hx1 && hx2)) // Hit point is on the right of the line
         continue;

      if (!hx1 && !hx2)
      {
         crosscount ^= 1;
         continue;
      }

      if (x2 == x1)
      {
         if (!hx2)
            crosscount ^= 1;
         continue;
      }

      // Now the hard part - the hit point is in the line bounding box

      if (x2 - (y2 - hitPos.y)*(x1 - x2) / (y1 - y2) > hitPos.x)
         crosscount ^= 1;
   }

   if (crosscount & 1)
   {
      coll.m_hitnormal = m_normal;

      if (!rigid)                 // non rigid body collision? return direction
         coll.m_hitflag = bUnHit; // UnHit signal	is receding from outside target

      coll.m_hitdistance = bnd;   // 3dhit actual contact distance ... 
      //coll.m_hitRigid = rigid;  // collision type

#ifdef NEW_PHYSICS
      coll.m_isContact = isContact;
      if (isContact)
         coll.m_hit_org_normalvelocity = bnv;
#endif

      return hittime;
   }

   return -1.0f;
}