void vParticleOperator_GravityWorld::Simulate( vParticle *parent )
{
	float dot_z = DotProduct( MainViewForward(), Vector( 0, 0, -1 ) );
	float rotation_dir = Sign( dot_z );

	int vx, vy, w, t;
	vgui::surface()->GetFullscreenViewport( vx, vy, w, t );

	Vector screen;
	if ( ScreenTransform( MainViewOrigin() + Vector( 0, 0, 100 ), screen ) )
		ScreenTransform( MainViewOrigin() - Vector( 0, 0, 100 ), screen );

	screen *= Vector( 0.5f, -0.5f, 0 );
	screen += Vector( 0.5f, 0.5f, 0 );

	Vector2D gravity_center( w * screen.x, t * screen.y );
	Vector2D delta = parent->vecPos - gravity_center;

	float screenLength = delta.NormalizeInPlace();
	delta *= rotation_dir * -1.0f;

	Vector2D accel = delta * vParticle::GetRelativeScale() * GetImpulse( parent ) * amt;

	float speedMult = 1.0f;

	if ( rotation_dir > 0 )
	{
		float drag = RemapValClamped( rotation_dir, 0.5f, 1, 1, 0.00001f );
		ScaleByFrametime( drag );

		speedMult = RemapValClamped( (screenLength/vParticle::GetRelativeScale()), 0, 1000, 0, 1 ) * (1.0f - drag) + drag;
	}

	parent->vecVelocity += accel;
	parent->vecVelocity *= speedMult;
}
double CXTPChartMathUtils::NormalizeRadian(double angleRadian)
{
	double x = fabs(angleRadian) / (m_dPI * 2);
	x = m_dPI * 2 * (x - floor(x));
	return x * Sign(angleRadian);
}
Пример #3
0
/**
* 计算用同一dash_power到达某点需要的时间
* Caculate cycles needed to a target position with a certain dash power.
* @param player the player to caculate.
* @param target the target position to go to.
* @param dash_power the power for dash to predict.
* @return an integer to show the cycles caculated.
*/
int Dasher::CyclePredictedToPoint(const PlayerState& player , Vector target , double dash_power)
{
	double corrected_dash_power = dash_power;
	double effective_power;
	double predicted_stamina = player.GetStamina();
	double predicted_effort  = player.GetEffort();
	double predicted_recovery = player.GetRecovery();
	double predicted_capacity = player.GetCapacity();
	double myang = player.GetBodyDir();
	Vector position = player.GetPos();
	Vector velocity;

	if (player.GetVelConf() < FLOAT_EPS)
	{
		velocity = Vector(0,0);
	}
	else
	{
		velocity = player.GetVel();
	}

	Vector last_position = position;
	int max_cyc = (int)(position.Dist(target) / player.GetEffectiveSpeedMax() + 100);
	int last_action = 0; /* 0 -- turn , 1 -- dash*/

	for (int i = 0;i < max_cyc;i++)
	{
		if (position.Dist(target) < PlayerParam::instance().AtPointBuffer())
		{
			return i;
		}

		if (position.Dist(target) > last_position.Dist(target) + FLOAT_EPS && last_action == 1)
		{
			return i;
		}

		last_position = position;

		/*decide if we should turn*/
		double targ_ang;
		if (dash_power > 0)
		{
			targ_ang = (target - position).Dir() - myang;
		}
		else
		{
			targ_ang = (target - position).Dir() - GetNormalizeAngleDeg(myang + 180);
		}

		double max_go_to_point_angle_err = 4; //见08CP_max_go_to_point_angle_err
		if (fabs(GetNormalizeAngleDeg(targ_ang)) > max_go_to_point_angle_err)
		{
			/*turnint*/
			double this_turn = MinMax(-player.GetMaxTurnAngle(), GetNormalizeAngleDeg(targ_ang) , player.GetMaxTurnAngle());

			myang += this_turn;
			corrected_dash_power = 0;
			last_action = 0;
		}
		else
		{
			corrected_dash_power = player.CorrectDashPowerForStamina(dash_power);
			if (fabs(corrected_dash_power) > predicted_stamina)
			{
				effective_power = Sign(corrected_dash_power) * predicted_stamina;
			}
			else
			{
				effective_power = corrected_dash_power;
			}

			effective_power *= predicted_effort;
			effective_power *= player.GetDashPowerRate();
			velocity += Polar2Vector(effective_power , myang);
			last_action = 1;
		}

		if (velocity.Mod() > player.GetEffectiveSpeedMax())
		{
			velocity *= (player.GetEffectiveSpeedMax()/ velocity.Mod());
		}

		position += velocity;
		velocity *= player.GetPlayerDecay();

		//08 内UpdatePredictStaminaWithDash函数 直接写入此函数
		if (dash_power > 0)
		{
			predicted_stamina -= dash_power;
		}
		else
		{
			predicted_stamina -= 2 * dash_power;
		}

		if (predicted_stamina < 0)
		{
			predicted_stamina = 0;
		}

		if (predicted_stamina < ServerParam::instance().recoverDecStamina() && predicted_recovery > ServerParam::instance().recoverMin())
		{
			predicted_recovery -= ServerParam::instance().recoverDec();
		}

		if (predicted_stamina < ServerParam::instance().effortDecStamina()  && predicted_effort > player.GetEffortMin())
		{
			predicted_effort -= ServerParam::instance().effortDec();
		}

		if (predicted_stamina > ServerParam::instance().effortIncStamina() && predicted_effort < player.GetEffortMax())
		{
			predicted_effort += ServerParam::instance().effortDec();
		}

		//增加capacity改进
		double stamina_inc = Min(predicted_recovery * player.GetStaminaIncMax() , predicted_capacity);
		predicted_stamina += stamina_inc;
		if (predicted_stamina > ServerParam::instance().staminaMax())
		{
			predicted_stamina = ServerParam::instance().staminaMax();
		}

		predicted_capacity -= stamina_inc;
		if (predicted_capacity < 0)
		{
			predicted_capacity = 0;
		}
	}

	return max_cyc;
}
Пример #4
0
bool ShootingCans::draw(bool hit, Vector &hitPoint) {

    switch (mode) {
    case INIT:
        startGame();
        infobox->set("bounce at the cans.");
        break;
    case PLAY:
        // check hit
        if (hit) {
            infobox->clear();
            ballHits++;

            if (!gameStarted) {
                gameStarted = true;
                startTime = ofGetElapsedTimef() + 120;
            }

            for (int i = 0; i < cans.size(); i++) {
                if (cans[i].checkHit(hitPoint)) {
                    points += 100;
                    signs.push_back(Sign("+100", hitPoint, 2.0));

                    shootedCans.push_back(cans[i]);
                    cans.erase(cans.begin() + i);
                    i--;

                    if (points == 1000) {
                        int timeBonus = (startTime - ofGetElapsedTimef()) * 10;
                        points += timeBonus;

                        string bonus = "timebonus: +" + ofToString(timeBonus);
                        signs.push_back(Sign(bonus, Vector((ofGetWidth() - gameFont.stringWidth(bonus)) / 2, ofGetHeight() / 2), 3.0));

                        points -= ballHits * 10;
                        string minus = "ballthrows: -" + ofToString(ballHits * 10);
                        signs.push_back(Sign(minus, Vector((ofGetWidth() - gameFont.stringWidth(minus)) / 2, ofGetHeight() / 2 + 40), 4.0));
                    }
                }
            }
        }

        if (gameStarted)
            screenTime = startTime - ofGetElapsedTimef();

        if ((cans.size() == 0 && signs.size() == 0) || screenTime <= 0)
            stopGame();

        for (int i = 0; i < shootedCans.size(); i++) {
            if (!shootedCans[i].draw()) {
                shootedCans.erase(shootedCans.begin() + i);
                i--;
            }
        }
        drawBg();
        break;
    case PANEL:
        drawBg();
        drawPanel();

        if (hit && !insertName)
            return false;

        break;
    default:
        break;
    }

    drawSigns();

    return true;
}
Пример #5
0
void CPhysicsSystem::PhysicsSimulate()
{
	CMiniProfilerGuard mpg(&g_mp_PhysicsSimulate);
	VPROF_BUDGET( "CPhysicsSystem::PhysicsSimulate", VPROF_BUDGETGROUP_PHYSICS );
	float frametime = gpGlobals->frametime;

	if ( physenv )
	{
		g_Collisions.BufferTouchEvents( true );
#ifdef _DEBUG
		physenv->DebugCheckContacts();
#endif
		frametime *= cl_phys_timescale.GetFloat();

		int maxTicks = cl_phys_maxticks.GetInt();
		if ( maxTicks )
		{
			float maxFrameTime = physenv->GetDeltaFrameTime( maxTicks ) - 1e-4f;
			frametime = clamp( frametime, 0, maxFrameTime );
		}

		physenv->Simulate( frametime );

		int activeCount = physenv->GetActiveObjectCount();
		g_mp_active_object_count.Add(activeCount);
		IPhysicsObject **pActiveList = NULL;
		if ( activeCount )
		{
			PHYS_PROFILE(aUpdateActiveObjects)
			pActiveList = (IPhysicsObject **)stackalloc( sizeof(IPhysicsObject *)*activeCount );
			physenv->GetActiveObjects( pActiveList );

			for ( int i = 0; i < activeCount; i++ )
			{
				C_BaseEntity *pEntity = reinterpret_cast<C_BaseEntity *>(pActiveList[i]->GetGameData());
				if ( pEntity )
				{
					//const CCollisionProperty *collProp = pEntity->CollisionProp();
					//debugoverlay->AddBoxOverlay( collProp->GetCollisionOrigin(), collProp->OBBMins(), collProp->OBBMaxs(), collProp->GetCollisionAngles(), 190, 190, 0, 0, 0.01 );

					if ( pEntity->CollisionProp()->DoesVPhysicsInvalidateSurroundingBox() )
					{
						pEntity->CollisionProp()->MarkSurroundingBoundsDirty();
					}
					pEntity->VPhysicsUpdate( pActiveList[i] );
					IPhysicsShadowController *pShadow = pActiveList[i]->GetShadowController();
					if ( pShadow )
					{
						// active shadow object, check for error
						Vector pos, targetPos;
						QAngle rot, targetAngles;
						pShadow->GetTargetPosition( &targetPos, &targetAngles );
						pActiveList[i]->GetPosition( &pos, &rot );
						Vector delta = targetPos - pos;
						float dist = VectorNormalize(delta);
						bool bBlocked = false;
						if ( dist > cl_phys_block_dist.GetFloat() )
						{
							Vector vel;
							pActiveList[i]->GetImplicitVelocity( &vel, NULL );
							float proj = DotProduct(vel, delta);
							if ( proj < dist * cl_phys_block_fraction.GetFloat() )
							{
								bBlocked = true;
								//Msg("%s was blocked %.3f (%.3f proj)!\n", pEntity->GetClassname(), dist, proj );
							}
						}
						Vector targetAxis;
						float deltaTargetAngle;
						RotationDeltaAxisAngle( rot, targetAngles, targetAxis, deltaTargetAngle );
						if ( fabsf(deltaTargetAngle) > 0.5f )
						{
							AngularImpulse angVel;
							pActiveList[i]->GetImplicitVelocity( NULL, &angVel );
							float proj = DotProduct( angVel, targetAxis ) * Sign(deltaTargetAngle);
							if ( proj < (fabsf(deltaTargetAngle) * cl_phys_block_fraction.GetFloat()) )
							{
								bBlocked = true;
								//Msg("%s was rot blocked %.3f proj %.3f!\n", pEntity->GetClassname(), deltaTargetAngle, proj );
							}
						}
					
						if ( bBlocked )
						{
							C_BaseEntity *pBlocker = FindPhysicsBlocker( pActiveList[i] );
							if ( pBlocker )
							{
								if ( IsBlockedShouldDisableCollisions( pEntity ) )
								{
									PhysDisableEntityCollisions( pEntity, pBlocker );
									pActiveList[i]->RecheckContactPoints();
									// GetClassname returns a pointer to the same buffer always!
									//Msg("%s blocked !", pEntity->GetClassname() ); Msg("by %s\n", pBlocker->GetClassname() );
								}
							}
						}
					}
				}
			}
		}

#if 0
		if ( cl_visualize_physics_shadows.GetBool() )
		{
			int entityCount = NUM_ENT_ENTRIES;
			for ( int i = 0; i < entityCount; i++ )
			{
				IClientEntity *pClientEnt = cl_entitylist->GetClientEntity(i);
				if ( !pClientEnt )
					continue;
				C_BaseEntity *pEntity = pClientEnt->GetBaseEntity();
				if ( !pEntity )
					continue;

				Vector pos;
				QAngle angle;
				IPhysicsObject *pObj = pEntity->VPhysicsGetObject();
				if ( !pObj || !pObj->GetShadowController() )
					continue;

				pObj->GetShadowPosition( &pos, &angle );
				debugoverlay->AddBoxOverlay( pos, pEntity->CollisionProp()->OBBMins(), pEntity->CollisionProp()->OBBMaxs(), angle, 255, 255, 0, 32, 0 );
				char tmp[256];
				V_snprintf( tmp, sizeof(tmp),"%s, (%s)\n", pEntity->GetClassname(), VecToString(angle) );
				debugoverlay->AddTextOverlay( pos, 0, tmp );
			}
		}
#endif
		g_Collisions.BufferTouchEvents( false );
		g_Collisions.FrameUpdate();
	}
	physicssound::PlayImpactSounds( m_impactSounds );
}
Пример #6
0
void MonotonicAccelInterpolate(const vector<Vector>& pts,vector<GeneralizedCubicBezierCurve>& paths,CSpace* space,GeodesicManifold* manifold)
{
  Assert(pts.size() >= 2);
  
  vector<Vector> tangents(pts.size()),inslopes(pts.size()-1),outslopes(pts.size()-1);
  paths.resize(pts.size()-1);
  for(size_t i=0;i<paths.size();i++) {
    paths[i].x0 = pts[i];
    paths[i].x3 = pts[i+1];
    paths[i].space = space;
    paths[i].manifold = manifold;
  }
  paths[0].x0 = pts[0];
  paths[0].x3 = pts[1];
  if(pts.size() == 2) {
    paths[0].SetSmoothTangents(NULL,NULL);
    return;
  }
  paths[0].SetSmoothTangents(NULL,&pts[2]);
  paths[0].Deriv(0,tangents[0]);
  paths.back().x0 = pts[pts.size()-2];
  paths.back().x3 = pts[pts.size()-1];
  paths.back().SetSmoothTangents(&pts[pts.size()-3],NULL);
  paths.back().Deriv(1,tangents.back());
  for(size_t i=1;i<pts.size();i++) {
    if(!manifold) {
      inslopes[i-1] = pts[i]-pts[i-1];
      outslopes[i-1].setRef(inslopes[i-1]);
    }
    else {
      manifold->InterpolateDeriv(pts[i-1],pts[i],0,inslopes[i-1]);
      manifold->InterpolateDeriv(pts[i],pts[i-1],0,outslopes[i-1]);
      outslopes[i-1].inplaceNegative();
    }
    if(i+1<pts.size()) {
      if(!manifold)
	tangents[i] = (pts[i+1]-pts[i-1])*0.5;
      else {
	Vector n,p;
	manifold->InterpolateDeriv(pts[i],pts[i+1],0,n);
	manifold->InterpolateDeriv(pts[i],pts[i-1],0,p);
	tangents[i] = (n-p)*0.5;
      }
    }
  }
  int n=pts[0].n;
  for(size_t i=0;i<pts.size();i++) {
    if(tangents[i].n != n) printf("%d / %d\n",i,tangents.size());
    Assert(tangents[i].n == n);
  }
  for(size_t i=0;i+1<pts.size();i++) {
    if(i == 1)
      cout<<"Orig tangent 2: "<<tangents[i+1]<<endl;
    for(int j=0;j<n;j++) {
      if(j==0) {
	printf("Segment %d: accel in %g, out %g\n",i,3.0*inslopes[i][j] - tangents[i+1][j]-2*tangents[i][j],2*tangents[i+1][j]+tangents[i][j] - 3.0*outslopes[i][j]);
      }
      if(Sign(3.0*inslopes[i][j] - tangents[i+1][j] - 2*tangents[i][j]) != Sign(2*tangents[i+1][j]+tangents[i][j] - 3.0*outslopes[i][j])) {
	//(3.0*mi - x - 2*t0)*(2*x+t0 - 3.0*mo) = 0
	//(- x + 3.0*mi - 2*t0)*(2*x+t0 - 3.0*mo) = 
	//    -2x^2 + x*(-t0+3mo+6mi-4t0) + (3mi-2t0)(t0-3mo) = 0
	//solve quadratic to set tangents[i+1][j] so one accel becomes
	//nullified
	Real a = -2.0;
	Real b = 6*inslopes[i][j] + 3*outslopes[i][j]-5*tangents[i][j];
	Real c = (3*inslopes[i][j]-2*tangents[i][j])*(tangents[i][j]-3*outslopes[i][j]);
	Real t1,t2;
	int res=quadratic(a,b,c,t1,t2);
	if(res == 0) {
	  if(j==0) 
	    printf("No solution to quadratic %g %g %g\n",a,b,c);
	}
	else {
	  assert(res > 0);
	  if(res == 2) {
	    //pick the closer one to the existing tangent
	    if(Abs(t1 - tangents[i+1][j]) > Abs(t2 - tangents[i+1][j]))
	      t1 = t2;
	  }
	  tangents[i+1][j] = t1;
	  if(j==0) {
	    printf("New accel in %g, out %g\n",3.0*inslopes[i][j] - tangents[i+1][j]-2*tangents[i][j],2*tangents[i+1][j]+tangents[i][j] - 3.0*outslopes[i][j]);
	  }
	}
      }
    }
    if(i == 1)
      cout<<"New tangent 2: "<<tangents[i+1]<<endl;
  }
  for(size_t i=0;i+1<pts.size();i++) {
    paths[i].SetNaturalTangents(tangents[i],tangents[i+1]);
    Vector temp,temp2;
    paths[i].Accel(0,temp);
    paths[i].Accel(1,temp2);
    cout<<"in "<<temp[0]<<" out "<<temp2[0]<<endl;
  }
}
Пример #7
0
void MN_BstRes::EvalProducts(CNodeEvalIndex & NEI)
{
    if (NoFlwIOs()<2)
        return;

    if (!bOnLine && !IO_Zero(0))
    {
        const int In  = TwoIOInIndex();
        const int Out = OtherEnd(In);
        SpConduit & Fi=*IOConduit(In);
        SpConduit & Fo=*IOConduit(Out);
        dDuty = 0.0;
        Fo.QCopy(Fi);
        IOFB(0,0)->SetQm(Sign(IOFB(0,0)->GetQm())*Fo.QMass(som_ALL));
        if (NetProbalMethod())
        {
            dPout = Fo.Press();
            dTout = Fo.Temp();
        }
        else
        {
            m_FTB.BeginEvalProducts(Fo);
            IOFB(0,0)->EvalProducts(IOP_Flng(In), IOP_Flng(Out), Fo, m_FTB);//);
            m_FTB.EndEvalProducts();
        }
        return;
    }

    if (NetProbalMethod())
    {
        const int In  = TwoIOInIndex();
        const int Out = OtherEnd(In);
        SpConduit & Fi=*IOConduit(In);
        SpConduit & Fo=*IOConduit(Out);
        if (IO_Zero(0))
        {
            Fi.QSetTraceMass();//QZero();
            Fo.QSetTraceMass();//QZero();
            IOFB(0,0)->SetQm(0.0);
            dDuty = 0.0;
            dPout = Fo.Press();
            dTout = Fo.Temp();
        }
        else
        {
            Fo.QCopy(Fi);
            IOFB(0,0)->SetQm(Sign(IOFB(0,0)->GetQm())*Fo.QMass(som_ALL));
            dPout = Fo.Press();
            switch (iPressMethod)
            {
            case BRPM_None :
                break;
            case BRPM_Fixed:
                dPout = Range(1.0, dPout_Rqd, 1.0e15);
                break;
            case BRPM_Boost:
            case BRPM_Drop :
                dPout = Range(1.0, dPout+dPressBoost_Rqd, 1.0e15);
                break;
            case BRPM_Atmos:
                dPout = AtmosPress();
                break;
            case BRPM_SatP : /*dPout = todo*/
                break;
            }

            if (bIsentropic)
            {   //for pump maintain entropy...
                const double TOut = Fo.Temp();
                const double h0 = Fo.totHf();
                const double s0 = Fo.totSf();
                CPumpTempFnd Fnd(Fo, dPout);
                Fnd.SetTarget(s0);
                if (Valid(dTout))
                {
                    Fnd.SetEstimate(dTout, -1.0);
                    //dTout = dNAN;
                }
                bool OK = 0;
                const double MnX = max(dTout-100.0, ZeroCinK); //WHAT LIMITS SHOULD BE USED???!!!
                const double MxX = dTout+200.0; //WHAT LIMITS SHOULD BE USED???!!!
                int iRet = Fnd.Start(MnX, MxX);
                if (iRet==RF_EstimateOK) //estimate is good, solve not required
                {
                    OK=1;
                }
                else
                {
                    if (iRet==RF_BadEstimate)
                        iRet = Fnd.Start(MnX, MxX); // Restart
                    if (iRet==RF_OK)
                        if (Fnd.Solve_Brent()==RF_OK)
                        {
                            OK=1;
                        }
                    if (iRet==RF_LoLimit)
                    {
                        //dCalcT = MnX;
                    }
                    else if (iRet==RF_HiLimit)
                    {
                        //dCalcT = MxX;
                    }
                }
                //SetCI(?, !OK); //Brent solve problem!
                dDuty = Fo.totHf() - h0;
            }
            else
            {
                if (Valid(dTout_Rqd))
                {
                    const double h0 = Fo.totHf();
                    Fo.SetTemp(dTout_Rqd);
                    dDuty = Fo.totHf() - h0;
                }
                else if (fabs(dDuty_Rqd)>1.0e-12)
                {
                    const double h0 = Fo.totHf();
                    Fo.Set_totHf(h0+dDuty_Rqd);
                    dDuty = dDuty_Rqd;
                }
                else
                    dDuty = 0.0;
                const double h1 = Fo.totHf();
                Fo.SetPress(dPout);
                Fo.Set_totHf(h1); //restore enthalpy
            }
            m_VLE.PFlash(Fo, IOP_Flng(Out), 0.0, VLEF_Null);
            dTout = Fo.Temp();
        }
    }
    else
    {   //dynamic...
        CLinkRec & L=m_Links[0];

        if (fabs(L.FB.m_Qm)==0)
        {
            SpConduit & Fi=*IOConduit(0);
            SpConduit & Fo=*IOConduit(1);

            if (m_LeakI.Enabled)
                m_LeakI.EvalProducts(Fi, false);
            else
                Fi.QSetTraceMass();

            L.Cd.QSetTraceMass();
            m_FTB.BeginEvalProducts(L.Cd);
            L.FB.EvalProducts(L.PB(0).P, L.PB(1).P, L.Cd, m_FTB);
            m_FTB.EndEvalProducts();

            if (m_LeakO.Enabled)
                m_LeakO.EvalProducts(Fo, false);
            else
                Fo.QSetTraceMass();
            dDuty = 0.0;
        }
        else
        {
            int In=(L.FB.m_Qm>0 ? 0:1);
            int Out=OtherEnd(In);

            SpConduit & Fi=*IOConduit(In);
            SpConduit & Fo=*IOConduit(Out);

            Fo.QCopy(Fi);

            //heat loss/gain for simple heater:
            const double PresO = Fo.Press();
            if (Valid(dTout_Rqd))
            {
                const double h0 = Fo.totHf();
                Fo.SetTemp(dTout_Rqd);
                dDuty = Fo.totHf() - h0;
                const double h1 = Fo.totHf();
                Fo.SetPress(PresO);
                Fo.Set_totHf(h1); //restore enthalpy
            }
            else if (fabs(dDuty_Rqd)>1.0e-12)
            {
                const double h0 = Fo.totHf();
                Fo.Set_totHf(h0+dDuty_Rqd);
                dDuty = dDuty_Rqd;
                const double h1 = Fo.totHf();
                Fo.SetPress(PresO);
                Fo.Set_totHf(h1); //restore enthalpy
            }
            else
                dDuty = 0.0;

            if (In==IOId_2IOIn && m_LeakI.Enabled)
                m_LeakI.EvalProducts(Fo, true);
            if (In==IOId_2IOOut && m_LeakO.Enabled)
                m_LeakO.EvalProducts(Fo, true);

            L.Cd.QCopy(Fo);

            m_FTB.BeginEvalProducts(Fo);
            L.FB.SetQm(Sign(L.FB.GetQm())*Fo.QMass(som_ALL));
            L.FB.EvalProducts(L.PB(In).P, L.PB(Out).P, L.Cd, m_FTB);

            if (m_VLE.Enabled())
            {
                m_FTB.AddVLEBegin();
                m_VLE.PFlash(Fo, L.PB(Out).P, /*Valid(L.FB.ShaftPower()) ? L.FB.ShaftPower()/0.8 :*/ 0.0, VLEF_Null);
                m_FTB.AddVLEEnd();
            }
            m_FTB.EndEvalProducts();

            if (Out==IOId_2IOOut && m_LeakO.Enabled)
                m_LeakO.EvalProducts(Fo, true);
            if (Out==IOId_2IOIn && m_LeakI.Enabled)
                m_LeakI.EvalProducts(Fo, true);
        }
    }
}
Пример #8
0
/* D is the current position */
bool_t snav_init(uint8_t a, float desired_course_rad, float radius) {
  wp_a = a;
  radius = fabs(radius);

  float da_x = WaypointX(wp_a) - estimator_x;
  float da_y = WaypointY(wp_a) - estimator_y;

  /* D_CD orthogonal to current course, CD on the side of A */
  float u_x = cos(M_PI_2 - estimator_hspeed_dir);
  float u_y = sin(M_PI_2 - estimator_hspeed_dir);
  d_radius = - Sign(u_x*da_y - u_y*da_x) * radius;
  wp_cd.x = estimator_x + d_radius * u_y;
  wp_cd.y = estimator_y - d_radius * u_x;
  wp_cd.a = WaypointAlt(wp_a);

  /* A_CA orthogonal to desired course, CA on the side of D */
  float desired_u_x = cos(M_PI_2 - desired_course_rad);
  float desired_u_y = sin(M_PI_2 - desired_course_rad);
  a_radius = Sign(desired_u_x*da_y - desired_u_y*da_x) * radius;
  u_a_ca_x = desired_u_y;
  u_a_ca_y = - desired_u_x;
  wp_ca.x = WaypointX(wp_a) + a_radius * u_a_ca_x;
  wp_ca.y = WaypointY(wp_a) + a_radius * u_a_ca_y;
  wp_ca.a = WaypointAlt(wp_a);

  /* Unit vector along CD-CA */
  u_x = wp_ca.x - wp_cd.x;
  u_y = wp_ca.y - wp_cd.y;
  float cd_ca = sqrt(u_x*u_x+u_y*u_y);

  /* If it is too close in reverse direction, set CA on the other side */
  if (a_radius * d_radius < 0 && cd_ca < 2 * radius) {
    a_radius = -a_radius;
    wp_ca.x = WaypointX(wp_a) + a_radius * u_a_ca_x;
    wp_ca.y = WaypointY(wp_a) + a_radius * u_a_ca_y;
    u_x = wp_ca.x - wp_cd.x;
    u_y = wp_ca.y - wp_cd.y;
    cd_ca = sqrt(u_x*u_x+u_y*u_y);
  }

  u_x /= cd_ca;
  u_y /= cd_ca;

  if (a_radius * d_radius > 0) {
    /* Both arcs are in the same direction */
    /* CD_TD orthogonal to CD_CA */
    wp_td.x = wp_cd.x - d_radius * u_y;
    wp_td.y = wp_cd.y + d_radius * u_x;

    /* CA_TA also orthogonal to CD_CA */
    wp_ta.x = wp_ca.x - a_radius * u_y;
    wp_ta.y = wp_ca.y + a_radius * u_x;
  } else {
    /* Arcs are in reverse directions: trigonemetric puzzle :-) */
    float alpha = atan2(u_y, u_x) + acos(d_radius/(cd_ca/2));
    wp_td.x = wp_cd.x + d_radius * cos(alpha);
    wp_td.y = wp_cd.y + d_radius * sin(alpha);

    wp_ta.x = wp_ca.x + a_radius * cos(alpha);
    wp_ta.y = wp_ca.y + a_radius * sin(alpha);
  }
  qdr_td = M_PI_2 - atan2(wp_td.y-wp_cd.y, wp_td.x-wp_cd.x);
  qdr_a = M_PI_2 - atan2(WaypointY(wp_a)-wp_ca.y, WaypointX(wp_a)-wp_ca.x);
  wp_td.a = wp_cd.a;
  wp_ta.a = wp_ca.a;
  ground_speed_timer = 0;

  return FALSE;
}
Пример #9
0
Model::Model(id_type id, Signatures& signatures)
    : id_ (id)
    , ref_sign_ (id)
    , signatures_ (signatures)
{
    int model_size = NORMA_SIZE; // should be 25
    int nb_signatures = signatures.size(); // should be 4 or 8

    if (nb_signatures == 0)
	return;
    else if (nb_signatures == 1)
    {
        ref_sign_ = Sign((*signatures.begin())->get_datas(), id);
	return;
    }

    list<VecParam> sum_vects;
    for (int j = 0; j < model_size; ++j) // foreach vector
    {
	VecParam sum_vect;

	Signatures::iterator it_sign = signatures.begin();
	if (it_sign != signatures.end())
	{
	    list<VecParam> vectors = (*it_sign)->get_datas();
	    list<VecParam>::iterator it_vect = vectors.begin();
	    advance(it_vect, j);
	    sum_vect = (*it_vect);

	    it_sign++;
	}
	for (; it_sign != signatures.end(); ++it_sign) // foreach signature
	{
	    list<VecParam> vectors = (*it_sign)->get_datas();
	    list<VecParam>::iterator it_vect = vectors.begin();
	    advance(it_vect, j);
	    VecParam vector = (*it_vect);

	    // sum j-th vector from all signatures into sum_vect
	    sum_vect.set_x(sum_vect.get_x() + vector.get_x());
	    sum_vect.set_y(sum_vect.get_y() + vector.get_y());
	    sum_vect.set_timeStamp(sum_vect.get_timeStamp() + vector.get_timeStamp());
	    sum_vect.set_position(sum_vect.get_position() + vector.get_position());
	    sum_vect.set_azimut(sum_vect.get_azimut() + vector.get_azimut());
	    sum_vect.set_altitude(sum_vect.get_altitude() + vector.get_altitude());
	    sum_vect.set_pression(sum_vect.get_pression() + vector.get_pression());
	}

	// divide sum_vect by n
	sum_vect.set_x(sum_vect.get_x() / nb_signatures);
	sum_vect.set_y(sum_vect.get_y() / nb_signatures);
	sum_vect.set_timeStamp(sum_vect.get_timeStamp() / nb_signatures);
	sum_vect.set_position(sum_vect.get_position() / nb_signatures);
	sum_vect.set_azimut(sum_vect.get_azimut() / nb_signatures);
	sum_vect.set_altitude(sum_vect.get_altitude() / nb_signatures);
	sum_vect.set_pression(sum_vect.get_pression() / nb_signatures);

	// add sum_vect to the list
	sum_vects.push_back(sum_vect);
    }

    /* WARNING: ONLY CONSIDERS SOME PARAMETERS
    list<VecParam>::iterator it_vect;
    for (it_vect = sum_vects.begin(); it_vect != sum_vects.end(); ++it_vect)
    {
      (*it_vect).set_position(1);
      (*it_vect).set_azimut(0);
      (*it_vect).set_altitude(0);
    }
    //*/

    // create model signature from list of vectors
    ref_sign_ = Sign(sum_vects, id);
}
Пример #10
0
static int DecodeACSign(WinZipJPEGDecompressor *self,int comp,unsigned int k,int absvalue,
const WinZipJPEGBlock *current,const WinZipJPEGBlock *north,const WinZipJPEGBlock *west,
const WinZipJPEGQuantizationTable *quantization)
{
	// Decode sign. (5.6.6.4)

	// Calculate sign context, or decode with fixed probability. (5.6.6.4.1)
	int predictedsign;
	if(IsFirstRowOrColumn(k))
	{
		int bdr=BDR(k,current,north,west,quantization);

		if(bdr==0) return NextBitFromWinZipJPEGArithmeticDecoder(&self->decoder,&self->fixedcontext);

		predictedsign=(bdr<0);
	}
	else if(k==4)
	{
		int sign1=Sign(north->c[k]);
		int sign2=Sign(west->c[k]);

		if(sign1+sign2==0) return NextBitFromWinZipJPEGArithmeticDecoder(&self->decoder,&self->fixedcontext);

		predictedsign=(sign1+sign2<0);
	}
	else if(IsSecondRow(k))
	{
		if(north->c[k]==0) return NextBitFromWinZipJPEGArithmeticDecoder(&self->decoder,&self->fixedcontext);

		predictedsign=(north->c[k]<0);
	}
	else if(IsSecondColumn(k))
	{
		if(west->c[k]==0) return NextBitFromWinZipJPEGArithmeticDecoder(&self->decoder,&self->fixedcontext);

		predictedsign=(west->c[k]<0);
	}
	else
	{
		return NextBitFromWinZipJPEGArithmeticDecoder(&self->decoder,&self->fixedcontext);
	}

	static const int n_for_k[64]={
		 0,
		 0, 1,
		 2, 3, 4,
		 5, 6, 7, 8,
		 9,10, 0,11,12,
		13,14, 0, 0,15,16,
		17,18, 0, 0, 0,19,20,
		21,22, 0, 0, 0, 0,23,24,
		25, 0, 0, 0, 0, 0,26,
		 0, 0, 0, 0, 0, 0,
		 0, 0, 0, 0, 0,
		 0, 0, 0, 0,
		 0, 0, 0,
		 0, 0,
		 0,
	};
	int n=n_for_k[k];

	int signcontext1=Min(Category(absvalue)/2,2);

	return NextBitFromWinZipJPEGArithmeticDecoder(&self->decoder,
	&self->acsignbins[comp][n][signcontext1][predictedsign]);
}
Пример #11
0
int CConcertoDlg::PrintPrevente(CDC* pdc,int idx,CString billet,CString libelle,CString prix,CString tpmtxt,CString tvatxt,CString spectacle,CString ticket,CString ntpm,CString place) 
{
	CString txtsign;
	CString sign;
	CString extrait;
	CString temp;
	CString tvatxt1;
	CString tvatxt2;
	CString temp1;
	CString temp2;
	CString temp3;
	CString ntemp;
	CString ftxt;
	CString fread;
	CString date;
	CString page;
	CString vsht;
	CString vsttc;
	CString haut;
	CString larg;
	CString pox;
	CString dir;
	CString contdir;
	CString buf;
	CString tch;
	CString tcpt;
	CString txtvaltva1;
	CString txtvaltva2;
	CString txtprixht;
	CTime ct;
	ct=CTime::GetCurrentTime();
	date=ct.Format("%d/%m/%Y  %H:%M:%S");
	CDC m_Cdc;
	CRect rect;
	//CRect butrect;
	CRect rct;
	CFont num;
	CFont df;
	CFont tf;
	CFont tpf;
	CFont mic;
	CFont mid;
	CFont miw;
	CFont mil;
	CFont mtp;
	CFont cbfont;
	float plargeur;
	float phauteur;
	float cblmarge;
	float cblarg;
	float x;
	float xl1;
	double valtva1;
	double valtva2;
	double valht;
	double tauxtva1;	
	double tauxtva2;
	double valprix;
	int largeur;//
	int hauteur;//
	int lg;//
	int bc;//
	int i;//
	int j;//
	int fi;
	int gdcx;//
	HANDLE hf;
	DWORD nbw;
	XFORM xForm;
	COLORREF pencolor=0x00000000;
	COLORREF blancolor=0x00FFFFFF;
	CPen finepen(PS_SOLID,2,pencolor);
	CBrush br;
	br.CreateSolidBrush(pencolor);
	if(pdc->m_hDC!=NULL)
	{
		if(noprint)
		{
			if(paravent)
			{
				pdc->SetGraphicsMode(GM_ADVANCED);
				pdc->GetWorldTransform(&xForm);
				xForm.eM11 = (FLOAT)0; 
				xForm.eM12 = (FLOAT)+0.65; 
				xForm.eM21 = (FLOAT) -0.70; 
				xForm.eM22 = (FLOAT)0; 
				xForm.eDx  = (FLOAT) +310.0;//invxa; 
				xForm.eDy  = (FLOAT) +10;//invya; 20
				pdc->SetWorldTransform(&xForm); 
				plargeur=(float)wlargeur/1;
			}
			else
				plargeur=(float)wlargeur/2;
			gdcx=(int)plargeur;
			phauteur=(float)tsorg;
			x=0;
			lmarge=0;
			rmarge=0;
			//cdc.Rectangle(60,5,xl1-5,340);
			rct.top=0;
			rct.bottom=tsorg;
			bc=(0xFFFFFF);
			rct.left=0;
			rct.right=(int)plargeur;
			pdc->FillSolidRect(&rct,bc);
			if(wlargeur>whauteur)				
			{
				cblmarge=plargeur/5;//-50;
				cblarg=5*plargeur/5;
			}
			else
			{
				cblmarge=plargeur/7;//-50;
				cblarg=5*plargeur/5;
			}
			if(paravent)
				hauteur= 700;
			else
				hauteur= 770;
		}
		else
		{
			lmarge=0;
			pdc->SetGraphicsMode(GM_ADVANCED);
			pdc->GetWorldTransform(&xForm);
			if(paravent)
			{
				if(printername.Find("KMGA")!=-1)
				{
					xForm.eM11 = (FLOAT)0.0; 
					xForm.eM12 = (FLOAT)-1.0; 
					xForm.eM21 = (FLOAT) +1.0; 
					xForm.eM22 = (FLOAT) 0.0; 
					xForm.eDx  = (FLOAT) 0.0;//invxa; 
					xForm.eDy  = (FLOAT) 800;//invya; 
				}
				else
				{
					if(printername.Find("KPSX")!=-1)
					{
						xForm.eM11 = (FLOAT) -1.0; 
						xForm.eM12 = (FLOAT) 0.0; 
						xForm.eM21 = (FLOAT) 0.0; 
						xForm.eM22 = (FLOAT) -1.0; 
						xForm.eDx  = (FLOAT) invxt; 
						xForm.eDy  = (FLOAT) invyt; 
					}
					else
					{
						if(printername.Find("Citizen CL-S400DT")!=-1)
						{
							xForm.eM11 = (FLOAT) 0.0; 
							xForm.eM12 = (FLOAT) -1.0; 
							xForm.eM21 = (FLOAT) +1.0; 
							xForm.eM22 = (FLOAT) 0.0; 
							xForm.eDx  = (FLOAT) 150; 
							xForm.eDy  = (FLOAT) 1080; 
							lmarge=80;
						}
					}
				}
			}
			else
			{
				if(printername.Find("KMGA")!=-1)
				{
					xForm.eM11 = (FLOAT) -1.0; 
					xForm.eM12 = (FLOAT) 0.0; 
					xForm.eM21 = (FLOAT) 0.0; 
					xForm.eM22 = (FLOAT) -1.0; 
					xForm.eDx  = (FLOAT) invxa; 
					xForm.eDy  = (FLOAT) invya; 
				}
				else
				{
					if(printername.Find("KPSX")!=-1)
					{
						xForm.eM11 = (FLOAT) -1.0; 
						xForm.eM12 = (FLOAT) 0.0; 
						xForm.eM21 = (FLOAT) 0.0; 
						xForm.eM22 = (FLOAT) -1.0; 
						xForm.eDx  = (FLOAT) invxt; 
						xForm.eDy  = (FLOAT) invyt; 
					}
					else
					{
						if(printername.Find("Citizen CL-S400DT")!=-1)
						{
							xForm.eM11 = (FLOAT) -1.00; 
							xForm.eM12 = (FLOAT) 0.0; 
							xForm.eM21 = (FLOAT) 0.0; 
							xForm.eM22 = (FLOAT) -1.00; 
							xForm.eDx  = (FLOAT) 590; 
							xForm.eDy  = (FLOAT) 810; 
						}
					}
				}
			}
			pdc->SetWorldTransform(&xForm); 
			if(printername.Find("Citizen CL-S400DT")!=-1&&paravent)
				gdcx=3*pdc->GetDeviceCaps(HORZRES)/4;//-(2*cdc.GetDeviceCaps(PHYSICALOFFSETX)));
			else
				if(printername.Find("Citizen CL-S400DT")!=-1&&!paravent)
					gdcx=4*pdc->GetDeviceCaps(HORZRES)/8;//-(2*cdc.GetDeviceCaps(PHYSICALOFFSETX)));
				else
					gdcx=pdc->GetDeviceCaps(HORZRES);//-(2*cdc.GetDeviceCaps(PHYSICALOFFSETX)));
			if(paravent)
			{
				plargeur=(float)midline;
				hauteur= 800;
			}
			else
			{
				plargeur=(float)gdcx;
				hauteur= 1000;
			}
			phauteur=(float)pdc->GetDeviceCaps(VERTRES);//-(2*cdc.GetDeviceCaps(PHYSICALOFFSETY)));
			x=(float)pdc->GetDeviceCaps(PHYSICALOFFSETX);
			if(paravent)
			{
				cblmarge=(7*(float)gdcx)/18;
				cblarg=(float)gdcx;
			}
			else
				if(printername.Find("Citizen CL-S400DT")!=-1&&!paravent)
				{
					cblmarge=(4*(float)gdcx)/18;
					cblarg=(float)gdcx;
				}
				else
				{
					cblmarge=((float)gdcx)/7;
					cblarg=(float)gdcx;
				}
		}
		CPen dashpen(PS_DASH,1,pencolor);
		xl1=(plargeur)-rmarge;
		largeur=(int)(plargeur/2.1);//
		if(paravent)
			num.CreateFont((int)hauteur/18,
				(int)plargeur/40,
				0,
				0,
				600 ,//Epaisseur
				0,
				0,
				0,
				DEFAULT_CHARSET,
				OUT_TT_PRECIS,
				CLIP_DEFAULT_PRECIS,
				NONANTIALIASED_QUALITY,//ANTIALIASED_QUALITY,//PROOF_QUALITY,
				DEFAULT_PITCH|FF_DONTCARE,
				"ARIAL");
		else
			num.CreateFont((int)hauteur/10,
				(int)plargeur/35,
				0,
				0,
				600 ,//Epaisseur
				0,
				0,
				0,
				DEFAULT_CHARSET,
				OUT_TT_PRECIS,
				CLIP_DEFAULT_PRECIS,
				NONANTIALIASED_QUALITY,//ANTIALIASED_QUALITY,//PROOF_QUALITY,
				DEFAULT_PITCH|FF_DONTCARE,
				"ARIAL");
		tpf.CreateFont((int)hauteur/12,
			(int)plargeur/35,
			0,
			0,
			600 ,//Epaisseur
			0,
			0,
			0,
			DEFAULT_CHARSET,
			OUT_TT_PRECIS,
			CLIP_DEFAULT_PRECIS,
			NONANTIALIASED_QUALITY,//ANTIALIASED_QUALITY,//PROOF_QUALITY,
			DEFAULT_PITCH|FF_DONTCARE,
			"ARIAL");
		tf.CreateFont((int)hauteur/15,
			(int)plargeur/40,
			0,
			0,
			1 ,//Epaisseur
			0,
			0,
			0,
			DEFAULT_CHARSET,
			OUT_TT_PRECIS,
			CLIP_DEFAULT_PRECIS,
			NONANTIALIASED_QUALITY,//ANTIALIASED_QUALITY,//PROOF_QUALITY,
			DEFAULT_PITCH|FF_DONTCARE,
			"ARIAL");
		mic.CreateFont((int)hauteur/25,
			(int)plargeur/35,
			0,
			0,
			1000 ,//Epaisseur
			0,
			0,
			0,
			DEFAULT_CHARSET,
			OUT_TT_PRECIS,
			CLIP_DEFAULT_PRECIS,
			NONANTIALIASED_QUALITY,//ANTIALIASED_QUALITY,//PROOF_QUALITY,
			DEFAULT_PITCH|FF_DONTCARE,
			"ARIAL");
		mid.CreateFont((int)hauteur/25,
			(int)plargeur/50,
			0,
			0,
			600 ,//Epaisseur
			0,
			0,
			0,
			DEFAULT_CHARSET,
			OUT_TT_PRECIS,
			CLIP_DEFAULT_PRECIS,
			NONANTIALIASED_QUALITY,//ANTIALIASED_QUALITY,//PROOF_QUALITY,
			DEFAULT_PITCH|FF_DONTCARE,
			"ARIAL");
		miw.CreateFont((int)hauteur/30,
			(int)plargeur/70,
			0,
			0,
			600 ,//Epaisseur
			0,
			0,
			0,
			DEFAULT_CHARSET,
			OUT_TT_PRECIS,
			CLIP_DEFAULT_PRECIS,
			NONANTIALIASED_QUALITY,//ANTIALIASED_QUALITY,//PROOF_QUALITY,
			DEFAULT_PITCH|FF_DONTCARE,
			"ARIAL");
		mil.CreateFont((int)hauteur/35,
			(int)plargeur/60,
			0,
			0,
			200 ,//Epaisseur
			0,
			0,
			0,
			DEFAULT_CHARSET,
			OUT_TT_PRECIS,
			CLIP_DEFAULT_PRECIS,
			NONANTIALIASED_QUALITY,//ANTIALIASED_QUALITY,//PROOF_QUALITY,
			DEFAULT_PITCH|FF_DONTCARE,
			"ARIAL");
		mtp.CreateFont((int)hauteur/30,
			(int)gdcx/60,
			0,
			0,
			400 ,//Epaisseur
			0,
			0,
			0,
			DEFAULT_CHARSET,
			OUT_TT_PRECIS,
			CLIP_DEFAULT_PRECIS,
			NONANTIALIASED_QUALITY,//ANTIALIASED_QUALITY,//PROOF_QUALITY,
			DEFAULT_PITCH|FF_DONTCARE,
			"ARIAL");
		df.CreateFont((int)hauteur/15,
			(int)plargeur/25,
			0,
			0,
			600 ,//Epaisseur
			0,
			0,
			0,
			DEFAULT_CHARSET,
			OUT_TT_PRECIS,
			CLIP_DEFAULT_PRECIS,
			NONANTIALIASED_QUALITY,//ANTIALIASED_QUALITY,//PROOF_QUALITY,
			DEFAULT_PITCH|FF_DONTCARE,
			"ARIAL");
		cbfont.CreateFont(hauteur/35,
			0,//wlargeur/200,
			0,
			0,
			400,//Epaisseur
			0,
			0,
			0,
			DEFAULT_CHARSET,
			OUT_TT_PRECIS,
			CLIP_DEFAULT_PRECIS,
			NONANTIALIASED_QUALITY,//ANTIALIASED_QUALITY,//PROOF_QUALITY,
			DEFAULT_PITCH|FF_DONTCARE,
			"ARIAL");
		i=midline;
		pdc->SetTextColor(0x000000);
		if(noprint)
		{
			if(paravent)
				xl1=9*(float)i/8;
			else
			{
				plargeur=(float)gdcx;
				xl1=(plargeur)-rmarge;
			}
		}
		else
		{
			if(paravent)
				xl1=(float)10*plargeur/8;
			else
				xl1=(plargeur)-rmarge;
		}	
		int toporg=DrawLogo(pdc,xl1);
		if(paravent)
			toporg=0;
		float y=(float)hauteur/15;//(150);
		if(noprint)
			rct.top=toporg+(int)(y/2);
		else
			rct.top=toporg;//+(int)(y/100);
		rct.bottom=rct.top+(LONG)y;
		if(paravent&&logo)
			rct.left=(5*(LONG)xl1)/12;
		else
			rct.left=(LONG)((10));
		rct.right=(LONG)((xl1-10));
		//rct.top+=hauteur/20;//60;
		if(paravent)
		{
			rct.top+=hauteur/20;//60;
			rct.bottom+=hauteur/12;//60;
		}
		else
		{
			rct.top+=hauteur/40;//60;
			rct.bottom+=hauteur/20;//60;
		}
		if(logo==0||paravent)
		{
			if(paravent)
				pdc->SelectObject(&num);
			else
				if(logo==0)
					pdc->SelectObject(&tpf);
				else
					pdc->SelectObject(&mic);
			pdc->DrawText(nom,-1,&rct,DT_CENTER|DT_SINGLELINE|DT_TOP|DT_NOPREFIX );
			if(paravent||logo==0)
			{
				if(paravent)
				{
					rct.top+=hauteur/20;//60;
					rct.bottom+=hauteur/20;//60;
				}
				else
				{
					rct.top+=hauteur/13;//60;
					rct.bottom+=hauteur/13;//60;
				}
			}
			else
			{
				rct.top+=hauteur/30;//60;
				rct.bottom+=hauteur/30;//60;
			}
		}
		pdc->SelectObject(&miw);
		if(adresse1!="")
		{
			pdc->DrawText(adresse1,-1,&rct,DT_CENTER|DT_SINGLELINE|DT_TOP|DT_NOPREFIX );
			rct.top+=hauteur/30;
			rct.bottom+=hauteur/30;
		}
		if(adresse2!="")
		{
			pdc->DrawText(adresse2+" "+pays,-1,&rct,DT_CENTER|DT_SINGLELINE|DT_TOP|DT_NOPREFIX );
			rct.top+=hauteur/30;
			rct.bottom+=hauteur/30;
		}
		if(siret!="")
		{
			pdc->SelectObject(&miw);
			pdc->DrawText(txtc[72]+" : "+siret+" "+txtc[95]+" : "+naf,-1,&rct,DT_CENTER|DT_SINGLELINE|DT_TOP|DT_NOPREFIX );//Siret
		}
		if(paravent)
		{
			rct.top+=hauteur/30;//40;
			rct.bottom+=hauteur/30;//40;
		}
		else
		{
			rct.top+=hauteur/30;//40;
			rct.bottom+=hauteur/30;//40;
		}
		pdc->SelectObject(&miw);
		pdc->DrawText(mentionp,-1,&rct,DT_CENTER|DT_SINGLELINE|DT_TOP|DT_NOPREFIX );
		if(printername.Find("Citizen CL-S400DT")!=-1&&!paravent)
		{
			rct.left=(LONG)10;
			rct.right=(LONG)((xl1-10));
		}
		else
			if(paravent)
				rct.left=(LONG)10;
			else
				rct.left=(LONG)10;
		rct.right=(LONG)((xl1-10));
		rct.top+=hauteur/30;//40;
		rct.bottom+=hauteur/30;//40;
		if(paravent)
			pdc->SelectObject(&df);
		else
			pdc->SelectObject(&mic);
		pdc->DrawText(date,-1,&rct,DT_CENTER|DT_SINGLELINE|DT_TOP |DT_NOPREFIX);
		if(paravent)
		{
			rct.top+=hauteur/15;//40;
			rct.bottom+=hauteur/15;//40;
		}
		else
		{
			rct.top+=hauteur/25;//40;
			rct.bottom+=hauteur/25;//40;
		}

		rct.left=(LONG)10;
		rct.right=(LONG)((xl1-10));
		pdc->SelectObject(&mic);
		if(libel1[idx].Find("$",0)==0)// Enlève un $ éventuellement présent en première position
			libelle.Replace("$","");
		temp1=txtc[96];//"ENTREE PAYEE"
		pdc->DrawText(temp1,-1,&rct,DT_CENTER|DT_SINGLELINE|DT_TOP|DT_NOPREFIX);//"ENTREE PAYEE"|DT_MODIFYSTRING);
		pdc->SelectObject(&mic);
		if(paravent)
		{
			rct.top+=hauteur/25;
			rct.bottom+=hauteur/25;
		}
		else
			if(logo)
			{
				rct.top+=hauteur/30;
				rct.bottom+=hauteur/30;
			}
			else
			{
				rct.top+=hauteur/25;
				rct.bottom+=hauteur/25;
			}
		if(printername.Find("Citizen CL-S400DT")!=-1&&!paravent)
			rct.left=(LONG)10;
		else
			rct.left=(LONG)10;
		if(place!="")
			rct.right=(LONG)(2*(xl1-10)/3);
		else
			rct.right=(LONG)((xl1-10));
		if(paravent)
			pdc->SelectObject(&mic);
		else
			if(logo)
				pdc->SelectObject(&mic);
			else
				pdc->SelectObject(&df);
		temp3=txtc[85];//"Prix"
		temp1=txtc[76];//"TTC"
		temp2=txtc[134];///"HT"
		temp=temp3+" "+prix+cur+" "+temp1;
		pdc->DrawText(temp,-1,&rct,DT_CENTER|DT_SINGLELINE|DT_TOP|DT_NOPREFIX );
		if(place!="")
		{//Pl.
			rct.left=rct.right;
			rct.right=(LONG)((xl1-10));
			temp1=txtc[93];//Pl.
			pdc->DrawText(temp1+" "+place,-1,&rct,DT_CENTER|DT_SINGLELINE|DT_TOP|DT_END_ELLIPSIS|DT_NOPREFIX);//|DT_MODIFYSTRING);*************
		}
				temp3=txtc[62];//TVA
				tauxtva1=atof(tvatxt);
				tauxtva2=0;
				valprix=atof(prix);
				valtva1=(valprix-(valprix/(1+(tauxtva1/100))));
				valtva2=0;
				valht=valprix-valtva1-valtva2;

				txtvaltva1.Format("%.2f"+cur,valtva1);
				txtvaltva2.Format("%.2f"+cur,valtva2);
				txtprixht.Format("%.2f"+cur,valht);
				if(tauxtva2==0)
					temp=temp2+":"+txtprixht+" "+temp3+" "+tvatxt+"%:"+" "+txtvaltva1;
				else
					temp=temp2+":"+txtprixht+" "+temp3+" "+tvatxt+"%:"+" "+txtvaltva1+" "+temp3+" "+tvatxt2+"%:"+" "+txtvaltva2;
				if(paravent||logo)
				{
					rct.top+=hauteur/25;
					rct.bottom+=hauteur/25;
					rct.left=(LONG)10;
					rct.right=(LONG)((xl1-10));
					pdc->SelectObject(&miw);
				}
				else
				{
					rct.top+=hauteur/15;
					rct.bottom+=hauteur/15;
					rct.left=(LONG)10;
					rct.right=(LONG)((xl1-10));
					pdc->SelectObject(&miw);
				}
				pdc->DrawText(temp,-1,&rct,DT_CENTER|DT_SINGLELINE|DT_TOP|DT_NOPREFIX );
			rct.top+=hauteur/38;
			rct.bottom+=hauteur/38;
		if(printername.Find("Citizen CL-S400DT")!=-1&&!paravent)
			rct.left=0;
		else
			rct.left=(LONG)10;
		rct.right=(LONG)((xl1-10));
		if(paravent||logo==0)
			pdc->SelectObject(&tf);
		else
			pdc->SelectObject(&mic);
		pdc->DrawText(libelle,-1,&rct,DT_CENTER|DT_SINGLELINE|DT_TOP|DT_NOPREFIX);//|DT_MODIFYSTRING);
		rct.left=(LONG)10;
		rct.right=(LONG)((xl1-10));
		if(paravent||logo==0)
		{
			rct.top+=hauteur/15;//40;
			rct.bottom+=hauteur/15;//40;
		}
		else
		{
			rct.top+=hauteur/25;
			rct.bottom+=hauteur/25;
		}
		pdc->SelectObject(&mid);
		if(((perso[idx]&0xF000)>>12)>1)
			temp1=txtc[156];//Valable à partir du
		else
			temp1=txtc[98];//Valable le
		temp="N° "+ticket+" "+temp1+": "+ spectacle;
		pdc->DrawText(temp,-1,&rct,DT_CENTER|DT_SINGLELINE|DT_TOP|DT_NOPREFIX  );//Valable le
		while(ntpm.GetLength()<8)
			ntpm="0"+ntpm;
		temp=billet.Mid(4,2);
		idx=atoi(temp);
		temp=temp+ntpm;//temp+ntpm
		i=0;
		while(i<10)//Crée un N° unique en fonction de N° touche et crypt
		{
			tch=temp.Mid(9-i,1);
			j=atoi(tch);
			j=j+i;
			if(j>9)
				j=j-10;
			tch=cript[j];
			tcpt=tch+tcpt;
			i++;
		}
		buf=poste.Right(1)+temp+";\r\n";// génération N° ticket
		GetBilletCode(poste.Right(1)+tcpt);
		int cent=(int)((xl1+10)+(lmarge+10))/2;
		tsorg=rct.top+hauteur/28;
		if(paravent)
			PrintBarre(pdc,(int)(7*cblmarge/6),tsorg,(int)cblarg,hauteur/10+tsorg);
		else
			PrintBarre(pdc,(int)(4*cblmarge/3),tsorg,(int)cblarg,hauteur/12+tsorg);
		if(paravent&&noprint)
		{
			pdc->SetGraphicsMode(GM_ADVANCED);
			pdc->GetWorldTransform(&xForm);
			xForm.eM11 = (FLOAT) 1; 
			xForm.eM12 = (FLOAT) 0; 
			xForm.eM21 = (FLOAT) 0; 
			xForm.eM22 = (FLOAT) 1; 
			xForm.eDx  = (FLOAT) 0.0;//invxa; 
			xForm.eDy  = (FLOAT) 0.00;//invya; 
			pdc->SetWorldTransform(&xForm); 
			i=midline;
			tsorg=3*i/4;
			pdc->SelectObject(&dashpen);
			pdc->MoveTo(0,tsorg);
			pdc->LineTo((int)xl1,tsorg);
		}
		if(!noprint||(noprint&&sp.IsWindowVisible()))
		{
			// enregistrement ticket
			if(dopen.GetLength()==0)
			{
				CTime tim=CTime::GetCurrentTime();
				if(InitCaisse(tim)==0)
				{
					if(infocert)
					{
						FonctionEditeur("Erreur initialisation fichier Data");
					}
					return 0;
				}
			}
			CString TGTZ;
			CString TGTP;
			TGTZ.Format("%.2f",GTZ);
			TGTP.Format("%.2f",GTP);
			txtvaltva1.Format("%.2f",val1[idx]);
			tvatxt1.Format("%.2f",tva1[idx]);
			temp=ticket+"    ;"+date+";"+prix+";"+tvatxt+";"+prix+";;;;"+TGTZ+";"+TGTP;
			if(infocert)
			{
				//temp1.Format("%.2f",valtva1+valtva2);
				//temp1.Replace(".","");
				temp1.Format("%.2f",tva1[idx]);
				temp2.Format("%.2f",val1[idx]);
				temp1+=","+temp2;
				temp2.Format("%.2f",tva2[idx]);
				temp1+=","+temp2;
				temp2.Format("%.2f",val2[idx]);
				temp1+=","+temp2;
				temp1.Replace(".","");
				spart[0]=temp1;
				temp1.Format("%.2f",valprix);
				temp1.Replace(".","");
				spart[1]=temp1;
				temp1=ct.Format("%Y%m%d%H%M%S");
				spart[2]=temp1;
				temp1=ticket;
				temp1.Replace(" ","");
				spart[3]=temp1;
				spart[4]=ticket.Left(1);
				spart[5]=sticket;
				sign=Sign(2);
				extrait=GetExtrait(sign);
				if(printername.Find("Citizen CL-S400DT")!=-1||printername.Find("KPSX")!=-1)
				{
					if(paravent)
					{
						xForm.eM11 = (FLOAT) -1.0; 
						xForm.eM12 = (FLOAT) 0.0; 
						xForm.eM21 = (FLOAT) 0.0; 
						xForm.eM22 = (FLOAT) -1.0; 
						xForm.eDx  = (FLOAT) 590; //580
						xForm.eDy  = (FLOAT) 800;
					}
					else
					{
						if(printername.Find("Citizen CL-S400DT")!=-1)
						{
							xForm.eM11 = (FLOAT) 0.0; 
							xForm.eM12 = (FLOAT) -1.0; 
							xForm.eM21 = (FLOAT) +1.0; 
							xForm.eM22 = (FLOAT) 0.0; 
							xForm.eDx  = (FLOAT) 530; 
							xForm.eDy  = (FLOAT) 750;
						}
						else
							{
								xForm.eM11 = (FLOAT) 0.0; 
								xForm.eM12 = (FLOAT) -1.0; 
								xForm.eM21 = (FLOAT) +1.0; 
								xForm.eM22 = (FLOAT) 0.0; 
								xForm.eDx  = (FLOAT) 350; 
								xForm.eDy  = (FLOAT) 600;
							}
					}
					pdc->SetWorldTransform(&xForm); 
					if(paravent)
						rct.top=30*hauteur/50;
					else
						rct.top=0;//30*hauteur/50;
					rct.bottom=rct.top+hauteur/15;
					if(lic[0]+lic[1]+lic[2]+lic[3]+lic[4]+lic[5]!="")
					{
						pdc->SelectObject(&mil);
						if(lic[3]==""&&lic[4]==""&&lic[5]=="")
						{
							rct.top+=hauteur/35;
							rct.bottom=rct.top+hauteur/35;
						}
						if(paravent)
							lg=(LONG)((xl1-10)/6);
						else
							lg=(LONG)(4*(xl1-10)/16);
						rct.left=(LONG)0;
						rct.right=lg/4;
						pdc->DrawText("Lic. :",-1,&rct,DT_LEFT|DT_SINGLELINE|DT_TOP|DT_NOPREFIX );
						rct.left=rct.right;
						rct.right=rct.left+lg;
						pdc->DrawText(lic[0],-1,&rct,DT_LEFT|DT_SINGLELINE|DT_TOP|DT_NOPREFIX );
						rct.left=rct.right;
						rct.right=rct.left+lg;
						pdc->DrawText(lic[1],-1,&rct,DT_LEFT|DT_SINGLELINE|DT_TOP|DT_NOPREFIX );
						rct.left=rct.right;
						rct.right=rct.left+lg;
						pdc->DrawText(lic[2],-1,&rct,DT_LEFT|DT_SINGLELINE|DT_TOP|DT_NOPREFIX );
						if(lic[3]!=""||lic[4]!=""||lic[5]!="")
						{
							rct.top+=hauteur/35;
							rct.bottom=rct.top+hauteur/35;
							rct.left=(LONG)((xl1-10)/20);
							rct.right=rct.left+lg;
							pdc->DrawText(lic[3],-1,&rct,DT_LEFT|DT_SINGLELINE|DT_TOP|DT_NOPREFIX );
							rct.left=rct.right;
							rct.right=rct.left+lg;
							pdc->DrawText(lic[4],-1,&rct,DT_LEFT|DT_SINGLELINE|DT_TOP|DT_NOPREFIX );
							rct.left=rct.right;
							rct.right=rct.left+lg;
							pdc->DrawText(lic[5],-1,&rct,DT_LEFT|DT_SINGLELINE|DT_TOP |DT_NOPREFIX);
						}
					}
					if(paravent)
						pdc->SelectObject(&mid);
					else
						pdc->SelectObject(&miw);
					rct.top+=hauteur/30;
					rct.bottom=rct.top+hauteur/25;
					rct.left=(LONG)10;
					if(paravent)
						rct.right=(LONG)((400));
					else
						rct.right=(LONG)((300));
					CString cat=categorie;
					if(ticimp==1)
					{
						temp1=cat+" ";
						cat=certnum;
						temp1+=cat;
						temp1+=" ";
						temp1+=extrait;
						temp2.Format(" V%.3f",fversion/1000);
						temp1+=temp2;
						printsigtxt=temp1;
						pdc->DrawText(temp1,-1,&rct,DT_CENTER|DT_SINGLELINE|DT_TOP|DT_NOPREFIX );
					}
				}
				temp=temp+"|"+sign+"\r\n";
			}
			else
				temp=temp+"\r\n";
			if(CWrite(opendir,temp,1))
			{
				if(infocert)
				{
					sticket=sign;
				}
			}
			else
			{
				if(infocert)
				{
					FonctionEditeur("Erreur écriture fichier Data");
				}
				return 0;
			}
		}
		if(!paravent)
		{
			xForm.eM11 = (FLOAT) -1.0; 
			xForm.eM12 = (FLOAT) 0.0; 
			xForm.eM21 = (FLOAT) 0.0; 
			xForm.eM22 = (FLOAT) -1.0; 
			xForm.eDx  = (FLOAT) 590; //580
			xForm.eDy  = (FLOAT) 840; 
			pdc->SetWorldTransform(&xForm); 
		}
		CString pathcontrol="";
		if((!sp.IsWindowVisible()&&noprint)||!noprint)
		{
			// ******************* Recherche d'un fichier existant ******************
			for(fi=1;fi<=16;fi++)
			{
				ftxt.Format("0%u",fi);
				pathcontrol=controldir+"\\"+poste+"tempcontrol"+ftxt.Right(2)+".dat";
				hf=(CreateFile(pathcontrol,GENERIC_READ|GENERIC_WRITE ,0,NULL,OPEN_EXISTING,FILE_FLAG_WRITE_THROUGH|FILE_ATTRIBUTE_NORMAL,NULL));
				if(hf!=INVALID_HANDLE_VALUE)
				{
					ReadFile(hf,fread.GetBuffer(11),11,&nbw,NULL);
					fread.ReleaseBuffer(nbw);
					if(fread.Mid(1,2)==buf.Mid(1,2))
						goto next;
					CloseHandle(hf);
				}
			}
			if(fi>16)
			{
				for(int fi=1;fi<=16;fi++)
				{
					ftxt.Format("0%u",fi);
					if((master&&alone==0)||master==0)
						pathcontrol=controldir+"\\"+poste+"tempcontrol"+ftxt.Right(2)+".dat";
					else
						if(alone==1)
							pathcontrol=controldir+"\\alone"+poste+"control"+ftxt.Right(2)+".dat";
					hf=(CreateFile(pathcontrol,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_WRITE_THROUGH|FILE_ATTRIBUTE_NORMAL,NULL));
					if(hf==INVALID_HANDLE_VALUE)
						break; // Vérification emplacement libre pour nouveau fichier
					else
						CloseHandle(hf);
				}
			}
			hf=(CreateFile(pathcontrol,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_WRITE_THROUGH|FILE_ATTRIBUTE_NORMAL,NULL));
			if(hf==INVALID_HANDLE_VALUE)
			{
reopen:;
				if((hf=(CreateFile(pathcontrol,GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_FLAG_WRITE_THROUGH|FILE_ATTRIBUTE_NORMAL,NULL)))==INVALID_HANDLE_VALUE)
				{
					Sleep(100);
					goto reopen;

				}
			}
next:;
			SetFilePointer(hf,NULL,NULL,FILE_END);
			WriteFile(hf,buf.GetBuffer(),buf.GetLength(),&nbw,NULL);
			CloseHandle(hf);
			temp=netcontdir+"\\"+poste+"tempcontrol"+ftxt.Right(2)+".dat";
			if(master==0&&netcontdir!=controldir)
			{
retry:;
				if(!CopyFile(pathcontrol,temp,FALSE))
				{
					Sleep(50);
					goto retry;
				}
				DeleteFile(pathcontrol);
			}
		}
		if(!noprint)
		{
		}
		else
		{
			pdc->SelectObject(&finepen);
			tsorg=rct.top+=hauteur/15;
			sp.GetClientRect(&rect);
			//SimTicketRect(pdc,rect);
		}
		InterlockedExchange(&artro,1);
		return 1;
	}
Пример #12
0
// "Slab" test
// See Real-Time Collision Detection p.180
bool Segment::Intersects( const AABB& a, CollisionInfo* const pInfo ) const
{
	float tMin = 0.0f;
	float tMax = 1.0f;

	int IntersectingAxis = -1;

	const Vector dir = m_Point2 - m_Point1;

	// Maybe an optimization?
	static const Vector kUnits = Vector( 1.0f, 1.0f, 1.0f );
	const Vector OneOverD = kUnits / dir;

	for( uint i = 0; i < 3; ++i )
	{
		if( Abs( dir.v[i] ) < SMALLER_EPSILON )
		{
			// Segment is (close to) parallel to slab in ith dimension. No intersection if origin is outside slab.
			if( m_Point1.v[i] < a.m_Min.v[i] || m_Point1.v[i] > a.m_Max.v[i] )
			{
				// But warn if there might be an intersection that we're ignoring (maybe epsilon is too large)
				DEVASSERT(
					( m_Point1.v[i] < a.m_Min.v[i] && m_Point2.v[i] < a.m_Min.v[i] ) ||
					( m_Point1.v[i] > a.m_Max.v[i] && m_Point2.v[i] > a.m_Max.v[i] ) );
				return false;
			}
		}
		else
		{
			float t1 = ( a.m_Min.v[i] - m_Point1.v[i] ) * OneOverD.v[i];
			float t2 = ( a.m_Max.v[i] - m_Point1.v[i] ) * OneOverD.v[i];
			if( t1 > t2 )
			{
				Swap( t1, t2 );
			}

			tMin = Max( tMin, t1 );
			tMax = Min( tMax, t2 );

			if( tMin == t1 )
			{
				IntersectingAxis = i;
			}

			if( tMin > tMax )
			{
				return false;
			}
		}
	}

	if( pInfo )
	{
		Vector Normal;
		if( IntersectingAxis >= 0 )
		{
			Normal.v[ IntersectingAxis ] = -Sign( dir.v[ IntersectingAxis ] );
		}
		//else
		//{
		//	WARN;
		//}

		pInfo->m_Collision		= true;
		pInfo->m_HitT			= tMin;
		pInfo->m_Intersection	= m_Point1 + pInfo->m_HitT * dir;
		pInfo->m_Plane			= Plane( Normal, pInfo->m_Intersection );
	}

	return true;
}
Пример #13
0
void C4PXS::Execute()
{
#ifdef DEBUGREC_PXS
	if (Config.General.DebugRec)
	{
		C4RCExecPXS rc;
		rc.x=x; rc.y=y; rc.iMat=Mat;
		rc.pos = 0;
		AddDbgRec(RCT_ExecPXS, &rc, sizeof(rc));
	}
#endif
	int32_t inmat;

	// Safety
	if (!MatValid(Mat))
		{ Deactivate(); return; }

	// Out of bounds
	if ((x<0) || (x>=::Landscape.GetWidth()) || (y<-10) || (y>=::Landscape.GetHeight()))
		{ Deactivate(); return; }

	// Material conversion
	int32_t iX = fixtoi(x), iY = fixtoi(y);
	inmat=GBackMat(iX,iY);
	C4MaterialReaction *pReact = ::MaterialMap.GetReactionUnsafe(Mat, inmat);
	if (pReact && (*pReact->pFunc)(pReact, iX,iY, iX,iY, xdir,ydir, Mat,inmat, meePXSPos, NULL))
		{ Deactivate(); return; }

	// Gravity
	ydir+=GravAccel;

	if (GBackDensity(iX, iY + 1) < ::MaterialMap.Map[Mat].Density)
	{
		// Air speed: Wind plus some random
		int32_t iWind = Weather.GetWind(iX, iY);
		C4Real txdir = itofix(iWind, 15) + C4REAL256(Random(1200) - 600);
		C4Real tydir = C4REAL256(Random(1200) - 600);

		// Air friction, based on WindDrift. MaxSpeed is ignored.
		int32_t iWindDrift = std::max(::MaterialMap.Map[Mat].WindDrift - 20, 0);
		xdir += ((txdir - xdir) * iWindDrift) * WindDrift_Factor;
		ydir += ((tydir - ydir) * iWindDrift) * WindDrift_Factor;
	}

	C4Real ctcox = x + xdir;
	C4Real ctcoy = y + ydir;

	int32_t iToX = fixtoi(ctcox), iToY = fixtoi(ctcoy);

	// In bounds?
	if (Inside<int32_t>(iToX, 0, ::Landscape.GetWidth()-1) && Inside<int32_t>(iToY, 0, ::Landscape.GetHeight()-1))
		// Check path
		if (::Landscape._PathFree(iX, iY, iToX, iToY))
		{
			x=ctcox; y=ctcoy;
			return;
		}

	// Test path to target position
	int32_t iX0 = iX, iY0 = iY;
	bool fStopMovement = false;
	do
	{
		// Step
		int32_t inX = iX + Sign(iToX - iX), inY = iY + Sign(iToY - iY);
		// Contact?
		inmat = GBackMat(inX, inY);
		C4MaterialReaction *pReact = ::MaterialMap.GetReactionUnsafe(Mat, inmat);
		if (pReact)
		{
			if ((*pReact->pFunc)(pReact, iX,iY, inX,inY, xdir,ydir, Mat,inmat, meePXSMove, &fStopMovement))
			{
				// destructive contact
				Deactivate();
				return;
			}
			else
			{
				// no destructive contact, but speed or position changed: Stop moving for now
				if (fStopMovement)
				{
					// But keep fractional positions to allow proper movement on moving ground
					if (iX != iX0) x = itofix(iX);
					if (iY != iY0) y = itofix(iY);
					return;
				}
				// there was a reaction func, but it didn't do anything - continue movement
			}
		}
		iX = inX; iY = inY;
	}
	while (iX != iToX || iY != iToY);

	// No contact? Free movement
	x=ctcox; y=ctcoy;
#ifdef DEBUGREC_PXS
	if (Config.General.DebugRec)
	{
		C4RCExecPXS rc;
		rc.x=x; rc.y=y; rc.iMat=Mat;
		rc.pos = 1;
		AddDbgRec(RCT_ExecPXS, &rc, sizeof(rc));
	}
#endif
	return;
}
Пример #14
0
void Ephemeris<Frame>::ComputeApsides(not_null<MassiveBody const*> const body1,
                                      not_null<MassiveBody const*> const body2,
                                      DiscreteTrajectory<Frame>& apoapsides1,
                                      DiscreteTrajectory<Frame>& periapsides1,
                                      DiscreteTrajectory<Frame>& apoapsides2,
                                      DiscreteTrajectory<Frame>& periapsides2) {
  not_null<ContinuousTrajectory<Frame> const*> const body1_trajectory =
      trajectory(body1);
  not_null<ContinuousTrajectory<Frame> const*> const body2_trajectory =
      trajectory(body2);
  typename ContinuousTrajectory<Frame>::Hint hint1;
  typename ContinuousTrajectory<Frame>::Hint hint2;

  // Computes the derivative of the squared distance between |body1| and |body2|
  // at time |t|.
  auto const evaluate_square_distance_derivative =
      [body1_trajectory, body2_trajectory, &hint1, &hint2](
          Instant const& t) -> Variation<Square<Length>> {
    DegreesOfFreedom<Frame> const body1_degrees_of_freedom =
        body1_trajectory->EvaluateDegreesOfFreedom(t, &hint1);
    DegreesOfFreedom<Frame> const body2_degrees_of_freedom =
        body2_trajectory->EvaluateDegreesOfFreedom(t, &hint2);
    RelativeDegreesOfFreedom<Frame> const relative =
        body1_degrees_of_freedom - body2_degrees_of_freedom;
    return 2.0 * InnerProduct(relative.displacement(), relative.velocity());
  };

  std::experimental::optional<Instant> previous_time;
  std::experimental::optional<Variation<Square<Length>>>
      previous_squared_distance_derivative;

  for (Instant time = t_min(); time <= t_max(); time += parameters_.step()) {
    Variation<Square<Length>> const squared_distance_derivative =
        evaluate_square_distance_derivative(time);
    if (previous_squared_distance_derivative &&
        Sign(squared_distance_derivative) !=
            Sign(*previous_squared_distance_derivative)) {
      CHECK(previous_time);

      // The derivative of |squared_distance| changed sign.  Find its zero by
      // bisection, this is the time of the apsis.  Then compute the apsis and
      // append it to one of the output trajectories.
      Instant const apsis_time = Bisect(evaluate_square_distance_derivative,
                                        *previous_time,
                                        time);
      DegreesOfFreedom<Frame> const apsis1_degrees_of_freedom =
          body1_trajectory->EvaluateDegreesOfFreedom(apsis_time, &hint1);
      DegreesOfFreedom<Frame> const apsis2_degrees_of_freedom =
          body2_trajectory->EvaluateDegreesOfFreedom(apsis_time, &hint2);
      if (Sign(squared_distance_derivative).Negative()) {
        apoapsides1.Append(apsis_time, apsis1_degrees_of_freedom);
        apoapsides2.Append(apsis_time, apsis2_degrees_of_freedom);
      } else {
        periapsides1.Append(apsis_time, apsis1_degrees_of_freedom);
        periapsides2.Append(apsis_time, apsis2_degrees_of_freedom);
      }
    }

    previous_time = time;
    previous_squared_distance_derivative = squared_distance_derivative;
  }
}
Пример #15
0
void Ephemeris<Frame>::ComputeApsides(
    not_null<MassiveBody const*> const body,
    typename DiscreteTrajectory<Frame>::Iterator const begin,
    typename DiscreteTrajectory<Frame>::Iterator const end,
    DiscreteTrajectory<Frame>& apoapsides,
    DiscreteTrajectory<Frame>& periapsides) {
  not_null<ContinuousTrajectory<Frame> const*> const body_trajectory =
      trajectory(body);
  typename ContinuousTrajectory<Frame>::Hint hint;

  std::experimental::optional<Instant> previous_time;
  std::experimental::optional<DegreesOfFreedom<Frame>>
      previous_degrees_of_freedom;
  std::experimental::optional<Square<Length>> previous_squared_distance;
  std::experimental::optional<Variation<Square<Length>>>
      previous_squared_distance_derivative;

  for (auto it = begin; it != end; ++it) {
    Instant const time = it.time();
    DegreesOfFreedom<Frame> const degrees_of_freedom = it.degrees_of_freedom();
    DegreesOfFreedom<Frame> const body_degrees_of_freedom =
        body_trajectory->EvaluateDegreesOfFreedom(time, &hint);
    RelativeDegreesOfFreedom<Frame> const relative =
        degrees_of_freedom - body_degrees_of_freedom;
    Square<Length> const squared_distance =
        InnerProduct(relative.displacement(), relative.displacement());
    // This is the derivative of |squared_distance|.
    Variation<Square<Length>> const squared_distance_derivative =
        2.0 * InnerProduct(relative.displacement(), relative.velocity());

    if (previous_squared_distance_derivative &&
        Sign(squared_distance_derivative) !=
            Sign(*previous_squared_distance_derivative)) {
      CHECK(previous_time &&
            previous_degrees_of_freedom &&
            previous_squared_distance);

      // The derivative of |squared_distance| changed sign.  Construct a Hermite
      // approximation of |squared_distance| and find its extrema.
      Hermite3<Instant, Square<Length>> const
          squared_distance_approximation(
              {*previous_time, time},
              {*previous_squared_distance, squared_distance},
              {*previous_squared_distance_derivative,
               squared_distance_derivative});
      std::set<Instant> const extrema =
          squared_distance_approximation.FindExtrema();

      // Now look at the extrema and check that exactly one is in the required
      // time interval.  This is normally the case, but it can fail due to
      // ill-conditioning.
      Instant apsis_time;
      int valid_extrema = 0;
      for (auto const& extremum : extrema) {
        if (extremum >= *previous_time && extremum <= time) {
          apsis_time = extremum;
          ++valid_extrema;
        }
      }
      if (valid_extrema != 1) {
        // Something went wrong when finding the extrema of
        // |squared_distance_approximation|. Use a linear interpolation of
        // |squared_distance_derivative| instead.
        apsis_time = Barycentre<Instant, Variation<Square<Length>>>(
            {time, *previous_time},
            {*previous_squared_distance_derivative,
             -squared_distance_derivative});
      }

      // Now that we know the time of the apsis, construct a Hermite
      // approximation of the position of the body, and use it to derive its
      // degrees of freedom.  Note that an extremum of
      // |squared_distance_approximation| is in general not an extremum for
      // |position_approximation|: the distance computed using the latter is a
      // 6th-degree polynomial.  However, approximating this polynomial using a
      // 3rd-degree polynomial would yield |squared_distance_approximation|, so
      // we shouldn't be far from the truth.
      Hermite3<Instant, Position<Frame>> position_approximation(
          {*previous_time, time},
          {previous_degrees_of_freedom->position(),
           degrees_of_freedom.position()},
          {previous_degrees_of_freedom->velocity(),
           degrees_of_freedom.velocity()});
      DegreesOfFreedom<Frame> const apsis_degrees_of_freedom(
          position_approximation.Evaluate(apsis_time),
          position_approximation.EvaluateDerivative(apsis_time));
      if (Sign(squared_distance_derivative).Negative()) {
        apoapsides.Append(apsis_time, apsis_degrees_of_freedom);
      } else {
        periapsides.Append(apsis_time, apsis_degrees_of_freedom);
      }
    }

    previous_time = time;
    previous_degrees_of_freedom = degrees_of_freedom;
    previous_squared_distance = squared_distance;
    previous_squared_distance_derivative = squared_distance_derivative;
  }
}
Пример #16
0
void SVDCMP(REAL **a, int m, int n, REAL *w, REAL **v) { 
/*------------------------------------------------------------------------------------- 
! Given a matrix a(1:m,1:n), this routine computes its singular value decomposition, 
! A = U · W · Vt. The matrix U replaces a on output. The diagonal matrix of singular
! values W is output as a vector w(1:n). The matrix V (not the transpose Vt) is output 
! as v(1:n,1:n). 
!------------------------------------------------------------------------------------*/
//Labels:  e1, e2, e3
  int i,its,j,jj,k,l,nm; 
  REAL anorm,c,f,g,h,s,scale,x,y,z;
  REAL rv1[NMAX];
     
  g=0.0;       //Householder reduction to bidiagonal form
  scale=0.0;
  anorm=0.0;
for (i=1; i<=n; i++) {
  l=i+1;
  rv1[i]=scale*g;
  g=0.0;
  s=0.0;
  scale=0.0;
  if (i <= m) {
    for (k=i; k<=m; k++)  scale += fabs(a[k][i]);
    if (scale != 0.0) {
	  for (k=i; k<=m; k++) {
        a[k][i] /= scale;
        s += a[k][i]*a[k][i];
      } 
      f=a[i][i];
      g=-Sign(sqrt(s),f);
      h=f*g-s;
      a[i][i]=f-g;
      for (j=l; j<=n; j++) {
        s=0.0;
        for (k=i; k<=m; k++) s += a[k][i]*a[k][j];
        f=s/h;
        for (k=i; k<=m; k++) a[k][j] += f*a[k][i];
      } 
      for (k=i; k<=m; k++) a[k][i] *= scale;
    } 
  } 
  w[i]=scale*g;
  g=0.0;
  s=0.0;
  scale=0.0;
  if (i <= m && i != n) {
    for (k=l; k<=n; k++)  scale += fabs(a[i][k]);
    if (scale != 0.0) {
	  for (k=l; k<=n; k++) {
        a[i][k] /= scale;
        s += a[i][k]*a[i][k];
      } 
      f=a[i][l];
      g=-Sign(sqrt(s),f);
      h=f*g-s;
      a[i][l]=f-g;
      for (k=l; k<=n; k++) rv1[k]=a[i][k]/h;
      for (j=l; j<=m; j++) {
        s=0.0;
        for (k=l; k<=n; k++) s += a[j][k]*a[i][k];
        for (k=l; k<=n; k++) a[j][k] += s*rv1[k];
      } 
      for (k=l; k<=n; k++) a[i][k] *= scale;
    } 
  } 
  anorm=Max(anorm,(fabs(w[i])+fabs(rv1[i])));
} // i loop
 
for (i=n; i>0; i--) {       //Accumulation of right-hand transformations
  if (i < n) {
    if (g != 0.0) {
      for (j=l; j<=n; j++)  //Double division to avoid possible underflow
        v[j][i]=(a[i][j]/a[i][l])/g;
      for (j=l; j<=n; j++) { 
        s=0.0;
        for (k=l; k<=n; k++) s += a[i][k]*v[k][j];
        for (k=l; k<=n; k++) v[k][j] += s*v[k][i];
      } 
    } 
    for (j=l; j<=n; j++) {
      v[i][j]=0.0;
      v[j][i]=0.0;
    } 
  } 
  v[i][i]=1.0;
  g=rv1[i];
  l=i;
} 

for (i=IMin(m,n); i>0; i--) {  //Accumulation of left-hand transformations
  l=i+1;
  g=w[i];
  for (j=l; j<=n; j++) a[i][j]=0.0;
  if (g != 0.0) {
    g=1.0/g;
    for (j=l; j<=n; j++) { 
      s=0.0;
      for (k=l; k<=m; k++) s += a[k][i]*a[k][j];
      f=(s/a[i][i])*g;
      for (k=i; k<=m; k++) a[k][j] += f*a[k][i];
    } 
    for (j=i; j<=m; j++) a[j][i] *= g;
  }   
  else
    for (j=i; j<=m; j++) a[j][i]=0.0;
  a[i][i] += 1.0;
} 

for (k=n; k>0; k--) {  //Diagonalization of the bidiagonal form: Loop over
                       //singular values, and over allowed iterations
for (its=1; its<=30; its++) {
for (l=k; l>0; l--) {  //Test for splitting
  nm=l-1;              //Note that rv1(1) is always zero
  if ((fabs(rv1[l])+anorm) == anorm) goto e2; 
  if ((fabs(w[nm])+anorm) == anorm)  goto e1; 
} 
e1: c=0.0;             //Cancellation of rv1(l), if l > 1
s=1.0;
for (i=l; i<=k; i++) {
  f=s*rv1[i];
  rv1[i]=c*rv1[i];
  if ((fabs(f)+anorm) == anorm) goto e2; 
  g=w[i];
  h=pythag(f,g);
  w[i]=h;
  h=1.0/h;
  c=g*h;
  s=-(f*h);
  for (j=1; j<=m; j++) {
    y=a[j][nm];
    z=a[j][i];
    a[j][nm]=(y*c)+(z*s);
    a[j][i]=-(y*s)+(z*c);
  } 
} 
e2: z=w[k];
if (l == k) {     //Convergence
  if (z < 0.0) {  //Singular value is made nonnegative
    w[k]=-z;
    for (j=1; j<=n; j++)  v[j][k]=-v[j][k];
  } 
  goto e3; 
} 
if (its == 30)  printf(" No convergence in svdcmp\n"); 
x=w[l];           //Shift from bottom 2-by-2 minor
nm=k-1;
y=w[nm];
g=rv1[nm];
h=rv1[k];
f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y);
g=pythag(f,1.0);
f=((x-z)*(x+z)+h*((y/(f+Sign(g,f)))-h))/x;
c=1.0;            //Next QR transformation:
s=1.0;
for (j=l; j<=nm; j++) {
  i=j+1;
  g=rv1[i];
  y=w[i];
  h=s*g;
  g=c*g;
  z=pythag(f,h);
  rv1[j]=z;
  c=f/z;
  s=h/z;
  f= (x*c)+(g*s);
  g=-(x*s)+(g*c);
  h=y*s;
  y=y*c;
  for (jj=1; jj<=n; jj++) {
    x=v[jj][j];
    z=v[jj][i];
    v[jj][j]= (x*c)+(z*s);
    v[jj][i]=-(x*s)+(z*c);
  } 
  z=pythag(f,h);
  w[j]=z;   //Rotation can be arbitrary if z = 0 
  if (z != 0.0) {
    z=1.0/z;
    c=f*z;
    s=h*z;
  } 
  f= (c*g)+(s*y);
  x=-(s*g)+(c*y);
  for (jj=1; jj<=m; jj++) {
    y=a[jj][j];
    z=a[jj][i];
    a[jj][j]= (y*c)+(z*s);
    a[jj][i]=-(y*s)+(z*c);
  } 
} //for j=l to nm
rv1[l]=0.0;
rv1[k]=f;
w[k]=x;

} //its loop
 
e3:;} //k loop
 
} //svdcmp()
Пример #17
0
Sign Identity<FromFrame, ToFrame>::Determinant() const {
  return Sign(1);
}
Пример #18
0
inline Sign Sign::ReadFromMessage(serialization::Sign const& message) {
  return Sign(message.negative() ? -1 : 1);
}
Пример #19
0
void CBaseContainerNode::OnDrag( Vector2D &delta )
{
	if ( m_iActiveScalingMode == CBORDER_INVALID )
		return BaseClass::OnDrag( delta );

	//Vector2D pos = GetPosition();

	Vector4D delta_NESW;
	Vector2D pos_delta;
	delta_NESW.Init();
	pos_delta.Init();

	Vector2D half( delta.x * 0.5f, delta.y * 0.5f );

	switch ( m_iActiveScalingMode )
	{
	default:
		Assert( 0 );
	case CBORDER_TOP_LEFT:
		delta_NESW.x += half.y;
		delta_NESW.z -= half.y;
		delta_NESW.y -= delta.x;
		pos_delta.x += delta.x;
		pos_delta.y += half.y;
		break;
	case CBORDER_TOP:
		delta_NESW.x += half.y;
		delta_NESW.z -= half.y;
		pos_delta.y += half.y;
		break;
	case CBORDER_TOP_RIGHT:
		delta_NESW.x += half.y;
		delta_NESW.z -= half.y;
		delta_NESW.y += delta.x;
		pos_delta.y += half.y;
		break;
	case CBORDER_RIGHT:
		delta_NESW.y += delta.x;
		break;
	case CBORDER_BOTTOM_RIGHT:
		delta_NESW.x -= half.y;
		delta_NESW.z += half.y;
		delta_NESW.y += delta.x;
		pos_delta.y += half.y;
		break;
	case CBORDER_BOTTOM:
		delta_NESW.x -= half.y;
		delta_NESW.z += half.y;
		pos_delta.y += half.y;
		break;
	case CBORDER_BOTTOM_LEFT:
		delta_NESW.x -= half.y;
		delta_NESW.z += half.y;
		delta_NESW.y -= delta.x;
		pos_delta.x += delta.x;
		pos_delta.y += half.y;
		break;
	case CBORDER_LEFT:
		delta_NESW.y -= delta.x;
		pos_delta.x += delta.x;
		break;
	}

	for ( int i = 0; i < 5; i++ )
	{
		if ( m_vecAccumulatedExtent[i] )
		{
			float *target = NULL;
			if ( i >= 3 )
				target = &pos_delta[ i - 3 ];
			else
				target = &delta_NESW[ i ];

			const bool bWasNeg = m_vecAccumulatedExtent[ i ] < 0;
			m_vecAccumulatedExtent[ i ] += *target;
			const bool bIsNeg = m_vecAccumulatedExtent[ i ] < 0;
			if ( bWasNeg && bIsNeg || !bWasNeg && !bIsNeg )
				*target = 0;
			else
			{
				*target = m_vecAccumulatedExtent[ i ] * 1;
				m_vecAccumulatedExtent[ i ] = 0;
			}
		}
	}

	Vector oldExtents = m_vecContainerExtents;
	for ( int i = 0; i < 3; i++ )
		m_vecContainerExtents[i] += delta_NESW[i];

	if ( m_vecContainerExtents[ 0 ] < m_flMinSizeY )
	{
		m_vecAccumulatedExtent[ 0 ] += min( m_vecContainerExtents[ 0 ] - m_flMinSizeY, 0 );
		m_vecAccumulatedExtent[ 4 ] -= min( m_vecContainerExtents[ 0 ] - m_flMinSizeY, 0 ) * Sign( pos_delta.y );

		float _save = oldExtents.x - m_flMinSizeY;
		_save = max( _save, 0 );
		pos_delta.y = _save * Sign( pos_delta.y );
		m_vecContainerExtents[ 0 ] = m_flMinSizeY;
	}
	if ( m_vecContainerExtents[ 2 ] > -m_flMinSizeY )
	{
		m_vecAccumulatedExtent[ 2 ] -= min( abs(m_vecContainerExtents[ 2 ]) - (m_flMinSizeY), 0 );
		m_vecContainerExtents[ 2 ] = -m_flMinSizeY;
	}
	if ( m_vecContainerExtents[ 1 ] < m_flMinSizeX )
	{
		if ( pos_delta.x > 0 )
		{
			float _save = oldExtents.y - m_flMinSizeX;
			_save = max( _save, 0 );
			pos_delta.x = _save;
		}
		m_vecAccumulatedExtent[ 3 ] -= min( m_vecContainerExtents[ 1 ] - m_flMinSizeX, 0 );
		m_vecAccumulatedExtent[ 1 ] += min( m_vecContainerExtents[ 1 ] - m_flMinSizeX, 0 );
		m_vecContainerExtents[ 1 ] = m_flMinSizeX;
	}

	m_vecContainerExtents[ 2 ] = -m_vecContainerExtents[ 0 ];

	Vector2D posOld = GetPosition();
	SetPosition( posOld + pos_delta );
}
Пример #20
0
inline Sign operator*(Sign const& left, Sign const& right) {
  return Sign(left.negative_ == right.negative_ ? 1 : -1);
}
Пример #21
0
void MonotonicInterpolate(const vector<Vector>& pts,const vector<Real>& times,vector<GeneralizedCubicBezierCurve>& paths,CSpace* space,GeodesicManifold* manifold)
{
  Assert(times.size()==pts.size());
  Assert(pts.size() >= 2);
  
  paths.resize(pts.size()-1);
  for(size_t i=0;i<paths.size();i++) {
    paths[i].x0 = pts[i];
    paths[i].x3 = pts[i+1];
    paths[i].space = space;
    paths[i].manifold = manifold;
  }
  vector<Real> durations(pts.size()-1);
  vector<Real> rates(pts.size()-1);
  for(size_t i=0;i+1<pts.size();i++) {
    durations[i] = times[i+1]-times[i];
    rates[i] = 1.0/durations[i];
  }
  vector<Vector> tangents(pts.size()),inslopes(pts.size()-1),outslopes(pts.size()-1);
  if(pts.size() == 2) {
    paths[0].SetSmoothTangents(NULL,NULL);
    return;
  }
  paths[0].SetSmoothTangents(NULL,&pts[2],1.0,durations[1]*rates[0]);
  paths[0].Deriv(0,tangents[0]);
  paths.back().x0 = pts[pts.size()-2];
  paths.back().x3 = pts[pts.size()-1];
  paths.back().SetSmoothTangents(&pts[pts.size()-3],NULL,durations[durations.size()-2]*rates.back(),1.0);
  paths.back().Deriv(1,tangents.back());
  for(size_t i=1;i<pts.size();i++) {
    if(!manifold) {
      inslopes[i-1] = pts[i]-pts[i-1];
      inslopes[i-1] *= rates[i-1];
      outslopes[i-1].setRef(inslopes[i-1]);
    }
    else {
      manifold->InterpolateDeriv(pts[i-1],pts[i],0,inslopes[i-1]);
      manifold->InterpolateDeriv(pts[i],pts[i-1],0,outslopes[i-1]);
      outslopes[i-1].inplaceNegative();
      inslopes[i-1] *= rates[i-1];
      outslopes[i-1] *= rates[i-1];
    }
    /* xi = y(0)
     * xp = y(-dtp)
     * xn = y(dtn)
     * fit a quadratic 
     *   y(u) = a u^2 + b u + c
     * and find y'(0)=b
     * 
     * c = xi
     * a dtn^2 + b dtn = xn-xi
     * a dtp^2 - b dtp = xp-xi
     * [dtn^2  dtn][a] = [xn-xi]
     * [dtp^2 -dtp][b]   [xp-xi]
     * -1/(dtn dtp)(dtn + dtp) [ -dtp   -dtn ][xn-xi] = [a]
     *                         [ -dtp^2 dtn^2][xp-xi]   [b]
     * b = dtp^2/(dtn dtp)(dtn + dtp) (xn-xi) - dtn^2/(dtn dtp)(dtn + dtp)(xp-xi)
     *   = 1/(dtn+dtp) (dtp/dtn (xn-xi) - dtn/dtp (xp-xi))
     */
    if(i+1<pts.size()) {
      Vector n,p;
      Real s1 = durations[i-1]*rates[i];
      Real s2 = durations[i]*rates[i-1];
      if(!manifold) {
	n = pts[i+1] - pts[i];
	p = pts[i-1] - pts[i];
      }
      else {
	manifold->InterpolateDeriv(pts[i],pts[i+1],0,n);
	manifold->InterpolateDeriv(pts[i],pts[i-1],0,p);
      }
      tangents[i] = (s2*n-s1*p)/(durations[i-1]+durations[i]);
    }
  }
  int n=pts[0].n;
  for(size_t i=0;i<pts.size();i++) {
    if(tangents[i].n != n) printf("%d / %d\n",i,tangents.size());
    Assert(tangents[i].n == n);
  }
  for(size_t i=0;i+1<pts.size();i++) {
    for(int j=0;j<n;j++) {
      if(Sign(tangents[i][j]) != Sign(inslopes[i][j]))
	tangents[i][j] = 0;
      else {
	if(tangents[i][j]>0) {
	  if(tangents[i][j] > 3.0*inslopes[i][j])
	    tangents[i][j] = 3.0*inslopes[i][j];
	}
	else {
	  if(tangents[i][j] < 3.0*inslopes[i][j])
	    tangents[i][j] = 3.0*inslopes[i][j];
	}
      }
      if(Sign(tangents[i+1][j]) != Sign(outslopes[i][j]))
	tangents[i+1][j] = 0;
      else {
	if(tangents[i+1][j]>0) {
	  if(tangents[i+1][j] > 3.0*outslopes[i][j])
	    tangents[i+1][j] = 3.0*outslopes[i][j];
	}
	else {
	  if(tangents[i+1][j] < 3.0*outslopes[i][j])
	    tangents[i+1][j] = 3.0*outslopes[i][j];
	}
      }
    }
  }
  for(size_t i=0;i+1<pts.size();i++) {
    paths[i].SetNaturalTangents(tangents[i]*durations[i],tangents[i+1]*durations[i]);
  }
}
Пример #22
0
bool Segment2D::Intersects( const Box2D& Box, CollisionInfo2D* const pInfo /*= NULL*/ ) const
{
	if( Box.Contains( m_Start ) )
	{
		if( pInfo )
		{
			pInfo->m_Collision = true;
			pInfo->m_EHitNormal = CollisionInfo2D::EHN_None;
			pInfo->m_HitNormal = Vector2();
			pInfo->m_HitT = 0.0f;
			pInfo->m_Intersection = m_Start;
		}

		return true;
	}

	float MinT = 0.0f;
	float MaxT = FLT_MAX;
	CollisionInfo2D::EHitNormal EnumHitNormal = CollisionInfo2D::EHN_None;
	Vector2 HitNormal;
	Vector2 Offset = m_End - m_Start;

	if( Abs( Offset.x ) < SMALLER_EPSILON )
	{
		if( m_Start.x < Box.m_Min.x || m_Start.x > Box.m_Max.x )
		{
			return false;
		}
	}
	else
	{
		float InvOffsetX = 1.0f / Offset.x;
		float T1 = ( Box.m_Min.x - m_Start.x ) * InvOffsetX;
		float T2 = ( Box.m_Max.x - m_Start.x ) * InvOffsetX;
		if( T1 > T2 )
		{
			Swap( T1, T2 );
		}
		MinT = Max( MinT, T1 );
		MaxT = Min( MaxT, T2 );
		if( MinT > MaxT )
		{
			return false;
		}

		if( MinT == T1 )
		{
			EnumHitNormal = ( Offset.x > 0.0f ) ? CollisionInfo2D::EHN_Left : CollisionInfo2D::EHN_Right;
			HitNormal.x = Sign( Offset.x );
		}
	}

	if( Abs( Offset.y ) < SMALLER_EPSILON )
	{
		if( m_Start.y < Box.m_Min.y || m_Start.y > Box.m_Max.y )
		{
			return false;
		}
	}
	else
	{
		float InvOffsetY = 1.0f / Offset.y;
		float T1 = ( Box.m_Min.y - m_Start.y ) * InvOffsetY;
		float T2 = ( Box.m_Max.y - m_Start.y ) * InvOffsetY;
		if( T1 > T2 )
		{
			Swap( T1, T2 );
		}
		MinT = Max( MinT, T1 );
		MaxT = Min( MaxT, T2 );
		if( MinT > MaxT )
		{
			return false;
		}

		if( MinT == T1 )
		{
			EnumHitNormal = ( Offset.y > 0.0f ) ? CollisionInfo2D::EHN_Up : CollisionInfo2D::EHN_Down;
			HitNormal.y = Sign( Offset.y );
		}
	}

	if( MinT > 1.0f )
	{
		return false;
	}

	ASSERT( EnumHitNormal != CollisionInfo2D::EHN_None );

	if( pInfo )
	{
		pInfo->m_Collision = true;
		pInfo->m_EHitNormal = EnumHitNormal;
		pInfo->m_HitNormal = HitNormal;
		pInfo->m_HitT = MinT;
		pInfo->m_Intersection = m_Start + Offset * MinT;
	}

	return true;
}
Пример #23
0
void MonotonicInterpolate(const vector<Vector>& pts,vector<GeneralizedCubicBezierCurve>& paths,CSpace* space,GeodesicManifold* manifold)
{
  Assert(pts.size() >= 2);
  
  paths.resize(pts.size()-1);
  for(size_t i=0;i<paths.size();i++) {
    paths[i].x0 = pts[i];
    paths[i].x3 = pts[i+1];
    paths[i].space = space;
    paths[i].manifold = manifold;
  }
  vector<Vector> tangents(pts.size()),inslopes(pts.size()-1),outslopes(pts.size()-1);
  if(pts.size() == 2) {
    paths[0].SetSmoothTangents(NULL,NULL);
    return;
  }
  paths[0].SetSmoothTangents(NULL,&pts[2]);
  paths[0].Deriv(0,tangents[0]);
  paths.back().x0 = pts[pts.size()-2];
  paths.back().x3 = pts[pts.size()-1];
  paths.back().SetSmoothTangents(&pts[pts.size()-3],NULL);
  paths.back().Deriv(1,tangents.back());
  for(size_t i=1;i<pts.size();i++) {
    if(!manifold) {
      inslopes[i-1] = pts[i]-pts[i-1];
      outslopes[i-1].setRef(inslopes[i-1]);
    }
    else {
      manifold->InterpolateDeriv(pts[i-1],pts[i],0,inslopes[i-1]);
      manifold->InterpolateDeriv(pts[i],pts[i-1],0,outslopes[i-1]);
      outslopes[i-1].inplaceNegative();
    }
    if(i+1<pts.size()) {
      if(!manifold)
	tangents[i] = (pts[i+1]-pts[i-1])*0.5;
      else {
	Vector n,p;
	manifold->InterpolateDeriv(pts[i],pts[i+1],0,n);
	manifold->InterpolateDeriv(pts[i],pts[i-1],0,p);
	tangents[i] = (n-p)*0.5;
      }
    }
  }
  int n=pts[0].n;
  for(size_t i=0;i<pts.size();i++) {
    if(tangents[i].n != n) printf("%d / %d\n",i,tangents.size());
    Assert(tangents[i].n == n);
  }
  for(size_t i=0;i+1<pts.size();i++) {
    for(int j=0;j<n;j++) {
      if(Sign(tangents[i][j]) != Sign(inslopes[i][j]))
	tangents[i][j] = 0;
      else {
	if(tangents[i][j]>0) {
	  if(tangents[i][j] > 3.0*inslopes[i][j])
	    tangents[i][j] = 3.0*inslopes[i][j];
	}
	else {
	  if(tangents[i][j] < 3.0*inslopes[i][j])
	    tangents[i][j] = 3.0*inslopes[i][j];
	}
      }
      if(Sign(tangents[i+1][j]) != Sign(outslopes[i][j]))
	tangents[i+1][j] = 0;
      else {
	if(tangents[i+1][j]>0) {
	  if(tangents[i+1][j] > 3.0*outslopes[i][j])
	    tangents[i+1][j] = 3.0*outslopes[i][j];
	}
	else {
	  if(tangents[i+1][j] < 3.0*outslopes[i][j])
	    tangents[i+1][j] = 3.0*outslopes[i][j];
	}
      }
    }
  }
  for(size_t i=0;i+1<pts.size();i++) {
    paths[i].SetNaturalTangents(tangents[i],tangents[i+1]);
  }
}
Пример #24
0
/* Implementation *************************************************************/
void CTimeSyncTrack::Process(CParameter& Parameter,
			     CComplexVector& veccChanEst, int iNewTiCorr,
			     FXP& rLenPDS_fxp, FXP& rOffsPDS_fxp)
{
  int			i, j;
  int			iIntShiftVal;
  int			iFirstPathDelay;
  CFReal		rPeakBound_fxp;	  
  CFReal		rPropGain_fxp;  
  long long		rCurEnergy_fxp;  
  long long		rWinEnergy_fxp;  
  long long		rMaxWinEnergy_fxp;
  
  _BOOLEAN	bDelayFound;        //ok
  _BOOLEAN	bPDSResultFound;    //ok
  
  /* Rotate the averaged PDP to follow the time shifts -------------------- */
  /* Update timing correction history (shift register) */
  vecTiCorrHist.AddEnd(iNewTiCorr);
  
  /* Calculate the actual shift of the timing correction. Since we do the
     timing correction at the sound card sample rate (48 kHz) and the
     estimated impulse response has a different sample rate (since the
     spectrum is only one little part of the sound card frequency range)
     we have to correct the timing correction by a certain bandwidth factor */
  
  const CFReal rActShiftTiCor_fxp = rFracPartTiCor_fxp -
    (_FREAL) vecTiCorrHist[0] * iNumCarrier / iDFTSize;
  
  /* Integer part of shift */
  const int iIntPartTiCorr = (int) Round(rActShiftTiCor_fxp);
  
  /* Extract the fractional part since we can only correct integer timing
     shifts */
  rFracPartTiCor_fxp = rActShiftTiCor_fxp - iIntPartTiCorr;
  
  /* Shift the values in the vector storing the averaged impulse response. We
     have to consider two cases for shifting (left and right shift) */
  if (rActShiftTiCor_fxp < 0)
    iIntShiftVal = iIntPartTiCorr + iNumIntpFreqPil;
  else
    iIntShiftVal = iIntPartTiCorr;
  
  /* If new correction is out of range, do not apply rotation */
  if ((iIntShiftVal > 0) && (iIntShiftVal < iNumIntpFreqPil))
    {
      /* Actual rotation of vector */
      vecrAvPoDeSp.Merge(vecrAvPoDeSp(iIntShiftVal + 1, iNumIntpFreqPil),
			 vecrAvPoDeSp(1, iIntShiftVal));
    }
  /* New estimate for impulse response ------------------------------------ */
  /* Apply hamming window, Eq (15) */
  veccPilots = veccChanEst * vecrHammingWindow;
  
  /* Transform in time-domain to get an estimate for the delay power profile,
     Eq (15) */
  veccPilots = Ifft(veccPilots, FftPlan);
  
  /* Average result, Eq (16) (Should be a moving average function, for
     simplicity we have chosen an IIR filter here) */
  IIR1(vecrAvPoDeSp, SqMag(veccPilots), rLamAvPDS);
  
  /* Rotate the averaged result vector to put the earlier peaks
     (which can also detected in a certain amount) at the beginning of
     the vector */
  vecrAvPoDeSpRot.Merge(vecrAvPoDeSp(iStPoRot, iNumIntpFreqPil),
			vecrAvPoDeSp(1, iStPoRot - 1));
  
  
  /* Different timing algorithms ------------------------------------------ */
  switch (TypeTiSyncTrac)
    {
    case TSFIRSTPEAK:
      /* Detect first peak algorithm proposed by Baoguo Yang */
      /* Lower and higher bound */
      rBoundHigher = Max(vecrAvPoDeSpRot) * rConst1;  //ok
      rBoundLower = Min(vecrAvPoDeSpRot) * rConst2;   //ok
      
      /* Calculate the peak bound, Eq (19) */
      rPeakBound_fxp = FXP (Max(rBoundHigher, rBoundLower));
      
      /* Get final estimate, Eq (18) */
      bDelayFound = FALSE; /* Init flag */
      for (i = 0; i < iNumIntpFreqPil - 1; i++)
	{
	  /* We are only interested in the first peak */
	  if (bDelayFound == FALSE)
	    {
	      if ((vecrAvPoDeSpRot[i] > vecrAvPoDeSpRot[i + 1]) &&
		  (FXP (vecrAvPoDeSpRot[i]) > rPeakBound_fxp))
		{
		  /* The first peak was found, store index */
		  iFirstPathDelay = i;
		  
		  /* Set the flag */
		  bDelayFound = TRUE;
		}
	    }
	}
      break;
      
    case TSENERGY:
      /* Determin position of window with maximum energy in guard-interval.
	 A window with the size of the guard-interval is moved over the entire
	 profile and the energy inside this window is calculated. The window
	 position which maximises this energy is taken as the new timing
	 position */
      rMaxWinEnergy_fxp = 0;
      iFirstPathDelay = 0;
      for (i = 0; i < iNumIntpFreqPil - 1 - rGuardSizeFFT; i++)
	{
	  rWinEnergy_fxp = 0;
	  
	  /* Energy IN the guard-interval */
	  for (j = 0; j < rGuardSizeFFT; j++)
	    rWinEnergy_fxp += (long long)(vecrAvPoDeSpRot[i + j]*(1<<FXP_TIME_SYNC_TRACK_SCALE));
	  
	  /* Get maximum */
	  if (rWinEnergy_fxp > rMaxWinEnergy_fxp)
	    {
	      rMaxWinEnergy_fxp = rWinEnergy_fxp;
	      iFirstPathDelay = i;
	    }
	}
      
      /* We always have a valid measurement, set flag */
      bDelayFound = TRUE;
      break;
    }
  
  
  /* Only apply timing correction if search was successful and tracking is
     activated */
  if ((bDelayFound == TRUE) && (bTiSyncTracking == TRUE))
    {
      /* Consider the rotation introduced for earlier peaks in path delay.
	 Since the "iStPoRot" is the position of the beginning of the block
	 at the end for cutting out, "iNumIntpFreqPil" must be substracted.
	 (Actually, a part of the following line should be look like this:
	 "iStPoRot - 1 - iNumIntpFreqPil + 1" but the "- 1 + 1" compensate
	 each other) */
      iFirstPathDelay += iStPoRot - iNumIntpFreqPil - iTargetTimingPos - 1;
      
      
      /* Correct timing offset -------------------------------------------- */
      /* Final offset is target position in comparision to the estimated first
	 path delay. Since we have a delay from the channel estimation, the
	 previous correction is subtracted "- vecrNewMeasHist[0]". If the
	 "real" correction arrives after the delay, this correction is
	 compensated. The length of the history buffer (vecrNewMeasHist) must
	 be equal to the delay of the channel estimation.
	 The corrections must be quantized to the upsampled output sample
	 rate ("* iDFTSize / iNumCarrier") */
      iDFTSize / iNumCarrier - veciNewMeasHist[0];
      const CFReal rTiOffset_fxp = (CFReal) -iFirstPathDelay *
	iDFTSize / iNumCarrier - veciNewMeasHist[0];
      
      /* Different controlling parameters for different types of tracking */
      switch (TypeTiSyncTrac)
	{
	case TSFIRSTPEAK:
	  /* Adapt the linear control parameter to the region, where the peak
	     was found. The region left of the desired timing position is
	     critical, because we immediately get ISI if a peak appers here.
	     Therefore we apply fast correction here. At the other positions,
	     we smooth the controlling to improve the immunity against false
	     peaks */
	  if (rTiOffset_fxp > 0)
	    rPropGain_fxp = CONT_PROP_BEFORE_GUARD_INT;
	  else
	    rPropGain_fxp = CONT_PROP_IN_GUARD_INT;
	  break;
	  
	case TSENERGY:
	  rPropGain_fxp = CONT_PROP_ENERGY_METHOD;
	  break;
	}
      
      /* In case of sample rate offset acquisition phase, use faster timing
	 corrections */
      if (bSamRaOffsAcqu == TRUE)
	rPropGain_fxp *= 2;
      
      /* Apply proportional control and fix result to sample grid */
      const CFReal rCurCorrValue_fxp = rTiOffset_fxp * rPropGain_fxp + rFracPartContr_fxp;
      
      const int iContrTiOffs = (int) Fix(rCurCorrValue_fxp);
      
      /* Calculate new fractional part of controlling */
      rFracPartContr_fxp = rCurCorrValue_fxp - iContrTiOffs;
      
      /* Manage correction history */
      veciNewMeasHist.AddEnd(0);
      for (i = 0; i < iSymDelay - 1; i++)
	veciNewMeasHist[i] += iContrTiOffs;
      
      /* Apply correction */
      Parameter.iTimingOffsTrack = -iContrTiOffs;
    }
  
  
  /* Sample rate offset estimation ---------------------------------------- */
  /* This sample rate offset estimation is based on the movement of the
     estimated PDS with time. The movement per symbol (or a number of symbols)
     is proportional to the sample rate offset. It has to be considered the
     PDS shiftings of the timing correction unit ("rActShiftTiCor" can be used
     for that). The procedere is to detect the maximum peak in the PDS and use
     this as a reference, assuming tha delay of this peak is not changing. The
     problem is when another peak get higher than this due to fading. In this
     case we must adjust the history to this new peak (the new reference) */
  int		iMaxInd;
  CReal	rMax;
  //int	rMax_fxp;
  
  /* Find index of maximum peak in PDS estimation. This is our reference
     for this estimation method */
  Max(rMax, iMaxInd, vecrAvPoDeSpRot);
  
  /* Integration of timing corrections
     FIXME: Check for overrun of "iIntegTiCorrections" variable! */
  iIntegTiCorrections += (long long) iIntPartTiCorr;
  
  /* We need to consider the timing corrections done by the timing unit. What
     we want to estimate is only the real movement of the detected maximum
     peak */
  const long long iCurRes = iIntegTiCorrections + iMaxInd;
  veciSRTiCorrHist.AddEnd(iCurRes);
  
  /* We assumed that the detected peak is always the same peak in the actual
     PDS. But due to fading the maximum can change to a different peak. In
     this case the estimation would be wrong. We try to detect the detection
     of a different peak by defining a maximum sample rate change. The sample
     rate offset is very likely to be very constant since usually crystal
     oscialltors are used. Thus, if a larger change of sample rate offset
     happens, we assume that the maximum peak has changed */
  const long long iNewDiff = veciSRTiCorrHist[iLenCorrectionHist - 2] - iCurRes;
  
  /* If change is larger than 2, it is most likely that a new peak was chosen
     by the maximum function. Also, if the sign has changed of the difference
     (and it is not zero), we also say that a new peak was selected */
  if ((llabs(iNewDiff) > 2) ||
      ((Sign(iOldNonZeroDiff) != Sign(iNewDiff)) && (iNewDiff != 0)))
    {
      /* Correct the complete history to the new reference peak. Reference
	 peak was already added, therefore do not use last element */
      for (i = 0; i < iLenCorrectionHist - 1; i++)
	veciSRTiCorrHist[i] -= iNewDiff;
    }
  
  /* Store old difference if it is not zero */
  if (iNewDiff != 0)
    iOldNonZeroDiff = iNewDiff;
  
  
  /* Check, if we are in acquisition phase */
  if (iResOffsetAcquCnt > 0)
    {
      /* Acquisition phase */
      iResOffsetAcquCnt--;
    }
  else
    {
      /* Apply the result from acquisition only once */
      if (bSamRaOffsAcqu == TRUE)
	{
	  /* End of acquisition phase */
	  bSamRaOffsAcqu = FALSE;
	  
	  /* Set sample rate offset to initial estimate. We consider the
	     initialization phase of channel estimation by "iSymDelay" */
	  /*rInitSamOffset = FXP GetSamOffHz(iCurRes - veciSRTiCorrHist[
	    iLenCorrectionHist - (iResOffAcqCntMax - iSymDelay)],
	    iResOffAcqCntMax - iSymDelay - 1); */
	  CFReal rInitSamOffset = FXP (GetSamOffHz(iCurRes - veciSRTiCorrHist[
									      iLenCorrectionHist - (iResOffAcqCntMax - iSymDelay)],
						   iResOffAcqCntMax - iSymDelay - 1)); 
	  
	  
#ifndef USE_SAMOFFS_TRACK_FRE_PIL
	  /* Apply initial sample rate offset estimation */
	  // (Parameter.rResampleOffset) -= rInitSamOffset;
	  FXP (Parameter.rResampleOffset) -= rInitSamOffset;
	  
#endif
	  
	  /* Reset estimation history (init with zeros) since the sample
	     rate offset was changed */
	  veciSRTiCorrHist.Init(iLenCorrectionHist, 0);
	  iIntegTiCorrections = 0;
	}
      else
	{
	  /* Tracking phase */
	  /* Get actual sample rate offset in Hertz */
	  /* const CReal rSamOffset = GetSamOffHz(iCurRes - veciSRTiCorrHist[0],
	     iLenCorrectionHist - 1); */
	  const CFReal rSamOffset = FXP (GetSamOffHz(iCurRes - veciSRTiCorrHist[0],
						     iLenCorrectionHist - 1));
	  
#ifndef USE_SAMOFFS_TRACK_FRE_PIL
	  /* Apply result from sample rate offset estimation */
	  //Parameter.rResampleOffset -= CONTR_SAMP_OFF_INT_FTI * rSamOffset;
	  FXP (Parameter.rResampleOffset) -= CONTR_SAMP_OFF_INT_FTI * rSamOffset;
#endif
	}
    }
  
  
  /* Delay spread length estimation --------------------------------------- */
  /* Estimate the noise energy using the minimum statistic. We assume that
     the noise variance is equal on all samples of the impulse response.
     Therefore we subtract the variance on each sample. The total estimated
     signal energy is the total energy minus the noise energy */
  /* Calculate total energy */
  const CFReal rTotEgy = Sum(vecrAvPoDeSpRot);
  
  /* Sort the values of the PDS to get the smallest values */
  CRealVector rSortAvPoDeSpRot(Sort(vecrAvPoDeSpRot));
  
  /* Average the result of smallest values and overestimate result */
  const long long rSigmaNoise_fxp =
    (long long)(Sum(rSortAvPoDeSpRot(1, NUM_SAM_IR_FOR_MIN_STAT - 1)) /
		NUM_SAM_IR_FOR_MIN_STAT * OVER_EST_FACT_MIN_STAT*(1<<FXP_TIME_SYNC_TRACK_SCALE));
  
  /* Calculate signal energy by subtracting the noise energy from total
     energy (energy cannot by negative -> bound at zero) */
  const long long rSigEnergyBound_fxp =
    (long long)((double)Max(rTotEgy - ((double)rSigmaNoise_fxp/(1<<FXP_TIME_SYNC_TRACK_SCALE)) * iNumIntpFreqPil,
			    (FXP)0)*(1<<FXP_TIME_SYNC_TRACK_SCALE));
  
  /* From left to the right -> search for end of PDS */
  rEstPDSEnd_fxp = (FXP) (iNumIntpFreqPil - 1);
  rCurEnergy_fxp = 0;
  bPDSResultFound = FALSE;
  for (i = 0; i < iNumIntpFreqPil; i++)
    {
      if (bPDSResultFound == FALSE)
	{
	  if (rCurEnergy_fxp > rSigEnergyBound_fxp)
	    {
	      /* Delay index */
	      rEstPDSEnd_fxp = (CReal) i;
	      
	      bPDSResultFound = TRUE;
	    }
	  
	  /* Accumulate signal energy, subtract noise on each sample */
	  rCurEnergy_fxp += (long long)(vecrAvPoDeSpRot[i]*(1<<FXP_TIME_SYNC_TRACK_SCALE)) - rSigmaNoise_fxp; //slu2 change
	}
    }
  
  /* From right to the left -> search for beginning of PDS */
  rEstPDSBegin_fxp = 0;
  rCurEnergy_fxp = 0;
  bPDSResultFound = FALSE;
  for (i = iNumIntpFreqPil - 1; i >= 0; i--)
    {
      if (bPDSResultFound == FALSE)
	{
	  if (rCurEnergy_fxp > rSigEnergyBound_fxp)
	    {
	      /* Delay index */
	      rEstPDSBegin_fxp = (CFReal) i;
	      
	      bPDSResultFound = TRUE;
	    }
	  
	  /* Accumulate signal energy, subtract noise on each sample */
	  rCurEnergy_fxp += (long long)(vecrAvPoDeSpRot[i]*(1<<FXP_TIME_SYNC_TRACK_SCALE)) - rSigmaNoise_fxp; //slu2 change
	}
    }
  
  /* If the signal energy is too low it can happen that the estimated
     beginning of the impulse response is before the end -> correct */
  if (rEstPDSBegin_fxp > rEstPDSEnd_fxp)
    {
      /* Set beginning and end to their maximum (minimum) value */
      //rEstPDSBegin = (CReal) 0.0;
      rEstPDSBegin_fxp = 0;
      rEstPDSEnd_fxp = (CFReal) (iNumIntpFreqPil - 1);
    }
  
  /* Correct estimates of begin and end of PDS by the rotation */
  const CReal rPDSLenCorrection = iNumIntpFreqPil - iStPoRot + 1; /* slu2: dont' have to change here */
  rEstPDSBegin_fxp -= FXP (rPDSLenCorrection);
  rEstPDSEnd_fxp -= FXP (rPDSLenCorrection);
  
  /* Set return parameters */
  rLenPDS_fxp = rEstPDSEnd_fxp - rEstPDSBegin_fxp;
  rOffsPDS_fxp= rEstPDSBegin_fxp;
}
Пример #25
0
void CUIHelper::PaintReferenceDamageAdj (CG16bitImage &Dest, int x, int y, int iLevel, int iHP, const int *iDamageAdj) const

