FTransform UAbilitySystemBlueprintLibrary::GetTargetDataOrigin(FGameplayAbilityTargetDataHandle TargetData, int32 Index) { FGameplayAbilityTargetData* Data = TargetData.Data[Index].Get(); if (Data) { if (Data->HasOrigin()) { return Data->GetOrigin(); } if (Data->HasHitResult()) { const FHitResult* HitResultPtr = Data->GetHitResult(); FTransform ReturnTransform; ReturnTransform.SetLocation(HitResultPtr->TraceStart); ReturnTransform.SetRotation((HitResultPtr->Location - HitResultPtr->TraceStart).GetSafeNormal().Rotation().Quaternion()); return ReturnTransform; } } return FTransform::Identity; }
void ULineBatchComponent::DrawSolidBox(const FBox& Box, const FTransform& Xform, const FColor& Color, uint8 DepthPriority, float LifeTime) { int32 const NewMeshIdx = BatchedMeshes.Add(FBatchedMesh()); FBatchedMesh& BM = BatchedMeshes[NewMeshIdx]; BM.Color = Color; BM.DepthPriority = DepthPriority; BM.RemainingLifeTime = LifeTime; BM.MeshVerts.AddUninitialized(8); BM.MeshVerts[0] = Xform.TransformPosition( FVector(Box.Min.X, Box.Min.Y, Box.Max.Z) ); BM.MeshVerts[1] = Xform.TransformPosition( FVector(Box.Max.X, Box.Min.Y, Box.Max.Z) ); BM.MeshVerts[2] = Xform.TransformPosition( FVector(Box.Min.X, Box.Min.Y, Box.Min.Z) ); BM.MeshVerts[3] = Xform.TransformPosition( FVector(Box.Max.X, Box.Min.Y, Box.Min.Z) ); BM.MeshVerts[4] = Xform.TransformPosition( FVector(Box.Min.X, Box.Max.Y, Box.Max.Z) ); BM.MeshVerts[5] = Xform.TransformPosition( FVector(Box.Max.X, Box.Max.Y, Box.Max.Z) ); BM.MeshVerts[6] = Xform.TransformPosition( FVector(Box.Min.X, Box.Max.Y, Box.Min.Z) ); BM.MeshVerts[7] = Xform.TransformPosition( FVector(Box.Max.X, Box.Max.Y, Box.Min.Z) ); // clockwise BM.MeshIndices.AddUninitialized(36); int32 const Indices[36] = { 3,2,0, 3,0,1, 7,3,1, 7,1,5, 6,7,5, 6,5,4, 2,6,4, 2,4,0, 1,0,4, 1,4,5, 7,6,2, 7,2,3 }; for (int32 Idx=0; Idx<36; ++Idx) { BM.MeshIndices[Idx] = Indices[Idx]; } MarkRenderStateDirty(); }
void UPrimitiveComponent::SyncComponentToRBPhysics() { if(!IsRegistered()) { UE_LOG(LogPhysics, Log, TEXT("SyncComponentToRBPhysics : Component not registered (%s)"), *GetPathName()); return; } // BodyInstance we are going to sync the component to FBodyInstance* UseBI = GetBodyInstance(); if(UseBI == NULL || !UseBI->IsValidBodyInstance()) { UE_LOG(LogPhysics, Log, TEXT("SyncComponentToRBPhysics : Missing or invalid BodyInstance (%s)"), *GetPathName()); return; } AActor* Owner = GetOwner(); if(Owner != NULL) { if (Owner->IsPendingKill() || !Owner->CheckStillInWorld()) { return; } } if (IsPendingKill() || !IsSimulatingPhysics()) { return; } // See if the transform is actually different, and if so, move the component to match physics const FTransform NewTransform = GetComponentTransformFromBodyInstance(UseBI); if(!NewTransform.EqualsNoScale(ComponentToWorld)) { const FVector MoveBy = NewTransform.GetLocation() - ComponentToWorld.GetLocation(); const FQuat NewRotation = NewTransform.GetRotation(); //@warning: do not reference BodyInstance again after calling MoveComponent() - events from the move could have made it unusable (destroying the actor, SetPhysics(), etc) MoveComponent(MoveBy, NewRotation, false, NULL, MOVECOMP_SkipPhysicsMove); } }
//============================================================================= void UMotionControllerComponent::FViewExtension::PreRenderViewFamily_RenderThread(FRHICommandListImmediate& RHICmdList, FSceneViewFamily& InViewFamily) { if (!MotionControllerComponent) { return; } FScopeLock ScopeLock(&CritSect); if (!MotionControllerComponent || MotionControllerComponent->bDisableLowLatencyUpdate || !CVarEnableMotionControllerLateUpdate.GetValueOnRenderThread()) { return; } // Poll state for the most recent controller transform FVector Position; FRotator Orientation; if (!MotionControllerComponent->PollControllerState(Position, Orientation)) { return; } if (LateUpdatePrimitives.Num()) { // Calculate the late update transform that will rebase all children proxies within the frame of reference const FTransform OldLocalToWorldTransform = MotionControllerComponent->CalcNewComponentToWorld(MotionControllerComponent->GetRelativeTransform()); const FTransform NewLocalToWorldTransform = MotionControllerComponent->CalcNewComponentToWorld(FTransform(Orientation, Position, MotionControllerComponent->GetComponentScale())); const FMatrix LateUpdateTransform = (OldLocalToWorldTransform.Inverse() * NewLocalToWorldTransform).ToMatrixWithScale(); // Apply delta to the affected scene proxies for (auto PrimitiveInfo : LateUpdatePrimitives) { FPrimitiveSceneInfo* RetrievedSceneInfo = InViewFamily.Scene->GetPrimitiveSceneInfo(*PrimitiveInfo.IndexAddress); FPrimitiveSceneInfo* CachedSceneInfo = PrimitiveInfo.SceneInfo; // If the retrieved scene info is different than our cached scene info then the primitive was removed from the scene if (CachedSceneInfo == RetrievedSceneInfo && CachedSceneInfo->Proxy) { CachedSceneInfo->Proxy->ApplyLateUpdateTransform(LateUpdateTransform); } } LateUpdatePrimitives.Reset(); } }
FTransform UPhATEdSkeletalMeshComponent::GetPrimitiveTransform(FTransform& BoneTM, int32 BodyIndex, EKCollisionPrimitiveType PrimType, int32 PrimIndex, float Scale) { UBodySetup* BodySetup = SharedData->PhysicsAsset->BodySetup[BodyIndex]; FVector Scale3D(Scale); FTransform ManTM = FTransform::Identity; if(SharedData->bManipulating && !SharedData->bRunningSimulation && SharedData->EditingMode == FPhATSharedData::PEM_BodyEdit) { FPhATSharedData::FSelection Body(BodyIndex, PrimType, PrimIndex); for(int32 i=0; i<SharedData->SelectedBodies.Num(); ++i) { if (Body == SharedData->SelectedBodies[i]) { ManTM = SharedData->SelectedBodies[i].ManipulateTM; break; } } } if (PrimType == KPT_Sphere) { FTransform PrimTM = ManTM * BodySetup->AggGeom.SphereElems[PrimIndex].GetTransform(); PrimTM.ScaleTranslation(Scale3D); return PrimTM * BoneTM; } else if (PrimType == KPT_Box) { FTransform PrimTM = ManTM * BodySetup->AggGeom.BoxElems[PrimIndex].GetTransform(); PrimTM.ScaleTranslation(Scale3D); return PrimTM * BoneTM; } else if (PrimType == KPT_Sphyl) { FTransform PrimTM = ManTM * BodySetup->AggGeom.SphylElems[PrimIndex].GetTransform(); PrimTM.ScaleTranslation(Scale3D); return PrimTM * BoneTM; } else if (PrimType == KPT_Convex) { FTransform PrimTM = ManTM * BodySetup->AggGeom.ConvexElems[PrimIndex].GetTransform(); PrimTM.ScaleTranslation(Scale3D); return PrimTM * BoneTM; } // Should never reach here check(0); return FTransform::Identity; }
FTransform FConstraintInstance::GetRefFrame(EConstraintFrame::Type Frame) const { FTransform Result; if(Frame == EConstraintFrame::Frame1) { Result = FTransform(PriAxis1, SecAxis1, PriAxis1 ^ SecAxis1, Pos1); } else { Result = FTransform(PriAxis2, SecAxis2, PriAxis2 ^ SecAxis2, Pos2); } float Error = FMath::Abs( Result.GetDeterminant() - 1.0f ); if(Error > 0.01f) { UE_LOG(LogPhysics, Warning, TEXT("FConstraintInstance::GetRefFrame : Contained scale.")); } return Result; }
void SStaticMeshEditorViewport::OnFocusViewportToSelection() { UStaticMeshSocket* SelectedSocket = StaticMeshEditorPtr.Pin()->GetSelectedSocket(); if( SelectedSocket && PreviewMeshComponent ) { FTransform SocketTransform; SelectedSocket->GetSocketTransform( SocketTransform, PreviewMeshComponent ); FVector Extent(30.0f); FVector Origin = SocketTransform.GetLocation(); FBox Box( Origin - Extent, Origin + Extent); EditorViewportClient->FocusViewportOnBox( Box ); } else if( PreviewMeshComponent ) { EditorViewportClient->FocusViewportOnBox( PreviewMeshComponent->Bounds.GetBox() ); } }
void FComponentEditorUtils::AdjustComponentDelta(USceneComponent* Component, FVector& Drag, FRotator& Rotation) { USceneComponent* ParentSceneComp = Component->GetAttachParent(); if (ParentSceneComp) { const FTransform ParentToWorldSpace = ParentSceneComp->GetSocketTransform(Component->AttachSocketName); if (!Component->bAbsoluteLocation) { //transform the drag vector in relative to the parent transform Drag = ParentToWorldSpace.InverseTransformVectorNoScale(Drag); //Now that we have a global drag we can apply the parent scale Drag = Drag * ParentToWorldSpace.Inverse().GetScale3D(); } if (!Component->bAbsoluteRotation) { Rotation = ( ParentToWorldSpace.Inverse().GetRotation() * Rotation.Quaternion() * ParentToWorldSpace.GetRotation() ).Rotator(); } } }
FTransform FTransformCurve::Evaluate(float CurrentTime, float BlendWeight) const { FTransform Value; Value.SetTranslation(TranslationCurve.Evaluate(CurrentTime, BlendWeight)); if (ScaleCurve.DoesContainKey()) { Value.SetScale3D(ScaleCurve.Evaluate(CurrentTime, BlendWeight)); } else { Value.SetScale3D(FVector(1.f)); } // blend rotation float curve FVector RotationAsVector = RotationCurve.Evaluate(CurrentTime, BlendWeight); // pitch, yaw, roll order - please check AddKey function FRotator Rotator(RotationAsVector.Y, RotationAsVector.Z, RotationAsVector.X); Value.SetRotation(FQuat(Rotator)); return Value; }
// Render a coordinate system indicator void USkeletalMeshComponent::RenderAxisGizmo( const FTransform& Transform, UCanvas* Canvas ) const { // Display colored coordinate system axes for this joint. const float AxisLength = 3.75f; const FVector Origin = Transform.GetLocation(); // Red = X FVector XAxis = Transform.TransformVector( FVector(1.0f,0.0f,0.0f) ); XAxis.Normalize(); DrawDebugCanvasLine(Canvas, Origin, Origin + XAxis * AxisLength, FLinearColor( 1.f, 0.3f, 0.3f)); // Green = Y FVector YAxis = Transform.TransformVector( FVector(0.0f,1.0f,0.0f) ); YAxis.Normalize(); DrawDebugCanvasLine(Canvas, Origin, Origin + YAxis * AxisLength, FLinearColor( 0.3f, 1.f, 0.3f)); // Blue = Z FVector ZAxis = Transform.TransformVector( FVector(0.0f,0.0f,1.0f) ); ZAxis.Normalize(); DrawDebugCanvasLine(Canvas, Origin, Origin + ZAxis * AxisLength, FLinearColor( 0.3f, 0.3f, 1.f)); }
void UBodySetup::AddBoxesToRigidActor(PxRigidActor* PDestActor, const FTransform& RelativeTM, const FVector& Scale3D, const FVector& Scale3DAbs, TArray<PxShape*>* NewShapes) const { float ContactOffsetFactor, MaxContactOffset; GetContactOffsetParams(ContactOffsetFactor, MaxContactOffset); PxMaterial* PDefaultMat = GetDefaultPhysMaterial(); for (int32 i = 0; i < AggGeom.BoxElems.Num(); i++) { const FKBoxElem& BoxElem = AggGeom.BoxElems[i]; PxBoxGeometry PBoxGeom; PBoxGeom.halfExtents.x = (0.5f * BoxElem.X * Scale3DAbs.X); PBoxGeom.halfExtents.y = (0.5f * BoxElem.Y * Scale3DAbs.Y); PBoxGeom.halfExtents.z = (0.5f * BoxElem.Z * Scale3DAbs.Z); FTransform BoxTransform = BoxElem.GetTransform() * RelativeTM; if (PBoxGeom.isValid() && BoxTransform.IsValid()) { PxTransform PLocalPose(U2PTransform(BoxTransform)); PLocalPose.p.x *= Scale3D.X; PLocalPose.p.y *= Scale3D.Y; PLocalPose.p.z *= Scale3D.Z; ensure(PLocalPose.isValid()); PxShape* NewShape = PDestActor->createShape(PBoxGeom, *PDefaultMat, PLocalPose); if (NewShapes) { NewShapes->Add(NewShape); } const float ContactOffset = FMath::Min(MaxContactOffset, ContactOffsetFactor * PBoxGeom.halfExtents.minElement()); NewShape->setContactOffset(ContactOffset); } else { UE_LOG(LogPhysics, Warning, TEXT("AddBoxesToRigidActor: [%s] BoxElems[%d] invalid or has invalid transform"), *GetPathNameSafe(GetOuter()), i); } } }
// NB: ElemTM is assumed to have no scaling in it! void FKBoxElem::DrawElemWire(FPrimitiveDrawInterface* PDI, const FTransform& ElemTM, float Scale, const FColor Color) { FVector B[2], P, Q, Radii; // X,Y,Z member variables are LENGTH not RADIUS Radii.X = Scale*0.5f*X; Radii.Y = Scale*0.5f*Y; Radii.Z = Scale*0.5f*Z; B[0] = Radii; // max B[1] = -1.0f * Radii; // min for( int32 i=0; i<2; i++ ) { for( int32 j=0; j<2; j++ ) { P.X=B[i].X; Q.X=B[i].X; P.Y=B[j].Y; Q.Y=B[j].Y; P.Z=B[0].Z; Q.Z=B[1].Z; PDI->DrawLine( ElemTM.TransformPosition(P), ElemTM.TransformPosition(Q), Color, SDPG_World); P.Y=B[i].Y; Q.Y=B[i].Y; P.Z=B[j].Z; Q.Z=B[j].Z; P.X=B[0].X; Q.X=B[1].X; PDI->DrawLine( ElemTM.TransformPosition(P), ElemTM.TransformPosition(Q), Color, SDPG_World); P.Z=B[i].Z; Q.Z=B[i].Z; P.X=B[j].X; Q.X=B[j].X; P.Y=B[0].Y; Q.Y=B[1].Y; PDI->DrawLine( ElemTM.TransformPosition(P), ElemTM.TransformPosition(Q), Color, SDPG_World); } } }
FVector UAnimGraphNode_ModifyBone::GetWidgetLocation(const USkeletalMeshComponent* SkelComp, FAnimNode_SkeletalControlBase* AnimNode) { USkeleton* Skeleton = SkelComp->SkeletalMesh->Skeleton; FVector WidgetLoc = FVector::ZeroVector; // if the current widget mode is translate, then shows the widget according to translation space if (CurWidgetMode == FWidget::WM_Translate) { FCSPose<FCompactPose>& MeshBases = AnimNode->ForwardedPose; WidgetLoc = ConvertWidgetLocation(SkelComp, MeshBases, Node.BoneToModify.BoneName, GetNodeValue(FString("Translation"), Node.Translation), Node.TranslationSpace); if (MeshBases.GetPose().IsValid() && Node.TranslationMode == BMM_Additive) { if(Node.TranslationSpace == EBoneControlSpace::BCS_WorldSpace || Node.TranslationSpace == EBoneControlSpace::BCS_ComponentSpace) { const FMeshPoseBoneIndex MeshBoneIndex(SkelComp->GetBoneIndex(Node.BoneToModify.BoneName)); const FCompactPoseBoneIndex BoneIndex = MeshBases.GetPose().GetBoneContainer().MakeCompactPoseIndex(MeshBoneIndex); if (BoneIndex != INDEX_NONE) { const FTransform& BoneTM = MeshBases.GetComponentSpaceTransform(BoneIndex); WidgetLoc += BoneTM.GetLocation(); } } } } else // if the current widget mode is not translate mode, then show the widget on the bone to modify { int32 MeshBoneIndex = SkelComp->GetBoneIndex(Node.BoneToModify.BoneName); if (MeshBoneIndex != INDEX_NONE) { const FTransform BoneTM = SkelComp->GetBoneTransform(MeshBoneIndex); WidgetLoc = BoneTM.GetLocation(); } } return WidgetLoc; }
void FAnimNode_CopyBone::EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, FCSPose<FCompactPose>& MeshBases, TArray<FBoneTransform>& OutBoneTransforms) { check(OutBoneTransforms.Num() == 0); // Pass through if we're not doing anything. if( !bCopyTranslation && !bCopyRotation && !bCopyScale ) { return; } // Get component space transform for source and current bone. const FBoneContainer& BoneContainer = MeshBases.GetPose().GetBoneContainer(); FCompactPoseBoneIndex SourceBoneIndex = SourceBone.GetCompactPoseIndex(BoneContainer); FCompactPoseBoneIndex TargetBoneIndex = TargetBone.GetCompactPoseIndex(BoneContainer); FTransform SourceBoneTM = MeshBases.GetComponentSpaceTransform(SourceBoneIndex); FTransform CurrentBoneTM = MeshBases.GetComponentSpaceTransform(TargetBoneIndex); if(ControlSpace != BCS_ComponentSpace) { // Convert out to selected space FAnimationRuntime::ConvertCSTransformToBoneSpace(SkelComp, MeshBases, SourceBoneTM, SourceBoneIndex, ControlSpace); FAnimationRuntime::ConvertCSTransformToBoneSpace(SkelComp, MeshBases, CurrentBoneTM, TargetBoneIndex, ControlSpace); } // Copy individual components if (bCopyTranslation) { CurrentBoneTM.SetTranslation( SourceBoneTM.GetTranslation() ); } if (bCopyRotation) { CurrentBoneTM.SetRotation( SourceBoneTM.GetRotation() ); } if (bCopyScale) { CurrentBoneTM.SetScale3D( SourceBoneTM.GetScale3D() ); } if(ControlSpace != BCS_ComponentSpace) { // Convert back out if we aren't operating in component space FAnimationRuntime::ConvertBoneSpaceTransformToCS(SkelComp, MeshBases, CurrentBoneTM, TargetBoneIndex, ControlSpace); } // Output new transform for current bone. OutBoneTransforms.Add(FBoneTransform(TargetBoneIndex, CurrentBoneTM)); }
void FKConvexElem::DrawElemWire(FPrimitiveDrawInterface* PDI, const FTransform& ElemTM, const float Scale, const FColor Color) const { #if WITH_PHYSX PxConvexMesh* Mesh = ConvexMesh; if(Mesh) { // Draw each triangle that makes up the convex hull PxU32 NbVerts = Mesh->getNbVertices(); const PxVec3* Vertices = Mesh->getVertices(); TArray<FVector> TransformedVerts; TransformedVerts.AddUninitialized(NbVerts); for(PxU32 i=0; i<NbVerts; i++) { TransformedVerts[i] = ElemTM.TransformPosition(P2UVector(Vertices[i]) * Scale); } const PxU8* PIndexBuffer = Mesh->getIndexBuffer(); PxU32 NbPolygons = Mesh->getNbPolygons(); for(PxU32 i=0;i<NbPolygons;i++) { PxHullPolygon Data; bool bStatus = Mesh->getPolygonData(i, Data); check(bStatus); const PxU8* PIndices = PIndexBuffer + Data.mIndexBase; for(PxU16 j=0;j<Data.mNbVerts;j++) { // Get the verts that make up this line. int32 I0 = PIndices[j]; int32 I1 = PIndices[j+1]; // Loop back last and first vertices if(j==Data.mNbVerts - 1) { I1 = PIndices[0]; } PDI->DrawLine( TransformedVerts[I0], TransformedVerts[I1], Color, SDPG_World ); } } } else { UE_LOG(LogPhysics, Log, TEXT("FKConvexElem::DrawElemWire : No ConvexMesh, so unable to draw.")); } #endif // WITH_PHYSX }
bool OSVRInterface::GetPose(FTransform& Value, bool Latest) const { if (Latest) { #if OSVR_ENABLED OSVR_TimeValue Time; OSVR_PoseState Pose; OSVR_ReturnCode ReturnCode = osvrGetPoseState(OSVRClientInterface, &Time, &Pose); Value.SetTranslation(OSVR2FVector(Pose.translation)); Value.SetRotation(OSVR2FQuat(Pose.rotation)); return ReturnCode == OSVR_RETURN_SUCCESS; #endif // OSVR_ENABLED } else { Value = PoseState; } return HasPoseState(); }
void ASmrActor::TransformBone(UPoseableMeshComponent* mesh, SMRJoint* bone) { //Build the local transform for this bone FTransform finalTransform; finalTransform.SetLocation(USmrFunctions::RightCoordToLeft(bone->getPosition())); finalTransform.SetRotation(USmrFunctions::RightCoordToLeft(bone->getOrientation())); if (bone->hasParent()) { //Get the component space transform for the parent bone FName parentName(bone->getParentName().c_str()); FTransform parentTransform = mesh->GetBoneTransformByName(parentName, EBoneSpaces::ComponentSpace); //Convert local transform to component space finalTransform *= parentTransform; } //Convert quaternion to Euler angles and apply to the mesh FVector euler = finalTransform.GetRotation().Euler(); FRotator rotator = FRotator::MakeFromEuler(euler); FName boneName(bone->getName().c_str()); mesh->SetBoneRotationByName(boneName, rotator, EBoneSpaces::ComponentSpace); }
float FAttenuationSettings::AttenuationEvalCapsule(const FTransform& SoundTransform, const FVector ListenerLocation, const float DistanceScale) const { float Distance = 0.f; const float CapsuleHalfHeight = AttenuationShapeExtents.X; const float CapsuleRadius = AttenuationShapeExtents.Y; // Capsule devolves to a sphere if HalfHeight <= Radius if (CapsuleHalfHeight <= CapsuleRadius ) { Distance = FMath::Max(FVector::Dist( SoundTransform.GetTranslation(), ListenerLocation ) - CapsuleRadius, 0.f); } else { const FVector PointOffset = (CapsuleHalfHeight - CapsuleRadius) * SoundTransform.GetUnitAxis( EAxis::Z ); const FVector StartPoint = SoundTransform.GetTranslation() + PointOffset; const FVector EndPoint = SoundTransform.GetTranslation() - PointOffset; Distance = FMath::PointDistToSegment(ListenerLocation, StartPoint, EndPoint) - CapsuleRadius; } return AttenuationEval(Distance, FalloffDistance, DistanceScale); }
void UDebugSkelMeshComponent::ConsumeRootMotion(const FVector& FloorMin, const FVector& FloorMax) { //Extract root motion regardless of where we use it so that we don't hit //problems with it building up in the instance FRootMotionMovementParams ExtractedRootMotion; if (UAnimInstance* AnimInst = GetAnimInstance()) { ExtractedRootMotion = AnimInst->ConsumeExtractedRootMotion(1.f); } if (bPreviewRootMotion) { if (ExtractedRootMotion.bHasRootMotion) { AddLocalTransform(ExtractedRootMotion.RootMotionTransform); //Handle moving component so that it stays within the editor floor FTransform CurrentTransform = GetRelativeTransform(); FVector Trans = CurrentTransform.GetTranslation(); Trans.X = WrapInRange(Trans.X, FloorMin.X, FloorMax.X); Trans.Y = WrapInRange(Trans.Y, FloorMin.Y, FloorMax.Y); CurrentTransform.SetTranslation(Trans); SetRelativeTransform(CurrentTransform); } } else { if (TurnTableMode == EPersonaTurnTableMode::Stopped) { SetWorldTransform(FTransform()); } else { SetRelativeLocation(FVector::ZeroVector); } } }
void FPhysScene::SyncComponentsToBodies(uint32 SceneType) { SCOPE_CYCLE_COUNTER(STAT_TotalPhysicsTime); SCOPE_CYCLE_COUNTER(STAT_SyncComponentsToBodies); for (FBodyInstance* BodyInstance : ActiveBodyInstances[SceneType]) { if (BodyInstance == nullptr) { continue; } check(BodyInstance->OwnerComponent->IsRegistered()); // shouldn't have a physics body for a non-registered component! AActor* Owner = BodyInstance->OwnerComponent->GetOwner(); // See if the transform is actually different, and if so, move the component to match physics const FTransform NewTransform = BodyInstance->GetUnrealWorldTransform(); if (!NewTransform.EqualsNoScale(BodyInstance->OwnerComponent->ComponentToWorld)) { const FVector MoveBy = NewTransform.GetLocation() - BodyInstance->OwnerComponent->ComponentToWorld.GetLocation(); const FRotator NewRotation = NewTransform.Rotator(); //@warning: do not reference BodyInstance again after calling MoveComponent() - events from the move could have made it unusable (destroying the actor, SetPhysics(), etc) BodyInstance->OwnerComponent->MoveComponent(MoveBy, NewRotation, false, NULL, MOVECOMP_SkipPhysicsMove); } // Check if we didn't fall out of the world if (Owner != NULL && !Owner->IsPendingKill()) { Owner->CheckStillInWorld(); } } #if WITH_APEX if (ActiveDestructibleActors[SceneType].Num()) { SCOPED_SCENE_READ_LOCK(GetPhysXScene(SceneType)); UDestructibleComponent::UpdateDestructibleChunkTM(ActiveDestructibleActors[SceneType]); } #endif }
float FKConvexElem::GetVolume(const FVector& Scale) const { float Volume = 0.0f; #if WITH_PHYSX if (ConvexMesh != NULL) { // Preparation for convex mesh scaling implemented in another changelist FTransform ScaleTransform = FTransform(FQuat::Identity, FVector::ZeroVector, Scale); int32 NumPolys = ConvexMesh->getNbPolygons(); PxHullPolygon PolyData; const PxVec3* Vertices = ConvexMesh->getVertices(); const PxU8* Indices = ConvexMesh->getIndexBuffer(); for (int32 PolyIdx = 0; PolyIdx < NumPolys; ++PolyIdx) { if (ConvexMesh->getPolygonData(PolyIdx, PolyData)) { for (int32 VertIdx = 2; VertIdx < PolyData.mNbVerts; ++ VertIdx) { // Grab triangle indices that we hit int32 I0 = Indices[PolyData.mIndexBase + 0]; int32 I1 = Indices[PolyData.mIndexBase + (VertIdx - 1)]; int32 I2 = Indices[PolyData.mIndexBase + VertIdx]; Volume += SignedVolumeOfTriangle(ScaleTransform.TransformPosition(P2UVector(Vertices[I0])), ScaleTransform.TransformPosition(P2UVector(Vertices[I1])), ScaleTransform.TransformPosition(P2UVector(Vertices[I2]))); } } } } #endif // WITH_PHYSX return Volume; }
void UBodySetup::AddSphylsToRigidActor(PxRigidActor* PDestActor, const FTransform& RelativeTM, const FVector& Scale3D, const FVector& Scale3DAbs, TArray<PxShape*>* NewShapes) const { float ContactOffsetFactor, MaxContactOffset; GetContactOffsetParams(ContactOffsetFactor, MaxContactOffset); PxMaterial* PDefaultMat = GetDefaultPhysMaterial(); float ScaleRadius = FMath::Max(Scale3DAbs.X, Scale3DAbs.Y); float ScaleLength = Scale3DAbs.Z; for (int32 i = 0; i < AggGeom.SphylElems.Num(); i++) { const FKSphylElem& SphylElem = AggGeom.SphylElems[i]; // this is a bit confusing since radius and height is scaled // first apply the scale first float Radius = FMath::Max(SphylElem.Radius * ScaleRadius, 0.1f); float Length = SphylElem.Length + SphylElem.Radius * 2.f; float HalfLength = Length * ScaleLength * 0.5f; Radius = FMath::Clamp(Radius, 0.1f, HalfLength); //radius is capped by half length float HalfHeight = HalfLength - Radius; HalfHeight = FMath::Max(0.1f, HalfHeight); PxCapsuleGeometry PCapsuleGeom; PCapsuleGeom.halfHeight = HalfHeight; PCapsuleGeom.radius = Radius; if (PCapsuleGeom.isValid()) { // The stored sphyl transform assumes the sphyl axis is down Z. In PhysX, it points down X, so we twiddle the matrix a bit here (swap X and Z and negate Y). PxTransform PLocalPose(U2PVector(RelativeTM.TransformPosition(SphylElem.Center)), U2PQuat(SphylElem.Orientation) * U2PSphylBasis); PLocalPose.p.x *= Scale3D.X; PLocalPose.p.y *= Scale3D.Y; PLocalPose.p.z *= Scale3D.Z; ensure(PLocalPose.isValid()); PxShape* NewShape = PDestActor->createShape(PCapsuleGeom, *PDefaultMat, PLocalPose); if (NewShapes) { NewShapes->Add(NewShape); } const float ContactOffset = FMath::Min(MaxContactOffset, ContactOffsetFactor * PCapsuleGeom.radius); NewShape->setContactOffset(ContactOffset); } else { UE_LOG(LogPhysics, Warning, TEXT("AddSphylsToRigidActor: [%s] SphylElems[%d] invalid"), *GetPathNameSafe(GetOuter()), i); } } }
void SetParameters(const FSceneView& View, const FMaterialRenderProxy* MaterialProxy, const FDeferredDecalProxy& DecalProxy) { const FPixelShaderRHIParamRef ShaderRHI = GetPixelShader(); FMaterialShader::SetParameters(ShaderRHI, MaterialProxy, *MaterialProxy->GetMaterial(GRHIFeatureLevel), View, true, ESceneRenderTargetsMode::SetTextures); FTransform ComponentTrans = DecalProxy.ComponentTrans; // 1,1,1 requires no scale // ComponentTrans = ComponentTrans.GetScaled(GDefaultDecalSize); FMatrix WorldToComponent = ComponentTrans.ToMatrixWithScale().Inverse(); // Set the transform from screen space to light space. if(ScreenToDecal.IsBound()) { const FMatrix ScreenToDecalValue = FMatrix( FPlane(1,0,0,0), FPlane(0,1,0,0), FPlane(0,0,View.ViewMatrices.ProjMatrix.M[2][2],1), FPlane(0,0,View.ViewMatrices.ProjMatrix.M[3][2],0) ) * View.InvViewProjectionMatrix * WorldToComponent; SetShaderValue(ShaderRHI, ScreenToDecal, ScreenToDecalValue); } // Set the transform from light space to world space (only for normals) if(DecalToWorld.IsBound()) { const FMatrix DecalToWorldValue = ComponentTrans.ToMatrixNoScale(); // 1,1,1 requires no scale // DecalToWorldValue = DecalToWorldValue.GetScaled(GDefaultDecalSize); SetShaderValue(ShaderRHI, DecalToWorld, DecalToWorldValue); } }
bool UPaperGroupedSpriteComponent::UpdateInstanceTransform(int32 InstanceIndex, const FTransform& NewInstanceTransform, bool bWorldSpace, bool bMarkRenderStateDirty) { if (!PerInstanceSpriteData.IsValidIndex(InstanceIndex)) { return false; } // Request navigation update UNavigationSystem::UpdateNavOctree(this); FSpriteInstanceData& InstanceData = PerInstanceSpriteData[InstanceIndex]; // Render data uses local transform of the instance FTransform LocalTransform = bWorldSpace ? NewInstanceTransform.GetRelativeTransform(ComponentToWorld) : NewInstanceTransform; InstanceData.Transform = LocalTransform.ToMatrixWithScale(); if (bPhysicsStateCreated) { // Physics uses world transform of the instance const FTransform WorldTransform = bWorldSpace ? NewInstanceTransform : (LocalTransform * ComponentToWorld); if (FBodyInstance* InstanceBodyInstance = InstanceBodies[InstanceIndex]) { // Update transform. InstanceBodyInstance->SetBodyTransform(WorldTransform, ETeleportType::None); InstanceBodyInstance->UpdateBodyScale(WorldTransform.GetScale3D()); } } // Request navigation update UNavigationSystem::UpdateNavOctree(this); if (bMarkRenderStateDirty) { MarkRenderStateDirty(); } return true; }
void FLevelUtils::ApplyLevelTransform( ULevel* Level, const FTransform& LevelTransform, bool bDoPostEditMove ) { bool bTransformActors = !LevelTransform.Equals(FTransform::Identity); if (bTransformActors) { if (!LevelTransform.GetRotation().IsIdentity()) { // If there is a rotation applied, then the relative precomputed bounds become invalid. Level->bTextureStreamingRotationChanged = true; } // Iterate over all actors in the level and transform them for( int32 ActorIndex=0; ActorIndex<Level->Actors.Num(); ActorIndex++ ) { AActor* Actor = Level->Actors[ActorIndex]; // Don't want to transform children they should stay relative to there parents. if( Actor && Actor->GetAttachParentActor() == NULL ) { // Has to modify root component directly as GetActorPosition is incorrect this early USceneComponent *RootComponent = Actor->GetRootComponent(); if (RootComponent) { RootComponent->SetRelativeLocationAndRotation( LevelTransform.TransformPosition(RootComponent->RelativeLocation), (FTransform(RootComponent->RelativeRotation) * LevelTransform).Rotator()); } } } #if WITH_EDITOR if( bDoPostEditMove ) { ApplyPostEditMove( Level ); } #endif // WITH_EDITOR Level->OnApplyLevelTransform.Broadcast(LevelTransform); } }
/** Tests shape components more efficiently than the with-adjustment case, but does less-efficient ppr-poly collision for meshes. */ static bool ComponentEncroachesBlockingGeometry_NoAdjustment(UWorld const* World, AActor const* TestActor, UPrimitiveComponent const* PrimComp, FTransform const& TestWorldTransform) { float const Epsilon = CVarEncroachEpsilon.GetValueOnGameThread(); if (World && PrimComp) { bool bFoundBlockingHit = false; static FName NAME_ComponentEncroachesBlockingGeometry_NoAdjustment = FName(TEXT("ComponentEncroachesBlockingGeometry_NoAdjustment")); ECollisionChannel const BlockingChannel = PrimComp->GetCollisionObjectType(); FCollisionShape const CollisionShape = PrimComp->GetCollisionShape(-Epsilon); if (CollisionShape.IsBox() && (Cast<UBoxComponent>(PrimComp) == nullptr)) { // we have a bounding box not for a box component, which means this was the fallback aabb // since we don't need the penetration info, go ahead and test the component itself for overlaps, which is more accurate if (PrimComp->IsRegistered()) { // must be registered TArray<FOverlapResult> Overlaps; FComponentQueryParams Params(NAME_ComponentEncroachesBlockingGeometry_NoAdjustment, TestActor); return World->ComponentOverlapMultiByChannel(Overlaps, PrimComp, TestWorldTransform.GetLocation(), TestWorldTransform.GetRotation(), BlockingChannel, Params); } else { UE_LOG(LogPhysics, Log, TEXT("Components must be registered in order to be used in a ComponentOverlapMulti call. PriComp: %s TestActor: %s"), *PrimComp->GetName(), *TestActor->GetName()); return false; } } else { FCollisionQueryParams Params(NAME_ComponentEncroachesBlockingGeometry_NoAdjustment, false, TestActor); return World->OverlapAnyTestByChannel(TestWorldTransform.GetLocation(), TestWorldTransform.GetRotation(), BlockingChannel, CollisionShape, Params); } } return false; }
FTransform FActorPositioning::GetCurrentViewportPlacementTransform(const AActor& Actor, bool bSnap) { FVector Collision = Actor.GetPlacementExtent(); const UActorFactory* Factory = GEditor->FindActorFactoryForActorClass(Actor.GetClass()); // Get cursor origin and direction in world space. FViewportCursorLocation CursorLocation = GCurrentLevelEditingViewportClient->GetCursorWorldLocationFromMousePos(); const auto CursorPos = CursorLocation.GetCursorPos(); FTransform ActorTransform = FTransform::Identity; if (CursorLocation.GetViewportType() == LVT_Perspective && !GCurrentLevelEditingViewportClient->Viewport->GetHitProxy( CursorPos.X, CursorPos.Y )) { ActorTransform.SetTranslation(GetActorPositionInFrontOfCamera(Actor, CursorLocation.GetOrigin(), CursorLocation.GetDirection())); } else { const FSnappedPositioningData PositioningData = FSnappedPositioningData(GCurrentLevelEditingViewportClient, GEditor->ClickLocation, GEditor->ClickPlane) .DrawSnapHelpers(true) .UseFactory(Factory) .UsePlacementExtent(Actor.GetPlacementExtent()); ActorTransform = bSnap ? GetSnappedSurfaceAlignedTransform(PositioningData) : GetSurfaceAlignedTransform(PositioningData); if (GetDefault<ULevelEditorViewportSettings>()->SnapToSurface.bEnabled) { // HACK: If we are aligning rotation to surfaces, we have to factor in the inverse of the actor transform so that the resulting transform after SpawnActor is correct. if (auto* RootComponent = Actor.GetRootComponent()) { RootComponent->UpdateComponentToWorld(); } ActorTransform = Actor.GetTransform().Inverse() * ActorTransform; } } return ActorTransform; }
FVector UAnimGraphNode_SkeletalControlBase::ConvertCSVectorToBoneSpace(const USkeletalMeshComponent* SkelComp, FVector& InCSVector, FA2CSPose& MeshBases, const FName& BoneName, const EBoneControlSpace Space) { FVector OutVector = InCSVector; if (MeshBases.IsValid()) { int32 MeshBoneIndex = SkelComp->GetBoneIndex(BoneName); switch (Space) { // World Space, no change in preview window case BCS_WorldSpace: case BCS_ComponentSpace: // Component Space, no change. break; case BCS_ParentBoneSpace: { const int32 ParentIndex = MeshBases.GetParentBoneIndex(MeshBoneIndex); if (ParentIndex != INDEX_NONE) { FTransform ParentTM = MeshBases.GetComponentSpaceTransform(ParentIndex); OutVector = ParentTM.InverseTransformVector(InCSVector); } } break; case BCS_BoneSpace: { FTransform BoneTM = MeshBases.GetComponentSpaceTransform(MeshBoneIndex); OutVector = BoneTM.InverseTransformVector(InCSVector); } break; } } return OutVector; }
FBox FKSphylElem::CalcAABB(const FTransform& BoneTM, float Scale) const { FTransform ElemTM = GetTransform(); ElemTM.ScaleTranslation( FVector(Scale) ); ElemTM *= BoneTM; const FVector SphylCenter = ElemTM.GetLocation(); // Get sphyl axis direction const FVector Axis = ElemTM.GetScaledAxis( EAxis::Z ); // Get abs of that vector const FVector AbsAxis(FMath::Abs(Axis.X), FMath::Abs(Axis.Y), FMath::Abs(Axis.Z)); // Scale by length of sphyl const FVector AbsDist = (Scale * 0.5f * Length) * AbsAxis; const FVector MaxPos = SphylCenter + AbsDist; const FVector MinPos = SphylCenter - AbsDist; const FVector Extent(Scale * Radius); FBox Result(MinPos - Extent, MaxPos + Extent); return Result; }
void AMyPlayer::MoveRight(float Value) { if ((Controller != NULL) && (Value != 0.0f) && this->GetActorLocation().X < 1950 && this->GetActorLocation().X > -150) { FTransform newLocation; newLocation.SetLocation(FVector(this->GetActorLocation().X + Value * speed, this->GetActorLocation().Y, this->GetActorLocation().Z)); newLocation.SetRotation(FQuat(FRotator(0, 0, 0))); SetActorTransform(newLocation); } else if (this->GetActorLocation().X >= 1950) { SetActorLocation(FVector(1949, this->GetActorLocation().Y, this->GetActorLocation().Z)); } else if (this->GetActorLocation().X <= -150) { SetActorLocation(FVector(-149, this->GetActorLocation().Y, this->GetActorLocation().Z)); } }