protected void SerializeInternal(MyObjectBuilder_FractureComponentBase ob)
        {
            Debug.Assert(m_tmpChildren.Count == 0);

            if (string.IsNullOrEmpty(Shape.Name) || Shape.IsCompound() || Shape.GetChildrenCount() > 0)
            {
                Shape.GetChildren(m_tmpChildren);
                foreach (var child in m_tmpChildren)
                {
                    var shape = new MyObjectBuilder_FractureComponentCubeBlock.FracturedShape()
                    {
                        Name  = child.ShapeName,
                        Fixed = MyDestructionHelper.IsFixed(child.Shape)
                    };
                    ob.Shapes.Add(shape);
                }
                m_tmpChildren.Clear();
            }
            else
            {
                ob.Shapes.Add(new MyObjectBuilder_FractureComponentCubeBlock.FracturedShape()
                {
                    Name = Shape.Name
                });
            }
        }
예제 #2
0
        private static void ConvertAllShapesToFractureComponentShapeBuilder(HkdBreakableShape shape, ref Matrix shapeRotation, MyBlockOrientation blockOrientation, HashSet <string> names, MyObjectBuilder_FractureComponentCubeBlock fractureComponentBuilder)
        {
            var name = shape.Name;

            if (names.Contains(name))
            {
                MyBlockOrientation shapeOrientation = new MyBlockOrientation(ref shapeRotation);
                if (shapeOrientation == blockOrientation)
                {
                    MyObjectBuilder_FractureComponentCubeBlock.FracturedShape builderShape = new MyObjectBuilder_FractureComponentBase.FracturedShape();
                    builderShape.Name  = name;
                    builderShape.Fixed = MyDestructionHelper.IsFixed(shape);

                    fractureComponentBuilder.Shapes.Add(builderShape);
                }
            }

            if (shape.GetChildrenCount() > 0)
            {
                List <HkdShapeInstanceInfo> children = new List <HkdShapeInstanceInfo>();
                shape.GetChildren(children);
                foreach (var child in children)
                {
                    var childShapeRotation = child.GetTransform();
                    ConvertAllShapesToFractureComponentShapeBuilder(child.Shape, ref childShapeRotation, blockOrientation, names, fractureComponentBuilder);
                }
            }
        }
예제 #3
0
        public override MyObjectBuilder_EntityBase GetObjectBuilder(bool copy = false)
        {
            var old = base.GetObjectBuilder(copy);
            var ob  = old as MyObjectBuilder_FracturedPiece;

            foreach (var def in OriginalBlocks)
            {
                ob.BlockDefinitions.Add(def);
            }
            if (Physics == null)
            {
                Debug.Assert(m_shapes.Count > 0, "Saving invalid piece!");
                foreach (var shape in m_shapes)
                {
                    ob.Shapes.Add(new MyObjectBuilder_FracturedPiece.Shape()
                    {
                        Name = shape.Name, Orientation = shape.Orientation
                    });
                }
                return(ob);
            }
            if (Physics.BreakableBody.BreakableShape.IsCompound() || string.IsNullOrEmpty(Physics.BreakableBody.BreakableShape.Name))
            {
                Physics.BreakableBody.BreakableShape.GetChildren(m_children);
                if (m_children.Count == 0)
                {
                    Debug.Fail("Saiving invalid piece!");
                    return(ob);
                }
                foreach (var child in m_children)
                {
                    var shape = new MyObjectBuilder_FracturedPiece.Shape()
                    {
                        Name        = child.ShapeName,
                        Orientation = Quaternion.CreateFromRotationMatrix(child.GetTransform().GetOrientation()),
                        Fixed       = MyDestructionHelper.IsFixed(child.Shape)
                    };
                    ob.Shapes.Add(shape);
                }

                if (Physics.IsInWorld)
                {
                    var fixedPosition = Physics.ClusterToWorld(Vector3.Transform(m_children[0].GetTransform().Translation, Physics.RigidBody.GetRigidBodyMatrix()));
                    var posOr         = ob.PositionAndOrientation.Value;
                    posOr.Position            = fixedPosition;
                    ob.PositionAndOrientation = posOr;
                }
                m_children.Clear();
            }
            else
            {
                ob.Shapes.Add(new MyObjectBuilder_FracturedPiece.Shape()
                {
                    Name = Physics.BreakableBody.BreakableShape.Name
                });
            }
            Debug.Assert(ob.Shapes.Count > 0, "Saiving invalid piece!");
            return(ob);
        }
예제 #4
0
        public override MyObjectBuilder_CubeBlock GetObjectBuilderCubeBlock(bool copy = false)
        {
            Debug.Assert(!MyFakes.ENABLE_FRACTURE_COMPONENT, "Fractured block saved with fracture components enabled");

            var ob = base.GetObjectBuilderCubeBlock(copy) as MyObjectBuilder_FracturedBlock;

            if (string.IsNullOrEmpty(Shape.Name) || Shape.IsCompound())
            {
                Shape.GetChildren(m_children);
                foreach (var child in m_children)
                {
                    var shape = new MyObjectBuilder_FracturedBlock.ShapeB()
                    {
                        Name        = child.ShapeName,
                        Orientation = Quaternion.CreateFromRotationMatrix(child.GetTransform().GetOrientation()),
                        Fixed       = MyDestructionHelper.IsFixed(child.Shape)
                    };
                    ob.Shapes.Add(shape);
                }
                m_children.Clear();
            }
            else
            {
                ob.Shapes.Add(new MyObjectBuilder_FracturedBlock.ShapeB()
                {
                    Name = Shape.Name
                });
            }

            foreach (var def in OriginalBlocks)
            {
                ob.BlockDefinitions.Add(def);
            }
            foreach (var or in Orientations)
            {
                ob.BlockOrientations.Add(or);
            }

            if (MultiBlocks != null)
            {
                foreach (var mbpart in MultiBlocks)
                {
                    if (mbpart != null)
                    {
                        ob.MultiBlocks.Add(new MyObjectBuilder_FracturedBlock.MyMultiBlockPart()
                        {
                            MultiBlockDefinition = mbpart.MultiBlockDefinition, MultiBlockId = mbpart.MultiBlockId
                        });
                    }
                    else
                    {
                        ob.MultiBlocks.Add(null);
                    }
                }
            }

            return(ob);
        }
        private void SectorOnContactPoint(int itemId, MyEntity other, ref MyPhysics.MyContactPointEvent e)
        {
            // if item is already disabled: puff
            // We get multiple contact points so this is for that
            if (m_sector.DataView.Items[itemId].ModelIndex < 0)
            {
                return;
            }

            var vel = Math.Abs(e.ContactPointEvent.SeparatingVelocity);

            if (other == null || other.Physics == null || other is MyFloatingObject)
            {
                return;
            }

            if (other is IMyHandheldGunObject <MyDeviceBase> )
            {
                return;
            }

            // Prevent debris from breaking trees.
            // Debris flies in unpredictable ways and this could cause out of sync tree destruction which would is bad.
            if (other.Physics.RigidBody != null && other.Physics.RigidBody.Layer == MyPhysics.CollisionLayers.DebrisCollisionLayer)
            {
                return;
            }

            // On objects held in manipulation tool, Havok returns high velocities, after this contact is fired by contraint solver.
            // Therefore we disable damage from objects connected by constraint to character
            if (MyManipulationTool.IsEntityManipulated(other))
            {
                return;
            }

            float otherMass = MyDestructionHelper.MassFromHavok(other.Physics.Mass);

            double impactEnergy = vel * vel * otherMass;

            // TODO: per item max impact energy
            if (impactEnergy > ItemResilience(itemId))
            {
                var normal = e.ContactPointEvent.ContactPoint.Normal;

                impactEnergy = MathHelper.Clamp(impactEnergy, 0, ItemResilience(itemId) * 10);

                Impact impact = new Impact(e.Position, normal, impactEnergy);

                m_sector.RaiseItemEvent(this, itemId, impact);
                DisableItemAndCreateDebris(ref impact, itemId);
            }

            // Meteor destroy always
            if (other is MyMeteor)
            {
                m_sector.EnableItem(itemId, false);
            }
        }
