示例#1
0
void Controller::move(SweptVolume& volume, const NxVec3& disp, NxU32 activeGroups, NxF32 minDist, NxU32& collisionFlags, NxF32 sharpness, const NxGroupsMask* groupsMask, bool constrainedClimbingMode)
	{
	// Dynamic-load the utility library
	if(!gUtilLib)
		gUtilLib = NxGetUtilLib();
	assert(gUtilLib);
	if(!gUtilLib)	return;

	SweepTest* ST = &cctModule;

	// Init CCT with per-controller settings
	ST->debugData		= manager->debugData;
	ST->mSkinWidth		= skinWidth;
	ST->mStepOffset		= stepOffset;
	ST->mUpDirection	= upDirection;
	ST->mHandleSlope	= handleSlope;
	ST->mSlopeLimit		= slopeLimit;
	ST->mFirstUpdate	= true;

	///////////

	Controller** boxUserData = NULL;
	NxExtendedBounds3* boxes = NULL;
	NxU32 nbBoxes = 0;

	Controller** capsuleUserData = NULL;
	NxExtendedCapsule* capsules = NULL;
	NxU32 nbCapsules = 0;

	if(1)
		{
		// Experiment - to do better
		NxU32 nbControllers = manager->getNbControllers();
		Controller** controllers = manager->getControllers();

		boxes = (NxExtendedBounds3*)NxAlloca(nbControllers*sizeof(NxExtendedBounds3));
		capsules = (NxExtendedCapsule*)NxAlloca(nbControllers*sizeof(NxExtendedCapsule));	// It's evil to waste that ram
		boxUserData = (Controller**)NxAlloca(nbControllers*sizeof(Controller*));
		capsuleUserData = (Controller**)NxAlloca(nbControllers*sizeof(Controller*));

		while(nbControllers--)
			{
			Controller* currentController = *controllers++;
			if(currentController==this)	continue;

			NxActor* pActor = currentController->getActor();
			int nbShapes = pActor->getNbShapes();
			NX_ASSERT( nbShapes == 1 );
			NxShape* pCurrentShape= pActor->getShapes()[0];

			// Depending on user settings the current controller can be:
			// - discarded
			// - always kept
			// - or tested against filtering flags
			NxCCTInteractionFlag interactionFlag = currentController->getInteraction();
			bool keepController = true;
			if(interactionFlag==NXIF_INTERACTION_EXCLUDE)			keepController = false;
			else if(interactionFlag==NXIF_INTERACTION_USE_FILTER)	keepController = (activeGroups & ( 1 << pCurrentShape->getGroup()))!=0;

			if(keepController)
				{
				if(currentController->type==NX_CONTROLLER_BOX)
					{
					currentController->getWorldBox(boxes[nbBoxes]);
					boxUserData[nbBoxes++] = currentController;
					}
				else if(currentController->type==NX_CONTROLLER_CAPSULE)
					{
					CapsuleController* CC = static_cast<CapsuleController*>(currentController);
					NxExtendedVec3 p0 = CC->position;
					NxExtendedVec3 p1 = CC->position;
					p0[ST->mUpDirection] -= CC->height*0.5f;
					p1[ST->mUpDirection] += CC->height*0.5f;
					capsules[nbCapsules].p0 = p0;
					capsules[nbCapsules].p1 = p1;
					capsules[nbCapsules].radius = CC->radius;
					capsuleUserData[nbCapsules++] = currentController;
					}
				else ASSERT(0);
				}
			}
		}

	///////////

	ST->mWalkExperiment = false;

	NxExtendedVec3 Backup = volume.mCenter;
	ST->MoveCharacter(scene,
		(Controller*)this,
		volume, disp,
		nbBoxes, nbBoxes ? boxes : NULL, nbBoxes ? (const void**)boxUserData : NULL,
		nbCapsules, nbCapsules ? capsules : NULL, nbCapsules ? (const void**)capsuleUserData : NULL,
		activeGroups, minDist, collisionFlags, groupsMask, constrainedClimbingMode);

	if(ST->mHitNonWalkable)
		{
		// A bit slow, but everything else I tried was less convincing...
		ST->mWalkExperiment = true;
		volume.mCenter = Backup;
		ST->MoveCharacter(scene,
			(Controller*)this,
			volume, disp,
			nbBoxes, nbBoxes ? boxes : NULL, nbBoxes ? (const void**)boxUserData : NULL,
			nbCapsules, nbCapsules ? capsules : NULL, nbCapsules ? (const void**)capsuleUserData : NULL,
			activeGroups, minDist, collisionFlags, groupsMask, constrainedClimbingMode);
		ST->mWalkExperiment = false;
		}

if(sharpness<0.0f)
volume.mCenter = Backup;

	// Copy results back
	position = volume.mCenter;

	NxVec3 Delta = Backup - volume.mCenter;
	NxF32 deltaM2 = Delta.magnitudeSquared();
	if(deltaM2!=0.0f)
		{
		// Update kinematic actor
		if(kineActor)
			kineActor->moveGlobalPosition(NxVec3((float)position.x, (float)position.y, (float)position.z));
		}

	filteredPosition = position;

sharpness = fabsf(sharpness);

	// Apply feedback filter if needed
	if(sharpness<1.0f)
		filteredPosition[upDirection] = feedbackFilter(position[upDirection], memory, sharpness);

//	if(manager->debugData)
//		manager->debugData->addAABB(cctModule.mCachedTBV, NX_ARGB_YELLOW);
	}
