void USkeletalMeshComponent::PostBlendPhysics()
{
	SCOPE_CYCLE_COUNTER(STAT_UpdateLocalToWorldAndOverlaps);
	
	// Flip bone buffer and send 'post anim' notification
	FinalizeBoneTransform();

	// Update Child Transform - The above function changes bone transform, so will need to update child transform
	UpdateChildTransforms();

	// animation often change overlap. 
	UpdateOverlaps();

	// Cached local bounds are now out of date
	InvalidateCachedBounds();

	// update bounds
	UpdateBounds();

	// Need to send new bounds to 
	MarkRenderTransformDirty();

	// New bone positions need to be sent to render thread
	MarkRenderDynamicDataDirty();
}
void UPaperFlipbookComponent::FlipbookChangedPhysicsState()
{
	// If the frame has changed and we're using animated collision, we need to recreate that state as well
	RecreatePhysicsState();

	// We just totally changed the physics setup so update overlaps too
	UpdateOverlaps();
}
void UPrimitiveComponent::OnComponentCollisionSettingsChanged()
{
	if (!IsTemplate() && IsRegistered())			// not for CDOs
	{
		// changing collision settings could affect touching status, need to update
		UpdateOverlaps();

		// update navigation data if needed
		const bool bNewNavRelevant = IsNavigationRelevant();
		if (bNavigationRelevant != bNewNavRelevant)
		{
			bNavigationRelevant = bNewNavRelevant;
			UNavigationSystem::UpdateNavOctree(this);
		}
	}
}
Esempio n. 4
0
void UBoxComponent::SetBoxExtent(FVector NewBoxExtent, bool bUpdateOverlaps)
{
	BoxExtent = NewBoxExtent;
	MarkRenderStateDirty();

	// do this if already created
	// otherwise, it hasn't been really created yet
	if (bPhysicsStateCreated)
	{
		DestroyPhysicsState();
		UpdateBodySetup();
		CreatePhysicsState();

		if ( bUpdateOverlaps && IsCollisionEnabled() && GetOwner() )
		{
			UpdateOverlaps();
		}
	}
}
void UCapsuleComponent::SetCapsuleSize(float NewRadius, float NewHalfHeight, bool bUpdateOverlaps)
{
	CapsuleHalfHeight = FMath::Max(NewHalfHeight, NewRadius);
	CapsuleRadius = NewRadius;
	MarkRenderStateDirty();

	// do this if already created
	// otherwise, it hasn't been really created yet
	if (bPhysicsStateCreated)
	{
		DestroyPhysicsState();
		UpdateBodySetup();
		CreatePhysicsState();

		if ( bUpdateOverlaps && IsCollisionEnabled() && GetOwner() )
		{
			UpdateOverlaps();
		}
	}
}
Esempio n. 6
0
void USkeletalMeshComponent::CompleteParallelBlendPhysics()
{
	Exchange(AnimEvaluationContext.LocalAtoms, AnimEvaluationContext.bDoInterpolation ? CachedLocalAtoms : LocalAtoms);
		

	FlipEditableSpaceBases();

	// Update Child Transform - The above function changes bone transform, so will need to update child transform
	UpdateChildTransforms();

	// animation often change overlap. 
	UpdateOverlaps();

	// New bone positions need to be sent to render thread
	MarkRenderDynamicDataDirty();

	FinalizeBoneTransform();

	ParallelAnimationEvaluationTask.SafeRelease();
	ParallelBlendPhysicsCompletionTask.SafeRelease();
}
void USkeletalMeshComponent::RefreshBoneTransforms()
{
	SCOPE_CYCLE_COUNTER(STAT_RefreshBoneTransforms);

	// Can't do anything without a SkeletalMesh
	// Do nothing more if no bones in skeleton.
	if( !SkeletalMesh || SpaceBases.Num() == 0 )
	{
		return;
	}
	
	AActor * Owner = GetOwner();
	const FAnimUpdateRateParameters  & UpdateRateParams = Owner ? Owner->AnimUpdateRateParams : FAnimUpdateRateParameters();

	{
		FScopeLockPhysXWriter LockPhysXForWriting;

		// Recalculate the RequiredBones array, if necessary
		if( !bRequiredBonesUpToDate )
		{
			RecalcRequiredBones(PredictedLODLevel);
		}

		// Update rate turned off, evaluate every frame.
		if( !bEnableUpdateRateOptimizations || (UpdateRateParams.GetEvaluationRate() <= 1) )
		{
			// evaluate pure animations, and fill up LocalAtoms
			EvaluateAnimation();
			// We need the mesh space bone transforms now for renderer to get delta from ref pose:
			FillSpaceBases();
			// Invalidate cached bones.
			CachedLocalAtoms.Empty();
			CachedSpaceBases.Empty();
		}
		else
		{
			// figure out if our cache is invalid.
			const bool bInvalidCachedBones = (LocalAtoms.Num() != SkeletalMesh->RefSkeleton.GetNum()) 
				|| (LocalAtoms.Num() != CachedLocalAtoms.Num())
				|| (SpaceBases.Num() != CachedSpaceBases.Num());

			// If cache is invalid, we need to rebuild it. And we can't interpolate.
			// (same path if we're not interpolating and not skipping a frame).
			if( bInvalidCachedBones || (!UpdateRateParams.ShouldInterpolateSkippedFrames() && !UpdateRateParams.ShouldSkipEvaluation()) )
			{
				// evaluate pure animations, and fill up LocalAtoms
				EvaluateAnimation();
				// Fill SpaceBases from LocalAtoms
				FillSpaceBases();

				// Cache bones
				CachedLocalAtoms = LocalAtoms;
				CachedSpaceBases = SpaceBases;
			}
			else
			{
				// No interpolation, just copy
				// @todo: if we don't blend any physics, we could even skip the copy.
				if( !UpdateRateParams.ShouldInterpolateSkippedFrames() )
				{
					LocalAtoms = CachedLocalAtoms;
					SpaceBases = CachedSpaceBases;
				}
				else
				{
					// If we are not skipping evaluation this frame, refresh cache.
					if( !UpdateRateParams.ShouldSkipEvaluation() )
					{
						// Preserve LocalAtoms and SpaceBases, so we can keep interpolation.
						Exchange(LocalAtoms, CachedLocalAtoms);
						Exchange(SpaceBases, CachedSpaceBases);

						// evaluate pure animations, and fill up LocalAtoms
						EvaluateAnimation();
						// Fill SpaceBases from LocalAtoms
						FillSpaceBases();

						Exchange(LocalAtoms, CachedLocalAtoms);
						Exchange(SpaceBases, CachedSpaceBases);
					}

					// Interpolate
					{
						SCOPE_CYCLE_COUNTER(STAT_InterpolateSkippedFrames);
						const float Alpha = 0.25f + (1.f / float(FMath::Max(UpdateRateParams.GetEvaluationRate(), 2) * 2));
						FAnimationRuntime::LerpBoneTransforms(LocalAtoms, CachedLocalAtoms, Alpha, RequiredBones);
						FAnimationRuntime::LerpBoneTransforms(SpaceBases, CachedSpaceBases, Alpha, RequiredBones);
					}
				}
			}
		}

		// Transforms updated, cached local bounds are now out of date.
		InvalidateCachedBounds();

		// update physics data from animated data
		UpdateKinematicBonesToPhysics(false);
		UpdateRBJointMotors();
	}

	// @todo anim : hack TTP 224385	ANIM: Skeletalmesh double buffer
	// this is problem because intermediate buffer changes physics position as well
	// this causes issue where a half of frame, physics position is fixed with anim pose, and the other half is real simulated position
	// if you enable physics in tick, since that's before physics update, you'll get animation pose dominating physics pose, which isn't what you want. (Or what you'll see)
	// so do not update transform if physics is on. This problem will be solved by double buffer, when we keep one buffer for intermediate, and the other buffer for result query
	{
		FScopeLockPhysXReader LockPhysXForReading;

		if( !IsSimulatingPhysics() )
		{
			SCOPE_CYCLE_COUNTER(STAT_UpdateLocalToWorldAndOverlaps);
			
			// New bone positions need to be sent to render thread
			UpdateComponentToWorld();	

			// animation often change overlap. 
			UpdateOverlaps();
		}
	}

	MarkRenderDynamicDataDirty();
}