예제 #6
0
        public static void CreateFracturePiece(MyEnvironmentItemDefinition itemDefinition, HkdBreakableShape oldBreakableShape, MatrixD worldMatrix, Vector3 hitNormal, List <HkdShapeInstanceInfo> shapeList,
                                               float forceMultiplier, bool canContainFixedChildren, string fallSound = "")
        {
            bool containsFixedChildren = false;

            if (canContainFixedChildren)
            {
                foreach (var shapeInst in shapeList)
                {
                    shapeInst.Shape.SetMotionQualityRecursively(HkdBreakableShape.BodyQualityType.QUALITY_DEBRIS);

                    var t = worldMatrix.Translation + worldMatrix.Up * 1.5f;
                    var o = Quaternion.CreateFromRotationMatrix(worldMatrix.GetOrientation());
                    MyPhysics.GetPenetrationsShape(shapeInst.Shape.GetShape(), ref t, ref o, m_tmpResults, MyPhysics.CollisionLayers.DefaultCollisionLayer);
                    bool flagSet = false;
                    foreach (var res in m_tmpResults)
                    {
                        var entity = res.GetCollisionEntity();

                        if (entity is MyVoxelMap)
                        {
                            shapeInst.Shape.SetFlagRecursively(HkdBreakableShape.Flags.IS_FIXED);
                            containsFixedChildren = true;
                            flagSet = true;
                            break;
                        }

                        if (flagSet)
                        {
                            break;
                        }
                    }
                    m_tmpResults.Clear();
                }
            }

            HkdBreakableShape compound = new HkdCompoundBreakableShape(oldBreakableShape, shapeList);

            ((HkdCompoundBreakableShape)compound).RecalcMassPropsFromChildren();
            //compound.SetMassRecursively(500);
            //compound.SetStrenghtRecursively(5000, 0.7f);

            var fp = MyDestructionHelper.CreateFracturePiece(compound, MyPhysics.SingleWorld.DestructionWorld, ref worldMatrix, containsFixedChildren, itemDefinition.Id, true);

            if (fp != null && !canContainFixedChildren)
            {
                ApplyImpulseToTreeFracture(ref worldMatrix, ref hitNormal, shapeList, ref compound, fp, forceMultiplier);
                fp.Physics.ForceActivate();
                if (fallSound.Length > 0)
                {
                    fp.StartFallSound(fallSound);
                }
            }
        }
예제 #7
0
        public override MyObjectBuilder_CubeBlock GetObjectBuilderCubeBlock(bool copy = false)
        {
            MyObjectBuilder_FracturedBlock.ShapeB eb2;
            MyObjectBuilder_FracturedBlock        objectBuilderCubeBlock = base.GetObjectBuilderCubeBlock(copy) as MyObjectBuilder_FracturedBlock;

            if (!string.IsNullOrEmpty(this.Shape.Name) && !this.Shape.IsCompound())
            {
                eb2 = new MyObjectBuilder_FracturedBlock.ShapeB {
                    Name = this.Shape.Name
                };
                objectBuilderCubeBlock.Shapes.Add(eb2);
            }
            else
            {
                this.Shape.GetChildren(m_children);
                foreach (HkdShapeInstanceInfo info in m_children)
                {
                    eb2 = new MyObjectBuilder_FracturedBlock.ShapeB {
                        Name = info.ShapeName
                    };
                    eb2.Orientation = Quaternion.CreateFromRotationMatrix(info.GetTransform().GetOrientation());
                    eb2.Fixed       = MyDestructionHelper.IsFixed(info.Shape);
                    MyObjectBuilder_FracturedBlock.ShapeB item = eb2;
                    objectBuilderCubeBlock.Shapes.Add(item);
                }
                m_children.Clear();
            }
            foreach (MyDefinitionId id in this.OriginalBlocks)
            {
                objectBuilderCubeBlock.BlockDefinitions.Add((SerializableDefinitionId)id);
            }
            foreach (MyBlockOrientation orientation in this.Orientations)
            {
                objectBuilderCubeBlock.BlockOrientations.Add(orientation);
            }
            if (this.MultiBlocks != null)
            {
                foreach (MultiBlockPartInfo info2 in this.MultiBlocks)
                {
                    if (info2 == null)
                    {
                        objectBuilderCubeBlock.MultiBlocks.Add(null);
                        continue;
                    }
                    MyObjectBuilder_FracturedBlock.MyMultiBlockPart item = new MyObjectBuilder_FracturedBlock.MyMultiBlockPart();
                    item.MultiBlockDefinition = (SerializableDefinitionId)info2.MultiBlockDefinition;
                    item.MultiBlockId         = info2.MultiBlockId;
                    objectBuilderCubeBlock.MultiBlocks.Add(item);
                }
            }
            return(objectBuilderCubeBlock);
        }
예제 #8
0
        private static void ConvertAllShapesToFractureComponentShapeBuilder(HkdBreakableShape shape, ref Matrix shapeRotation, MyBlockOrientation blockOrientation,
                                                                            HashSet <Tuple <string, float> > namesAndBuildProgress, MyObjectBuilder_FractureComponentCubeBlock fractureComponentBuilder, out float buildProgress)
        {
            buildProgress = 1f;

            var name = shape.Name;
            Tuple <string, float> foundTuple = null;

            foreach (var tuple in namesAndBuildProgress)
            {
                if (tuple.Item1 == name)
                {
                    foundTuple = tuple;
                    break;
                }
            }

            if (foundTuple != null)
            {
                MyBlockOrientation shapeOrientation = new MyBlockOrientation(ref shapeRotation);
                if (shapeOrientation == blockOrientation)
                {
                    MyObjectBuilder_FractureComponentCubeBlock.FracturedShape builderShape = new MyObjectBuilder_FractureComponentBase.FracturedShape();
                    builderShape.Name  = name;
                    builderShape.Fixed = MyDestructionHelper.IsFixed(shape);

                    fractureComponentBuilder.Shapes.Add(builderShape);
                    buildProgress = foundTuple.Item2;
                }
            }

            if (shape.GetChildrenCount() > 0)
            {
                List <HkdShapeInstanceInfo> children = new List <HkdShapeInstanceInfo>();
                shape.GetChildren(children);
                foreach (var child in children)
                {
                    var   childShapeRotation = child.GetTransform();
                    float localBuildProgress;
                    ConvertAllShapesToFractureComponentShapeBuilder(child.Shape, ref childShapeRotation, blockOrientation, namesAndBuildProgress,
                                                                    fractureComponentBuilder, out localBuildProgress);

                    if (foundTuple == null)
                    {
                        buildProgress = localBuildProgress;
                    }
                }
            }
        }
예제 #9
0
 public override void HandleInput()
 {
     if ((this.m_isActive && (MyScreenManager.GetScreenWithFocus() is MyGuiScreenGamePlay)) && ((MyInput.Static.ENABLE_DEVELOPER_KEYS || !MySession.Static.SurvivalMode) || MySession.Static.IsUserAdmin(Sync.MyId)))
     {
         base.HandleInput();
         if (MyControllerHelper.IsControl(MySpaceBindingCreator.CX_CHARACTER, MyControlsSpace.PRIMARY_TOOL_ACTION, MyControlStateType.NEW_PRESSED, false))
         {
             this.m_startTime = MySandboxGame.TotalGamePlayTimeInMilliseconds;
         }
         if (MyControllerHelper.IsControl(MySpaceBindingCreator.CX_CHARACTER, MyControlsSpace.PRIMARY_TOOL_ACTION, MyControlStateType.NEW_RELEASED, false))
         {
             MyObjectBuilder_CubeGrid[] gridPrefab = MyPrefabManager.Static.GetGridPrefab(this.CurrentDefinition.PrefabToThrow);
             Vector3D zero    = Vector3D.Zero;
             Vector3D forward = Vector3D.Zero;
             if (USE_SPECTATOR_FOR_THROW)
             {
                 zero    = MySpectator.Static.Position;
                 forward = MySpectator.Static.Orientation.Forward;
             }
             else if ((MySession.Static.GetCameraControllerEnum() != MyCameraControllerEnum.ThirdPersonSpectator) && (MySession.Static.GetCameraControllerEnum() != MyCameraControllerEnum.Entity))
             {
                 zero    = MySector.MainCamera.Position;
                 forward = MySector.MainCamera.WorldMatrix.Forward;
             }
             else
             {
                 if (MySession.Static.ControlledEntity == null)
                 {
                     return;
                 }
                 zero    = MySession.Static.ControlledEntity.GetHeadMatrix(true, true, false, false).Translation;
                 forward = MySession.Static.ControlledEntity.GetHeadMatrix(true, true, false, false).Forward;
             }
             Vector3D vectord3 = zero + forward;
             Vector3D vectord4 = (forward * MathHelper.Clamp(((((float)(MySandboxGame.TotalGamePlayTimeInMilliseconds - this.m_startTime)) / 1000f) / this.CurrentDefinition.PushTime) * this.CurrentDefinition.MaxSpeed, this.CurrentDefinition.MinSpeed, this.CurrentDefinition.MaxSpeed)) + MySession.Static.ControlledEntity.Entity.Physics.LinearVelocity;
             float    num2     = 0f;
             if (this.CurrentDefinition.Mass != null)
             {
                 num2 = MyDestructionHelper.MassToHavok(this.CurrentDefinition.Mass.Value);
             }
             gridPrefab[0].EntityId = MyEntityIdentifier.AllocateId(MyEntityIdentifier.ID_OBJECT_TYPE.ENTITY, MyEntityIdentifier.ID_ALLOCATION_METHOD.RANDOM);
             EndpointId targetEndpoint = new EndpointId();
             Vector3D?  position       = null;
             MyMultiplayer.RaiseStaticEvent <MyObjectBuilder_CubeGrid, Vector3D, Vector3D, float, MyCueId>(s => new Action <MyObjectBuilder_CubeGrid, Vector3D, Vector3D, float, MyCueId>(MySessionComponentThrower.OnThrowMessageSuccess), gridPrefab[0], vectord3, vectord4, num2, this.CurrentDefinition.ThrowSound, targetEndpoint, position);
             this.m_startTime = 0;
         }
     }
 }
