예제 #1
0
파일: CBigMap.cpp 프로젝트: svn2github/ybtx
void CBigMap::DrawBigMap()
{
	CFRect rtWnd = CFRect( 0, 0, (float)GetWndWidth(), (float)GetWndHeight() );

	CColor uColor = CColor::White;
	CVector2f vStart( (float)GetWndHandle()->m_xScreen, (float)GetWndHandle()->m_yScreen );
	CVector2f rtScreen[4] = { vStart
		, vStart + CVector2f((float)GetWndHandle()->m_Width,0.0f)
		, vStart + CVector2f(0.0f,(float)GetWndHandle()->m_Height)
		, vStart + CVector2f((float)GetWndHandle()->m_Width,(float)GetWndHandle()->m_Height)};

	float Zoom = GetRootWnd()->GetZoomSize();

	IMAGE& image = GetWndHandle()->m_Enable.GetImage(0);
	
	CFRect rtImage((float)image.posWnd.x, (float)image.posWnd.y, image.posWnd.x + abs(image.rtTexture.Width()), image.posWnd.y + abs(image.rtTexture.Height()));
	rtImage.top		*= Zoom;
	rtImage.left	*= Zoom;
	rtImage.bottom	*= Zoom;
	rtImage.right	*= Zoom;
	CFRect rtDraw = rtWnd.Intersection(rtImage).Offset(0.0f,0.0f);
	CFRect rtText(
		image.rtTexture.left,
		image.rtTexture.top,
		( rtImage.right  - rtImage.left )*image.rtTexture.Width() /rtImage.Width()  + image.rtTexture.left,
		( rtImage.bottom -  rtImage.top )*image.rtTexture.Height()/rtImage.Height() + image.rtTexture.top);

	if(m_bOpen&&!m_bClose)
		DrawRect(m_MapTextureOpen, rtDraw, uColor, &rtText,false);
	else
		DrawRect( rtScreen, uColor,m_pAlphaTexture,m_MapTextureOpen,m_MapTextureClose/*,&rtText,m_BackTexUV*/, RS_GUI_BIGMAP, GetWndHandle()->m_fZ );	
}
예제 #2
0
//-----------------------------------------------------------------------------
// Purpose: Checks a position to make sure a corner of a building can live there
//-----------------------------------------------------------------------------
bool CBaseObject::VerifyCorner( const Vector &vBottomCenter, float xOffset, float yOffset )
{
	// Start slightly above the surface
	Vector vStart( vBottomCenter.x + xOffset, vBottomCenter.y + yOffset, vBottomCenter.z + 0.1 );

	trace_t tr;
	UTIL_TraceLine( 
		vStart, 
		vStart - Vector( 0, 0, TF_OBJ_GROUND_CLEARANCE ), 
		MASK_PLAYERSOLID_BRUSHONLY, this, COLLISION_GROUP_PLAYER_MOVEMENT, &tr );

	// Cannot build on very steep slopes ( > 45 degrees )
	if ( tr.fraction < 1.0f )
	{
		Vector vecUp(0,0,1);
		tr.plane.normal.NormalizeInPlace();
		float flDot = DotProduct( tr.plane.normal, vecUp );

		if ( flDot < 0.65 )
		{
			// Too steep
			return false;
		}
	}

	return !tr.startsolid && tr.fraction < 1;
}
예제 #3
0
파일: wire.c 프로젝트: DerekAJohnson/cysat
static char cRead( char cBus, char cAddress, char *pcData, char cBytes )
{
    vStart( cBus );

    /* Check if SCL is not held down */
    if( !cGetSCL( cBus ) )
    {
        return wireSTATUS_HELD_LOW;
    }

    /* Send Address */
    cSendByte( cBus, cAddress | 0x01 );
    if( !cGetAck( cBus ) )
    {
        vStop( cBus );
        return wireSTATUS_NACK;
    }

    /* Read Data */
    while( cBytes-- )
    {
        *pcData = cGetByte( cBus );
        pcData++;

        if( cBytes > 0 )
        {
            vSendAck( cBus );
        }
    }

    vSendNack(cBus);
    vStop( cBus );
    
    return wireSTATUS_SUCCESS;
}
예제 #4
0
파일: wire.c 프로젝트: DerekAJohnson/cysat
static char cWrite( char cBus, char cAddress, char *pcData, char cBytes )
{
    vStart( cBus );

    /* Check if SCL is not held down */
    if( !cGetSCL( cBus ) )
    {
        return wireSTATUS_HELD_LOW;
    }

    /* Send Address */
    cSendByte( cBus, cAddress & 0xFE );
    if( !cGetAck( cBus ) )
    {
        vStop( cBus );
        return wireSTATUS_FAIL;
    }

    /* Send Data */
    while( cBytes-- )
    {
        cSendByte( cBus, *pcData );
        if( !cGetAck( cBus ) )
        {
            vStop( cBus );
            return wireSTATUS_NACK;
        }
        ++pcData;
    }

    vStop( cBus );
    return wireSTATUS_SUCCESS;
}
예제 #5
0
/**
 * @return The angle from between two vectors using the current vector as the center
 * return 0, if the angle is not well defined
 */
