/// <summary>
        /// Update and get current weights of the weapon variants.
        /// </summary>
        /// <returns>Weights. Normalized.</returns>
        Vector4D UpdateAndGetWeaponVariantWeights(MyHandItemDefinition handItemDefinition)
        {
            float characterSpeed;
            Character.AnimationController.Variables.GetValue(MyAnimationVariableStorageHints.StrIdSpeed, out characterSpeed);
            bool isWalkingState = MyCharacter.IsRunningState(Character.GetCurrentMovementState()) && characterSpeed > Character.Definition.MaxWalkSpeed;
            bool isShooting = Character.IsShooting(MyShootActionEnum.PrimaryAction) && (!Character.IsSprinting);
            bool isInIronSight = Character.ZoomMode == MyZoomModeEnum.IronSight && (!Character.IsSprinting);

            float deltaW = MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS / handItemDefinition.BlendTime;
            float deltaShootW = MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS / handItemDefinition.ShootBlend;
            // blend into the current variant
            // if currently shooting/ironsight -> use "shooting" blend speed
            m_weaponPositionVariantWeightCounters.X += !isWalkingState && !isShooting && !isInIronSight ? deltaW : (isShooting || isInIronSight ? -deltaShootW : -deltaW);
            m_weaponPositionVariantWeightCounters.Y += isWalkingState && !isShooting && !isInIronSight ? deltaW : (isShooting || isInIronSight ? -deltaShootW : -deltaW);
            m_weaponPositionVariantWeightCounters.Z += isShooting && !isInIronSight ? deltaShootW : (isInIronSight ? -deltaShootW : -deltaW);
            m_weaponPositionVariantWeightCounters.W += isInIronSight ? deltaShootW : (isShooting ? -deltaShootW : -deltaW);
            m_weaponPositionVariantWeightCounters = Vector4.Clamp(m_weaponPositionVariantWeightCounters, Vector4.Zero, Vector4.One);

            Vector4D rtnWeights = new Vector4D(MathHelper.SmoothStep(0, 1, m_weaponPositionVariantWeightCounters.X),
                MathHelper.SmoothStep(0, 1, m_weaponPositionVariantWeightCounters.Y),
                MathHelper.SmoothStep(0, 1, m_weaponPositionVariantWeightCounters.Z),
                MathHelper.SmoothStep(0, 1, m_weaponPositionVariantWeightCounters.W));

            double weightSum = rtnWeights.X + rtnWeights.Y + rtnWeights.Z + rtnWeights.W;
            return rtnWeights / weightSum;
        }
        private void EquipWeapon(IMyHandheldGunObject<MyDeviceBase> newWeapon, bool showNotification = false)
        {
          //  Debug.Assert(newWeapon != null);
            if (newWeapon == null)
                return;

            MyEntity gunEntity = (MyEntity)newWeapon;
            gunEntity.Render.CastShadows = true;
            gunEntity.Render.NeedsResolveCastShadow = false;
            gunEntity.Save = false;
            gunEntity.OnClose += gunEntity_OnClose;

            MyEntities.Add(gunEntity);

            m_handItemDefinition = null;
            m_currentWeapon = newWeapon;
            m_currentWeapon.OnControlAcquired(this);

            UseAnimationForWeapon |= m_currentWeapon.ForceAnimationInsteadOfIK;

            if (WeaponEquiped != null)
                WeaponEquiped(m_currentWeapon);

            MyAnalyticsHelper.ReportActivityStart(this, "item_equip", "character", "toolbar_item_usage", m_currentWeapon.GetType().Name);

            // CH:TODO: The hand item definitions should be changed to handheld gun object definitions and should be taken according to m_currentWeapon typeId
            if (m_currentWeapon.PhysicalObject != null)
            {
                var handItemId = m_currentWeapon.PhysicalObject.GetId();

                m_handItemDefinition = MyDefinitionManager.Static.TryGetHandItemForPhysicalItem(handItemId);
                System.Diagnostics.Debug.Assert(m_handItemDefinition != null, "Create definition for this hand item!");
            }
            else if (m_currentWeapon.DefinitionId.TypeId == typeof(MyObjectBuilder_CubePlacer))
            {
                var gunID = new MyDefinitionId(typeof(MyObjectBuilder_CubePlacer));

                m_handItemDefinition = MyDefinitionManager.Static.TryGetHandItemDefinition(ref gunID);
                System.Diagnostics.Debug.Assert(m_handItemDefinition != null, "Create definition for this hand item!");
            }

            //Setup correct worldmatrix to weapon
            //CalculateDependentMatrices();

            if (m_handItemDefinition != null && !string.IsNullOrEmpty(m_handItemDefinition.FingersAnimation))
            {
                string animationSubtype;
                if (!m_characterDefinition.AnimationNameToSubtypeName.TryGetValue(m_handItemDefinition.FingersAnimation, out animationSubtype))
                {
                    animationSubtype = m_handItemDefinition.FingersAnimation;
                }
                var def = MyDefinitionManager.Static.TryGetAnimationDefinition(animationSubtype);
                if (!def.LeftHandItem.TypeId.IsNull)
                {
                    m_currentWeapon.OnControlReleased();
                    (m_currentWeapon as MyEntity).Close(); //no dual wielding now
                    m_currentWeapon = null;
                }

                PlayCharacterAnimation(m_handItemDefinition.FingersAnimation, MyBlendOption.Immediate, def.Loop ? MyFrameOption.Loop : MyFrameOption.PlayOnce, 1.0f, 1, false, null);
                if (UseNewAnimationSystem)
                {
                    TriggerCharacterAnimationEvent("equip_left_tool", true);
                    TriggerCharacterAnimationEvent("equip_right_tool", true);
                    TriggerCharacterAnimationEvent(m_handItemDefinition.Id.SubtypeName.ToLower(), true);
                    TriggerCharacterAnimationEvent(m_handItemDefinition.FingersAnimation.ToLower(), true);
                }

                if (!def.LeftHandItem.TypeId.IsNull)
                {
                    if (m_leftHandItem != null)
                    {
                        (m_leftHandItem as IMyHandheldGunObject<Sandbox.Game.Weapons.MyDeviceBase>).OnControlReleased();
                        m_leftHandItem.Close();
                    }

                    // CH: TODO: The entity id is not synced, but it never was in this place. It should be fixed later
                    long handItemId = MyEntityIdentifier.AllocateId();
                    uint? inventoryItemId = null;
                    var builder = GetObjectBuilderForWeapon(def.LeftHandItem, ref inventoryItemId, handItemId);
                    var leftHandItem = CreateGun(builder, inventoryItemId);

                    if (leftHandItem != null)
                    {
                        m_leftHandItem = leftHandItem as MyEntity;
                        leftHandItem.OnControlAcquired(this);
                        UpdateLeftHandItemPosition();

                        MyEntities.Add(m_leftHandItem);
                    }
                }
            }
            else if (m_handItemDefinition != null)
            {
                if (UseNewAnimationSystem)
                {
                    TriggerCharacterAnimationEvent("equip_left_tool", true);
                    TriggerCharacterAnimationEvent("equip_right_tool", true);
                    TriggerCharacterAnimationEvent(m_handItemDefinition.Id.SubtypeName.ToLower(), true);
                }
            }
            else
            {
                StopFingersAnimation(0);
            }

            var consumer = gunEntity.Components.Get<MyResourceSinkComponent>();
            if (consumer != null && SuitRechargeDistributor != null)
                SuitRechargeDistributor.AddSink(consumer);

            if (showNotification)
            {
                var notificationUse = new MyHudNotification(MySpaceTexts.NotificationUsingWeaponType, 2000);
                notificationUse.SetTextFormatArguments(MyDeviceBase.GetGunNotificationName(newWeapon.DefinitionId));
                MyHud.Notifications.Add(notificationUse);
            }

            Static_CameraAttachedToChanged(null, null);
            if (!(IsUsing is MyCockpit))
                MyHud.Crosshair.ResetToDefault(clear: false);

        }
        /// <summary>
        /// Apply bouncing movement on weapon.
        /// </summary>
        /// <param name="handItemDefinition">definition of hand item</param>
        /// <param name="weaponMatrixLocal">current weapon matrix (character local space)</param>
        private void ApplyWeaponBouncing(MyHandItemDefinition handItemDefinition, ref MatrixD weaponMatrixLocal)
        {
            if (!Character.AnimationController.CharacterBones.IsValidIndex(Character.SpineBoneIndex))
                return;

            bool isLocallyControlled = Character.ControllerInfo.IsLocallyControlled();
            bool isInFirstPerson = (Character.IsInFirstPersonView || Character.ForceFirstPersonCamera) && isLocallyControlled;

            var spineBone = Character.AnimationController.CharacterBones[Character.SpineBoneIndex];
            Vector3 spinePos = spineBone.AbsoluteTransform.Translation - Character.AnimationController.CharacterBonesSorted[0].Translation;
            m_spineRestPositionX.Add(spinePos.X);
            m_spineRestPositionY.Add(spinePos.Y);
            m_spineRestPositionZ.Add(spinePos.Z);
            Vector3 spineAbsRigPos = spineBone.GetAbsoluteRigTransform().Translation;
            Vector3 spineRestPos = new Vector3(spineAbsRigPos.X, m_spineRestPositionY.Get(), spineAbsRigPos.Z);

            Vector3 bounceOffset = (spinePos - spineRestPos);
            bounceOffset.Z = isInFirstPerson ? bounceOffset.Z : 0;
            m_sprintStatusWeight += Character.IsSprinting ? m_sprintStatusGainSpeed : -m_sprintStatusGainSpeed;
            m_sprintStatusWeight = MathHelper.Clamp(m_sprintStatusWeight, 0, 1);
            if (isInFirstPerson)
            {
                // multiply only when in first person
                bounceOffset *= 1 + Math.Max(0, handItemDefinition.RunMultiplier - 1) * m_sprintStatusWeight;
                bounceOffset.X *= handItemDefinition.XAmplitudeScale;
                bounceOffset.Y *= handItemDefinition.YAmplitudeScale;
                bounceOffset.Z *= handItemDefinition.ZAmplitudeScale;
            }

            bounceOffset.Z += m_backkickPos;

            weaponMatrixLocal.Translation += bounceOffset;
        }
 protected MyBlockPlacerBase(MyHandItemDefinition definition)
     : base(definition, 0.5f, 500)
 {
 }
 protected MyBlockPlacerBase(MyHandItemDefinition definition)
     : base(500)
 {
     m_definition = definition;
 }
        private void TransformItem(MyHandItemDefinition item)
        {
            //SwapYZ(ref item.ItemLocation);
            //SwapYZ(ref item.ItemLocation3rd);
            //SwapYZ(ref item.ItemShootLocation);
            //SwapYZ(ref item.ItemShootLocation3rd);
            //SwapYZ(ref item.ItemWalkingLocation);
            //SwapYZ(ref item.ItemWalkingLocation3rd);
            ////SwapYZ(ref CurrentSelectedItem.LeftHand);
            ////SwapYZ(ref CurrentSelectedItem.RightHand);
            //SwapYZ(ref item.MuzzlePosition);


            Reorientate(ref item.LeftHand);
            Reorientate(ref item.RightHand);
        }
 protected virtual void handItemsCombo_ItemSelected()
 {
     CurrentSelectedItem = m_handItemDefinitions[(int)m_handItemsCombo.GetSelectedKey()]; ;
 }