예제 #10
0
        public static void CreateFracturePiece(MyEnvironmentItemDefinition itemDefinition, HkdBreakableShape oldBreakableShape, MatrixD worldMatrix, Vector3 hitNormal, List <HkdShapeInstanceInfo> shapeList, float forceMultiplier, bool canContainFixedChildren, string fallSound = "")
        {
            bool isStatic = false;

            if (canContainFixedChildren)
            {
                foreach (HkdShapeInstanceInfo info in shapeList)
                {
                    info.Shape.SetMotionQualityRecursively(HkdBreakableShape.BodyQualityType.QUALITY_DEBRIS);
                    Vector3D   translation = worldMatrix.Translation + (worldMatrix.Up * 1.5);
                    Quaternion rotation    = Quaternion.CreateFromRotationMatrix(worldMatrix.GetOrientation());
                    MyPhysics.GetPenetrationsShape(info.Shape.GetShape(), ref translation, ref rotation, MyEnvironmentItems.m_tmpResults, 15);
                    bool flag2 = false;
                    using (List <HkBodyCollision> .Enumerator enumerator2 = MyEnvironmentItems.m_tmpResults.GetEnumerator())
                    {
                        while (enumerator2.MoveNext())
                        {
                            if (enumerator2.Current.GetCollisionEntity() is MyVoxelMap)
                            {
                                info.Shape.SetFlagRecursively(HkdBreakableShape.Flags.IS_FIXED);
                                isStatic = true;
                                flag2    = true;
                            }
                            else if (!flag2)
                            {
                                continue;
                            }
                            break;
                        }
                    }
                    MyEnvironmentItems.m_tmpResults.Clear();
                }
            }
            HkdBreakableShape shape = (HkdBreakableShape) new HkdCompoundBreakableShape(new HkdBreakableShape?(oldBreakableShape), shapeList);

            shape.RecalcMassPropsFromChildren();
            MyFracturedPiece fp = MyDestructionHelper.CreateFracturePiece(shape, ref worldMatrix, isStatic, new MyDefinitionId?(itemDefinition.Id), true);

            if ((fp != null) && !canContainFixedChildren)
            {
                ApplyImpulseToTreeFracture(ref worldMatrix, ref hitNormal, shapeList, ref shape, fp, forceMultiplier);
                fp.Physics.ForceActivate();
                if (fallSound.Length > 0)
                {
                    fp.StartFallSound(fallSound);
                }
            }
        }
예제 #11
0
        void Physics_ContactPointCallback(ref MyPhysics.MyContactPointEvent e)
        {
            var vel   = Math.Abs(e.ContactPointEvent.SeparatingVelocity);
            var other = e.ContactPointEvent.GetOtherEntity(this);

            if (other == null || other.Physics == null)
            {
                return;
            }

            float otherMass = MyDestructionHelper.MassFromHavok(other.Physics.Mass);

            if (other is Sandbox.Game.Entities.Character.MyCharacter)
            {
                otherMass = other.Physics.Mass;
            }

            float impactEnergy = vel * vel * otherMass;

            // If environment item is hit by a gun, nothing happens here. If you want a weapon damage to env. items, call DoDamage there
            if (impactEnergy > 350000 && !(other is IMyHandheldGunObject <MyDeviceBase>))
            {
                int bodyId   = e.ContactPointEvent.Base.BodyA.GetEntity() == this ? 0 : 1;
                var shapeKey = e.ContactPointEvent.GetShapeKey(bodyId);
                var position = Physics.ClusterToWorld(e.ContactPointEvent.ContactPoint.Position);
                var sectorId = MyEnvironmentSector.GetSectorId(position, m_definition.SectorSize);
                HkStaticCompoundShape shape = (HkStaticCompoundShape)Physics.RigidBody.GetShape();
                int  physicsInstanceId;
                uint childKey;
                if (shapeKey == uint.MaxValue) //jn: TODO find out why this happens, there is ticket for it https://app.asana.com/0/9887996365574/26645443970236
                {
                    ProfilerShort.End();
                    return;
                }
                shape.DecomposeShapeKey(shapeKey, out physicsInstanceId, out childKey);

                int itemInstanceId;
                if (m_physicsShapeInstanceIdToLocalId.TryGetValue(physicsInstanceId, out itemInstanceId))
                {
                    DoDamage(1.0f, itemInstanceId, e.Position, -e.ContactPointEvent.ContactPoint.Normal);
                }
            }
        }