double RS_Vector::angleBetween(const RS_Vector& v1, const RS_Vector& v2) const {
    if (!valid || !v1.valid || !v2.valid) {
        return 0.0;
    }
    else {
        RS_Vector vStart(v1- (*this));
        RS_Vector vEnd(v2- (*this));
        //        if( vStart.magnitude() < RS_TOLERANCE
        //                || vEnd.magnitude() < RS_TOLERANCE) return 0.0;
        return RS_Math::correctAngle( atan2( vStart.x*vEnd.y-vStart.y*vEnd.x, vStart.x*vEnd.x+vStart.y*vEnd.y));

        //         std::cout<<"old algorithm:: "<<RS_Math::correctAngle(vEnd.angle() - vStart.angle())<<std::endl;
//        return RS_Math::correctAngle(vEnd.angle() - vStart.angle());
    }
}
예제 #6
0
파일: aicombat.cpp 프로젝트: Chiur/openmw
    bool AiCombat::execute (const MWWorld::Ptr& actor,float duration)
    {
        //General description
        if(!actor.getClass().getCreatureStats(actor).isHostile()
                || actor.getClass().getCreatureStats(actor).getHealth().getCurrent() <= 0)
            return true;

        if(mTarget.getClass().getCreatureStats(mTarget).isDead())
            return true;

        //Update every frame
        if(mCombatMove)
        {
            mTimerCombatMove -= duration;
            if( mTimerCombatMove <= 0)
            {
                mTimerCombatMove = 0;
                mMovement.mPosition[1] = mMovement.mPosition[0] = 0;
                mCombatMove = false;
            }
        }

        actor.getClass().getMovementSettings(actor) = mMovement;

        if (mRotate)
        {
            if (zTurn(actor, Ogre::Degree(mTargetAngle)))
                mRotate = false;
        }


        mTimerAttack -= duration;
        actor.getClass().getCreatureStats(actor).setAttackingOrSpell(mStrike);

        float tReaction = 0.25f;
        if(mTimerReact < tReaction)
        {
            mTimerReact += duration;
            return false;
        }

        //Update with period = tReaction

        mTimerReact = 0;

        //actual attacking logic
        //TODO: Some skills affect period of strikes.For berserk-like style period ~ 0.25f
        float attackPeriod = 1.0f;
        if(mReadyToAttack)
        {
            if(mTimerAttack <= -attackPeriod)
            {
                //TODO: should depend on time between 'start' to 'min attack'
                //for better controlling of NPCs' attack strength.
                //Also it seems that this time is different for slash/thrust/chop
                mTimerAttack = 0.35f * static_cast<float>(rand())/RAND_MAX;
                mStrike = true;

                //say a provoking combat phrase
                if (actor.getClass().isNpc())
                {
                    const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
                    int chance = store.get<ESM::GameSetting>().find("iVoiceAttackOdds")->getInt();
                    int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
                    if (roll < chance)
                    {
                        MWBase::Environment::get().getDialogueManager()->say(actor, "attack");
                    }
                }
            }
            else if (mTimerAttack <= 0)
                mStrike = false;
        }
        else
        {
            mTimerAttack = -attackPeriod;
            mStrike = false;
        }

        const MWWorld::Class &cls = actor.getClass();
        const ESM::Weapon *weapon = NULL;
        MWMechanics::WeaponType weaptype;
        float weapRange, weapSpeed = 1.0f;

        actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true);

        if (actor.getClass().hasInventoryStore(actor))
        {
            MWMechanics::DrawState_ state = actor.getClass().getCreatureStats(actor).getDrawState();
            if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing)
                actor.getClass().getCreatureStats(actor).setDrawState(MWMechanics::DrawState_Weapon);

            //Get weapon speed and range
            MWWorld::ContainerStoreIterator weaponSlot =
                MWMechanics::getActiveWeapon(cls.getCreatureStats(actor), cls.getInventoryStore(actor), &weaptype);

            if (weaptype == WeapType_HandToHand)
            {
                const MWWorld::Store<ESM::GameSetting> &gmst =
                    MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
                weapRange = gmst.find("fHandToHandReach")->getFloat();
            }
            else
            {
                weapon = weaponSlot->get<ESM::Weapon>()->mBase;
                weapRange = weapon->mData.mReach;
                weapSpeed = weapon->mData.mSpeed;
            }
            weapRange *= 100.0f;
        }
        else //is creature
        {
            weaptype = WeapType_HandToHand; //doesn't matter, should only reflect if it is melee or distant weapon
            weapRange = 150; //TODO: use true attack range (the same problem in Creature::hit)
        }

        ESM::Position pos = actor.getRefData().getPosition();

        float rangeMelee;
        float rangeCloseUp;
        bool distantCombat = false;
        if (weaptype==WeapType_BowAndArrow || weaptype==WeapType_Crossbow || weaptype==WeapType_Thrown)
        {
            rangeMelee = 1000; // TODO: should depend on archer skill
            rangeCloseUp = 0; //doesn't needed when attacking from distance
            distantCombat = true;
        }
        else
        {
            rangeMelee = weapRange;
            rangeCloseUp = 300;
        }

        Ogre::Vector3 vStart(pos.pos[0], pos.pos[1], pos.pos[2]);
        ESM::Position targetPos = mTarget.getRefData().getPosition();
        Ogre::Vector3 vDest(targetPos.pos[0], targetPos.pos[1], targetPos.pos[2]);
        Ogre::Vector3 vDir = vDest - vStart;
        float distBetween = vDir.length();

        if(distBetween < rangeMelee || (distBetween <= rangeCloseUp && mFollowTarget) )
        {
            //Melee and Close-up combat
            vDir.z = 0;
            float dirLen = vDir.length();
            mTargetAngle = Ogre::Radian( Ogre::Math::ACos(vDir.y / dirLen) * sgn(Ogre::Math::ASin(vDir.x / dirLen)) ).valueDegrees();
            mRotate = true;

            //bool LOS = MWBase::Environment::get().getWorld()->getLOS(actor, mTarget);
            if (mFollowTarget && distBetween > rangeMelee)
            {
                //Close-up combat: just run up on target
                mMovement.mPosition[1] = 1;
            }
            else
            {
                //Melee: stop running and attack
                mMovement.mPosition[1] = 0;

                // When attacking with a weapon, choose between slash, thrust or chop
                if (actor.getClass().hasInventoryStore(actor))
                    chooseBestAttack(weapon, mMovement);

                if(mMovement.mPosition[0] || mMovement.mPosition[1])
                {
                    mTimerCombatMove = 0.1f + 0.1f * static_cast<float>(rand())/RAND_MAX;
                    mCombatMove = true;
                }
                else if(actor.getClass().isNpc() && (!distantCombat || (distantCombat && rangeMelee/5)))
                {
                    //apply sideway movement (kind of dodging) with some probability
                    if(static_cast<float>(rand())/RAND_MAX < 0.25)
                    {
                        mMovement.mPosition[0] = static_cast<float>(rand())/RAND_MAX < 0.5? 1: -1;
                        mTimerCombatMove = 0.05f + 0.15f * static_cast<float>(rand())/RAND_MAX;
                        mCombatMove = true;
                    }
                }

                if(distantCombat && distBetween < rangeMelee/4)
                {
                    mMovement.mPosition[1] = -1;
                }

                mReadyToAttack = true;
                //only once got in melee combat, actor is allowed to use close-up shortcutting
                mFollowTarget = true;
            }
        }
        else
        {
            //target is at far distance: build path to target OR follow target (if previously actor had reached it once)
            mFollowTarget = false;

            buildNewPath(actor); //may fail to build a path, check before use

            //delete visited path node
            mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2]);

            //if no new path leave mTargetAngle unchanged
            if(!mPathFinder.getPath().empty())
            {
                //try shortcut
                if(vDir.length() < mPathFinder.getDistToNext(pos.pos[0],pos.pos[1],pos.pos[2]) && MWBase::Environment::get().getWorld()->getLOS(actor, mTarget))
                    mTargetAngle = Ogre::Radian( Ogre::Math::ACos(vDir.y / vDir.length()) * sgn(Ogre::Math::ASin(vDir.x / vDir.length())) ).valueDegrees();
                else
                    mTargetAngle = mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]);
                mRotate = true;
            }

            mMovement.mPosition[1] = 1;
            mReadyToAttack = false;
        }

        if(distBetween > rangeMelee)
        {
            //special run attack; it shouldn't affect melee combat tactics
            if(actor.getClass().getMovementSettings(actor).mPosition[1] == 1)
            {
                //check if actor can overcome the distance = distToTarget - attackerWeapRange
                //less than in time of playing weapon anim from 'start' to 'hit' tags (t_swing)
                //then start attacking
                float speed1 = cls.getSpeed(actor);
                float speed2 = mTarget.getClass().getSpeed(mTarget);
                if(mTarget.getClass().getMovementSettings(mTarget).mPosition[0] == 0
                        && mTarget.getClass().getMovementSettings(mTarget).mPosition[1] == 0)
                    speed2 = 0;

                float s1 = distBetween - weapRange;
                float t = s1/speed1;
                float s2 = speed2 * t;
                float t_swing = 0.17f/weapSpeed;//instead of 0.17 should be the time of playing weapon anim from 'start' to 'hit' tags
                if (t + s2/speed1 <= t_swing)
                {
                    mReadyToAttack = true;
                    if(mTimerAttack <= -attackPeriod)
                    {
                        mTimerAttack = 0.3f*static_cast<float>(rand())/RAND_MAX;
                        mStrike = true;
                    }
                }
            }
        }

        actor.getClass().getMovementSettings(actor) = mMovement;

        return false;
    }