//	PaintReferenceDamageAdj
//
//	Takes an array of damage type adj values and displays them

	{
	int i;
	bool bSortByDamageType = true;
	bool bOptionShowDamageAdjAsHP = false;

	const CVisualPalette &VI = m_HI.GetVisuals();
	const CG16bitFont &Small = VI.GetFont(fontSmall);
	const CG16bitFont &Medium = VI.GetFont(fontMedium);
	WORD wColorRef = VI.GetColor(colorTextHighlight);

	//	Must have positive HP

	if (iHP == 0)
		return;

	//	Sort damage types from highest to lowest

	CSymbolTable Sorted;
	int iLengthEstimate = 0;
	int iImmuneCount = 0;
	for (i = 0; i < damageCount; i++)
		{
		//	Skip if this damage type is not appropriate to our level

		int iDamageLevel = GetDamageTypeLevel((DamageTypes)i);
		if (iDamageLevel < iLevel - 5 || iDamageLevel > iLevel + 3)
			continue;

		//	Skip if the damage adj is 100%

		if (iDamageAdj[i] == iHP)
			continue;

		//	Figure out the sort order

		CString sKey;
		if (bSortByDamageType)
			sKey = strPatternSubst(CONSTLIT("%02d"), i);
		else
			{
			DWORD dwHighToLow = (iDamageAdj[i] == -1 ? 0 : 1000000 - iDamageAdj[i]);
			sKey = strPatternSubst(CONSTLIT("%08x %02d"), dwHighToLow, i);
			}

		//	Add to list

		DWORD dwValue = MAKELONG((WORD)i, (WORD)(short)iDamageAdj[i]);

		Sorted.AddEntry(sKey, (CObject *)dwValue);

		//	Estimate how many entries we will have (so we can decide the font size)
		//	We assume that immune entries get collapsed.

		if (iDamageAdj[i] != -1)
			iLengthEstimate++;
		else
			iImmuneCount++;
		}

	//	If we have six or more icons, then we need to paint smaller

	iLengthEstimate += Min(2, iImmuneCount);
	const CG16bitFont &TheFont = (iLengthEstimate >= 6 ? Small : Medium);
	int cyOffset = (Medium.GetHeight() - TheFont.GetHeight()) / 2;
	
	//	Paint the icons

	for (i = 0; i < Sorted.GetCount(); i++)
		{
		DWORD dwValue = (DWORD)Sorted.GetValue(i);
		int iDamageType = LOWORD(dwValue);
		int iDamageAdj = (int)(short)HIWORD(dwValue);
		int iPercentAdj = (100 * (iDamageAdj - iHP) / iHP);

		//	Prettify the % by rounding to a number divisible by 5

		int iPrettyPercent = 5 * ((iPercentAdj + 2 * Sign(iPercentAdj)) / 5);

		//	Skip if prettify results in 0%

		if (bOptionShowDamageAdjAsHP && iPrettyPercent == 0)
			continue;

		//	Draw icon

		g_pHI->GetVisuals().DrawDamageTypeIcon(Dest, x, y, (DamageTypes)iDamageType);
		x += DAMAGE_TYPE_ICON_WIDTH + DAMAGE_ADJ_ICON_SPACING_X;

		//	If we have a bunch of entries with "immune", then compress them

		if (i < (Sorted.GetCount() - 1)
				&& iDamageAdj == -1
				&& (iDamageAdj == (int)(short)HIWORD((DWORD)Sorted.GetValue(i + 1))))
			continue;

		//	Figure out how to display damage adj

		CString sStat;
		if (iDamageAdj == -1)
			sStat = CONSTLIT("immune");
		else if (bOptionShowDamageAdjAsHP)
			sStat = strFromInt(iDamageAdj);
		else
			sStat = strPatternSubst(CONSTLIT("%s%d%%"), (iPrettyPercent > 0 ? CONSTLIT("+") : NULL_STR), iPrettyPercent);
		
		//	Draw

		Dest.DrawText(x,
				y + cyOffset,
				TheFont,
				wColorRef,
				sStat,
				0,
				&x);

		x += DAMAGE_ADJ_SPACING_X;
		}
	}