예제 #12
0
        private static void ConvertAllShapesToFractureComponentShapeBuilder(HkdBreakableShape shape, ref Matrix shapeRotation, MyBlockOrientation blockOrientation, HashSet <Tuple <string, float> > namesAndBuildProgress, MyObjectBuilder_FractureComponentCubeBlock fractureComponentBuilder, out float buildProgress)
        {
            buildProgress = 1f;
            string name = shape.Name;
            Tuple <string, float> tuple = null;

            foreach (Tuple <string, float> tuple2 in namesAndBuildProgress)
            {
                if (tuple2.Item1 == name)
                {
                    tuple = tuple2;
                    break;
                }
            }
            if ((tuple != null) && (new MyBlockOrientation(ref shapeRotation) == blockOrientation))
            {
                MyObjectBuilder_FractureComponentBase.FracturedShape item = new MyObjectBuilder_FractureComponentBase.FracturedShape {
                    Name  = name,
                    Fixed = MyDestructionHelper.IsFixed(shape)
                };
                fractureComponentBuilder.Shapes.Add(item);
                buildProgress = tuple.Item2;
            }
            if (shape.GetChildrenCount() > 0)
            {
                List <HkdShapeInstanceInfo> list = new List <HkdShapeInstanceInfo>();
                shape.GetChildren(list);
                foreach (HkdShapeInstanceInfo info in list)
                {
                    float  num;
                    Matrix transform = info.GetTransform();
                    ConvertAllShapesToFractureComponentShapeBuilder(info.Shape, ref transform, blockOrientation, namesAndBuildProgress, fractureComponentBuilder, out num);
                    if (tuple == null)
                    {
                        buildProgress = num;
                    }
                }
            }
        }
        public override MyObjectBuilder_CubeBlock GetObjectBuilderCubeBlock(bool copy = false)
        {
            var ob = base.GetObjectBuilderCubeBlock(copy) as MyObjectBuilder_FracturedBlock;

            if (string.IsNullOrEmpty(Shape.Name) || Shape.IsCompound())
            {
                Shape.GetChildren(m_children);
                foreach (var child in m_children)
                {
                    var shape = new MyObjectBuilder_FracturedBlock.ShapeB()
                    {
                        Name        = child.ShapeName,
                        Orientation = Quaternion.CreateFromRotationMatrix(child.GetTransform().GetOrientation()),
                        Fixed       = MyDestructionHelper.IsFixed(child.Shape)
                    };
                    ob.Shapes.Add(shape);
                }
                m_children.Clear();
            }
            else
            {
                ob.Shapes.Add(new MyObjectBuilder_FracturedBlock.ShapeB()
                {
                    Name = Shape.Name
                });
            }
            foreach (var def in OriginalBlocks)
            {
                ob.BlockDefinitions.Add(def);
            }
            foreach (var or in Orientations)
            {
                ob.BlockOrientations.Add(or);
            }
            return(ob);
        }
        public void LoadModelDestruction(MyPhysicalModelDefinition modelDef, bool dontCreateFracturePieces, Vector3 defaultSize, bool destructionRequired = true, bool useShapeVolume = false)
        {
            var model = MyModels.GetModelOnlyData(modelDef.Model);

            var material = modelDef.PhysicalMaterial;

            if (model != null)
            {
                bool forceCollisionsInsteadDestruction = false;

                //if (model.AssetName.Contains("StoneBattlementAdvancedStraightTop"))
                //{
                //}

                model.LoadUV = true;
                HkdBreakableShape bShape;
                bool createPieceData = false;
                bool recalculateMass = false;
                bool registerShape   = false;

                //TODO: Dynamic fracturing is workaround. We need to find the way how to serialize fractured model directly into hkt
                //      and then load it from BreakableShapes.
                if (model.ModelFractures != null)
                {
                    if (model.HavokCollisionShapes != null && model.HavokCollisionShapes.Length > 0)
                    {
                        CreateBreakableShapeFromCollisionShapes(model, defaultSize, modelDef);

                        var physicsMesh = CreatePhysicsMesh(model);

                        Storage.RegisterShapeWithGraphics(physicsMesh, model.HavokBreakableShapes[0], modelDef.Id.SubtypeName);

                        string modPath = null;

                        if (Path.IsPathRooted(model.AssetName))
                        {
                            modPath = model.AssetName.Remove(model.AssetName.LastIndexOf("Models"));
                        }

                        FractureBreakableShape(model.HavokBreakableShapes[0], model.ModelFractures, modPath);

                        recalculateMass = true;
                        registerShape   = true;
                        createPieceData = true;
                    }
                }
                else
                if (model.HavokDestructionData != null && !forceCollisionsInsteadDestruction)
                {
                    try
                    {
                        //string dump = Storage.DumpDestructionData(model.HavokDestructionData);
                        if (model.HavokBreakableShapes == null) //models are cached between sessions
                        {
                            model.HavokBreakableShapes = Storage.LoadDestructionDataFromBuffer(model.HavokDestructionData);
                            createPieceData            = true;
                            recalculateMass            = true;
                            registerShape = true;
                        }
                    }
                    catch
                    {
                        model.HavokBreakableShapes = null;
                    }
                }
                model.HavokDestructionData = null; //we dont need to hold the byte data after loading shape
                model.HavokData            = null;

                if (model.HavokBreakableShapes == null && destructionRequired)
                {
                    MyLog.Default.WriteLine(model.AssetName + " does not have destruction data");

                    CreateBreakableShapeFromCollisionShapes(model, defaultSize, modelDef);

                    recalculateMass = true;
                    registerShape   = true;

                    if (MyFakes.SHOW_MISSING_DESTRUCTION && destructionRequired)
                    {
                        //Show missing destructions in pink
                        VRageRender.MyRenderProxy.ChangeModelMaterial(model.AssetName, "Debug");
                    }
                }

                if (model.HavokBreakableShapes == null)
                {
                    MyLog.Default.WriteLine(string.Format("Model {0} - Unable to load havok destruction data", model.AssetName), LoggingOptions.LOADING_MODELS);
                    return;
                }

                System.Diagnostics.Debug.Assert(model.HavokBreakableShapes.Length > 0, "Incomplete destruction data");
                bShape = model.HavokBreakableShapes[0];

                //bShape.GetChildren(m_tmpChildrenList);
                //if (m_tmpChildrenList.Count == 0)
                //    bShape.UserObject = (uint)HkdBreakableShape.Flags.FRACTURE_PIECE;

                if (dontCreateFracturePieces)
                {
                    bShape.SetFlagRecursively(HkdBreakableShape.Flags.DONT_CREATE_FRACTURE_PIECE);
                }

                //m_tmpChildrenList.Clear();

                if (registerShape)
                {
                    bShape.AddReference();

                    Storage.RegisterShape(
                        bShape,
                        modelDef.Id.SubtypeName
                        );
                }

                // Necessary, otherwise materials on fractures would be missing
                VRageRender.MyRenderProxy.PreloadMaterials(model.AssetName);

                if (createPieceData)
                {
                    CreatePieceData(model, bShape);
                }

                if (recalculateMass)
                {
                    var volume = bShape.CalculateGeometryVolume();
                    if (volume <= 0 || useShapeVolume)
                    {
                        volume = bShape.Volume;
                    }
                    var realMass = volume * material.Density;
                    if (bShape.Name == "House Half Timber Triangle")
                    {
                    }
                    System.Diagnostics.Debug.Assert(realMass > 0, "Invalid mass data");

                    bShape.SetMassRecursively(MyDestructionHelper.MassToHavok(realMass));
                }
                //Debug.Assert(CheckVolumeMassRec(bShape, 0.00001f, 0.01f), "Low volume or mass." + bShape.Name);
                DisableRefCountRec(bShape);

                if (MyFakes.LAZY_LOAD_DESTRUCTION)
                {
                    BlockShapePool.AllocateForDefinition(modelDef, MyBlockShapePool.PREALLOCATE_COUNT);
                }
            }
            else
            {
                //No armor in ME!
            }
        }
예제 #15
0
        private void InitInternal()
        {
            // TODO: This will be fixed and made much more simple once ore models are done
            // https://app.asana.com/0/6594565324126/10473934569658

            var physicalItem = MyDefinitionManager.Static.GetPhysicalItemDefinition(Item.Content);

            m_health = physicalItem.Health;

            string model = physicalItem.Model;

            VoxelMaterial = null;
            float scale = 1.0f;

            if (Item.Content is MyObjectBuilder_Ore)
            {
                string oreSubTypeId = physicalItem.Id.SubtypeId.ToString();
                foreach (var mat in MyDefinitionManager.Static.GetVoxelMaterialDefinitions())
                {
                    if (oreSubTypeId == mat.MinedOre)
                    {
                        VoxelMaterial = mat;
                        model         = MyDebris.GetRandomDebrisVoxel();
                        scale         = (float)Math.Pow((float)Item.Amount * physicalItem.Volume / MyDebris.VoxelDebrisModelVolume, 0.333f);
                        break;
                    }
                }

                scale = (float)Math.Pow((float)Item.Amount * physicalItem.Volume / MyDebris.VoxelDebrisModelVolume, 0.333f);
            }

            if (scale < 0.05f)
            {
                Close();
            }
            else if (scale < 0.15f)
            {
                scale = 0.15f;
            }

            FormatDisplayName(m_displayedText, Item);
            Init(m_displayedText, model, null, null, null);

            PositionComp.Scale = scale; // Must be set after init


            var massProperties = new HkMassProperties();
            var mass           = MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(physicalItem.Mass) : physicalItem.Mass;

            HkShape shape       = GetPhysicsShape(mass * (float)Item.Amount, scale, out massProperties);
            var     scaleMatrix = Matrix.CreateScale(scale);

            if (Physics != null)
            {
                Physics.Close();
            }
            Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEBRIS);

            if (VoxelMaterial != null)
            {
                HkConvexTransformShape transform = new HkConvexTransformShape((HkConvexShape)shape, ref scaleMatrix, HkReferencePolicy.None);

                Physics.CreateFromCollisionObject(transform, Vector3.Zero, MatrixD.Identity, massProperties, MyPhysics.FloatingObjectCollisionLayer);

                Physics.Enabled = true;
                transform.Base.RemoveReference();
            }
            else
            {
                Physics.CreateFromCollisionObject(shape, Vector3.Zero, MatrixD.Identity, massProperties, MyPhysics.FloatingObjectCollisionLayer);
                Physics.Enabled = true;
            }

            Physics.MaterialType            = VoxelMaterial != null ? MyMaterialType.ROCK : MyMaterialType.METAL;
            Physics.PlayCollisionCueEnabled = true;

            NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME;
        }
