/// <inheritdoc /> protected override void OnApplyTransformation(ref Vector3 translationDelta, ref Quaternion rotationDelta, ref Vector3 scaleDelta) { base.OnApplyTransformation(ref translationDelta, ref rotationDelta, ref scaleDelta); bool applyRotation = !rotationDelta.IsIdentity; bool useObjCenter = ActivePivot == PivotType.ObjectCenter; Vector3 gizmoPosition = Position; // Get instance transform var foliage = GizmoMode.SelectedFoliage; if (!foliage) { throw new InvalidOperationException("No foliage selected."); } var instanceIndex = GizmoMode.SelectedInstanceIndex; if (instanceIndex < 0 || instanceIndex >= foliage.InstancesCount) { throw new InvalidOperationException("No foliage instance selected."); } var instance = foliage.GetInstance(instanceIndex); var trans = foliage.Transform.LocalToWorld(instance.Transform); // Apply rotation if (applyRotation) { Vector3 pivotOffset = trans.Translation - gizmoPosition; if (useObjCenter || pivotOffset.IsZero) { trans.Orientation *= Quaternion.Invert(trans.Orientation) * rotationDelta * trans.Orientation; } else { Matrix.RotationQuaternion(ref trans.Orientation, out var transWorld); Matrix.RotationQuaternion(ref rotationDelta, out var deltaWorld); Matrix world = transWorld * Matrix.Translation(pivotOffset) * deltaWorld * Matrix.Translation(-pivotOffset); trans.SetRotation(ref world); trans.Translation += world.TranslationVector; } } // Apply scale const float scaleLimit = 99_999_999.0f; trans.Scale = Float3.Clamp(trans.Scale + scaleDelta, new Float3(-scaleLimit), new Float3(scaleLimit)); // Apply translation trans.Translation += translationDelta; // Transform foliage instance instance.Transform = foliage.Transform.WorldToLocal(trans); foliage.SetInstanceTransform(instanceIndex, ref instance.Transform); foliage.RebuildClusters(); }
/// <summary> /// Applies the transform to the collection of scene graph nodes. /// </summary> /// <param name="selection">The selection.</param> /// <param name="translationDelta">The translation delta.</param> /// <param name="rotationDelta">The rotation delta.</param> /// <param name="scaleDelta">The scale delta.</param> public void ApplyTransform(List <SceneGraphNode> selection, ref Vector3 translationDelta, ref Quaternion rotationDelta, ref Vector3 scaleDelta) { bool applyRotation = !rotationDelta.IsIdentity; bool useObjCenter = TransformGizmo.ActivePivot == TransformGizmoBase.PivotType.ObjectCenter; Vector3 gizmoPosition = TransformGizmo.Position; // Transform selected objects for (int i = 0; i < selection.Count; i++) { var obj = selection[i]; var trans = obj.Transform; // Apply rotation if (applyRotation) { Vector3 pivotOffset = trans.Translation - gizmoPosition; if (useObjCenter || pivotOffset.IsZero) { //trans.Orientation *= rotationDelta; trans.Orientation *= Quaternion.Invert(trans.Orientation) * rotationDelta * trans.Orientation; } else { Matrix.RotationQuaternion(ref trans.Orientation, out var transWorld); Matrix.RotationQuaternion(ref rotationDelta, out var deltaWorld); Matrix world = transWorld * Matrix.Translation(pivotOffset) * deltaWorld * Matrix.Translation(-pivotOffset); trans.SetRotation(ref world); trans.Translation += world.TranslationVector; } } // Apply scale const float scaleLimit = 99_999_999.0f; trans.Scale = Float3.Clamp(trans.Scale + scaleDelta, new Float3(-scaleLimit), new Float3(scaleLimit)); // Apply translation trans.Translation += translationDelta; obj.Transform = trans; } }