/*!
  The Creature blueprint has the variable simdata which is updated here.
*/
void BulletCreature::CollectData() {
  SimData data = blueprint_.simdata;

  data.distance_light += GetDistanceToLight();
  data.distance_z = GetCenterOfMass().getZ();
  data.max_y = (GetCenterOfMass().getY() > data.max_y) ?
          GetCenterOfMass().getY() : data.max_y;
  data.accumulated_y += GetCenterOfMass().getY();
  data.deviation_x = abs(GetCenterOfMass().getX())+0.0001;
  data.accumulated_head_y += GetHeadPosition().getY();

  blueprint_.simdata = data;
}
void CompoundBody::ComputeInertia()
{
	//http://en.wikipedia.org/wiki/Parallel_axis_theorem
	//Uses the parallel axis theorem to compute a combined
	//Inertia tensor in world space around the center of mass
	//for the entire compound body

	//Skew-symmetric matrices are used as a supplement to
	//cross products.

	AglMatrix inertia = AglMatrix::zeroMatrix();
	AglMatrix id = AglMatrix::identityMatrix();
	for (unsigned int i = 0; i < mChildren.size(); i++)
	{
		AglMatrix orientation = mChildren[i]->GetWorld();
		orientation[15] = 1;
		orientation[14] = 0;
		orientation[13] = 0;
		orientation[12] = 0;
		AglMatrix InertiaWorld = AglMatrix::transpose(orientation) * mChildren[i]->GetLocalInertia() * orientation;
		AglVector3 r = mChildren[i]->GetLocalCenterOfMass() - GetCenterOfMass();

		//OuterProduct
		AglMatrix outer(r.x * r.x, r.x * r.y, r.x * r.z, 0, r.y * r.x, r.y * r.y, r.z * r.x, 0,
						r.z * r.x, r.z * r.y, r.z * r.x, 0, 0, 0, 0, 0);

		inertia += InertiaWorld + (id*AglVector3::dotProduct(r, r) - outer) * mChildren[i]->GetLocalMass();
	}
	mInertiaWorld = inertia;
	mInverseInertiaWorld = AglMatrix::inverse(mInertiaWorld);
}
void mitk::ConnectomicsNetworkCreator::CreateNewNode( int label, itk::Index<3> index, bool useCoM )
{
  // Only create node if it does not exist yet

  if( ! ( m_LabelToNodePropertyMap.count( label ) > 0 ) )
  {
    NetworkNode newNode;

    newNode.coordinates.resize( 3 );
    if( !useCoM )
    {
      for( unsigned int loop = 0; loop < newNode.coordinates.size() ; loop++ )
      {
        newNode.coordinates[ loop ] = index[ loop ] ;
      }
    }
    else
    {
      std::vector<double> labelCoords = GetCenterOfMass( label );
      for( unsigned int loop = 0; loop < newNode.coordinates.size() ; loop++ )
      {
        newNode.coordinates[ loop ] = labelCoords.at( loop ) ;
      }
    }

    newNode.label = LabelToString( label );

    m_LabelToNodePropertyMap.insert( std::pair< ImageLabelType, NetworkNode >( label, newNode ) );
  }
}
CvPlot* CvArmyAI::CheckTargetReached(PlayerTypes eEnemy, bool bNavalOp, int iMaxDistance)
{
	//check if we're at the target
	CvPlot *pTargetPlot = GetGoalPlot();
	CvPlot *pCenterOfMass = GetCenterOfMass(NO_DOMAIN);
	if(pCenterOfMass && pTargetPlot && plotDistance(*pCenterOfMass,*pTargetPlot) <= iMaxDistance)
		return pTargetPlot;

	//check early termination if we ran into the enemy
	if(GetArmyAIState() == ARMYAISTATE_MOVING_TO_DESTINATION)
	{
		CvPlot*	pEnemyPlot = DetectNearbyEnemy(eEnemy, bNavalOp);
		if(pEnemyPlot != NULL)
		{
			CvCity* pCity = pEnemyPlot->getWorkingCity();
			if(pCity != NULL)
			{
				if (bNavalOp && pCity->isCoastal() && pCity->waterArea()==pTargetPlot->area())
					pEnemyPlot = pCity->plot();

				if (!bNavalOp && pCity->area()==pTargetPlot->area())
					pEnemyPlot = pCity->plot();

				if (pEnemyPlot!=GetGoalPlot())
				{
					if(GC.getLogging() && GC.getAILogging())
					{
						CvString strMsg;
						strMsg.Format("Switching target from %d,%d to closest city at %d,%d", GetGoalX(), GetGoalY(), pEnemyPlot->getX(), pEnemyPlot->getY() );
						GET_PLAYER(m_eOwner).getAIOperation(m_iOperationID)->LogOperationSpecialMessage(strMsg);
					}
				}

				return pEnemyPlot;
			}
		}
	}

	return NULL;
}