예제 #16
0
        public override void Init(MyObjectBuilder_EntityBase objectBuilder)
        {
            base.Init(objectBuilder);
            var ob = objectBuilder as MyObjectBuilder_FracturedPiece;

            if (ob.Shapes.Count == 0)
            {
                Debug.Fail("Invalid fracture piece! Dont call init without valid OB. Use pool/noinit.");
                throw new Exception("Fracture piece has no shapes."); //throwing exception, otherwise there is fp with null physics which can mess up somwhere else
            }

            foreach (var shape in ob.Shapes)
            {
                Render.AddPiece(shape.Name, Matrix.CreateFromQuaternion(shape.Orientation));
            }
            OriginalBlocks.Clear();
            foreach (var def in ob.BlockDefinitions)
            {
                string model = null;
                MyPhysicalModelDefinition mdef;
                if (MyDefinitionManager.Static.TryGetDefinition <MyPhysicalModelDefinition>(def, out mdef))
                {
                    model = mdef.Model;
                }
                MyCubeBlockDefinition blockDef = null;
                MyDefinitionManager.Static.TryGetDefinition <MyCubeBlockDefinition>(def, out blockDef);

                if (model == null)
                {
                    Debug.Fail("Fracture piece Definition not found");
                    continue;
                }

                model = mdef.Model;
                if (VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes == null)
                {
                    MyDestructionData.Static.LoadModelDestruction(model, mdef, Vector3.One);
                }
                var shape = VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes[0];
                var si    = new HkdShapeInstanceInfo(shape, null, null);
                m_children.Add(si);
                shape.GetChildren(m_children);

                if (blockDef != null && blockDef.BuildProgressModels != null)
                {
                    foreach (var progress in blockDef.BuildProgressModels)
                    {
                        model = progress.File;
                        if (VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes == null)
                        {
                            MyDestructionData.Static.LoadModelDestruction(model, blockDef, Vector3.One);
                        }
                        shape = VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes[0];
                        si    = new HkdShapeInstanceInfo(shape, null, null);
                        m_children.Add(si);
                        shape.GetChildren(m_children);
                    }
                }

                OriginalBlocks.Add(def);
            }
            m_shapes.AddRange(ob.Shapes);

            Vector3?offset      = null;
            int     shapeAtZero = 0;

            for (int i = 0; i < m_children.Count; i++)
            {
                var child = m_children[i];
                Func <MyObjectBuilder_FracturedPiece.Shape, bool> x = s => s.Name == child.ShapeName;
                var result = m_shapes.Where(x);
                if (result.Count() > 0)
                {
                    var found = result.First();
                    var m     = Matrix.CreateFromQuaternion(found.Orientation);
                    if (!offset.HasValue && found.Name == m_shapes[0].Name)
                    {
                        offset      = child.GetTransform().Translation;
                        shapeAtZero = m_shapeInfos.Count;
                    }
                    m.Translation = child.GetTransform().Translation;
                    var si = new HkdShapeInstanceInfo(child.Shape.Clone(), m);
                    if (found.Fixed)
                    {
                        si.Shape.SetFlagRecursively(HkdBreakableShape.Flags.IS_FIXED);
                    }
                    m_shapeInfos.Add(si);
                    m_shapes.Remove(found);
                }
                else
                {
                    child.GetChildren(m_children);
                }
            }

            if (m_shapeInfos.Count == 0)
            {
                List <string> shapesToLoad = new List <string>();
                foreach (var obShape in ob.Shapes)
                {
                    shapesToLoad.Add(obShape.Name);
                }

                var shapesStr = shapesToLoad.Aggregate((str1, str2) => str1 + ", " + str2);
                var blocksStr = OriginalBlocks.Aggregate("", (str, defId) => str + ", " + defId.ToString());
                var failMsg   = "No relevant shape was found for fractured piece. It was probably reexported and names changed. Shapes: " + shapesStr + ". Original blocks: " + shapesStr;

                Debug.Fail(failMsg);
                //HkdShapeInstanceInfo si = new HkdShapeInstanceInfo(new HkdBreakableShape((HkShape)new HkBoxShape(Vector3.One)), Matrix.Identity);
                //m_shapeInfos.Add(si);
                throw new Exception(failMsg);
            }

            if (offset.HasValue)
            {
                for (int i = 0; i < m_shapeInfos.Count; i++)
                {
                    var m = m_shapeInfos[i].GetTransform();
                    m.Translation -= offset.Value;
                    m_shapeInfos[i].SetTransform(ref m);
                }
                {
                    var m = m_shapeInfos[shapeAtZero].GetTransform();
                    m.Translation = Vector3.Zero;
                    m_shapeInfos[shapeAtZero].SetTransform(ref m);
                }
            }

            if (m_shapeInfos.Count > 0)
            {
                if (m_shapeInfos.Count == 1)
                {
                    Shape = m_shapeInfos[0].Shape;
                }
                else
                {
                    Shape = new HkdCompoundBreakableShape(null, m_shapeInfos);
                    ((HkdCompoundBreakableShape)Shape).RecalcMassPropsFromChildren();
                }
                Shape.SetStrenght(MyDestructionConstants.STRENGTH);
                var mp = new HkMassProperties();
                Shape.BuildMassProperties(ref mp);
                Shape.SetChildrenParent(Shape);
                Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEBRIS);
                Physics.CanUpdateAccelerations    = true;
                Physics.InitialSolverDeactivation = HkSolverDeactivation.High;
                Physics.CreateFromCollisionObject(Shape.GetShape(), Vector3.Zero, PositionComp.WorldMatrix, mp);
                Physics.BreakableBody = new HkdBreakableBody(Shape, Physics.RigidBody, MyPhysics.SingleWorld.DestructionWorld, (Matrix)PositionComp.WorldMatrix);
                Physics.BreakableBody.AfterReplaceBody += Physics.FracturedBody_AfterReplaceBody;

                if (OriginalBlocks.Count > 0)
                {
                    MyPhysicalModelDefinition def;
                    if (MyDefinitionManager.Static.TryGetDefinition <MyPhysicalModelDefinition>(OriginalBlocks[0], out def))
                    {
                        Physics.MaterialType = def.PhysicalMaterial.Id.SubtypeId;
                    }
                }


                var  rigidBody = Physics.RigidBody;
                bool isFixed   = MyDestructionHelper.IsFixed(Physics.BreakableBody.BreakableShape);
                if (isFixed)
                {
                    rigidBody.UpdateMotionType(HkMotionType.Fixed);
                    rigidBody.LinearVelocity  = Vector3.Zero;
                    rigidBody.AngularVelocity = Vector3.Zero;
                }


                Physics.Enabled = true;
            }
            m_children.Clear();
            m_shapeInfos.Clear();
        }
예제 #17
0
        internal void InitFromBreakableBody(HkdBreakableBody b, MatrixD worldMatrix, MyCubeBlock block)
        {
            ProfilerShort.Begin("RemoveGen&SetFixed");

            OriginalBlocks.Clear();
            if (block != null)
            {
                if (block is MyCompoundCubeBlock)
                {
                    foreach (var block2 in (block as MyCompoundCubeBlock).GetBlocks())
                    {
                        OriginalBlocks.Add(block2.BlockDefinition.Id);
                    }
                }
                else if (block is MyFracturedBlock)
                {
                    OriginalBlocks.AddRange((block as MyFracturedBlock).OriginalBlocks);
                }
                else
                {
                    OriginalBlocks.Add(block.BlockDefinition.Id);
                }
            }

            var  rigidBody = b.GetRigidBody();
            bool isFixed   = MyDestructionHelper.IsFixed(b.BreakableShape);

            if (isFixed)
            {
                rigidBody.UpdateMotionType(HkMotionType.Fixed);
                rigidBody.LinearVelocity  = Vector3.Zero;
                rigidBody.AngularVelocity = Vector3.Zero;
            }

            ProfilerShort.Begin("Sync");
            if (SyncFlag)
            {
                CreateSync();
            }
            ProfilerShort.End();

            PositionComp.WorldMatrix = worldMatrix;
            Physics.Flags            = isFixed ? RigidBodyFlag.RBF_STATIC : RigidBodyFlag.RBF_DEBRIS;
            Physics.BreakableBody    = b;
            rigidBody.UserObject     = Physics;
            if (!isFixed)
            {
                rigidBody.Motion.SetDeactivationClass(HkSolverDeactivation.High);
                rigidBody.EnableDeactivation = true;
                if (MyFakes.REDUCE_FRACTURES_COUNT)
                {
                    if (b.BreakableShape.Volume < 1 && MyRandom.Instance.Next(6) > 1)
                    {
                        rigidBody.Layer = MyFracturedPiecesManager.FakePieceLayer;
                    }
                    else
                    {
                        rigidBody.Layer = MyPhysics.CollisionLayers.DefaultCollisionLayer;
                    }
                }
                else
                {
                    rigidBody.Layer = MyPhysics.CollisionLayers.DefaultCollisionLayer;
                }
            }
            else
            {
                rigidBody.Layer = MyPhysics.CollisionLayers.StaticCollisionLayer;
            }
            Physics.BreakableBody.AfterReplaceBody += Physics.FracturedBody_AfterReplaceBody;

            if (OriginalBlocks.Count > 0)
            {
                MyPhysicalModelDefinition def;
                if (MyDefinitionManager.Static.TryGetDefinition <MyPhysicalModelDefinition>(OriginalBlocks[0], out def))
                {
                    Physics.MaterialType = def.PhysicalMaterial.Id.SubtypeId;
                }
            }

            ProfilerShort.BeginNextBlock("Enable");
            Physics.Enabled = true;
            MyDestructionHelper.FixPosition(this);
            SetDataFromHavok(b.BreakableShape);
            var coml = b.GetRigidBody().CenterOfMassLocal;
            var comw = b.GetRigidBody().CenterOfMassWorld;
            var com  = b.BreakableShape.CoM;

            b.GetRigidBody().CenterOfMassLocal = com;
            b.BreakableShape.RemoveReference();
            ProfilerShort.End();
        }
예제 #18
0
 private static float GetRealMass(float physicsMass)
 {
     return(MyDestructionHelper.MassFromHavok(physicsMass));
 }