示例#2
0
//----------------------------------------------------------------------------
bool Input::update( void)
{
//    XTRACE();
    bool isDown;
    Trigger trigger;

    static float nextTime = Timer::getTime()+0.5f;
    float thisTime = Timer::getTime();
    if( thisTime > nextTime)
    {
        updateMouseSettings();
        nextTime = thisTime+0.5f;
    }

    _valDX = 0.0f;
    _valDY = 0.0f;

    while( tryGetTrigger( trigger, isDown))
    {
        if( trigger.type == eUnknownTrigger)
        {
            //for unkown trigger we don't need to do a lookup
            continue;
        }

        if( _interceptor)
        {
            //feed trigger to interceptor instead of normal callback mechanism
            _interceptor->input( trigger, isDown);
            continue;
        }

        if( !_bindMode)
        {
            //find callback for this trigger
            //i.e. the action bound to this key
            Callback * cb = findHash( trigger, _callbackMap);
            if( cb)
            {
//                LOG_INFO << "Callback for [" << cb->getActionName() << "]" << endl;
                cb->performAction( trigger, isDown);
            }
        }
        else if( _callback && (trigger.type!=eMotionTrigger))
        {
            //Note: motion triggers can't be bound

            //we are in bind-mode, so bind this trigger to callback
            bind( trigger, _callback);
            //go back to normal mode
            _bindMode = false;
        }
        else if( !_callback)
        {
            LOG_ERROR << "Input is in bind mode, but callback is 0" << endl;
            _bindMode = false;
        }
    }
    _valDX = feedbackFilter( _valDX, _dampVal, _memoryDX);
    _valDY = feedbackFilter( _valDY, _dampVal, _memoryDY);

    if( (fabs(_valDX)>1.0e-10) || (fabs(_valDY)>1.0e-10))
    {
        trigger.type = eMotionTrigger;
        trigger.fData1 = _valDX;
        trigger.fData2 = _valDY;

        if( _interceptor)
        {
            //feed trigger to interceptor instead of normal callback mechanism
            _interceptor->input( trigger, true);
        }
        else
        {
            Callback * cb = findHash( trigger, _callbackMap);
            if( cb)
            {
//                LOG_INFO << "Callback for [" << cb->getActionName() << "]" << endl;
                cb->performAction( trigger, isDown);
            }
        }
    }

    return true;
}