Пример #26
0
bool InterpolateConstrainedMultiPath(Robot& robot,const MultiPath& path,vector<GeneralizedCubicBezierSpline>& paths,Real xtol)
{
  //sanity check -- make sure it's a continuous path
  if(!path.IsContinuous()) {
    fprintf(stderr,"InterpolateConstrainedMultiPath: path is discontinuous\n");
    return false;
  }
  if(path.sections.empty()) {
    fprintf(stderr,"InterpolateConstrainedMultiPath: path is empty\n");
    return false;
  }

  if(path.settings.contains("resolution")) {
    //see if the resolution is high enough to just interpolate directly
    Real res=path.settings.as<Real>("resolution");
    if(res <= xtol) {
      printf("Direct interpolating trajectory with res %g\n",res);
      //just interpolate directly
      RobotCSpace space(robot);
      RobotGeodesicManifold manifold(robot);
      paths.resize(path.sections.size());
      for(size_t i=0;i<path.sections.size();i++) {
	if(path.sections[i].times.empty()) {
	  SPLINE_INTERPOLATE_FUNC(path.sections[i].milestones,paths[i].segments,
			       &space,&manifold);
	  //uniform timing
	  paths[i].durations.resize(paths[i].segments.size());
	  Real dt=1.0/Real(paths[i].segments.size());
	  for(size_t j=0;j<paths[i].segments.size();j++)
	    paths[i].durations[j] = dt;
	}
	else {
	  SPLINE_INTERPOLATE_FUNC(path.sections[i].milestones,path.sections[i].times,paths[i].segments,
			       &space,&manifold);
	  //get timing from path
	  paths[i].durations.resize(paths[i].segments.size());
	  for(size_t j=0;j<paths[i].segments.size();j++)
	    paths[i].durations[j] = path.sections[i].times[j+1]-path.sections[i].times[j];
	}
      }
      return true;
    }
  }
  printf("Discretizing constrained trajectory at res %g\n",xtol);

  RobotCSpace cspace(robot);
  RobotGeodesicManifold manifold(robot);

  //create transition constraints and derivatives
  vector<vector<IKGoal> > stanceConstraints(path.sections.size());
  vector<vector<IKGoal> > transitionConstraints(path.sections.size()-1);
  vector<Config> transitionDerivs(path.sections.size()-1);
  for(size_t i=0;i<path.sections.size();i++) 
    path.GetIKProblem(stanceConstraints[i],i);
  for(size_t i=0;i+1<path.sections.size();i++) {
    //put all nonredundant constraints into transitionConstraints[i]
    transitionConstraints[i]=stanceConstraints[i];
    for(size_t j=0;j<stanceConstraints[i+1].size();j++) {
      bool res=AddGoalNonredundant(stanceConstraints[i+1][j],transitionConstraints[i]);
      if(!res) {
	fprintf(stderr,"Conflict between goal %d of stance %d and stance %d\n",j,i+1,i);
	fprintf(stderr,"  Link %d\n",stanceConstraints[i+1][j].link);
	return false;
      }
    }

    const Config& prev=path.sections[i].milestones[path.sections[i].milestones.size()-2];
    const Config& next=path.sections[i+1].milestones[1];
    manifold.InterpolateDeriv(prev,next,0.5,transitionDerivs[i]);
    transitionDerivs[i] *= 0.5;

    //check for overshoots a la MonotonicInterpolate
    Vector inslope,outslope;
    manifold.InterpolateDeriv(prev,path.sections[i].milestones.back(),1.0,inslope);
    manifold.InterpolateDeriv(path.sections[i].milestones.back(),next,0.0,outslope);
    for(int j=0;j<transitionDerivs[i].n;j++) {
      if(Sign(transitionDerivs[i][j]) != Sign(inslope[j]) || Sign(transitionDerivs[i][j]) != Sign(outslope[j])) transitionDerivs[i][j] = 0;
      else {
	if(transitionDerivs[i][j] > 0) {
	  if(transitionDerivs[i][j] > 3.0*outslope[j])
	    transitionDerivs[i][j] = 3.0*outslope[j];
	  if(transitionDerivs[i][j] > 3.0*inslope[j])
	    transitionDerivs[i][j] = 3.0*inslope[j];
	}
	else {
	  if(transitionDerivs[i][j] < 3.0*outslope[j])
	    transitionDerivs[i][j] = 3.0*outslope[j];
	  if(transitionDerivs[i][j] < 3.0*inslope[j])
	    transitionDerivs[i][j] = 3.0*inslope[j];
	}
      }
    }

    //project "natural" derivative onto transition manifold
    RobotIKFunction f(robot);
    f.UseIK(transitionConstraints[i]);
    GetDefaultIKDofs(robot,transitionConstraints[i],f.activeDofs);
    Vector temp(f.activeDofs.Size()),dtemp(f.activeDofs.Size()),dtemp2;
    f.activeDofs.InvMap(path.sections[i].milestones.back(),temp);
    f.activeDofs.InvMap(transitionDerivs[i],dtemp);
    Matrix J;
    f.PreEval(temp);
    f.Jacobian(temp,J);
    RobustSVD<Real> svd;
    if(!svd.set(J)) {
      fprintf(stderr,"Unable to set SVD of transition constraints %d\n",i);
      return false;
    }
    svd.nullspaceComponent(dtemp,dtemp2);
    dtemp -= dtemp2;
    f.activeDofs.Map(dtemp,transitionDerivs[i]);
  }

  //start constructing path
  paths.resize(path.sections.size());   
  for(size_t i=0;i<path.sections.size();i++) {
    paths[i].segments.resize(0);
    paths[i].durations.resize(0);

    Vector dxprev,dxnext;
    if(i>0) 
      dxprev.setRef(transitionDerivs[i-1]); 
    if(i<transitionDerivs.size()) 
      dxnext.setRef(transitionDerivs[i]); 
    if(stanceConstraints[i].empty()) {
      SPLINE_INTERPOLATE_FUNC(path.sections[i].milestones,paths[i].segments,&cspace,&manifold);
      DiscretizeSpline(paths[i],xtol);

      //Note: discretizeSpline will fill in the spline durations
    }
    else {
      RobotSmoothConstrainedInterpolator interp(robot,stanceConstraints[i]);
      interp.xtol = xtol;
      if(!MultiSmoothInterpolate(interp,path.sections[i].milestones,dxprev,dxnext,paths[i])) {
	/** TEMP - test no inter-section smoothing**/
	//if(!MultiSmoothInterpolate(interp,path.sections[i].milestones,paths[i])) {
	fprintf(stderr,"Unable to interpolate section %d\n",i);
	return false;
      }
    }
    //set the time scale if the input path is timed
    if(!path.sections[i].times.empty()) {
      //printf("Time scaling section %d to duration %g\n",i,path.sections[i].times.back()-path.sections[i].times.front());
      paths[i].TimeScale(path.sections[i].times.back()-path.sections[i].times.front());
    }
  }
  return true;
}
// Load assets
bool ModuleSceneIntro::Start()
{
    LOG("Loading Intro assets");
    bool ret = true;
    bool activation = false;

    App->renderer->camera.x = App->renderer->camera.y = 0;

    circle = App->textures->Load("pinball/ball.png");

    background = App->textures->Load("pinball/PinballBackGround2.png");
    foreground = App->textures->Load("pinball/PinballForeground.png");



    App->audio->PlayMusic("pinball/Sountrack.ogg", 0.0f);

    // SENSOR
    green = App->textures->Load("pinball/verde.png");
    purple = App->textures->Load("pinball/morado.png");
    blue = App->textures->Load("pinball/azul.png");
    arrow_pink = App->textures->Load("pinball/rosa.png");

    sfx_bonus = App->audio->LoadFx("pinball/ding.wav");
    sfx_spawn = App->audio->LoadFx("pinball/respawn.ogg");
    sfx_launcher = App->audio->LoadFx("pinball/shoot.ogg");
    sfx_charge = App->audio->LoadFx("pinball/charge.ogg");


    // MAPA

    int	map[156] = {
        676, 747,
        684, 749,
        692, 744,
        694, 733,
        690, 722,
        681, 716,
        669, 716,
        646, 337,
        637, 254,
        630, 208,
        618, 173,
        600, 143,
        574, 116,
        543, 97,
        500, 82,
        445, 72,
        390, 68,
        325, 70,
        267, 77,
        237, 87,
        221, 65,
        203, 51,
        175, 43,
        149, 52,
        128, 72,
        128, 100,
        140, 123,
        158, 143,
        138, 170,
        119, 203,
        110, 232,
        103, 270,
        103, 305,
        109, 337,
        120, 369,
        138, 400,
        153, 423,
        170, 448,
        172, 457,
        163, 466,
        154, 480,
        152, 495,
        159, 510,
        167, 517,
        180, 518,
        183, 525,
        170, 567,
        160, 569,
        147, 560,
        130, 560,
        119, 570,
        113, 583,
        112, 598,
        119, 612,
        127, 620,
        138, 629,
        132, 641,
        121, 652,
        113, 661,
        110, 673,
        102, 837,
        89, 1025,
        128, 1024,
        133, 946,
        143, 932,
        319, 980,
        265, 1031,
        459, 1031,
        405, 979,
        584, 926,
        594, 944,
        595, 1009,
        637, 1008,
        607, 376,
        617, 367,
        634, 747,
        646, 999,
        688, 999
    };

    int barras_cash[16] = {
        226, 218,
        227, 229,
        229, 234,
        232, 234,
        233, 229,
        232, 217,
        230, 213,
        227, 214
    };

    int barras_cash_2[16] = {
        267, 239,
        270, 239,
        272, 235,
        270, 220,
        268, 216,
        263, 217,
        262, 221,
        264, 235
    };

    int barras_sup[16] = {
        375, 155,
        379, 158,
        385, 158,
        387, 154,
        386, 130,
        383, 125,
        377, 125,
        374, 130
    };

    int barras_sup_2[16] = {
        430, 156,
        437, 155,
        440, 148,
        438, 128,
        434, 121,
        427, 121,
        423, 129,
        425, 149
    };

    int base_flip_der[20] = {
        577, 679,
        581, 848,
        477, 887,
        491, 893,
        494, 903,
        488, 917,
        582, 882,
        587, 873,
        583, 680,
        581, 676
    };

    int base_flip_izq[24] = {
        152, 698,
        148, 846,
        151, 851,
        247, 888,
        240, 895,
        238, 902,
        238, 911,
        151, 884,
        145, 879,
        143, 871,
        147, 698,
        150, 695
    };

    int cash[192] = {
        260, 391,
        288, 379,
        311, 368,
        319, 362,
        325, 355,
        327, 348,
        327, 337,
        294, 190,
        329, 150,
        331, 146,
        332, 136,
        329, 129,
        322, 125,
        312, 124,
        294, 127,
        269, 135,
        248, 143,
        228, 153,
        206, 167,
        190, 180,
        173, 197,
        161, 213,
        147, 236,
        140, 261,
        140, 283,
        142, 305,
        147, 325,
        156, 343,
        168, 363,
        182, 383,
        193, 396,
        203, 410,
        207, 413,
        210, 409,
        199, 396,
        185, 377,
        169, 353,
        157, 331,
        150, 310,
        147, 288,
        147, 268,
        152, 243,
        159, 227,
        175, 206,
        196, 189,
        220, 174,
        240, 166,
        260, 163,
        273, 167,
        283, 176,
        287, 186,
        295, 219,
        297, 241,
        296, 252,
        304, 256,
        309, 269,
        309, 277,
        304, 285,
        310, 290,
        313, 305,
        316, 318,
        320, 332,
        321, 344,
        318, 353,
        310, 360,
        300, 362,
        291, 361,
        281, 356,
        273, 354,
        248, 354,
        231, 351,
        219, 344,
        210, 332,
        206, 319,
        205, 305,
        206, 292,
        209, 284,
        201, 280,
        196, 272,
        194, 262,
        200, 252,
        198, 243,
        196, 229,
        192, 226,
        186, 230,
        180, 241,
        175, 253,
        172, 269,
        172, 283,
        175, 300,
        179, 311,
        186, 324,
        198, 339,
        213, 354,
        227, 366,
        245, 380
    };

    int curva_der_arriba[52] = {
        486, 162,
        508, 163,
        533, 171,
        549, 184,
        564, 202,
        577, 224,
        586, 244,
        593, 268,
        596, 282,
        597, 295,
        606, 295,
        608, 283,
        604, 251,
        598, 225,
        592, 204,
        584, 186,
        573, 168,
        559, 153,
        544, 142,
        520, 129,
        499, 124,
        482, 123,
        476, 127,
        475, 137,
        477, 149,
        480, 158
    };

    int tri_der[30] = {
        523, 711,
        478, 819,
        476, 825,
        476, 831,
        479, 838,
        484, 842,
        492, 843,
        543, 819,
        548, 813,
        550, 807,
        546, 715,
        544, 710,
        540, 705,
        532, 704,
        526, 706
    };


    int tri_izq[30] = {
        204, 711,
        252, 820,
        252, 832,
        248, 840,
        242, 844,
        235, 843,
        188, 822,
        182, 816,
        180, 808,
        182, 718,
        183, 712,
        186, 706,
        191, 703,
        197, 704,
        202, 708
    };

    int reb_der[6] = {
        523, 711,
        496, 766,
        475, 820
    };


    int reb_izq[6] = {
        204, 711,
        231, 766,
        253, 820
    };

    int via_superior[112] = {
        485, 193,
        491, 190,
        497, 190,
        513, 197,
        531, 212,
        546, 227,
        558, 245,
        567, 266,
        570, 293,
        568, 326,
        558, 354,
        541, 386,
        530, 414,
        525, 428,
        513, 439,
        499, 446,
        493, 447,
        473, 450,
        490, 428,
        521, 382,
        556, 330,
        566, 312,
        538, 289,
        520, 323,
        510, 338,
        497, 356,
        454, 385,
        435, 432,
        431, 436,
        426, 432,
        431, 425,
        433, 413,
        430, 405,
        421, 402,
        418, 395,
        422, 391,
        427, 391,
        437, 371,
        442, 357,
        440, 348,
        442, 339,
        440, 327,
        434, 300,
        428, 297,
        430, 290,
        434, 285,
        440, 280,
        447, 267,
        445, 254,
        459, 233,
        469, 229,
        478, 227,
        485, 224,
        490, 215,
        491, 207,
        490, 197
    };


    int via_central[76] = {
        562, 602,
        580, 578,
        575, 536,
        566, 503,
        551, 460,
        520, 385,
        492, 320,
        481, 289,
        481, 272,
        487, 257,
        501, 252,
        516, 251,
        529, 258,
        537, 272,
        537, 286,
        530, 303,
        519, 321,
        507, 339,
        539, 358,
        554, 335,
        565, 313,
        572, 289,
        572, 268,
        568, 250,
        558, 234,
        543, 222,
        519, 214,
        496, 214,
        472, 223,
        456, 238,
        447, 257,
        442, 286,
        447, 310,
        458, 342,
        497, 434,
        528, 515,
        536, 544,
        538, 575
    };

    int via_inferior[44] = {
        518, 537,
        511, 543,
        504, 547,
        500, 555,
        500, 563,
        529, 609,
        536, 611,
        536, 554,
        532, 530,
        548, 511,
        566, 503,
        574, 527,
        581, 608,
        584, 612,
        579, 448,
        573, 443,
        567, 447,
        561, 461,
        551, 487,
        548, 503,
        535, 519,
        524, 531
    };

    int muerte[6] = {
        303, 1000,
        463, 1000,
        463, 1001
    };

    int reb_bajo_izq[6] = {
        85, 1000,
        130, 1000,
        130, 1001
    };

    int reb_bajo_der[6] = {
        595, 1000,
        640, 1000,
        640, 1001
    };


    App->physics->CreateObj(0, 0, map, 156, 0, 0, 0, 0.2f, false, b_static);
    App->physics->CreateObj(0, 0, barras_cash, 16, 0, 0, 0, 0.2f, false, b_static);
    App->physics->CreateObj(0, 0, barras_cash_2, 16, 0, 0, 0, 0.2f, false, b_static);
    App->physics->CreateObj(0, 0, barras_sup, 16, 0, 0, 0, 0.2f, false, b_static);
    App->physics->CreateObj(0, 0, barras_sup_2, 16, 0, 0, 0, 0.2f, false, b_static);
    App->physics->CreateObj(0, 0, base_flip_der, 20, 0, 0, 0, 0.2f, false, b_static);
    App->physics->CreateObj(0, 0, base_flip_izq, 22, 0, 0, 0, 0.2f, false, b_static);
    App->physics->CreateObj(0, 0, cash, 192, 0, 0, 0, 0.2f, false, b_static);
    App->physics->CreateObj(0, 0, curva_der_arriba, 52, 0, 0, 0, 0.2f, false, b_static);
    App->physics->CreateObj(0, 0, tri_der, 30, 0, 0, 0, 0.2f, false, b_static);
    App->physics->CreateObj(0, 0, tri_izq, 30, 0, 0, 0, 0.2f, false, b_static);
    App->physics->CreateObj(0, 0, reb_der, 6, 0, 0, 0, 2.0f, false, b_static);
    App->physics->CreateObj(0, 0, reb_izq, 6, 0, 0, 0, 2.0f, false, b_static);
    App->physics->CreateObj(0, 0, reb_bajo_der, 6, 0, 0, 0, 5.0f, false, b_static);
    App->physics->CreateObj(0, 0, reb_bajo_izq, 6, 0, 0, 0, 5.0f, false, b_static);


    // PUENTE
    if (!activation)
    {
        App->physics->CreateObj(0, 0, via_superior, 112, 0, 0, 0, 0.2f, false, b_static);
        App->physics->CreateObj(0, 0, via_inferior, 44, 0, 0, 0, 0.2f, false, b_static);
    }
    if (activation)
    {
        App->physics->CreateObj(0, 0, via_central, 76, 0, 0, 0, 0.2f, false, b_static);
    }

    App->physics->CreateObj(183, 98, NULL, 0, 55, 0, 0, 1.2f, false, b_static);
    App->physics->CreateObj(215, 272, NULL, 0, 35, 0, 0, 1.2f, false, b_static);
    App->physics->CreateObj(295, 272, NULL, 0, 30, 0, 0, 1.2f, false, b_static);
    App->physics->CreateObj(255, 310, NULL, 0, 30, 0, 0, 1.0f, false, b_static);
    App->physics->CreateObj(364, 218, NULL, 0, 35, 0, 0, 1.2f, false, b_static);
    App->physics->CreateObj(425, 266, NULL, 0, 35, 0, 0, 1.2f, false, b_static);
    App->physics->CreateObj(470, 208, NULL, 0, 35, 0, 0, 1.2f, false, b_static);

    //SENSOR MUERTE ABAJO
    morir = App->physics->CreateObj(0, 0, muerte, 6, 0, 0, 0, 0, true, b_static);
    morir->listener = this;

    signs.PushBack(Sign(this, 454, 112, lightTypes::green)); // Not Working anyway...

    return ret;
}
Пример #28
0
int main(int argc, char* argv[])
{
    wchar_t* ModuleName = L"klick.sys";
    
    ULONG FileSize;

    MyReadFile ( argv[1], g_File, &FileSize );

    PCHAR pKey1, pKey2, pSign;
    ULONG Key1Size, Key2Size, RegSize;
    char *pBasePtr = &g_File[0];

    CheckForSignOld( pBasePtr, g_File.size(), &FileSize );        

    GetCryptoCPtrs( pBasePtr, FileSize, &pKey1, &Key1Size, &pKey2, &Key2Size, &pSign, &RegSize, &FileSize );        
    
    PIMAGE_DOS_HEADER   Dos_header = (PIMAGE_DOS_HEADER)pBasePtr;
    PIMAGE_NT_HEADERS   PE_header = (PIMAGE_NT_HEADERS)( (char*)pBasePtr + Dos_header->e_lfanew );

    PE_header->OptionalHeader.CheckSum = 0;

    bool RetVal = false;
    HDSKM libDSKM;
    ULONG dskm_err = DSKM_ERR_OK ;

    libDSKM = DSKM_InitLibraryEx(Kl1Alloc, Kl1Free, NULL, TRUE) ;

    HDSKMLIST list1;
    dskm_err = DSKM_ParList_Create(&list1);

    CReadObj Key1( pKey1, Key1Size );
    CReadObj Key2( pKey2, Key2Size );
    CReadObj Sign( pSign, RegSize );
    
    HDSKMLISTOBJ param1 = DSKM_ParList_AddBufferedReg(list1, 0, Key1.m_pBase, Key1.m_Size, (pfnDSKM_GetBuffer_CallBack)ReadBuffByFile, &Key1 ) ;
    HDSKMLISTOBJ param2 = DSKM_ParList_AddBufferedReg(list1, 0, Key2.m_pBase, Key2.m_Size, (pfnDSKM_GetBuffer_CallBack)ReadBuffByFile, &Key2 ) ;
    HDSKMLISTOBJ param3 = DSKM_ParList_AddBufferedReg(list1, 0, Sign.m_pBase, Sign.m_Size, (pfnDSKM_GetBuffer_CallBack)ReadBuffByFile, &Sign ) ;

    dskm_err = DSKM_PrepareRegsSet(libDSKM, list1, 0);

    dskm_err = DSKM_ParList_Delete(list1) ;

    // Check

    HDSKMLIST list2 = 0 ;
    DSKM_ParList_Create(&list2);

    CReadObj File( pBasePtr, FileSize );

    HDSKMLISTOBJ param4 = DSKM_ParList_AddBufferedObject(list2, 0, File.m_pBase, File.m_Size, (pfnDSKM_GetBuffer_CallBack)ReadBuffByFile, &File ) ;

    dskm_err = DSKM_ParList_SetObjectHashingProp(list2, param4, ModuleName, 2 *( wcslen ( ModuleName ) + 1 ) ) ;

    dskm_err = DSKM_CheckObjectsUsingRegsSet( libDSKM, list2, 0) ;

    if ( dskm_err == DSKM_ERR_OK )
        RetVal = true;

    DSKM_ParList_Delete(list2) ;

    DSKM_DeInitLibrary( libDSKM, TRUE ) ;

	return 0;
}
Пример #29
0
void C4Object::DoMovement()
{
	int32_t iContact=0;
	bool fAnyContact=false; int iContacts = 0;
	BYTE fTurned=0,fRedirectYR=0,fNoAttach=0;
	// Restrictions
	if (Def->NoHorizontalMove) xdir=0;
	// Dig free target area
	C4PropList* pActionDef = GetAction();
	if (pActionDef)
		if (pActionDef->GetPropertyInt(P_DigFree))
		{
			int ctcox, ctcoy;
			// Shape size square
			if (pActionDef->GetPropertyInt(P_DigFree)==1)
			{
				ctcox=fixtoi(fix_x+xdir); ctcoy=fixtoi(fix_y+ydir);
				::Landscape.DigFreeRect(ctcox+Shape.GetX(),ctcoy+Shape.GetY(),Shape.Wdt,Shape.Hgt,this);
			}
			// Free size round (variable size)
			else
			{
				ctcox=fixtoi(fix_x+xdir); ctcoy=fixtoi(fix_y+ydir);
				int32_t rad = pActionDef->GetPropertyInt(P_DigFree);
				if (Con<FullCon) rad = rad*6*Con/5/FullCon;
				::Landscape.DigFree(ctcox,ctcoy-1,rad,this);
			}
		}

	// store previous movement and ocf
	C4Real oldxdir(xdir), oldydir(ydir);
	uint32_t old_ocf = OCF;

	bool fMoved = false;
	C4Real new_x = fix_x + xdir;
	C4Real new_y = fix_y + ydir;
	SideBounds(new_x);

	if (!Action.t_attach) // Unattached movement  = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
	{
		// Horizontal movement - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
		// Move to target
		while (fixtoi(new_x) != fixtoi(fix_x))
		{
			// Next step
			int step = Sign(new_x - fix_x);
			uint32_t border_hack_contacts = 0;
			iContact=ContactCheck(GetX() + step, GetY(), &border_hack_contacts);
			if (iContact || border_hack_contacts)
			{
				fAnyContact=true; iContacts |= t_contact | border_hack_contacts;
			}
			if (iContact)
			{
				// Abort horizontal movement
				new_x = fix_x;
				// Vertical redirection (always)
				RedirectForce(xdir,ydir,-1);
				ApplyFriction(ydir,ContactVtxFriction(this));
			}
			else // Free horizontal movement
			{
				DoMotion(step, 0);
				fMoved = true;
			}
		}
		// Vertical movement - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
		// Movement target
		new_y = fix_y + ydir;
		// Movement bounds (vertical)
		VerticalBounds(new_y);
		// Move to target
		while (fixtoi(new_y) != fixtoi(fix_y))
		{
			// Next step
			int step = Sign(new_y - fix_y);
			if ((iContact=ContactCheck(GetX(), GetY() + step, nullptr, ydir > 0)))
			{
				fAnyContact=true; iContacts |= t_contact;
				new_y = fix_y;
				// Vertical contact horizontal friction
				ApplyFriction(xdir,ContactVtxFriction(this));
				// Redirection slide or rotate
				if (!ContactVtxCNAT(this,CNAT_Left))
					RedirectForce(ydir,xdir,-1);
				else if (!ContactVtxCNAT(this,CNAT_Right))
					RedirectForce(ydir,xdir,+1);
				else
				{
					// living things are always capable of keeping their rotation
					if (OCF & OCF_Rotate) if (iContact==1) if (!Alive)
							{
								RedirectForce(ydir,rdir,-ContactVtxWeight(this));
								fRedirectYR=1;
							}
					ydir=0;
				}
			}
			else // Free vertical movement
			{
				DoMotion(0,step);
				fMoved = true;
			}
		}
	}
	if (Action.t_attach) // Attached movement = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
	{
		VerticalBounds(new_y);
		// Move to target
		do
		{
			// Set next step target
			int step_x = 0, step_y = 0;
			if (fixtoi(new_x) != GetX())
				step_x = Sign(fixtoi(new_x) - GetX());
			else if (fixtoi(new_y) != GetY())
				step_y = Sign(fixtoi(new_y) - GetY());
			int32_t ctx = GetX() + step_x;
			int32_t cty = GetY() + step_y;
			// Attachment check
			if (!Shape.Attach(ctx,cty,Action.t_attach))
				fNoAttach=1;
			else
			{
				// Attachment change to ctx/cty overrides target
				if (ctx != GetX() + step_x)
				{
					xdir = Fix0; new_x = itofix(ctx);
				}
				if (cty != GetY() + step_y)
				{
					ydir = Fix0; new_y = itofix(cty);
				}
			}
			// Contact check & evaluation
			uint32_t border_hack_contacts = 0;
			iContact=ContactCheck(ctx,cty,&border_hack_contacts);
			if (iContact || border_hack_contacts)
			{
				fAnyContact=true; iContacts |= border_hack_contacts | t_contact;
			}
			if (iContact)
			{
				// Abort movement
				if (ctx != GetX())
				{
					ctx = GetX(); new_x = fix_x;
				}
				if (cty != GetY())
				{
					cty = GetY(); new_y = fix_y;
				}
			}
			DoMotion(ctx - GetX(), cty - GetY());
			fMoved = true;
		}
		while (fixtoi(new_x) != GetX() || fixtoi(new_y) != GetY());
	}

	if(fix_x != new_x || fix_y != new_y)
	{
		fMoved = true;
		if (pSolidMaskData) pSolidMaskData->Remove(true);
		fix_x = new_x;
		fix_y = new_y;
	}
	// Rotation  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	if (OCF & OCF_Rotate && !!rdir)
	{
		C4Real target_r = fix_r + rdir * 5;
		// Rotation limit
		if (Def->Rotateable>1)
		{
			if (target_r > itofix(Def->Rotateable))
				{ target_r = itofix(Def->Rotateable); rdir=0; }
			if (target_r < itofix(-Def->Rotateable))
				{ target_r = itofix(-Def->Rotateable); rdir=0; }
		}
		int32_t ctx=GetX(); int32_t cty=GetY();
		// Move to target
		while (fixtoi(fix_r) != fixtoi(target_r))
		{
			// Save step undos
			C4Real lcobjr = fix_r; C4Shape lshape=Shape;
			// Try next step
			fix_r += Sign(target_r - fix_r);
			UpdateShape();
			// attached rotation: rotate around attachment pos
			if (Action.t_attach && !fNoAttach)
			{
				// more accurately, attachment should be evaluated by a rotation around the attachment vertex
				// however, as long as this code is only used for some surfaces adjustment for large vehicles,
				// it's enough to assume rotation around the center
				ctx=GetX(); cty=GetY();
				// evaluate attachment, but do not bother about attachment loss
				// that will then be done in next execution cycle
				Shape.Attach(ctx,cty,Action.t_attach);
			}
			// check for contact
			if ((iContact=ContactCheck(ctx,cty))) // Contact
			{
				fAnyContact=true; iContacts |= t_contact;
				// Undo step and abort movement
				Shape=lshape;
				target_r = fix_r = lcobjr;
				// last UpdateShape-call might have changed sector lists!
				UpdatePos();
				// Redirect to GetY()
				if (iContact==1) if (!fRedirectYR)
						RedirectForce(rdir,ydir,-1);
				// Stop rotation
				rdir=0;
			}
			else
			{
				fTurned=1;
				if (ctx != GetX() || cty != GetY())
				{
					fix_x = itofix(ctx); fix_y = itofix(cty);
				}
			}
		}
		// Circle bounds
		if (target_r < -FixHalfCircle) { target_r += FixFullCircle; }
		if (target_r > +FixHalfCircle) { target_r -= FixFullCircle; }
		fix_r = target_r;
	}
	// Reput solid mask if moved by motion
	if (fMoved || fTurned) UpdateSolidMask(true);
	// Misc checks ===========================================================================================
	// InLiquid check
	// this equals C4Object::UpdateLiquid, but the "fNoAttach=false;"-line
	if (IsInLiquidCheck()) // In Liquid
	{
		if (!InLiquid) // Enter liquid
		{
			if (OCF & OCF_HitSpeed2) if (Mass>3)
					Splash(GetX(),GetY()+1,std::min(Shape.Wdt*Shape.Hgt/10,20),this);
			fNoAttach=false;
			InLiquid=1;
		}
	}
	else // Out of liquid
	{
		if (InLiquid) // Leave liquid
			InLiquid=0;
	}
	// Contact Action
	if (fAnyContact)
	{
		t_contact = iContacts;
		ContactAction();
	}
	// Attachment Loss Action
	if (fNoAttach)
		NoAttachAction();
	// Movement Script Execution
	if (fAnyContact)
	{
		C4AulParSet pars(C4VInt(fixtoi(oldxdir, 100)), C4VInt(fixtoi(oldydir, 100)));
		if (old_ocf & OCF_HitSpeed1) Call(PSF_Hit, &pars);
		if (old_ocf & OCF_HitSpeed2) Call(PSF_Hit2, &pars);
		if (old_ocf & OCF_HitSpeed3) Call(PSF_Hit3, &pars);
	}
	// Rotation gfx
	if (fTurned)
		UpdateFace(true);
	else
		// pos changed?
		if (fMoved) UpdatePos();
}
Пример #30
0
bool WorkspaceBound::SetIntersection(const WorkspaceBound& a, const WorkspaceBound& b)
{
  if(a.IsEmpty() || b.IsEmpty()) { SetEmpty(); return false; }
  Sphere3D sa,sb;
  Circle3D c;
  sa.center = a.center; sa.radius = a.outerRadius;
  sb.center = b.center; sb.radius = b.outerRadius;
  int res = BallBallIntersection(sa,sb,c);
  Real solidAngle = Min(a.maxAngle*a.outerRadius,b.maxAngle*b.outerRadius);
  if(res==2) {  //it's a circle
    Assert(c.radius <= a.outerRadius+Epsilon && c.radius <= b.outerRadius+Epsilon);
    if(!sa.contains(c.center) || !sb.contains(c.center)) {
      cout<<"Uh... circle intersection of balls isn't contained in them"<<endl;
      cout<<sa.center<<" r "<<sa.radius<<endl;
      cout<<sb.center<<" r "<<sb.radius<<endl;
      cout<<"Center "<<c.center<<" radius "<<c.radius<<endl;
      getchar();
    }
    Assert(sa.contains(c.center));
    Assert(sb.contains(c.center));

    //If a and b lie on opposite sides of c's plane,
    //use the sphere that contains c.
    //Otherwise, the smallest circle that contains the intersection
    //is the smaller of a and b
    Real offset=c.axis.dot(c.center);
    if(Sign(c.axis.dot(a.center)-offset) == Sign(c.axis.dot(b.center)-offset)) {
      //on same side of plane
      if(b.outerRadius < a.outerRadius) res=4;
      else res=3;
    }
  }
  switch(res) {
  case 0: 
    center = Half*(a.center + b.center);
    outerRadius=0;
    innerRadius=-(a.center-b.center).norm();
    maxAngle=-Inf;
    break;
  case 1:  //point
  case 2:  //circle
    center=c.center;
    outerRadius=c.radius;
    innerRadius=0;  //TODO: find this?
    //get the maxAngle that gives the right solid angle
    if(solidAngle >= outerRadius*TwoPi) maxAngle = TwoPi;
    else maxAngle = solidAngle/outerRadius;
    break;
  case 3:  //a completely contained within b
    Assert(a.outerRadius <= b.outerRadius);
    operator = (a);
    if(solidAngle < maxAngle*outerRadius) 
      maxAngle = solidAngle / outerRadius;
    break;
  case 4:
    //b contained completely in a
    Assert(a.outerRadius >= b.outerRadius);
    operator = (b);
    if(solidAngle < maxAngle*outerRadius) 
      maxAngle = solidAngle / outerRadius;
    break;
  }
  return true;
}