예제 #19
0
        private void InitInternal()
        {
            // TODO: This will be fixed and made much more simple once ore models are done
            // https://app.asana.com/0/6594565324126/10473934569658

            var itemDefinition = MyDefinitionManager.Static.GetPhysicalItemDefinition(Item.Content);

            m_health = itemDefinition.Health;

            // Setting voxel material (if applicable)
            VoxelMaterial = null;
            if (itemDefinition.VoxelMaterial != MyStringHash.NullOrEmpty)
            {
                VoxelMaterial = MyDefinitionManager.Static.GetVoxelMaterialDefinition(itemDefinition.VoxelMaterial.String);
            }
            else if (Item.Content is MyObjectBuilder_Ore)
            {
                string oreSubTypeId    = itemDefinition.Id.SubtypeName;
                string materialName    = (Item.Content as MyObjectBuilder_Ore).GetMaterialName();
                bool   hasMaterialName = (Item.Content as MyObjectBuilder_Ore).HasMaterialName();

                foreach (var mat in MyDefinitionManager.Static.GetVoxelMaterialDefinitions())
                {
                    if ((hasMaterialName && materialName == mat.Id.SubtypeName) || (hasMaterialName == false && oreSubTypeId == mat.MinedOre))
                    {
                        VoxelMaterial = mat;
                        break;
                    }
                }
            }

            // Setting the item's model
            string model = itemDefinition.Model;

            if (itemDefinition.HasModelVariants)
            {
                int modelNum = itemDefinition.Models.Length;
                Debug.Assert(m_modelVariant >= 0 && m_modelVariant < modelNum, "Model variant overflow. This can happen if model variants changed");
                m_modelVariant = m_modelVariant % modelNum;

                model = itemDefinition.Models[m_modelVariant];
            }
            else if (Item.Content is MyObjectBuilder_Ore && VoxelMaterial != null)
            {
                // Only ores without found voxel material use the defined model (otherwise, the scrap metal does not work)
                model = MyDebris.GetRandomDebrisVoxel();
            }

            // Setting the scale
            float scale = this.Item.Scale;

            if (Item.Content is MyObjectBuilder_Ore)
            {
                scale *= (float)Math.Pow((float)Item.Amount * itemDefinition.Volume / MyDebris.VoxelDebrisModelVolume, 0.333f);
            }
            else
            {
                scale *= (float)Math.Pow(itemDefinition.Volume / itemDefinition.ModelVolume, 0.333f);
            }
            if (scale < 0.05f)
            {
                Close();
            }
            else if (scale < 0.15f)
            {
                scale = 0.15f;
            }

            FormatDisplayName(m_displayedText, Item);
            Debug.Assert(model != null, "Floating object model is null");
            Init(m_displayedText, model, null, null, null);

            PositionComp.Scale = scale; // Must be set after init

            var massProperties = new HkMassProperties();
            var mass           = MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(itemDefinition.Mass) : itemDefinition.Mass;

            mass = mass * (float)Item.Amount;

            HkShape shape       = GetPhysicsShape(mass, scale, out massProperties);
            var     scaleMatrix = Matrix.CreateScale(scale);

            if (Physics != null)
            {
                Physics.Close();
            }
            Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEBRIS);

            int layer = mass > MyPerGameSettings.MinimumLargeShipCollidableMass ? MyPhysics.CollisionLayers.FloatingObjectCollisionLayer : MyPhysics.CollisionLayers.LightFloatingObjectCollisionLayer;

            if (VoxelMaterial != null || (shape.IsConvex && scale != 1f))
            {
                HkConvexTransformShape transform = new HkConvexTransformShape((HkConvexShape)shape, ref scaleMatrix, HkReferencePolicy.None);

                Physics.CreateFromCollisionObject(transform, Vector3.Zero, MatrixD.Identity, massProperties, layer);

                Physics.Enabled = true;
                transform.Base.RemoveReference();
            }
            else
            {
                Physics.CreateFromCollisionObject(shape, Vector3.Zero, MatrixD.Identity, massProperties, layer);
                Physics.Enabled = true;
            }

            Physics.MaterialType            = this.EvaluatePhysicsMaterial(itemDefinition.PhysicalMaterial);
            Physics.PlayCollisionCueEnabled = true;
            Physics.RigidBody.ContactSoundCallbackEnabled = true;
            m_easeCollisionForce      = new HkEasePenetrationAction(Physics.RigidBody, 2f);
            m_massChangeForCollisions = 0.010f;

            NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME;
        }
예제 #20
0
        private bool CreateOwnerVirtualPhysics()
        {
            if (Owner == null)
            {
                return(false);
            }

            OwnerVirtualPhysics = new MyCharacterVirtualPhysicsBody(Owner, RigidBodyFlag.RBF_KINEMATIC);
            var     massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(0.1f, MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(Owner.Definition.Mass) : Owner.Definition.Mass);
            HkShape sh             = new HkSphereShape(0.1f);

            OwnerVirtualPhysics.InitialSolverDeactivation = HkSolverDeactivation.Off;
            MatrixD headWorldMatrix = Owner.GetHeadMatrix(false, forceHeadBone: true);

            OwnerVirtualPhysics.CreateFromCollisionObject(sh, Vector3.Zero, headWorldMatrix, massProperties, Sandbox.Engine.Physics.MyPhysics.NoCollisionLayer);
            OwnerVirtualPhysics.RigidBody.EnableDeactivation = false;
            // Character ray casts includes also NoCollision layer shapes so setup property for ignoring the body
            OwnerVirtualPhysics.RigidBody.SetProperty(HkCharacterRigidBody.MANIPULATED_OBJECT, 0);
            sh.RemoveReference();

            OwnerVirtualPhysics.Enabled = true;

            return(true);
        }
예제 #21
0
        public bool InitRagdoll()
        {
            if (MyFakes.ENABLE_RAGDOLL_DEBUG)
            {
                MyLog.Default.WriteLine("RagdollComponent.InitRagdoll");
            }
            if (base.Character.Physics.Ragdoll != null)
            {
                base.Character.Physics.CloseRagdollMode();
                base.Character.Physics.Ragdoll.ResetToRigPose();
                base.Character.Physics.Ragdoll.SetToKeyframed();
                return(true);
            }
            base.Character.Physics.Ragdoll = new HkRagdoll();
            bool flag = false;

            if ((base.Character.Model.HavokData != null) && (base.Character.Model.HavokData.Length != 0))
            {
                try
                {
                    flag = base.Character.Physics.Ragdoll.LoadRagdollFromBuffer(base.Character.Model.HavokData);
                }
                catch (Exception)
                {
                    base.Character.Physics.CloseRagdoll();
                    base.Character.Physics.Ragdoll = null;
                }
            }
            else if (base.Character.Definition.RagdollDataFile != null)
            {
                string path = Path.Combine(MyFileSystem.ContentPath, base.Character.Definition.RagdollDataFile);
                if (File.Exists(path))
                {
                    flag = base.Character.Physics.Ragdoll.LoadRagdollFromFile(path);
                }
            }
            if (base.Character.Definition.RagdollRootBody != string.Empty)
            {
                base.Character.Physics.Ragdoll.SetRootBody(base.Character.Definition.RagdollRootBody);
            }
            if (!flag)
            {
                base.Character.Physics.Ragdoll.Dispose();
                base.Character.Physics.Ragdoll = null;
            }
            using (List <HkRigidBody> .Enumerator enumerator = base.Character.Physics.Ragdoll.RigidBodies.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    enumerator.Current.UserObject = base.Character;
                }
            }
            if ((base.Character.Physics.Ragdoll != null) && MyPerGameSettings.Destruction)
            {
                base.Character.Physics.Ragdoll.SetToDynamic();
                HkMassProperties properties = new HkMassProperties();
                foreach (HkRigidBody body in base.Character.Physics.Ragdoll.RigidBodies)
                {
                    properties.Mass          = MyDestructionHelper.MassToHavok(body.Mass);
                    properties.InertiaTensor = Matrix.CreateScale((float)0.04f) * body.InertiaTensor;
                    body.SetMassProperties(ref properties);
                }
                base.Character.Physics.Ragdoll.SetToKeyframed();
            }
            if ((base.Character.Physics.Ragdoll != null) && MyFakes.ENABLE_RAGDOLL_DEFAULT_PROPERTIES)
            {
                base.Character.Physics.SetRagdollDefaults();
            }
            if (MyFakes.ENABLE_RAGDOLL_DEBUG)
            {
                MyLog.Default.WriteLine("RagdollComponent.InitRagdoll - FINISHED");
            }
            return(flag);
        }
