public void UpdatePositions()
        {
            // If we're snapping, match relative thickness scaling with root
            //SetThicknessScalingTypeToRoot();

            Tip.localScale  = tipScale;
            Root.localScale = rootScale;

            Tip.localPosition = tipPosition + TipSpawnOffset;

            if (IsAttached &&
                part.parent != null &&
                part.parent.Modules.Contains <WingManipulator>() &&
                !IgnoreSnapping &&
                !doNotParticipateInParentSnapping)
            {
                WingManipulator Parent = part.parent.Modules.GetModule <WingManipulator>();
                part.transform.position = Parent.Tip.position + 0.1f * Parent.Tip.right; // set the new part inward just a little bit
                rootScale = Parent.tipScale;
            }

            if (symmetricMovement == false)
            {
                tipPosition.y = Root.localPosition.y;
            }
            else
            {
                tipPosition.y  = 0f;
                tipPosition.x  = 0f;
                rootPosition.x = 0f;
                rootPosition.y = 0f;

                Root.localPosition = -(tipPosition + TipSpawnOffset);
            }
        }
        // Gather the Cl of all our children for connection strength calculations.
        public void GatherChildrenCl()
        {
            ChildrenCl = 0;

            // Add up the Cl and ChildrenCl of all our children to our ChildrenCl
            foreach (Part p in part.children)
            {
                WingManipulator child = p.Modules.GetModule <WingManipulator>();
                if (child != null)
                {
                    ChildrenCl += child.Cl;
                    ChildrenCl += child.ChildrenCl;
                }
            }

            // If parent is a pWing, trickle the call to gather ChildrenCl down to them.
            if (part.parent != null)
            {
                WingManipulator Parent = part.parent.Modules.GetModule <WingManipulator>();
                if (Parent != null)
                {
                    Parent.GatherChildrenCl();
                }
            }
        }
        // Updates child pWings
        public void UpdateChildren()
        {
            // Get the list of child parts
            foreach (Part p in part.children)
            {
                // Check that it is a pWing and that it is affected by parent snapping
                WingManipulator wing = p.Modules.GetModule <WingManipulator>();
                if (wing != null && !wing.IgnoreSnapping && !wing.doNotParticipateInParentSnapping)
                {
                    // Update its positions and refresh the collider
                    wing.UpdatePositions();
                    wing.SetupCollider();

                    // If its a wing, refresh its aerodynamic values
                    wing.CalculateAerodynamicValues();
                }
            }
        }
        protected bool triggerUpdate = false; // if this is true, an update will be done and it set false.
        // this will set the triggerUpdate field true on all wings on the vessel.
        public void TriggerUpdateAllWings()
        {
            var plist = new List <Part>();

            if (HighLogic.LoadedSceneIsEditor)
            {
                plist = EditorLogic.SortedShipList;
            }
            else
            {
                plist = part.vessel.Parts;
            }

            foreach (Part p in plist)
            {
                WingManipulator wing = p.Modules.GetModule <WingManipulator>();
                if (wing != null)
                {
                    wing.triggerUpdate = true;
                }
            }
        }
        public void MatchTaperEvent()
        {
            // Check for a valid parent
            // Get parents taper
            WingManipulator parentWing = part.parent.Modules.GetModule <WingManipulator>();

            if (parentWing == null)
            {
                return;
            }

            Vector3 changeTipScale = (float)(b_2 / parentWing.b_2) * (parentWing.tipScale - parentWing.rootScale);

            // Scale the tip
            tipScale.Set(
                Mathf.Max(rootScale.x + changeTipScale.x, 0.01f),
                Mathf.Max(rootScale.y + changeTipScale.y, 0.01f),
                Mathf.Max(rootScale.z + changeTipScale.z, 0.01f));

            // Update part and children
            UpdateAllCopies(true);
        }
        public void UpdateAllCopies(bool childrenNeedUpdate)
        {
            UpdatePositions();
            SetupCollider();

            if (updateChildren && childrenNeedUpdate)
            {
                UpdateChildren();
            }

            CalculateAerodynamicValues();

            foreach (Part p in part.symmetryCounterparts)
            {
                if (p == null)
                {
                    continue;
                }
                WingManipulator clone = p.Modules.GetModule <WingManipulator>();

                clone.rootScale   = rootScale;
                clone.tipScale    = tipScale;
                clone.tipPosition = tipPosition;

                clone.relativeThicknessScaling = relativeThicknessScaling;
                //clone.SetThicknessScalingEventName();

                clone.UpdatePositions();
                clone.SetupCollider();

                if (updateChildren && childrenNeedUpdate)
                {
                    clone.UpdateChildren();
                }

                clone.CalculateAerodynamicValues();
            }
        }
        /// <summary>
        /// set resources in this tank and all symmetry counterparts
        /// </summary>
        private void FuelTankTypeChanged()
        {
            FuelSetResources();
            foreach (Part p in part.symmetryCounterparts)
            {
                if (p == null) // fixes nullref caused by removing mirror sym while hovering over attach location
                {
                    continue;
                }

                WingManipulator wing = p.Modules.GetModule <WingManipulator>();
                if (wing != null)
                {
                    wing.fuelSelectedTankSetup = fuelSelectedTankSetup;
                    wing.FuelSetResources();
                }
            }

            UpdateWindow();
            if (HighLogic.LoadedSceneIsEditor)
            {
                GameEvents.onEditorShipModified.Fire(EditorLogic.fetch.ship);
            }
        }