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)); } }
bool UPrimitiveComponent::WeldToImplementation(USceneComponent * InParent, FName ParentSocketName /* = Name_None */, bool bWeldSimulatedChild /* = false */) { //WeldToInternal assumes attachment is already done if (AttachParent != InParent || AttachSocketName != ParentSocketName) { return false; } //Check that we can actually our own socket name FBodyInstance* BI = GetBodyInstance(NAME_None, false); if (BI == NULL) { return false; } if (BI->ShouldInstanceSimulatingPhysics() && bWeldSimulatedChild == false) { return false; } UnWeldFromParent(); //make sure to unweld from wherever we currently are FName SocketName; UPrimitiveComponent * RootComponent = GetRootWelded(this, ParentSocketName, &SocketName, true); if (RootComponent) { if (FBodyInstance* RootBI = RootComponent->GetBodyInstance(SocketName, false)) { if (BI->WeldParent == RootBI) //already welded so stop { return true; } BI->bWelded = true; //There are multiple cases to handle: //Root is kinematic, simulated //Child is kinematic, simulated //Child always inherits from root //if root is kinematic simply set child to be kinematic and we're done if (RootComponent->IsSimulatingPhysics(SocketName) == false) { BI->WeldParent = NULL; SetSimulatePhysics(false); return false; //return false because we need to continue with regular body initialization } //root is simulated so we actually weld the body FTransform RelativeTM = RootComponent == AttachParent ? GetRelativeTransform() : GetComponentToWorld().GetRelativeTransform(RootComponent->GetComponentToWorld()); //if direct parent we already have relative. Otherwise compute it RootBI->Weld(BI, GetComponentToWorld()); BI->WeldParent = RootBI; return true; } } return false; }
void UPoseableMeshComponent::SetBoneTransformByName(FName BoneName, const FTransform& InTransform, EBoneSpaces::Type BoneSpace) { if( !SkeletalMesh || !RequiredBones.IsValid() ) { return; } int32 BoneIndex = GetBoneIndex(BoneName); if(BoneIndex >=0 && BoneIndex < LocalAtoms.Num()) { LocalAtoms[BoneIndex] = InTransform; // If we haven't requested local space we need to transform the position passed in //if(BoneSpace != EBoneSpaces::LocalSpace) { if(BoneSpace == EBoneSpaces::WorldSpace) { LocalAtoms[BoneIndex].SetToRelativeTransform(GetComponentToWorld()); } int32 ParentIndex = RequiredBones.GetParentBoneIndex(BoneIndex); if(ParentIndex >=0) { FA2CSPose CSPose; CSPose.AllocateLocalPoses(RequiredBones, LocalAtoms); LocalAtoms[BoneIndex].SetToRelativeTransform(CSPose.GetComponentSpaceTransform(ParentIndex)); } // Need to send new state to render thread MarkRenderDynamicDataDirty(); } } }
void UCreatureMeshComponent::DoCreatureMeshUpdate(int render_packet_idx) { SCOPE_CYCLE_COUNTER(STAT_CreatureMesh_MeshUpdate); FCProceduralMeshSceneProxy *localRenderProxy = GetLocalRenderProxy(); if (localRenderProxy) { localRenderProxy->SetNeedsIndexUpdate(creature_core.should_update_render_indices); } // 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)); } }
FTransform UCreatureMeshComponent::GetBluePrintBoneXform(FString name_in, bool world_transform, float position_slide_factor) { return creature_core.GetBluePrintBoneXform(name_in, world_transform, position_slide_factor, GetComponentToWorld()); }
void UPrimitiveComponent::UnWeldFromParent() { FBodyInstance* NewRootBI = GetBodyInstance(NAME_None, false); UWorld* CurrentWorld = GetWorld(); if (NewRootBI == NULL || NewRootBI->bWelded == false || CurrentWorld == nullptr || IsPendingKill()) { return; } FName SocketName; UPrimitiveComponent * RootComponent = GetRootWelded(this, AttachSocketName, &SocketName); if (RootComponent) { if (FBodyInstance* RootBI = RootComponent->GetBodyInstance(SocketName, false)) { bool bRootIsBeingDeleted = RootComponent->HasAnyFlags(RF_PendingKill) || RootComponent->HasAnyFlags(RF_Unreachable); if (!bRootIsBeingDeleted) { //create new root RootBI->UnWeld(NewRootBI); //don't bother fixing up shapes if RootComponent is about to be deleted } NewRootBI->bWelded = false; const FBodyInstance* PrevWeldParent = NewRootBI->WeldParent; NewRootBI->WeldParent = nullptr; bool bHasBodySetup = GetBodySetup() != nullptr; //if BodyInstance hasn't already been created we need to initialize it if (bHasBodySetup && NewRootBI->IsValidBodyInstance() == false) { bool bPrevAutoWeld = NewRootBI->bAutoWeld; NewRootBI->bAutoWeld = false; NewRootBI->InitBody(GetBodySetup(), GetComponentToWorld(), this, CurrentWorld->GetPhysicsScene()); NewRootBI->bAutoWeld = bPrevAutoWeld; } if(PrevWeldParent == nullptr) //our parent is kinematic so no need to do any unwelding/rewelding of children { return; } //now weld its children to it TArray<FBodyInstance*> ChildrenBodies; TArray<FName> ChildrenLabels; GetWeldedBodies(ChildrenBodies, ChildrenLabels); for (int32 ChildIdx = 0; ChildIdx < ChildrenBodies.Num(); ++ChildIdx) { FBodyInstance* ChildBI = ChildrenBodies[ChildIdx]; if (ChildBI != NewRootBI) { if (!bRootIsBeingDeleted) { RootBI->UnWeld(ChildBI); } //At this point, NewRootBI must be kinematic because it's being unwelded. It's up to the code that simulates to call Weld on the children as needed ChildBI->WeldParent = nullptr; //null because we are currently kinematic } } } } }