예제 #22
0
        public override bool HandleInput()
        {
            if (base.HandleInput())
            {
                return(true);
            }

            bool handled = false;

            if (MyInput.Static.IsAnyCtrlKeyPressed() && MyInput.Static.IsNewLeftMouseReleased())
            {
                Hammer();
            }

            if (MyInput.Static.IsNewKeyPressed(MyKeys.NumPad1))
            {
                ApplyMassMultiplier = !ApplyMassMultiplier;
                handled             = true;
            }
            var mul = 1;

            if (MyInput.Static.IsKeyPress(MyKeys.N))
            {
                mul = 10;
            }
            if (MyInput.Static.IsKeyPress(MyKeys.B))
            {
                mul = 100;
            }
            if (MyInput.Static.IsNewKeyPressed(MyKeys.OemQuotes))
            {
                if (MassMultiplier > 1)
                {
                    MassMultiplier += mul;
                }
                else
                {
                    MassMultiplier *= mul;
                }
                handled = true;
            }
            if (MyInput.Static.IsNewKeyPressed(MyKeys.OemSemicolon))
            {
                if (MassMultiplier > 1)
                {
                    MassMultiplier -= mul;
                }
                else
                {
                    MassMultiplier /= mul;
                }
                handled = true;
            }

            if (MySector.MainCamera != null)
            {
                List <MyPhysics.HitInfo> lst = new List <MyPhysics.HitInfo>();
                MyPhysics.CastRay(MySector.MainCamera.Position, MySector.MainCamera.Position + MySector.MainCamera.ForwardVector * 100, lst);
                foreach (var hit in lst)
                {
                    VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(600, 10), hit.HkHitInfo.Body.GetEntity().ToString() + " "
                                                              + MyDestructionHelper.MassFromHavok(hit.HkHitInfo.Body.Mass), Color.White, 0.8f);
                    VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(600, 30), "Layer: " + hit.HkHitInfo.Body.Layer, Color.White, 0.8f);

                    if (hit.HkHitInfo.Body.GetEntity() is MyCubeGrid)
                    {
                        var grid = hit.HkHitInfo.Body.GetEntity() as MyCubeGrid;
                        var det  = grid.GetBlocks().FirstElement().FatBlock.UseObjectsComponent.DetectorPhysics;
                        //var layer = det.RigidBody.Layer;
                    }

                    break;
                }
            }

            if (MyInput.Static.IsNewKeyPressed(MyKeys.NumPad9))
            {
                MyScriptManager.Static.LoadData();
            }

            if (MyAudio.Static != null)
            {
                foreach (var em in MyAudio.Static.Get3DSounds())
                {
                    VRageRender.MyRenderProxy.DebugDrawSphere(em.SourcePosition, 0.1f, Color.Red, 1, false);
                }
            }

            return(handled);
        }
예제 #23
0
        private void InitInternal()
        {
            MyPhysicalItemDefinition physicalItemDefinition = MyDefinitionManager.Static.GetPhysicalItemDefinition(this.Item.Content);

            this.m_health      = physicalItemDefinition.Health;
            this.VoxelMaterial = null;
            if (physicalItemDefinition.VoxelMaterial != MyStringHash.NullOrEmpty)
            {
                this.VoxelMaterial = MyDefinitionManager.Static.GetVoxelMaterialDefinition(physicalItemDefinition.VoxelMaterial.String);
            }
            else if (this.Item.Content is MyObjectBuilder_Ore)
            {
                string subtypeName  = physicalItemDefinition.Id.SubtypeName;
                string materialName = (this.Item.Content as MyObjectBuilder_Ore).GetMaterialName();
                bool   flag         = (this.Item.Content as MyObjectBuilder_Ore).HasMaterialName();
                foreach (MyVoxelMaterialDefinition definition2 in MyDefinitionManager.Static.GetVoxelMaterialDefinitions())
                {
                    if ((flag && (materialName == definition2.Id.SubtypeName)) || (!flag && (subtypeName == definition2.MinedOre)))
                    {
                        this.VoxelMaterial = definition2;
                        break;
                    }
                }
            }
            if ((this.VoxelMaterial != null) && (this.VoxelMaterial.DamagedMaterial != MyStringHash.NullOrEmpty))
            {
                this.VoxelMaterial = MyDefinitionManager.Static.GetVoxelMaterialDefinition(this.VoxelMaterial.DamagedMaterial.ToString());
            }
            string model = physicalItemDefinition.Model;

            if (physicalItemDefinition.HasModelVariants)
            {
                int length = physicalItemDefinition.Models.Length;
                this.m_modelVariant = this.m_modelVariant % length;
                model = physicalItemDefinition.Models[this.m_modelVariant];
            }
            else if ((this.Item.Content is MyObjectBuilder_Ore) && (this.VoxelMaterial != null))
            {
                float num5 = 50f;
                model = MyDebris.GetAmountBasedDebrisVoxel(Math.Max((float)this.Item.Amount, num5));
            }
            float scale = 0.7f;

            this.FormatDisplayName(this.m_displayedText, this.Item);
            float?nullable = null;

            this.Init(this.m_displayedText, model, null, nullable, null);
            HkMassProperties massProperties = new HkMassProperties();
            float            mass           = MathHelper.Clamp((float)((MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(physicalItemDefinition.Mass) : physicalItemDefinition.Mass) * ((float)this.Item.Amount)), (float)3f, (float)100000f);
            HkShape          shape          = this.GetPhysicsShape(mass, scale, out massProperties);

            massProperties.Mass = mass;
            Matrix identity = Matrix.Identity;

            if (this.Physics != null)
            {
                this.Physics.Close();
            }
            this.Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEBRIS);
            int collisionFilter = (mass > MyPerGameSettings.MinimumLargeShipCollidableMass) ? 0x17 : 10;

            this.Physics.LinearDamping  = 0.1f;
            this.Physics.AngularDamping = 2f;
            if (!shape.IsConvex || (shape.ShapeType == HkShapeType.Sphere))
            {
                this.Physics.CreateFromCollisionObject(shape, Vector3.Zero, MatrixD.Identity, new HkMassProperties?(massProperties), collisionFilter);
                this.Physics.Enabled = true;
            }
            else
            {
                HkConvexTransformShape shape2 = new HkConvexTransformShape((HkConvexShape)shape, ref identity, HkReferencePolicy.None);
                this.Physics.CreateFromCollisionObject((HkShape)shape2, Vector3.Zero, MatrixD.Identity, new HkMassProperties?(massProperties), collisionFilter);
                this.Physics.Enabled = true;
                shape2.Base.RemoveReference();
            }
            this.Physics.Friction                = 2f;
            this.Physics.MaterialType            = this.EvaluatePhysicsMaterial(physicalItemDefinition.PhysicalMaterial);
            this.Physics.PlayCollisionCueEnabled = true;
            this.Physics.RigidBody.ContactSoundCallbackEnabled = true;
            base.NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME;
            this.Physics.RigidBody.SetProperty(HkCharacterRigidBody.FLOATING_OBJECT, 0f);
            this.Physics.RigidBody.CenterOfMassLocal = Vector3.Zero;
            HkMassChangerUtil.Create(this.Physics.RigidBody, 0x10200, 1f, 0f);
        }
        public override void UpdateBeforeSimulation()
        {
            //if (MyFakes.ENABLE_RAGDOLL_DEBUG) Debug.WriteLine("RagdollComponent.UpdateBeforeSimulation");
            base.UpdateBeforeSimulation();

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Update Ragdoll");
            UpdateRagdoll();
            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            // TODO: This should be changed so the ragdoll gets registered in the generators, now for SE, apply gravity explictly
            // Apply Gravity on Ragdoll
            // OM: This should be called only in SE, in ME this is handled by world!
            if (Character.Physics != null &&
                Character.Physics.Ragdoll != null &&
                Character.Physics.Ragdoll.InWorld &&
                (!Character.Physics.Ragdoll.IsKeyframed || RagdollMapper.IsPartiallySimulated) &&
                (IsRagdollMoving || m_gravityTimer > 0))
            {
                Vector3 gravity = MyGravityProviderSystem.CalculateTotalGravityInPoint(Character.PositionComp.WorldAABB.Center) + Character.GetPhysicsBody().HavokWorld.Gravity *MyPerGameSettings.CharacterGravityMultiplier;
                Character.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_FORCE, gravity * (MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(Character.Definition.Mass) : Character.Definition.Mass), null, null);
                m_gravityTimer = IsRagdollMoving ? GRAVITY_DELAY : m_gravityTimer - 1;
            }

            if (Character.Physics != null && Character.Physics.Ragdoll != null && IsRagdollMoving)
            {
                m_lastPosition = Character.Physics.Ragdoll.WorldMatrix.Translation;
            }
        }
        public override void UpdateBeforeSimulation()
        {
            //if (MyFakes.ENABLE_RAGDOLL_DEBUG) Debug.WriteLine("RagdollComponent.UpdateBeforeSimulation");
            base.UpdateBeforeSimulation();

            // TODO: This should be changed so the ragdoll gets registered in the generators, now for SE, apply gravity explictly
            // Apply Gravity on Ragdoll
            // OM: This should be called only in SE, in ME this is handled by world!
            if (Character.Physics.Ragdoll != null && Character.Physics.Ragdoll.InWorld && (!Character.Physics.Ragdoll.IsKeyframed || RagdollMapper.IsPartiallySimulated) && (MyPerGameSettings.Game == GameEnum.SE_GAME))
            {
                Vector3 gravity = MyGravityProviderSystem.CalculateTotalGravityInPoint(Character.PositionComp.WorldAABB.Center) + Character.Physics.HavokWorld.Gravity * MyCharacter.CHARACTER_GRAVITY_MULTIPLIER;
                Character.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_FORCE, gravity * (MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(Character.Definition.Mass) : Character.Definition.Mass), null, null);
            }

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Update Ragdoll");
            UpdateRagdoll();
            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
        }
