bool FInstancedStaticMeshSCSEditorCustomization::HandleGetWidgetLocation(class USceneComponent* InSceneComponent, FVector& OutWidgetLocation) { // location is average of selected instances float SelectedInstanceCount = 0.0f; FVector AverageLocation = FVector::ZeroVector; UInstancedStaticMeshComponent* InstancedStaticMeshComponent = CastChecked<UInstancedStaticMeshComponent>(InSceneComponent); // Ensure that selected instances are up-to-date ValidateSelectedInstances(InstancedStaticMeshComponent); for (int32 InstanceIndex = 0; InstanceIndex < InstancedStaticMeshComponent->SelectedInstances.Num(); InstanceIndex++) { if (InstancedStaticMeshComponent->SelectedInstances[InstanceIndex]) { AverageLocation += InstancedStaticMeshComponent->GetComponentToWorld().TransformPosition(InstancedStaticMeshComponent->PerInstanceSMData[InstanceIndex].Transform.GetOrigin()); SelectedInstanceCount += 1.0f; } } if (SelectedInstanceCount > 0.0f) { OutWidgetLocation = AverageLocation / SelectedInstanceCount; return true; } return false; }
bool FInstancedStaticMeshSCSEditorCustomization::HandleViewportDrag(class USceneComponent* InSceneComponent, class USceneComponent* InComponentTemplate, const FVector& InDeltaTranslation, const FRotator& InDeltaRotation, const FVector& InDeltaScale, const FVector& InPivot) { check(InSceneComponent->IsA(UInstancedStaticMeshComponent::StaticClass())); UInstancedStaticMeshComponent* InstancedStaticMeshComponentScene = CastChecked<UInstancedStaticMeshComponent>(InSceneComponent); UInstancedStaticMeshComponent* InstancedStaticMeshComponentTemplate = CastChecked<UInstancedStaticMeshComponent>(InComponentTemplate); // transform pivot into component's space const FVector LocalPivot = InstancedStaticMeshComponentScene->GetComponentToWorld().InverseTransformPosition(InPivot); // Ensure that selected instances are up-to-date ValidateSelectedInstances(InstancedStaticMeshComponentScene); bool bMovedInstance = false; check(InstancedStaticMeshComponentScene->SelectedInstances.Num() == InstancedStaticMeshComponentScene->PerInstanceSMData.Num()); for(int32 InstanceIndex = 0; InstanceIndex < InstancedStaticMeshComponentScene->SelectedInstances.Num(); InstanceIndex++) { if (InstancedStaticMeshComponentScene->SelectedInstances[InstanceIndex] && InstancedStaticMeshComponentTemplate->PerInstanceSMData.IsValidIndex(InstanceIndex)) { FMatrix& MatrixScene = InstancedStaticMeshComponentScene->PerInstanceSMData[InstanceIndex].Transform; FMatrix& MatrixTemplate = InstancedStaticMeshComponentTemplate->PerInstanceSMData[InstanceIndex].Transform; FVector Translation = MatrixScene.GetOrigin(); FRotator Rotation = MatrixScene.Rotator(); FVector Scale = MatrixScene.GetScaleVector(); FVector NewTranslation = Translation; FRotator NewRotation = Rotation; FVector NewScale = Scale; if( !InDeltaRotation.IsZero() ) { NewRotation = FRotator( InDeltaRotation.Quaternion() * Rotation.Quaternion() ); NewTranslation -= LocalPivot; NewTranslation = FRotationMatrix( InDeltaRotation ).TransformPosition( NewTranslation ); NewTranslation += LocalPivot; } NewTranslation += InDeltaTranslation; if( !InDeltaScale.IsNearlyZero() ) { const FScaleMatrix ScaleMatrix( InDeltaScale ); FVector DeltaScale3D = ScaleMatrix.TransformPosition( Scale ); NewScale = Scale + DeltaScale3D; NewTranslation -= LocalPivot; NewTranslation += ScaleMatrix.TransformPosition( NewTranslation ); NewTranslation += LocalPivot; } MatrixScene = FScaleRotationTranslationMatrix(NewScale, NewRotation, NewTranslation); MatrixTemplate = FScaleRotationTranslationMatrix(NewScale, NewRotation, NewTranslation); bMovedInstance = true; } } return bMovedInstance; }