void ControlledActor::tryStandup()
{
	// overlap with upper part
	if(mType==PxControllerShapeType::eBOX)
	{
	}
	else if(mType==PxControllerShapeType::eCAPSULE)
	{
		PxScene* scene = mController->getScene();
		PxSceneReadLock scopedLock(*scene);
		
		PxCapsuleController* capsuleCtrl = static_cast<PxCapsuleController*>(mController);

		PxReal r = capsuleCtrl->getRadius();
		PxReal dh = mStandingSize - mCrouchingSize-2*r;
		PxCapsuleGeometry geom(r, dh*.5f);

		PxExtendedVec3 position = mController->getPosition();
		PxVec3 pos((float)position.x,(float)position.y+mStandingSize*.5f+r,(float)position.z);
		PxQuat orientation(PxHalfPi, PxVec3(0.0f, 0.0f, 1.0f));

		PxOverlapBuffer hit;
		if(scene->overlap(geom, PxTransform(pos,orientation), hit, PxQueryFilterData(PxQueryFlag::eANY_HIT|PxQueryFlag::eSTATIC|PxQueryFlag::eDYNAMIC)))
			return;
	}

	// if no hit, we can stand up
	resizeStanding();

	mDoStandup = false;
	mIsCrouching = false;
}
void Cct::findTouchedGeometry(
	const InternalCBData_FindTouchedGeom* userData,
	const PxExtendedBounds3& worldBounds,		// ### we should also accept other volumes

	TriArray& worldTriangles,
	IntArray& triIndicesArray,
	IntArray& geomStream,

	const CCTFilter& filter,
	const CCTParams& params,
	PxU16& nbTessellation)
{
	PX_ASSERT(userData);
	
	const PxInternalCBData_FindTouchedGeom* internalData = static_cast<const PxInternalCBData_FindTouchedGeom*>(userData);
	PxScene* scene = internalData->scene;
	Cm::RenderBuffer* renderBuffer = internalData->renderBuffer;

	PxExtendedVec3 Origin;	// Will be TouchedGeom::mOffset
	getCenter(worldBounds, Origin);

	// Find touched *boxes* i.e. touched objects' AABBs in the world
	// We collide against dynamic shapes too, to get back dynamic boxes/etc
	// TODO: add active groups in interface!
	PxQueryFlags sqFilterFlags;
	if(filter.mStaticShapes)	sqFilterFlags |= PxQueryFlag::eSTATIC;
	if(filter.mDynamicShapes)	sqFilterFlags |= PxQueryFlag::eDYNAMIC;
	if(filter.mFilterCallback)
	{
		if(filter.mPreFilter)
			sqFilterFlags |= PxQueryFlag::ePREFILTER;
		if(filter.mPostFilter)
			sqFilterFlags |= PxQueryFlag::ePOSTFILTER;
	}

	// ### this one is dangerous
	const PxBounds3 tmpBounds(toVec3(worldBounds.minimum), toVec3(worldBounds.maximum));	// LOSS OF ACCURACY

	// PT: unfortunate conversion forced by the PxGeometry API
	PxVec3 center = tmpBounds.getCenter(), extents = tmpBounds.getExtents();

	const PxU32 size = 100;
	PxOverlapHit hits[size];

	PxQueryFilterData sceneQueryFilterData = filter.mFilterData ? PxQueryFilterData(*filter.mFilterData, sqFilterFlags) : PxQueryFilterData(sqFilterFlags);

	PxOverlapBuffer hitBuffer(hits, size);
	sceneQueryFilterData.flags |= PxQueryFlag::eNO_BLOCK; // fix for DE8255
	scene->overlap(PxBoxGeometry(extents), PxTransform(center), hitBuffer, sceneQueryFilterData, filter.mFilterCallback);
	PxU32 numberHits = hitBuffer.getNbAnyHits();
	for(PxU32 i = 0; i < numberHits; i++)
	{
		const PxOverlapHit& hit = hitBuffer.getAnyHit(i);
		PxShape* shape = hit.shape;
		PxRigidActor* actor = hit.actor;
		if(!shape || !actor)
			continue;

		// Filtering

		// Discard all CCT shapes, i.e. kinematic actors we created ourselves. We don't need to collide with them since they're surrounded
		// by the real CCT volume - and collisions with those are handled elsewhere.
		if(internalData->cctShapeHashSet->contains(shape))
			continue;

		// Ubi (EA) : Discarding Triggers :
		if(shape->getFlags() & PxShapeFlag::eTRIGGER_SHAPE)
			continue;

		// PT: here you might want to disable kinematic objects.

		// Output shape to stream
		const PxTransform globalPose = getShapeGlobalPose(*shape, *actor);

		const PxGeometryType::Enum type = shape->getGeometryType();	// ### VIRTUAL!
		if(type==PxGeometryType::eSPHERE)				outputSphereToStream		(shape, actor, globalPose, geomStream, Origin);
		else	if(type==PxGeometryType::eCAPSULE)		outputCapsuleToStream		(shape, actor, globalPose, geomStream, Origin);
		else	if(type==PxGeometryType::eBOX)			outputBoxToStream			(shape, actor, globalPose, geomStream, worldTriangles, triIndicesArray, Origin, tmpBounds, params, nbTessellation);
		else	if(type==PxGeometryType::eTRIANGLEMESH)	outputMeshToStream			(shape, actor, globalPose, geomStream, worldTriangles, triIndicesArray, Origin, tmpBounds, params, renderBuffer, nbTessellation);
		else	if(type==PxGeometryType::eHEIGHTFIELD)	outputHeightFieldToStream	(shape, actor, globalPose, geomStream, worldTriangles, triIndicesArray, Origin, tmpBounds, params, renderBuffer, nbTessellation);
		else	if(type==PxGeometryType::eCONVEXMESH)	outputConvexToStream		(shape, actor, globalPose, geomStream, worldTriangles, triIndicesArray, Origin, tmpBounds, params, renderBuffer, nbTessellation);
		else	if(type==PxGeometryType::ePLANE)		outputPlaneToStream			(shape, actor, globalPose, geomStream, worldTriangles, triIndicesArray, Origin, tmpBounds, params, renderBuffer);
	}
}