예제 #26
0
        void Physics_ContactPointCallback(ref Engine.Physics.MyPhysics.MyContactPointEvent e)
        {
            //  RestoreDynamicMasses();
            //if (m_frameCounter > DYNAMIC_UPDATE_DELAY)
            //    m_frameCounter = 0;
            //else
            //    return;

            if (m_lastFrameCollision != m_frameCounter)
            {
                DynamicWeights.Clear();
            }

            MyGridContactInfo info = new MyGridContactInfo(ref e.ContactPointEvent, m_grid);

            if (info.CollidingEntity.Physics.IsStatic)
            {
                return;
            }

            float speed = info.CollidingEntity.Physics.LinearVelocity.Length();

            if (speed < 0.1f)
            {
                return;
            }

            Vector3I blockPos = m_grid.WorldToGridInteger(info.ContactPosition + Vector3.Up * 0.25f);

            float dot = Vector3.Dot(Vector3.Normalize(info.CollidingEntity.Physics.LinearVelocity), Vector3.Down);

            float collidingMass = 0;

            m_constrainedGrid.Clear();
            MyCubeGrid collidingGrid = info.CollidingEntity as MyCubeGrid;

            if (collidingGrid != null)
            {
                m_constrainedGrid.Add(collidingGrid);

                AddConstrainedGrids(collidingGrid);

                foreach (var grid in m_constrainedGrid)
                {
                    collidingMass += grid.Physics.Mass;
                }
            }
            else
            {
                collidingMass = info.CollidingEntity.Physics.Mass;
            }

            collidingMass = info.CollidingEntity is Sandbox.Game.Entities.Character.MyCharacter ? MassToSI(collidingMass) : MassToSI(MyDestructionHelper.MassFromHavok(collidingMass));

            float siMass = collidingMass * MyPetaInputComponent.SI_DYNAMICS_MULTIPLIER;

            //if (dot < 0) //impact from downside
            //    return;


            float impact = siMass * speed * dot + siMass;

            if (impact < 0)
            {
                return;
            }

            if (m_grid.GridSizeEnum == MyCubeSize.Large)
            {
            }

            DynamicWeights[blockPos] = impact;

            m_needsRecalc = true;

            m_lastFrameCollision = m_frameCounter;

            if (!m_collidingEntities.ContainsKey(info.CollidingEntity))
            {
                m_collidingEntities.Add(info.CollidingEntity, new CollidingEntityInfo()
                {
                    Position  = blockPos,
                    FrameTime = m_frameCounter
                });
                info.CollidingEntity.PositionComp.OnPositionChanged += PositionComp_OnPositionChanged;
            }
            else
            {
                m_collidingEntities[info.CollidingEntity].FrameTime = m_frameCounter;
            }
        }
        /// <summary>
        /// Loads Ragdoll data
        /// </summary>
        /// <param name="ragDollFile"></param>
        public bool InitRagdoll()
        {
            if (MyFakes.ENABLE_RAGDOLL_DEBUG)
            {
                Debug.WriteLine("RagdollComponent.InitRagdoll");
                MyLog.Default.WriteLine("RagdollComponent.InitRagdoll");
            }

            if (Character.Physics.Ragdoll != null)
            {
                Character.Physics.CloseRagdollMode();
                Character.Physics.Ragdoll.ResetToRigPose();

                Character.Physics.Ragdoll.SetToKeyframed();
                return(true);
            }

            Character.Physics.Ragdoll = new HkRagdoll();

            bool dataLoaded = false;

            if (Character.Model.HavokData != null && Character.Model.HavokData.Length > 0)
            {
                try
                {
                    dataLoaded = Character.Physics.Ragdoll.LoadRagdollFromBuffer(Character.Model.HavokData);
                }
                catch (Exception e)
                {
                    Debug.Fail("Error loading ragdoll from buffer: " + e.Message);
                    Character.Physics.CloseRagdoll();
                    Character.Physics.Ragdoll = null;
                }
            }
            else if (Character.Definition.RagdollDataFile != null)
            {
                String ragDollFile = System.IO.Path.Combine(MyFileSystem.ContentPath, Character.Definition.RagdollDataFile);
                if (System.IO.File.Exists(ragDollFile))
                {
                    dataLoaded = Character.Physics.Ragdoll.LoadRagdollFromFile(ragDollFile);
                }
                else
                {
                    System.Diagnostics.Debug.Fail("Cannot find ragdoll file: " + ragDollFile);
                }
            }

            if (Character.Definition.RagdollRootBody != String.Empty)
            {
                if (!Character.Physics.Ragdoll.SetRootBody(Character.Definition.RagdollRootBody))
                {
                    Debug.Fail("Can not set root body with name: " + Character.Definition.RagdollRootBody + " on model " + Character.ModelName + ". Please check your definitions.");
                }
            }

            if (!dataLoaded)
            {
                Character.Physics.Ragdoll.Dispose();
                Character.Physics.Ragdoll = null;
            }
            foreach (var body in Character.Physics.Ragdoll.RigidBodies)
            {
                body.UserObject = Character;
            }

            if (Character.Physics.Ragdoll != null && MyPerGameSettings.Destruction) //scaling weights and IT
            {
                Character.Physics.Ragdoll.SetToDynamic();
                var mp = new HkMassProperties();
                foreach (var body in Character.Physics.Ragdoll.RigidBodies)
                {
                    mp.Mass          = MyDestructionHelper.MassToHavok(body.Mass);
                    mp.InertiaTensor = Matrix.CreateScale(1.0f / 25.0f) * body.InertiaTensor;
                    body.SetMassProperties(ref mp);
                }
                Character.Physics.Ragdoll.SetToKeyframed();
            }

            if (Character.Physics.Ragdoll != null && MyFakes.ENABLE_RAGDOLL_DEFAULT_PROPERTIES)
            {
                Character.Physics.SetRagdollDefaults();
            }

            if (MyFakes.ENABLE_RAGDOLL_DEBUG)
            {
                Debug.WriteLine("RagdollComponent.InitRagdoll - FINISHED");
                MyLog.Default.WriteLine("RagdollComponent.InitRagdoll - FINISHED");
            }

            return(dataLoaded);
        }
예제 #28
0
        public void InitFromDefinition(MyObjectBuilder_EntityBase entityBuilder, MyDefinitionId definitionId)
        {
            Debug.Assert(entityBuilder != null, "Invalid arguments!");

            MyPhysicalItemDefinition entityDefinition;

            if (!MyDefinitionManager.Static.TryGetDefinition(definitionId, out entityDefinition))
            {
                Debug.Fail("Definition: " + DefinitionId.ToString() + " was not found!");
                return;
            }

            DefinitionId = definitionId;

            Flags |= EntityFlags.Visible | EntityFlags.NeedsDraw | EntityFlags.Sync | EntityFlags.InvalidateOnMove;

            StringBuilder name = new StringBuilder(entityDefinition.DisplayNameText);

            Init(name, entityDefinition.Model, null, null, null);

            CreateSync();

            if (entityBuilder.PositionAndOrientation.HasValue)
            {
                MatrixD worldMatrix = MatrixD.CreateWorld(
                    (Vector3D)entityBuilder.PositionAndOrientation.Value.Position,
                    (Vector3)entityBuilder.PositionAndOrientation.Value.Forward,
                    (Vector3)entityBuilder.PositionAndOrientation.Value.Up);
                PositionComp.SetWorldMatrix(worldMatrix);
            }

            Name = name.Append("_(").Append(entityBuilder.EntityId).Append(")").ToString();

            Render.UpdateRenderObject(true);

            Physics = new Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_DEFAULT);
            if (ModelCollision != null && ModelCollision.HavokCollisionShapes.Length >= 1)
            {
                HkMassProperties massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(entityDefinition.Size / 2, (MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(entityDefinition.Mass) : entityDefinition.Mass));;
                Physics.CreateFromCollisionObject(ModelCollision.HavokCollisionShapes[0], Vector3.Zero, WorldMatrix, massProperties);
                Physics.RigidBody.AngularDamping = 2;
                Physics.RigidBody.LinearDamping  = 1;
            }
            Physics.Enabled = true;

            EntityId = entityBuilder.EntityId;
        }