예제 #7
0
/**
  * this should handle modifyOffset
  *@ coord, indicate direction of offset
  *@ distance of offset
  *
  *@Author, Dongxu Li
  */
bool RS_Polyline::offset(const RS_Vector& coord, const double& distance){
    double dist;
    //find the nearest one
    int length=count();
		std::vector<RS_Vector> intersections(length);
    if(length>1){//sort the polyline entity start/end point order
        int i(0);
        double d0,d1;
        RS_Entity* en0(entityAt(0));
        RS_Entity* en1(entityAt(1));

        RS_Vector vStart(en0->getStartpoint());
        RS_Vector vEnd(en0->getEndpoint());
        en1->getNearestEndpoint(vStart,&d0);
        en1->getNearestEndpoint(vEnd,&d1);
        if(d0<d1) en0->revertDirection();
        for(i=1;i<length;en0=en1){
                //linked to head-tail chain
            en1=entityAt(i);
            vStart=en1->getStartpoint();
            vEnd=en1->getEndpoint();
            en0->getNearestEndpoint(vStart,&d0);
            en0->getNearestEndpoint(vEnd,&d1);
            if(d0>d1) en1->revertDirection();
            intersections[i-1]=(en0->getEndpoint()+en1->getStartpoint())*0.5;
            i++;
        }

    }
    RS_Entity* en(getNearestEntity(coord, &dist, RS2::ResolveNone));
    if(en==NULL) return false;
    int indexNearest=findEntity(en);
    //        RS_Vector vp(en->getNearestPointOnEntity(coord,false));
    //        RS_Vector direction(en->getTangentDirection(vp));
    //        RS_Vector vp1(-direction.y,direction.x);//normal direction
    //        double a2(vp1.squared());
    //        if(a2<RS_TOLERANCE2) return false;
    //        vp1 *= distance/sqrt(a2);
    //        move(vp1);
    //        return true;

    RS_Polyline* pnew= static_cast<RS_Polyline*>(clone());
    int i;
    i=indexNearest;
    int previousIndex(i);
    pnew->entityAt(i)->offset(coord,distance);
    RS_Vector vp;
    //offset all
    //fixme, this is too ugly
    for(i=indexNearest-1;i>=0;i--){
        RS_VectorSolutions sol0=RS_Information::getIntersection(pnew->entityAt(previousIndex),entityAt(i),true);
//        RS_VectorSolutions sol1;
        double dmax(RS_TOLERANCE15);
        RS_Vector trimP(false);
		for(const RS_Vector& vp: sol0){

			double d0( (vp - pnew->entityAt(previousIndex)->getStartpoint()).squared());//potential bug, need to trim better
            if(d0>dmax) {
                dmax=d0;
				trimP=vp;
            }
        }
        if(trimP.valid){
            static_cast<RS_AtomicEntity*>(pnew->entityAt(previousIndex))->trimStartpoint(trimP);
            static_cast<RS_AtomicEntity*>(pnew->entityAt(i))->trimEndpoint(trimP);
            vp=pnew->entityAt(previousIndex)->getMiddlePoint();
        }else{
            vp=pnew->entityAt(previousIndex)->getStartpoint();
            vp.rotate(entityAt(previousIndex)->getStartpoint(),entityAt(i)->getDirection2()-entityAt(previousIndex)->getDirection1()+M_PI);
        }
        pnew->entityAt(i)->offset(vp,distance);
        previousIndex=i;
    }

    previousIndex=indexNearest;
    for(i=indexNearest+1;i<length;i++){
        RS_VectorSolutions sol0=RS_Information::getIntersection(pnew->entityAt(previousIndex),entityAt(i),true);
//        RS_VectorSolutions sol1;
        double dmax(RS_TOLERANCE15);
        RS_Vector trimP(false);
		for(const RS_Vector& vp: sol0){
			double d0( (vp - pnew->entityAt(previousIndex)->getEndpoint()).squared());//potential bug, need to trim better
            if(d0>dmax) {
                dmax=d0;
				trimP=vp;
            }
        }
        if(trimP.valid){
            static_cast<RS_AtomicEntity*>(pnew->entityAt(previousIndex))->trimEndpoint(trimP);
            static_cast<RS_AtomicEntity*>(pnew->entityAt(i))->trimStartpoint(trimP);
            vp=pnew->entityAt(previousIndex)->getMiddlePoint();
        }else{
            vp=pnew->entityAt(previousIndex)->getEndpoint();
            vp.rotate(entityAt(previousIndex)->getEndpoint(),entityAt(i)->getDirection1()-entityAt(previousIndex)->getDirection2()+M_PI);
        }
        pnew->entityAt(i)->offset(vp,distance);
        previousIndex=i;
    }
    //trim
    //connect and trim        RS_Modification m(*container, graphicView);
    for(i=0;i<length-1;i++){
        RS_VectorSolutions sol0=RS_Information::getIntersection(pnew->entityAt(i),pnew->entityAt(i+1),true);
        if(sol0.getNumber()==0) {
            sol0=RS_Information::getIntersection(pnew->entityAt(i),pnew->entityAt(i+1));
//            RS_Vector vp0(pnew->entityAt(i)->getEndpoint());
//            RS_Vector vp1(pnew->entityAt(i+1)->getStartpoint());
//            double a0(intersections.at(i).angleTo(vp0));
//            double a1(intersections.at(i).angleTo(vp1));
            RS_VectorSolutions sol1;
			for(const RS_Vector& vp: sol0){
				if(RS_Math::isAngleBetween(intersections.at(i).angleTo(vp),
                                           pnew->entityAt(i)->getDirection2(),
                                           pnew->entityAt(i+1)->getDirection1(),
                                           false)==false){
					sol1.push_back(vp);
                }
            }
            if(sol1.getNumber()==0) continue;
            RS_Vector trimP(sol1.getClosest(intersections.at(i)));
            static_cast<RS_AtomicEntity*>(pnew->entityAt(i))->trimEndpoint(trimP);
            static_cast<RS_AtomicEntity*>(pnew->entityAt(i+1))->trimStartpoint(trimP);
        }else{
            RS_Vector trimP(sol0.getClosest(pnew->entityAt(i)->getStartpoint()));
            static_cast<RS_AtomicEntity*>(pnew->entityAt(i))->trimEndpoint(trimP);
            static_cast<RS_AtomicEntity*>(pnew->entityAt(i+1))->trimStartpoint(trimP);
        }

    }

    *this = *pnew;
    return true;


}
예제 #8
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : time - 
//			type - 
// Output : float
//-----------------------------------------------------------------------------
float CSentence::GetIntensity( float time, float endtime )
{
	float zeroValue = 0.5f;
	
	int c = GetNumSamples();
	
	if ( c <= 0 )
	{
		return zeroValue;
	}
	
	int i;
	for ( i = -1 ; i < c; i++ )
	{
		CEmphasisSample *s = GetBoundedSample( i, endtime );
		CEmphasisSample *n = GetBoundedSample( i + 1, endtime );
		if ( !s || !n )
			continue;

		if ( time >= s->time && time <= n->time )
		{
			break;
		}
	}

	int prev = i - 1;
	int start = i;
	int end = i + 1;
	int next = i + 2;

	prev = max( -1, prev );
	start = max( -1, start );
	end = min( end, GetNumSamples() );
	next = min( next, GetNumSamples() );

	CEmphasisSample *esPre = GetBoundedSample( prev, endtime );
	CEmphasisSample *esStart = GetBoundedSample( start, endtime );
	CEmphasisSample *esEnd = GetBoundedSample( end, endtime );
	CEmphasisSample *esNext = GetBoundedSample( next, endtime );

	float dt = esEnd->time - esStart->time;
	dt = clamp( dt, 0.01f, 1.0f );

	Vector vPre( esPre->time, esPre->value, 0 );
	Vector vStart( esStart->time, esStart->value, 0 );
	Vector vEnd( esEnd->time, esEnd->value, 0 );
	Vector vNext( esNext->time, esNext->value, 0 );

	float f2 = ( time - esStart->time ) / ( dt );
	f2 = clamp( f2, 0.0f, 1.0f );

	Vector vOut;
	Catmull_Rom_Spline( 
		vPre,
		vStart,
		vEnd,
		vNext,
		f2, 
		vOut );

	float retval = clamp( vOut.y, 0.0f, 1.0f );
	return retval;
}
예제 #9
0
//determines if the specified segment intersects a polygon. It fills out
//passed in datastructure appropriately.
bool CLightingBSP::IntersectSegment(const PVector& vSegStart, const PVector& vSegEnd, 
									CLightBSPStack* pStack, CIntersectInfo* pInfo) const
{
	ASSERT(pStack);

	uint32 nStackOff = 0;

	//the working endpoints
	PVector vStart(vSegStart);
	PVector vEnd(vSegEnd);

	//the polygon hit
	CLightBSPPoly* pHitPoly;

	//the working node
	CLightBSPNode* pNode = m_pHead;

	while(1)
	{
		//classify the points
		PReal fStartDot = vStart.Dot(pNode->m_vPlaneNorm) - pNode->m_fPlaneDist;
		PReal fEndDot	= vEnd.Dot(pNode->m_vPlaneNorm) - pNode->m_fPlaneDist;

		//check for the same side
		if((fStartDot >= 0) && (fEndDot >= 0))
		{
			//we are in the front
			pNode = pNode->m_pFront;
		}
		else if((fStartDot < 0) && (fEndDot < 0))
		{
			//we are in the back
			pNode = pNode->m_pBack;
		}
		else
		{
			//save the node that we want to test first
			pStack[nStackOff].m_pTest	= pNode;
			pStack[nStackOff].m_vEnd	= vEnd;

			//we have intersected
			if(fStartDot < 0)
			{
				//setup our stack information
				pStack[nStackOff].m_pNode	= pNode->m_pFront;

				//we do the back first
				pNode = pNode->m_pBack;
			}
			else
			{
				//setup our stack information
				pStack[nStackOff].m_pNode	= pNode->m_pBack;

				//we do the front first
				pNode = pNode->m_pFront;
			}

			//calculate the new working endpoint
			vEnd = vStart + (vEnd - vStart) * -fStartDot / (fEndDot - fStartDot);

			//next stack item
			nStackOff++;
		}

		//if we hit a null node, we need to bubble out of the stack, or bail
		while(pNode == NULL)
		{
			//if the stack is empty, no intersection occurred
			if(nStackOff == 0)
				return false;

			//pop the stack
			nStackOff--;

			//the stack is not empty, we need to test against the specified node,
			//and then check behind it if no hit occurred
			if(pHitPoly = CheckHitNode(pStack[nStackOff].m_pTest, vEnd))
			{
				if(pInfo)
				{
					pInfo->m_vNormal		= pStack[nStackOff].m_pTest->m_vPlaneNorm;
					pInfo->m_vIntersectPt	= vEnd;
					pInfo->m_nFlags			= pHitPoly->m_nFlags;
				}
				return true;
			}

			//no intersection, so we now need to process the back half
			vStart = vEnd;
			vEnd = pStack[nStackOff].m_vEnd;
			pNode = pStack[nStackOff].m_pNode;
		}

	} //infinite loop. Exits when stack is popped off completely, or when poly is hit
}
예제 #10
0
bool ExportMediaDialog::MessageReceived(EMListenerRepository* p_opSender, uint32 p_vMessage)
{
	switch(p_vMessage)
	{
/*	case EM_DRAW:
		if(p_opSender == m_opMainView)
		{
			eo << "EM_DRAW: m_oBackgroundView" << ef;
			m_opMainView -> SetHighColor(EMColor(0, 255, 0, 255));
			m_opMainView -> FillRect(m_opMainView -> Bounds());
		}
		else
			eo << "EM_DRAW (unknown)" << ef;
		return true;
*/	case EM_BUTTON_SETTINGS:
		EMCommandRepository::Instance() -> ExecuteCommand(COMMAND_DISPLAY_EXPORT_MEDIA_SETTINGS_DIALOG, m_opDialogWindow, reinterpret_cast<void*>(m_opExportTypeComboBox -> GetSelectionIndex()), this);
		m_opExportTypeComboBox -> Notify(EXPORT_TYPE_COMBO_BOX_CHANGED);
		return true;
	case EM_BUTTON_BROWSE:
		eo << "Browse button pressed" << ef;
		if(m_opBrowseWindow == NULL)
			m_opBrowseWindow = EMFactory::Instance() -> CreateBrowseWindow(m_opMainView -> GetNativeView(), "Browse");
		if(m_opBrowseWindow -> DisplayDialog())
			m_opExportToTextControl -> SetText(m_opBrowseWindow -> GetPath() -> c_str());

		return true;
/*	case EM_BUTTON_SAVE_TEMPLATE:
		eo << "Save Template button pressed" << ef;
		return true;
	case EM_BUTTON_DELETE_TEMPLATE:
		eo << "Delete Template button pressed" << ef;
		return true;
*/	case EM_RENDERING_COULD_NOT_START:
		if(m_vExporting)
			StopExporting(false);
		return true;
	case EM_RENDERING_HAS_FINNISHED:
		if(m_vExporting == false)
			return true;
	case EM_GUI_COMPONENT_ENTER_PRESSED:
	case EM_BUTTON_EXPORT:
		{
		eo << "Export button pressed" << ef;
			if(m_vExporting == false)
			{
				if(InvalidCharExist(m_opExportToTextControl -> Text(), m_opFilenameTextControl -> Text()))
				{
					eo << "Invalid Character found!!" << ef;
					return true;
				}

				string oDirectoryTemp = m_opExportToTextControl -> Text();
				if(oDirectoryTemp.length() != oDirectoryTemp.find_last_of("\\") + 1)
				{
					oDirectoryTemp.append("\\");
					m_opExportToTextControl -> SetText(oDirectoryTemp.c_str());
				}


				int vResult = CreateDir(const_cast<char*>(m_opExportToTextControl -> Text()), const_cast<char*>(m_opFilenameTextControl -> Text()));
				switch(vResult)
				{
				case RESULT_OK:
					m_vExporting = true;
					m_vExportTypeOld = m_opExportTypeComboBox -> GetSelectionIndex();
					m_oExportToOld = m_opExportToTextControl -> Text();
				//	m_oFilenameOld = m_
					Export();
					return true;
				case RESULT_NOT_OK:
				case RESULT_NO_BUTTON:
					eo << "Go back to dialog" << ef;
					return true;
				case RESULT_CANCEL_BUTTON:
					eo << "Close dialog and do nothing" << ef;
					break;
				}
			}
			else
			{
				StopExporting();
				return true;
			}
			HideDialog();
			return true;
		}
	case EM_GUI_COMPONENT_ESC_PRESSED:
	case EM_BUTTON_CANCEL:
		eo << "Cancel button pressed" << ef;
		if(m_vExporting)
			StopExporting();
		HideDialog();
		return true;
	case EM_TEXT_CONTROL_CHANGE:
		eo << "EM_TEXT_CONTROL_FILENAME_CHANGE" << ef;
		if(strlen(m_opFilenameTextControl -> Text()) == 0 || strlen(m_opExportToTextControl -> Text()) == 0)
			m_opExportButton -> Enable(false);
		else
			m_opExportButton -> Enable(true);
		if(p_opSender == m_opExportToTextControl)
		{
			if(m_vFilenameChanged)
			{
				m_vExportToChanged = false;
				m_vFilenameChanged = false;
			}
			else
				m_vExportToChanged = true;
		}
		if(p_opSender == m_opFilenameTextControl)
		{
			m_vFilenameChanged = true;
			AddToExportToTextControl();
		}
		return true;
	case EM_GUI_COMPONENT_GOT_FOCUS:
		eo << "EM_TEXT_CONTROL_GOT_FOCUS" << ef;
		if(p_opSender == m_opFilenameTextControl)
		{
			eo << "Filename got Focus" << ef;
			string oFilename(m_opFilenameTextControl -> Text());
			m_opFilenameTextControl -> SetSelection(0, oFilename.find_last_of('.'));
		}
		if(p_opSender == m_opDialogWindow)
			m_opExportButton -> SetFocus();
		m_opDialogWindow -> SetCurrentFocus();
		return true;
	case EM_GUI_COMPONENT_TAB_PRESSED:
		eo << "EM_GUI_COMPONENT_TAB_PRESSED" << ef;
		m_opDialogWindow -> NextTab();
		return true;
	case EM_GUI_COMPONENT_SHIFT_TAB_PRESSED:
		m_opDialogWindow -> PreviousTab();
		return true;
	case EM_TEXT_CONTROL_END_PRESSED:
		if(p_opSender == m_opFilenameTextControl)
		{
			eo << "EM_TEXT_CONTROL_END_ARROW_PRESSED" << ef;
			uint32 vModifiers = EMKeyboard::Instance() -> GetModifiers();
			if((vModifiers & EM_SHIFT_KEY) == EM_SHIFT_KEY)
			{
				int32 vStart(0);
				int32 vEnd(0);
				m_opFilenameTextControl -> GetSelection(vStart, vEnd);
				m_opFilenameTextControl -> SetSelection(vStart, strlen(m_opFilenameTextControl -> Text()) - m_oFileExtension.length());
			}
			else
				m_opFilenameTextControl -> SetSelection(strlen(m_opFilenameTextControl -> Text()) - m_oFileExtension.length(), strlen(m_opFilenameTextControl -> Text()) - m_oFileExtension.length());
			return true;
		}
		return false;
	case EM_TEXT_CONTROL_DELETE_PRESSED:
		if(p_opSender == m_opFilenameTextControl)
		{
			eo << "EM_TEXT_CONTROL_DELETE_PRESSED" << ef;
			int32 vStart(0);
			int32 vEnd(0);
			m_opFilenameTextControl -> GetSelection(vStart, vEnd);
			if(vStart == vEnd && vEnd >= strlen(m_opFilenameTextControl -> Text()) - m_oFileExtension.length())
				return true;
		}
		return false;
	case EM_TEXT_CONTROL_DOWN_ARROW_PRESSED:
	case EM_TEXT_CONTROL_RIGHT_ARROW_PRESSED:
		if(p_opSender == m_opFilenameTextControl)
		{
			eo << "EM_TEXT_CONTROL_DOWN/RIGHT_ARROW_PRESSED" << ef;
			int32 vStart(0);
			int32 vEnd(0);
			m_opFilenameTextControl -> GetSelection(vStart, vEnd);
			if(vEnd >= strlen(m_opFilenameTextControl -> Text()) - m_oFileExtension.length())
				return true;
		}
		return false;
	case EM_TEXT_CONTROL_LEFT_MOUSE_BUTTON_DOWN:
		if(p_opSender == m_opFilenameTextControl)
		{
			int32 vStart(0);
			int32 vEnd(0);
			m_opFilenameTextControl -> GetSelection(vStart, vEnd);
			if(vEnd >= strlen(m_opFilenameTextControl -> Text()) - m_oFileExtension.length() && vStart >= strlen(m_opFilenameTextControl -> Text()) - m_oFileExtension.length())
			{
				m_opFilenameTextControl -> SetSelection(strlen(m_opFilenameTextControl -> Text()) - m_oFileExtension.length(), strlen(m_opFilenameTextControl -> Text()) - m_oFileExtension.length());
				//return true;
			}
			else if(vEnd >= strlen(m_opFilenameTextControl -> Text()) - m_oFileExtension.length() && vStart < strlen(m_opFilenameTextControl -> Text()) - m_oFileExtension.length())
			{
				m_opFilenameTextControl -> SetSelection(vStart, strlen(m_opFilenameTextControl -> Text()) - m_oFileExtension.length());
				//return true;
			}

		}
		return false;
	case EM_TEXT_CONTROL_MENU_SELECTED:
		eo << "EM_TEXT_CONTROL_MENU_SELECTED" << ef;
		if(p_opSender == m_opFilenameTextControl)
		{
			m_vSelectedFromMenu = true;
			return true;
		}
		return false;
	case EM_TEXT_CONTROL_SET_SELECTION:
		eo << "EM_TEXT_CONTROL_SET_SELECTION" << ef;
		if(p_opSender == m_opFilenameTextControl)
		{
			if(m_vSelectedFromMenu)
			{
				m_vSelectedFromMenu = false;
				m_opFilenameTextControl -> SetSelection(0, strlen(m_opFilenameTextControl -> Text()) - m_oFileExtension.length());
				return true;
			}
		}
		return false;
	case EXPORT_TYPE_COMBO_BOX_CHANGED:
		{
			eo << "EXPORT_TYPE_COMBO_BOX_CHANGED" << ef;
			switch(m_opExportTypeComboBox -> GetSelectionIndex())
			{
			case 0:
				m_vRenderAudio = true;
				m_vRenderVideo = false;
				m_oFileExtension = ".wav";
				break;
			case 1:
				m_vRenderAudio = true;
				m_vRenderVideo = true;
				//m_oFileExtension = ".avi";
				m_oFileExtension = ExportMediaSettingsDialog::m_vFileExtension;
				break;
			case 2:
				m_vRenderAudio = false;
				m_vRenderVideo = true;
				//m_oFileExtension = ".avi";
				m_oFileExtension = ExportMediaSettingsDialog::m_vFileExtension;
				break;
			}
			string oFilename;
			oFilename.append(m_oDefaultFilename);
			oFilename.append(m_oFileExtension);
			m_opFilenameTextControl -> SetText(oFilename.c_str());
			return true;
		}
	case EM_CLOSE_WINDOW:
		eo << "EM_CLOSE_WINDOW" << ef;
		if(m_vExporting)
		{
			StopExporting();
			return true;
		}
		HideDialog();
		return true;
	}
	return false;
}