void UAnimGraphNode_TwoBoneIK::DrawTargetLocation(FPrimitiveDrawInterface* PDI, USkeletalMeshComponent* SkelComp, USkeleton * Skeleton, EBoneControlSpace SpaceBase, FName SpaceBoneName, const FVector & TargetLocation, const FColor & TargetColor, const FColor & BoneColor) const { const bool bInBoneSpace = (SpaceBase == BCS_ParentBoneSpace) || (SpaceBase == BCS_BoneSpace); const int32 SpaceBoneIndex = bInBoneSpace ? Skeleton->GetReferenceSkeleton().FindBoneIndex(SpaceBoneName) : INDEX_NONE; // Transform EffectorLocation from EffectorLocationSpace to ComponentSpace. FTransform TargetTransform = FTransform (TargetLocation); FTransform CSTransform; ConvertToComponentSpaceTransform(SkelComp, TargetTransform, CSTransform, SpaceBoneIndex, SpaceBase); FTransform WorldTransform = CSTransform * SkelComp->ComponentToWorld; #if 0 // @TODO : remove this code because this doesn't show correct target location DrawCoordinateSystem( PDI, WorldTransform.GetLocation(), WorldTransform.GetRotation().Rotator(), 20.f, SDPG_Foreground ); DrawWireDiamond( PDI, WorldTransform.ToMatrixWithScale(), 2.f, TargetColor, SDPG_Foreground ); #endif if (bInBoneSpace) { ConvertToComponentSpaceTransform(SkelComp, FTransform::Identity, CSTransform, SpaceBoneIndex, SpaceBase); WorldTransform = CSTransform * SkelComp->ComponentToWorld; DrawCoordinateSystem( PDI, WorldTransform.GetLocation(), WorldTransform.GetRotation().Rotator(), 20.f, SDPG_Foreground ); DrawWireDiamond( PDI, WorldTransform.ToMatrixWithScale(), 2.f, BoneColor, SDPG_Foreground ); } }
void UAnimGraphNode_BoneDrivenController::Draw(FPrimitiveDrawInterface* PDI, USkeletalMeshComponent* SkelMeshComp) const { static const float ArrowHeadWidth = 5.0f; static const float ArrowHeadHeight = 8.0f; const int32 SourceIdx = SkelMeshComp->GetBoneIndex(Node.SourceBone.BoneName); const int32 TargetIdx = SkelMeshComp->GetBoneIndex(Node.TargetBone.BoneName); if ((SourceIdx != INDEX_NONE) && (TargetIdx != INDEX_NONE)) { const FTransform SourceTM = SkelMeshComp->GetSpaceBases()[SourceIdx] * SkelMeshComp->ComponentToWorld; const FTransform TargetTM = SkelMeshComp->GetSpaceBases()[TargetIdx] * SkelMeshComp->ComponentToWorld; PDI->DrawLine(TargetTM.GetLocation(), SourceTM.GetLocation(), FLinearColor(0.0f, 0.0f, 1.0f), SDPG_Foreground, 0.5f); const FVector ToTarget = TargetTM.GetTranslation() - SourceTM.GetTranslation(); const FVector UnitToTarget = ToTarget.GetSafeNormal(); FVector Midpoint = SourceTM.GetTranslation() + 0.5f * ToTarget + 0.5f * UnitToTarget * ArrowHeadHeight; FVector YAxis; FVector ZAxis; UnitToTarget.FindBestAxisVectors(YAxis, ZAxis); const FMatrix ArrowMatrix(UnitToTarget, YAxis, ZAxis, Midpoint); DrawConnectedArrow(PDI, ArrowMatrix, FLinearColor(0.0f, 1.0f, 0.0), ArrowHeadHeight, ArrowHeadWidth, SDPG_Foreground); PDI->DrawPoint(SourceTM.GetTranslation(), FLinearColor(0.8f, 0.8f, 0.2f), 5.0f, SDPG_Foreground); PDI->DrawPoint(SourceTM.GetTranslation() + ToTarget, FLinearColor(0.8f, 0.8f, 0.2f), 5.0f, SDPG_Foreground); } }
bool UGripMotionControllerComponent::TeleportMoveGrippedActor(AActor * GrippedActorToMove) { if (!GrippedActorToMove || !GrippedActors.Num()) return false; FTransform WorldTransform; FTransform InverseTransform = this->GetComponentTransform().Inverse(); for (int i = GrippedActors.Num() - 1; i >= 0; --i) { if (GrippedActors[i].Actor == GrippedActorToMove) { // GetRelativeTransformReverse had some serious f*****g floating point errors associated with it that was f*****g everything up // Not sure whats wrong with the function but I might want to push a patch out eventually WorldTransform = GrippedActors[i].RelativeTransform.GetRelativeTransform(InverseTransform); // Need to use WITH teleport for this function so that the velocity isn't updated and without sweep so that they don't collide GrippedActors[i].Actor->SetActorTransform(WorldTransform, false, NULL, ETeleportType::TeleportPhysics); FBPActorPhysicsHandleInformation * Handle = GetPhysicsGrip(GrippedActors[i]); if (Handle && Handle->KinActorData) { { PxScene* PScene = GetPhysXSceneFromIndex(Handle->SceneIndex); if (PScene) { SCOPED_SCENE_WRITE_LOCK(PScene); Handle->KinActorData->setKinematicTarget(PxTransform(U2PVector(WorldTransform.GetLocation()), Handle->KinActorData->getGlobalPose().q)); Handle->KinActorData->setGlobalPose(PxTransform(U2PVector(WorldTransform.GetLocation()), Handle->KinActorData->getGlobalPose().q)); } } //Handle->KinActorData->setGlobalPose(PxTransform(U2PVector(WorldTransform.GetLocation()), Handle->KinActorData->getGlobalPose().q)); UPrimitiveComponent *root = Cast<UPrimitiveComponent>(GrippedActors[i].Actor->GetRootComponent()); if (root) { FBodyInstance * body = root->GetBodyInstance(); if (body) { body->SetBodyTransform(WorldTransform, ETeleportType::TeleportPhysics); } } } return true; } } return false; }
FVector FEdMode::GetWidgetLocation() const { if(UsesPropertyWidgets()) { AActor* SelectedActor = GetFirstSelectedActorInstance(); if(SelectedActor != NULL) { if(EditedPropertyName != TEXT("")) { FVector LocalPos = FVector::ZeroVector; if(bEditedPropertyIsTransform) { FTransform LocalTM = GetPropertyValueByName<FTransform>(SelectedActor, EditedPropertyName, EditedPropertyIndex); LocalPos = LocalTM.GetLocation(); } else { LocalPos = GetPropertyValueByName<FVector>(SelectedActor, EditedPropertyName, EditedPropertyIndex); } FTransform ActorToWorld = SelectedActor->ActorToWorld(); FVector WorldPos = ActorToWorld.TransformPosition(LocalPos); return WorldPos; } } } //UE_LOG(LogEditorModes, Log, TEXT("In FEdMode::GetWidgetLocation")); return Owner->PivotLocation; }
FBoxSphereBounds UPaperFlipbookComponent::CalcBounds(const FTransform& LocalToWorld) const { if (SourceFlipbook != nullptr) { // Graphics bounds. FBoxSphereBounds NewBounds = SourceFlipbook->GetRenderBounds().TransformBy(LocalToWorld); // Add bounds of collision geometry (if present). if (CachedBodySetup != nullptr) { const FBox AggGeomBox = CachedBodySetup->AggGeom.CalcAABB(LocalToWorld); if (AggGeomBox.IsValid) { NewBounds = Union(NewBounds, FBoxSphereBounds(AggGeomBox)); } } // Apply bounds scale NewBounds.BoxExtent *= BoundsScale; NewBounds.SphereRadius *= BoundsScale; return NewBounds; } else { return FBoxSphereBounds(LocalToWorld.GetLocation(), FVector::ZeroVector, 0.f); } }
void SStaticMeshEditorViewport::OnFocusViewportToSelection() { // If we have selected sockets, focus on them UStaticMeshSocket* SelectedSocket = StaticMeshEditorPtr.Pin()->GetSelectedSocket(); if( SelectedSocket && PreviewMeshComponent ) { FTransform SocketTransform; SelectedSocket->GetSocketTransform( SocketTransform, PreviewMeshComponent ); const FVector Extent(30.0f); const FVector Origin = SocketTransform.GetLocation(); const FBox Box(Origin - Extent, Origin + Extent); EditorViewportClient->FocusViewportOnBox( Box ); return; } // If we have selected primitives, focus on them FBox Box(0); const bool bSelectedPrim = StaticMeshEditorPtr.Pin()->CalcSelectedPrimsAABB(Box); if (bSelectedPrim) { EditorViewportClient->FocusViewportOnBox(Box); return; } // Fallback to focusing on the mesh, if nothing else if( PreviewMeshComponent ) { EditorViewportClient->FocusViewportOnBox( PreviewMeshComponent->Bounds.GetBox() ); return; } }
bool GetMovementBaseTransform(const UPrimitiveComponent* MovementBase, const FName BoneName, FVector& OutLocation, FQuat& OutQuat) { if (MovementBase) { if (BoneName != NAME_None) { const USkeletalMeshComponent* SkeletalBase = Cast<USkeletalMeshComponent>(MovementBase); if (SkeletalBase) { const int32 BoneIndex = SkeletalBase->GetBoneIndex(BoneName); if (BoneIndex != INDEX_NONE) { const FTransform BoneTransform = SkeletalBase->GetBoneTransform(BoneIndex); OutLocation = BoneTransform.GetLocation(); OutQuat = BoneTransform.GetRotation(); return true; } UE_LOG(LogCharacter, Warning, TEXT("GetMovementBaseTransform(): Invalid bone '%s' for SkeletalMeshComponent base %s"), *BoneName.ToString(), *GetPathNameSafe(MovementBase)); return false; } // TODO: warn if not a skeletal mesh but providing bone index. } // No bone supplied OutLocation = MovementBase->GetComponentLocation(); OutQuat = MovementBase->GetComponentQuat(); return true; } // NULL MovementBase OutLocation = FVector::ZeroVector; OutQuat = FQuat::Identity; return false; }
void UCreatureMeshComponent::DoCreatureMeshUpdate(int render_packet_idx) { // Update Mesh SetBoundsScale(creature_bounds_scale); SetBoundsOffset(creature_bounds_offset); SetExtraXForm(GetComponentToWorld()); ForceAnUpdate(render_packet_idx); // Debug if (creature_debug_draw) { FSphere debugSphere = GetDebugBoundsSphere(); DrawDebugSphere( GetWorld(), debugSphere.Center, debugSphere.W, 32, FColor(255, 0, 0) ); GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Sphere pos is: (%f, %f, %f)"), debugSphere.Center.X, debugSphere.Center.Y, debugSphere.Center.Z)); FTransform wTransform = GetComponentToWorld(); GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Walk pos is: (%f, %f, %f)"), wTransform.GetLocation().X, wTransform.GetLocation().Y, wTransform.GetLocation().Z)); } }
FBoxSphereBounds UPaperGroupedSpriteComponent::CalcBounds(const FTransform& BoundTransform) const { bool bHadAnyBounds = false; FBoxSphereBounds NewBounds(ForceInit); if (PerInstanceSpriteData.Num() > 0) { const FMatrix BoundTransformMatrix = BoundTransform.ToMatrixWithScale(); for (const FSpriteInstanceData& InstanceData : PerInstanceSpriteData) { if (InstanceData.SourceSprite != nullptr) { const FBoxSphereBounds RenderBounds = InstanceData.SourceSprite->GetRenderBounds(); const FBoxSphereBounds InstanceBounds = RenderBounds.TransformBy(InstanceData.Transform * BoundTransformMatrix); if (bHadAnyBounds) { NewBounds = NewBounds + InstanceBounds; } else { NewBounds = InstanceBounds; bHadAnyBounds = true; } } } } return bHadAnyBounds ? NewBounds : FBoxSphereBounds(BoundTransform.GetLocation(), FVector::ZeroVector, 0.f); }
// NB: ElemTM is assumed to have no scaling in it! void FKSphylElem::DrawElemWire(FPrimitiveDrawInterface* PDI, const FTransform& ElemTM, float Scale, const FColor Color) { FVector Origin = ElemTM.GetLocation(); FVector XAxis = ElemTM.GetScaledAxis( EAxis::X ); FVector YAxis = ElemTM.GetScaledAxis( EAxis::Y ); FVector ZAxis = ElemTM.GetScaledAxis( EAxis::Z ); // Draw top and bottom circles FVector TopEnd = Origin + Scale*0.5f*Length*ZAxis; FVector BottomEnd = Origin - Scale*0.5f*Length*ZAxis; DrawCircle(PDI,TopEnd, XAxis, YAxis, Color, Scale*Radius, DrawCollisionSides, SDPG_World); DrawCircle(PDI,BottomEnd, XAxis, YAxis, Color, Scale*Radius, DrawCollisionSides, SDPG_World); // Draw domed caps DrawHalfCircle(PDI, TopEnd, YAxis, ZAxis, Color,Scale* Radius); DrawHalfCircle(PDI, TopEnd, XAxis, ZAxis, Color, Scale*Radius); FVector NegZAxis = -ZAxis; DrawHalfCircle(PDI, BottomEnd, YAxis, NegZAxis, Color, Scale*Radius); DrawHalfCircle(PDI, BottomEnd, XAxis, NegZAxis, Color, Scale*Radius); // Draw connecty lines PDI->DrawLine(TopEnd + Scale*Radius*XAxis, BottomEnd + Scale*Radius*XAxis, Color, SDPG_World); PDI->DrawLine(TopEnd - Scale*Radius*XAxis, BottomEnd - Scale*Radius*XAxis, Color, SDPG_World); PDI->DrawLine(TopEnd + Scale*Radius*YAxis, BottomEnd + Scale*Radius*YAxis, Color, SDPG_World); PDI->DrawLine(TopEnd - Scale*Radius*YAxis, BottomEnd - Scale*Radius*YAxis, Color, SDPG_World); }
FMatrix USkeletalMeshComponent::GetTransformMatrix() const { FTransform RootTransform = GetBoneTransform(0); FVector Translation; FQuat Rotation; // if in editor, it should always use localToWorld // if root motion is ignored, use root transform if( GetWorld()->IsGameWorld() || !SkeletalMesh ) { // add root translation info Translation = RootTransform.GetLocation(); } else { Translation = ComponentToWorld.TransformPosition(SkeletalMesh->RefSkeleton.GetRefBonePose()[0].GetTranslation()); } // if root rotation is ignored, use root transform rotation Rotation = RootTransform.GetRotation(); // now I need to get scale // only LocalToWorld will have scale FVector ScaleVector = ComponentToWorld.GetScale3D(); Rotation.Normalize(); return FScaleMatrix(ScaleVector)*FQuatRotationTranslationMatrix(Rotation, Translation); }
void UBodySetup::RescaleSimpleCollision( FVector BuildScale ) { if( BuildScale3D != BuildScale ) { // Back out the old scale when applying the new scale const FVector ScaleMultiplier3D = (BuildScale / BuildScale3D); for (int32 i = 0; i < AggGeom.ConvexElems.Num(); i++) { FKConvexElem* ConvexElem = &(AggGeom.ConvexElems[i]); FTransform ConvexTrans = ConvexElem->GetTransform(); FVector ConvexLoc = ConvexTrans.GetLocation(); ConvexLoc *= ScaleMultiplier3D; ConvexTrans.SetLocation(ConvexLoc); ConvexElem->SetTransform(ConvexTrans); TArray<FVector>& Vertices = ConvexElem->VertexData; for (int32 VertIndex = 0; VertIndex < Vertices.Num(); ++VertIndex) { Vertices[VertIndex] *= ScaleMultiplier3D; } ConvexElem->UpdateElemBox(); } // @todo Deal with non-vector properties by just applying the max value for the time being const float ScaleMultiplier = ScaleMultiplier3D.GetMax(); for (int32 i = 0; i < AggGeom.SphereElems.Num(); i++) { FKSphereElem* SphereElem = &(AggGeom.SphereElems[i]); SphereElem->Center *= ScaleMultiplier3D; SphereElem->Radius *= ScaleMultiplier; } for (int32 i = 0; i < AggGeom.BoxElems.Num(); i++) { FKBoxElem* BoxElem = &(AggGeom.BoxElems[i]); BoxElem->Center *= ScaleMultiplier3D; BoxElem->X *= ScaleMultiplier3D.X; BoxElem->Y *= ScaleMultiplier3D.Y; BoxElem->Z *= ScaleMultiplier3D.Z; } for (int32 i = 0; i < AggGeom.SphylElems.Num(); i++) { FKSphylElem* SphylElem = &(AggGeom.SphylElems[i]); SphylElem->Center *= ScaleMultiplier3D; SphylElem->Radius *= ScaleMultiplier; SphylElem->Length *= ScaleMultiplier; } BuildScale3D = BuildScale; } }
void ANimModCharacter::OnEndCrouch(float HalfHeightAdjust, float ScaledHalfHeightAdjust) { Super::OnEndCrouch(HalfHeightAdjust, ScaledHalfHeightAdjust); FTransform currentTransform = Mesh1P->GetRelativeTransform(); FVector origin = currentTransform.GetLocation(); origin.Z += (DefaultBaseEyeHeight - CrouchedEyeHeight);// HalfHeightAdjust; //This is different than the one passed in in OnStartCrouch... FRotator rotation = currentTransform.GetRotation().Rotator(); Mesh1P->SetRelativeLocationAndRotation(origin, rotation, false, nullptr, ETeleportType::TeleportPhysics); }
PxTransform U2PTransform(const FTransform& UTransform) { PxQuat PQuat = U2PQuat(UTransform.GetRotation()); PxVec3 PPos = U2PVector(UTransform.GetLocation()); PxTransform Result(PPos, PQuat); return Result; }
void UTerrainZoneComponent::SerializeInstancedMeshes(FBufferArchive& BinaryData) { int32 MeshCount = InstancedMeshMap.Num(); BinaryData << MeshCount; for (auto& Elem : InstancedMeshMap) { UHierarchicalInstancedStaticMeshComponent* InstancedStaticMeshComponent = Elem.Value; int32 MeshTypeId = Elem.Key; int32 MeshInstanceCount = InstancedStaticMeshComponent->GetInstanceCount(); BinaryData << MeshTypeId; BinaryData << MeshInstanceCount; for (int32 InstanceIdx = 0; InstanceIdx < MeshInstanceCount; InstanceIdx++) { FTransform InstanceTransform; InstancedStaticMeshComponent->GetInstanceTransform(InstanceIdx, InstanceTransform, true); float X = InstanceTransform.GetLocation().X; float Y = InstanceTransform.GetLocation().Y; float Z = InstanceTransform.GetLocation().Z; float Roll = InstanceTransform.Rotator().Roll; float Pitch = InstanceTransform.Rotator().Pitch; float Yaw = InstanceTransform.Rotator().Yaw; float ScaleX = InstanceTransform.GetScale3D().X; float ScaleY = InstanceTransform.GetScale3D().Y; float ScaleZ = InstanceTransform.GetScale3D().Z; BinaryData << X; BinaryData << Y; BinaryData << Z; BinaryData << Roll; BinaryData << Pitch; BinaryData << Yaw; BinaryData << ScaleX; BinaryData << ScaleY; BinaryData << ScaleZ; } } }
void ANimModCharacter::OnStartCrouch(float HalfHeightAdjust, float ScaledHalfHeightAdjust) { Super::OnStartCrouch(HalfHeightAdjust, ScaledHalfHeightAdjust); //FVector origin = Mesh1P->ComponentToWorld.GetLocation(); FTransform currentTransform = Mesh1P->GetRelativeTransform(); FVector origin = currentTransform.GetLocation(); origin.Z -= (DefaultBaseEyeHeight - CrouchedEyeHeight);// HalfHeightAdjust; FRotator rotation = currentTransform.GetRotation().Rotator(); Mesh1P->SetRelativeLocationAndRotation(origin, rotation, false, nullptr, ETeleportType::TeleportPhysics); }
void UGridMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); if (Moving) { /* Find the next location */ Distance = FMath::Min(Spline->GetSplineLength(), Distance + (MaxSpeed * DeltaTime)); /* Grab our current transform so we can find the velocity if we need it later */ AActor *Owner = GetOwner(); FTransform OldTransform = Owner->GetTransform(); /* Find the next loaction from the spline*/ FTransform NewTransform = Spline->GetTransformAtDistanceAlongSpline(Distance, ESplineCoordinateSpace::Local); /* Restrain rotation axis */ FRotator Rotation = NewTransform.Rotator(); Rotation.Roll = LockRoll ? 0 : Rotation.Roll; Rotation.Pitch = LockPitch ? 0 : Rotation.Pitch; Rotation.Yaw = LockYaw ? 0 : Rotation.Yaw; NewTransform.SetRotation(Rotation.Quaternion()); Owner->SetActorTransform(NewTransform); /* Check if we're reached our destination*/ if (Distance >= Spline->GetSplineLength()) { Moving = false; Distance = 0; Velocity = FVector::ZeroVector; OnMovementEndEvent.Broadcast(); } else { Velocity = (NewTransform.GetLocation() - OldTransform.GetLocation()) * (1 / DeltaTime); } // update velocity so it can be fetched by the pawn UpdateComponentVelocity(); } }
// NB: ElemTM is assumed to have no scaling in it! void FKSphereElem::DrawElemWire(FPrimitiveDrawInterface* PDI, const FTransform& ElemTM, float Scale, const FColor Color) { FVector ElemCenter = ElemTM.GetLocation(); FVector X = ElemTM.GetScaledAxis( EAxis::X ); FVector Y = ElemTM.GetScaledAxis( EAxis::Y ); FVector Z = ElemTM.GetScaledAxis( EAxis::Z ); DrawCircle(PDI,ElemCenter, X, Y, Color, Scale*Radius, DrawCollisionSides, SDPG_World); DrawCircle(PDI,ElemCenter, X, Z, Color, Scale*Radius, DrawCollisionSides, SDPG_World); DrawCircle(PDI,ElemCenter, Y, Z, Color, Scale*Radius, DrawCollisionSides, SDPG_World); }
void FAnimNode_Mirror::MirrorPose(FTransform& InPose, const uint8 InMirrorAxis, const uint8 InPosFowdMirror) { FVector lMirroredLoc = InPose.GetLocation(); if (InPosFowdMirror == 1) { lMirroredLoc.X = -lMirroredLoc.X; } else { if (InPosFowdMirror == 2) { lMirroredLoc.Y = -lMirroredLoc.Y; } else { if (InPosFowdMirror == 3) { lMirroredLoc.Z = -lMirroredLoc.Z; } } } InPose.SetLocation(lMirroredLoc); switch (InMirrorAxis) { case 1: { float lY = -InPose.GetRotation().Y; float lZ = -InPose.GetRotation().Z; InPose.SetRotation(FQuat(InPose.GetRotation().X, lY, lZ, InPose.GetRotation().W)); break; } case 2: { float lX = -InPose.GetRotation().X; float lZ = -InPose.GetRotation().Z; InPose.SetRotation(FQuat(lX, InPose.GetRotation().Y, lZ, InPose.GetRotation().W)); break; } case 3: { float lX = -InPose.GetRotation().X; float lY = -InPose.GetRotation().Y; InPose.SetRotation(FQuat(lX, lY, InPose.GetRotation().Z, InPose.GetRotation().W)); break; } } };
void FAnimNode_LookAt::EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, const FBoneContainer& RequiredBones, FA2CSPose& MeshBases, TArray<FBoneTransform>& OutBoneTransforms) { check(OutBoneTransforms.Num() == 0); FTransform ComponentBoneTransform = MeshBases.GetComponentSpaceTransform(BoneToModify.BoneIndex); // get target location FVector TargetLocationInComponentSpace; if (LookAtBone.IsValid(RequiredBones)) { FTransform LookAtTransform = MeshBases.GetComponentSpaceTransform(LookAtBone.BoneIndex); TargetLocationInComponentSpace = LookAtTransform.GetLocation(); } else { TargetLocationInComponentSpace = SkelComp->ComponentToWorld.InverseTransformPosition(LookAtLocation); } CurrentLookAtLocation = TargetLocationInComponentSpace; // lookat vector FVector LookAtVector = GetAlignVector(ComponentBoneTransform, LookAtAxis); // flip to target vector if it wasnt negative bool bShouldFlip = LookAtAxis == EAxisOption::X_Neg || LookAtAxis == EAxisOption::Y_Neg || LookAtAxis == EAxisOption::Z_Neg; FVector ToTarget = CurrentLookAtLocation - ComponentBoneTransform.GetLocation(); ToTarget.Normalize(); if (bShouldFlip) { ToTarget *= -1.f; } // get delta rotation FQuat DeltaRot = FQuat::FindBetween(LookAtVector, ToTarget); // transform current rotation to delta rotation FQuat CurrentRot = ComponentBoneTransform.GetRotation(); FQuat NewRotation = DeltaRot * CurrentRot; ComponentBoneTransform.SetRotation(NewRotation); OutBoneTransforms.Add( FBoneTransform(BoneToModify.BoneIndex, ComponentBoneTransform) ); }
FTransform ATLSkillsTreeCharacter::GetFixedSpringArmTransform(USpringArmComponent* SpringArm) { FTransform result; if (SpringArm) { result = SpringArm->GetComponentTransform(); //We want a fixed location for our transform, since we don't want to spawn our skills //right on top of our character. result.SetLocation(result.GetLocation() + SpringArm->GetForwardVector() * 100); } return result; }
/** 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; }
void FPhysScene::SyncComponentsToBodies(uint32 SceneType) { #if WITH_PHYSX PxScene* PScene = GetPhysXScene(SceneType); check(PScene); SCENE_LOCK_READ(PScene); PxU32 NumTransforms = 0; const PxActiveTransform* PActiveTransforms = PScene->getActiveTransforms(NumTransforms); SCENE_UNLOCK_READ(PScene); for(PxU32 TransformIdx=0; TransformIdx<NumTransforms; TransformIdx++) { const PxActiveTransform& PActiveTransform = PActiveTransforms[TransformIdx]; FBodyInstance* BodyInst = FPhysxUserData::Get<FBodyInstance>(PActiveTransform.userData); if( BodyInst != NULL && BodyInst->InstanceBodyIndex == INDEX_NONE && BodyInst->OwnerComponent != NULL && BodyInst->IsInstanceSimulatingPhysics() ) { check(BodyInst->OwnerComponent->IsRegistered()); // shouldn't have a physics body for a non-registered component! AActor* Owner = BodyInst->OwnerComponent->GetOwner(); // See if the transform is actually different, and if so, move the component to match physics const FTransform NewTransform = BodyInst->GetUnrealWorldTransform(); if(!NewTransform.EqualsNoScale(BodyInst->OwnerComponent->ComponentToWorld)) { const FVector MoveBy = NewTransform.GetLocation() - BodyInst->OwnerComponent->ComponentToWorld.GetLocation(); const FRotator NewRotation = NewTransform.Rotator(); //UE_LOG(LogTemp, Log, TEXT("MOVING: %s"), *BodyInst->OwnerComponent->GetPathName()); //@warning: do not reference BodyInstance again after calling MoveComponent() - events from the move could have made it unusable (destroying the actor, SetPhysics(), etc) BodyInst->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(); } } } #endif }
void FBodyInstance2D::SetBodyTransform(const FTransform& NewTransform) { #if WITH_BOX2D if (BodyInstancePtr != NULL) { const FVector NewLocation = NewTransform.GetLocation(); const b2Vec2 NewLocation2D(FPhysicsIntegration2D::ConvertUnrealVectorToBox(NewLocation)); //@TODO: What about scale? const FRotator NewRotation3D(NewTransform.GetRotation()); const float NewAngle = FMath::DegreesToRadians(NewRotation3D.Pitch); BodyInstancePtr->SetTransform(NewLocation2D, NewAngle); } #endif }
FVector FObserveBoneEditMode::GetWidgetLocation() const { USkeletalMeshComponent* SkelComp = GetAnimPreviewScene().GetPreviewMeshComponent(); USkeleton* Skeleton = SkelComp->SkeletalMesh->Skeleton; FVector WidgetLoc = FVector::ZeroVector; int32 MeshBoneIndex = SkelComp->GetBoneIndex(GraphNode->Node.BoneToObserve.BoneName); if (MeshBoneIndex != INDEX_NONE) { const FTransform BoneTM = SkelComp->GetBoneTransform(MeshBoneIndex); WidgetLoc = BoneTM.GetLocation(); } return WidgetLoc; }
/** * Render bones for debug display */ void USkeletalMeshComponent::DebugDrawBones(UCanvas* Canvas, bool bSimpleBones) const { if (GetWorld()->IsGameWorld() && SkeletalMesh && Canvas) { // draw spacebases, we could cache parent bones, but this is mostly debug feature, I'm not caching it right now for ( int32 Index=0; Index<RequiredBones.Num(); ++Index ) { int32 BoneIndex = RequiredBones[Index]; int32 ParentIndex = SkeletalMesh->RefSkeleton.GetParentIndex(BoneIndex); FTransform BoneTM = (SpaceBases[BoneIndex] * ComponentToWorld); FVector Start, End; FLinearColor LineColor; End = BoneTM.GetLocation(); if (ParentIndex >=0) { Start = (SpaceBases[ParentIndex] * ComponentToWorld).GetLocation(); LineColor = FLinearColor::White; } else { Start = ComponentToWorld.GetLocation(); LineColor = FLinearColor::Red; } if(bSimpleBones) { DrawDebugCanvasLine(Canvas, Start, End, LineColor); } else { static const float SphereRadius = 1.0f; //Calc cone size FVector EndToStart = (Start-End); float ConeLength = EndToStart.Size(); float Angle = FMath::RadiansToDegrees(FMath::Atan(SphereRadius / ConeLength)); DrawDebugCanvasWireSphere(Canvas, End, LineColor, SphereRadius, 10); DrawDebugCanvasWireCone(Canvas, FTransform(FRotationMatrix::MakeFromX(EndToStart)*FTranslationMatrix(End)), ConeLength, Angle, 4, LineColor); } RenderAxisGizmo(BoneTM, Canvas); } } }
void DrawDebugCanvasWireCone(UCanvas* Canvas, const FTransform& Transform, float ConeRadius, float ConeAngle, int32 ConeSides, FColor Color) { static const float TwoPI = 2.0f * PI; static const float ToRads = PI / 180.0f; static const float MaxAngle = 89.0f * ToRads + 0.001f; const float ClampedConeAngle = FMath::Clamp(ConeAngle * ToRads, 0.001f, MaxAngle); const float SinClampedConeAngle = FMath::Sin( ClampedConeAngle ); const float CosClampedConeAngle = FMath::Cos( ClampedConeAngle ); const FVector ConeDirection(1,0,0); const FVector ConeUpVector(0,1,0); const FVector ConeLeftVector(0,0,1); TArray<FVector> Verts; Verts.AddUninitialized( ConeSides ); for ( int32 i = 0 ; i < Verts.Num() ; ++i ) { const float Theta = static_cast<float>( (TwoPI * i) / Verts.Num() ); Verts[i] = (ConeDirection * (ConeRadius * CosClampedConeAngle)) + ((SinClampedConeAngle * ConeRadius * FMath::Cos( Theta )) * ConeUpVector) + ((SinClampedConeAngle * ConeRadius * FMath::Sin( Theta )) * ConeLeftVector); } // Transform to world space. for ( int32 i = 0 ; i < Verts.Num() ; ++i ) { Verts[i] = Transform.TransformPosition( Verts[i] ); } // Draw spokes. for ( int32 i = 0 ; i < Verts.Num(); ++i ) { DrawDebugCanvasLine( Canvas, Transform.GetLocation(), Verts[i], Color ); } // Draw rim. for ( int32 i = 0 ; i < Verts.Num()-1 ; ++i ) { DrawDebugCanvasLine( Canvas, Verts[i], Verts[i+1], Color ); } DrawDebugCanvasLine( Canvas, Verts[Verts.Num()-1], Verts[0], Color ); }
FVector FStaticMeshEditorViewportClient::GetWidgetLocation() const { const UStaticMeshSocket* SelectedSocket = StaticMeshEditorPtr.Pin()->GetSelectedSocket(); if( SelectedSocket ) { FMatrix SocketTM; SelectedSocket->GetSocketMatrix(SocketTM, StaticMeshComponent); return SocketTM.GetOrigin(); } FTransform PrimTransform = FTransform::Identity; const bool bSelectedPrim = StaticMeshEditorPtr.Pin()->GetLastSelectedPrimTransform(PrimTransform); if (bSelectedPrim) { return PrimTransform.GetLocation(); } return FVector::ZeroVector; }
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 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() ); } }