Beispiel #1
0
        protected override void Init(MyObjectBuilder_DefinitionBase builder)
        {
            base.Init(builder);

            var ob = builder as MyObjectBuilder_CubeBlockDefinition;

            MyDebug.AssertDebug(ob != null);

            this.Size  = ob.Size;
            this.Model = ob.Model;
            this.UseModelIntersection = ob.UseModelIntersection;
            this.CubeSize             = ob.CubeSize;
            this.ModelOffset          = ob.ModelOffset;
            this.BlockTopology        = ob.BlockTopology;
            this.PhysicsOption        = ob.PhysicsOption;
            this.BlockPairName        = ob.BlockPairName;
            this.m_center             = ob.Center ?? ((Size - 1) / 2);
            this.m_symmetryX          = ob.MirroringX;
            this.m_symmetryY          = ob.MirroringY;
            this.m_symmetryZ          = ob.MirroringZ;
            this.DeformationRatio     = ob.DeformationRatio;
            this.EdgeType             = ob.EdgeType;
            this.AutorotateMode       = ob.AutorotateMode;
            this.m_mirroringBlock     = ob.MirroringBlock;
            this.MultiBlock           = ob.MultiBlock;
            this.GuiVisible           = ob.GuiVisible;
            this.Rotation             = ob.Rotation;
            this.Direction            = ob.Direction;
            this.Mirrored             = ob.Mirrored;
            this.RandomRotation       = ob.RandomRotation;
            this.BuildType            = ob.BuildType != null?ob.BuildType.ToLower() : null;

            this.GeneratedBlockType = MyStringId.GetOrCompute(ob.GeneratedBlockType != null ? ob.GeneratedBlockType.ToLower() : null);
            if (ob.DamageEffectId != 0)
            {
                this.DamageEffectID = ob.DamageEffectId;
            }

            this.CompoundTemplates = ob.CompoundTemplates;
            Debug.Assert(this.CompoundTemplates == null || this.CompoundTemplates.Length > 0, "Wrong compound templates, array is empty");

            if (ob.SubBlockDefinitions != null)
            {
                SubBlockDefinitions = new Dictionary <string, MyDefinitionId>();

                foreach (var definition in ob.SubBlockDefinitions)
                {
                    MyDefinitionId defId;
                    if (SubBlockDefinitions.TryGetValue(definition.SubBlock, out defId))
                    {
                        MyDebug.AssertDebug(false, "Subblock definition already defined!");
                        continue;
                    }

                    defId = definition.Id;
                    SubBlockDefinitions.Add(definition.SubBlock, defId);
                }
            }

            if (ob.BlockVariants != null)
            {
                BlockStages = new MyDefinitionId[ob.BlockVariants.Length];

                for (int i = 0; i < ob.BlockVariants.Length; ++i)
                {
                    BlockStages[i] = ob.BlockVariants[i];
                }
            }

            var cubeDef = ob.CubeDefinition;

            if (cubeDef != null)
            {
                MyCubeDefinition tmp = new MyCubeDefinition();
                tmp.CubeTopology = cubeDef.CubeTopology;
                tmp.ShowEdges    = cubeDef.ShowEdges;

                var sides = cubeDef.Sides;
                tmp.Model       = new string[sides.Length];
                tmp.PatternSize = new Vector2I[sides.Length];
                for (int j = 0; j < sides.Length; ++j)
                {
                    var side = sides[j];
                    tmp.Model[j]       = side.Model;
                    tmp.PatternSize[j] = side.PatternSize;
                }
                this.CubeDefinition = tmp;
            }

            var components = ob.Components;

            MyDebug.AssertDebug(components != null);
            MyDebug.AssertDebug(components.Length != 0);
            float mass = 0.0f;
            float criticalIntegrity  = 0f;
            float ownershipIntegrity = 0f;

            if (components != null && components.Length != 0)
            {
                Components = new MyCubeBlockDefinition.Component[components.Length];

                float integrity           = 0.0f;
                int   criticalTypeCounter = 0;
                for (int j = 0; j < components.Length; ++j)
                {
                    var component = components[j];

                    MyCubeBlockDefinition.Component tmp = new MyCubeBlockDefinition.Component()
                    {
                        Count      = component.Count,
                        Definition = MyDefinitionManager.Static.GetComponentDefinition(new MyDefinitionId(component.Type, component.Subtype))
                    };

                    if (component.Type == typeof(MyObjectBuilder_Component) && component.Subtype == "Computer")
                    {
                        if (ownershipIntegrity == 0)
                        {
                            ownershipIntegrity = integrity + tmp.Definition.MaxIntegrity;
                        }
                    }

                    integrity += tmp.Count * tmp.Definition.MaxIntegrity;
                    if (component.Type == ob.CriticalComponent.Type &&
                        component.Subtype == ob.CriticalComponent.Subtype)
                    {
                        if (criticalTypeCounter == ob.CriticalComponent.Index)
                        {
                            CriticalGroup     = (UInt16)j;
                            criticalIntegrity = integrity - 1;
                        }
                        ++criticalTypeCounter;
                    }

                    mass += tmp.Count * tmp.Definition.Mass;

                    Components[j] = tmp;
                }
                MaxIntegrity          = integrity;
                IntegrityPointsPerSec = integrity / ob.BuildTimeSeconds;
                DisassembleRatio      = ob.DisassembleRatio;
                Mass = mass;
            }

            CriticalIntegrityRatio  = criticalIntegrity / MaxIntegrity;
            OwnershipIntegrityRatio = ownershipIntegrity / MaxIntegrity;

            if (ob.BuildProgressModels != null)
            {
                ob.BuildProgressModels.Sort((a, b) => a.BuildPercentUpperBound.CompareTo(b.BuildPercentUpperBound));
                this.BuildProgressModels = new BuildProgressModel[ob.BuildProgressModels.Count];
                for (int i = 0; i < BuildProgressModels.Length; ++i)
                {
                    var builderModel = ob.BuildProgressModels[i];
                    if (!string.IsNullOrEmpty(builderModel.File))
                    {
                        this.BuildProgressModels[i] = new BuildProgressModel()
                        {
                            BuildRatioUpperBound = builderModel.BuildPercentUpperBound * CriticalIntegrityRatio,
                            File = builderModel.File,
                            RandomOrientation = builderModel.RandomOrientation
                        };
                    }
                }
            }

            if (ob.GeneratedBlocks != null)
            {
                this.GeneratedBlockDefinitions = new MyDefinitionId[ob.GeneratedBlocks.Length];

                for (int i = 0; i < ob.GeneratedBlocks.Length; ++i)
                {
                    var genBlockId = ob.GeneratedBlocks[i];
                    Debug.Assert(!string.IsNullOrEmpty(genBlockId.SubtypeName));
                    Debug.Assert(!string.IsNullOrEmpty(genBlockId.TypeIdString));

                    this.GeneratedBlockDefinitions[i] = genBlockId;
                }
            }

            Skeleton = ob.Skeleton;
            if (Skeleton != null)
            {
                Bones = new Dictionary <Vector3I, Vector3>(ob.Skeleton.Count);
                foreach (var bone in Skeleton)
                {
                    Bones[bone.BonePosition] = Vector3UByte.Denormalize(bone.BoneOffset, MyDefinitionManager.Static.GetCubeSize(ob.CubeSize));
                }
            }

            IsAirTight = ob.IsAirTight;

            InitMountPoints(ob);
            InitPressurization();

            InitNavigationInfo(ob, ob.NavigationDefinition);

            CheckBuildProgressModels();
            // Components and CriticalComponent will be initialized elsewhere

            this.PrimarySound = new MySoundPair(ob.PrimarySound);
        }
        void CollectBlock(MySlimBlock block, MyPhysicsOption physicsOption, IDictionary <Vector3I, HkMassElement> massResults, bool allowSegmentation = true)
        {
            if (!block.HasPhysics)
            {
                return;
            }

            if (massResults != null)
            {
                AddMass(block, massResults);
            }

            if (block.BlockDefinition.BlockTopology == MyBlockTopology.Cube)
            {
                Debug.Assert(block.Min == block.Max, "Calculation assume that cube blocks have size 1x1x1");
                var cubeTopology = block.BlockDefinition.CubeDefinition.CubeTopology;
                if (MyFakes.ENABLE_SIMPLE_GRID_PHYSICS)
                {
                    physicsOption = MyPhysicsOption.Box;
                }
                else if ((cubeTopology == MyCubeTopology.Box) && block.CubeGrid.Skeleton.IsDeformed(block.Min, 0.05f, block.CubeGrid, false))
                {
                    physicsOption = MyPhysicsOption.Convex;
                }

                switch (physicsOption)
                {
                case MyPhysicsOption.Box:
                    AddBoxes(block);
                    break;

                case MyPhysicsOption.Convex:
                    AddConvexShape(block, true);
                    break;
                }
            }
            else
            {
                if (physicsOption != MyPhysicsOption.None)
                {
                    var havokShapes = block.FatBlock.ModelCollision.HavokCollisionShapes;

                    if ((havokShapes != null && havokShapes.Length > 0) && !MyFakes.ENABLE_SIMPLE_GRID_PHYSICS)
                    {
                        // first set of shapes goes into block.Position
                        Vector3 blockPos;
                        if (block.FatBlock.ModelCollision.ExportedWrong)
                        {
                            blockPos = block.Position * block.CubeGrid.GridSize;
                        }
                        else
                        {
                            blockPos = block.FatBlock.PositionComp.LocalMatrix.Translation;
                        }
                        HkShape[]  shapes = block.FatBlock.ModelCollision.HavokCollisionShapes;
                        Quaternion blockOrientation;
                        block.Orientation.GetQuaternion(out blockOrientation);

                        if (shapes.Length == 1 && shapes[0].ShapeType == HkShapeType.List)
                        {
                            HkListShape list = (HkListShape)shapes[0];
                            for (int i = 0; i < list.TotalChildrenCount; i++)
                            {
                                HkShape child = list.GetChildByIndex(i);
                                System.Diagnostics.Debug.Assert(child.IsConvex, "Children in the list must be convex!");
                                Shapes.Add(new HkConvexTransformShape((HkConvexShape)child, ref blockPos, ref blockOrientation, ref Vector3.One, HkReferencePolicy.None));
                            }
                        }
                        else
                        if (shapes.Length == 1 && shapes[0].ShapeType == HkShapeType.Mopp)
                        {
                            HkMoppBvTreeShape list = (HkMoppBvTreeShape)shapes[0];
                            for (int i = 0; i < list.ShapeCollection.ShapeCount; i++)
                            {
                                HkShape child = list.ShapeCollection.GetShape((uint)i, null);
                                System.Diagnostics.Debug.Assert(child.IsConvex, "Children in the list must be convex!");
                                Shapes.Add(new HkConvexTransformShape((HkConvexShape)child, ref blockPos, ref blockOrientation, ref Vector3.One, HkReferencePolicy.None));
                            }
                        }
                        else
                        {
                            for (int i = 0; i < shapes.Length; i++)
                            {
                                Shapes.Add(new HkConvexTransformShape((HkConvexShape)shapes[i], ref blockPos, ref blockOrientation, ref Vector3.One, HkReferencePolicy.None));
                            }
                        }
                        ShapeInfos.Add(new ShapeInfo()
                        {
                            Count = shapes.Length, Min = block.Min, Max = block.Max
                        });
                    }
                    else
                    {
                        // This will add boxes
                        for (int x = block.Min.X; x <= block.Max.X; x++)
                        {
                            for (int y = block.Min.Y; y <= block.Max.Y; y++)
                            {
                                for (int z = block.Min.Z; z <= block.Max.Z; z++)
                                {
                                    var pos = new Vector3I(x, y, z);
                                    // NOTE: Disabled because it's not visually represented
                                    //if (block.CubeGrid.Skeleton.IsDeformed(pos, 0.05f) && !MyFakes.ENABLE_SIMPLE_GRID_PHYSICS)
                                    //{
                                    //    AddConvexShape(pos, block.CubeGrid.Skeleton, false);
                                    //}
                                    //else

                                    if (allowSegmentation)
                                    {
                                        m_tmpCubes.Add(pos);
                                    }
                                    else
                                    {
                                        Vector3 min = pos * block.CubeGrid.GridSize - new Vector3(block.CubeGrid.GridSize / 2.0f);
                                        Vector3 max = pos * block.CubeGrid.GridSize + new Vector3(block.CubeGrid.GridSize / 2.0f);
                                        AddBox(pos, pos, ref min, ref max);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        protected override void Init(MyObjectBuilder_DefinitionBase builder)
        {
            base.Init(builder);

            var ob = builder as MyObjectBuilder_CubeBlockDefinition;
            MyDebug.AssertDebug(ob != null);

            this.Size                  = ob.Size;
            this.Model                 = ob.Model;
            this.UseModelIntersection  = ob.UseModelIntersection;
            this.CubeSize              = ob.CubeSize;
            this.ModelOffset           = ob.ModelOffset;
            this.BlockTopology         = ob.BlockTopology;
            this.PhysicsOption         = ob.PhysicsOption;
            this.BlockPairName         = ob.BlockPairName;
            this.m_center              = ob.Center ?? ((Size - 1) / 2);
            this.m_symmetryX           = ob.MirroringX;
            this.m_symmetryY           = ob.MirroringY;
            this.m_symmetryZ           = ob.MirroringZ;
            this.DeformationRatio      = ob.DeformationRatio;
            this.EdgeType              = ob.EdgeType;
            this.AutorotateMode        = ob.AutorotateMode;
            this.m_mirroringBlock      = ob.MirroringBlock;
            this.MultiBlock            = ob.MultiBlock;
            this.GuiVisible            = ob.GuiVisible;
            this.Rotation              = ob.Rotation;
            this.Direction             = ob.Direction;
            this.Mirrored              = ob.Mirrored;
            this.RandomRotation        = ob.RandomRotation;
            this.BuildType             = ob.BuildType != null ? ob.BuildType.ToLower() : null;
            this.GeneratedBlockType    = MyStringId.GetOrCompute(ob.GeneratedBlockType != null ? ob.GeneratedBlockType.ToLower() : null);
            if (ob.DamageEffectId != 0)
                this.DamageEffectID = ob.DamageEffectId;

            this.CompoundTemplates = ob.CompoundTemplates;
            Debug.Assert(this.CompoundTemplates == null || this.CompoundTemplates.Length > 0, "Wrong compound templates, array is empty");

            if (ob.SubBlockDefinitions != null)
            {
                SubBlockDefinitions = new Dictionary<string, MyDefinitionId>();

                foreach (var definition in ob.SubBlockDefinitions)
                {
                    MyDefinitionId defId;
                    if (SubBlockDefinitions.TryGetValue(definition.SubBlock, out defId))
                    {
                        MyDebug.AssertDebug(false, "Subblock definition already defined!");
                        continue;
                    }

                    defId = definition.Id;
                    SubBlockDefinitions.Add(definition.SubBlock, defId);
                }
            }

            if (ob.BlockVariants != null)
            {
                BlockStages = new MyDefinitionId[ob.BlockVariants.Length];

                for (int i = 0; i < ob.BlockVariants.Length; ++i)
                {
                    BlockStages[i] = ob.BlockVariants[i];
                }
            }

            var cubeDef = ob.CubeDefinition;
            if (cubeDef != null)
            {
                MyCubeDefinition tmp = new MyCubeDefinition();
                tmp.CubeTopology = cubeDef.CubeTopology;
                tmp.ShowEdges = cubeDef.ShowEdges;

                var sides = cubeDef.Sides;
                tmp.Model = new string[sides.Length];
                tmp.PatternSize = new Vector2I[sides.Length];
                for (int j = 0; j < sides.Length; ++j)
                {
                    var side = sides[j];
                    tmp.Model[j] = side.Model;
                    tmp.PatternSize[j] = side.PatternSize;
                }
                this.CubeDefinition = tmp;
            }

            var components = ob.Components;
            MyDebug.AssertDebug(components != null);
            MyDebug.AssertDebug(components.Length != 0);
            float mass = 0.0f;
            float criticalIntegrity = 0f;
            float ownershipIntegrity = 0f;
            if (components != null && components.Length != 0)
            {
                Components = new MyCubeBlockDefinition.Component[components.Length];

                float integrity = 0.0f;
                int criticalTypeCounter = 0;
                for (int j = 0; j < components.Length; ++j)
                {
                    var component = components[j];

                    MyCubeBlockDefinition.Component tmp = new MyCubeBlockDefinition.Component()
                    {
                        Count = component.Count,
                        Definition = MyDefinitionManager.Static.GetComponentDefinition(new MyDefinitionId(component.Type, component.Subtype))
                    };

                    if (component.Type == typeof(MyObjectBuilder_Component) && component.Subtype == "Computer")
                    {
                        if (ownershipIntegrity == 0)
                            ownershipIntegrity = integrity + tmp.Definition.MaxIntegrity;
                    }

                    integrity += tmp.Count * tmp.Definition.MaxIntegrity;
                    if (component.Type == ob.CriticalComponent.Type &&
                        component.Subtype == ob.CriticalComponent.Subtype)
                    {
                        if (criticalTypeCounter == ob.CriticalComponent.Index)
                        {
                            CriticalGroup = (UInt16)j;
                            criticalIntegrity = integrity-1;
                        }
                        ++criticalTypeCounter;
                    }

                    mass += tmp.Count * tmp.Definition.Mass;

                    Components[j] = tmp;
                }
                MaxIntegrity = integrity;
                IntegrityPointsPerSec = integrity / ob.BuildTimeSeconds;
                DisassembleRatio = ob.DisassembleRatio;
                Mass = mass;
            }

            CriticalIntegrityRatio = criticalIntegrity / MaxIntegrity;
            OwnershipIntegrityRatio = ownershipIntegrity / MaxIntegrity;

            if (ob.BuildProgressModels != null)
            {
                ob.BuildProgressModels.Sort((a, b) => a.BuildPercentUpperBound.CompareTo(b.BuildPercentUpperBound));
                this.BuildProgressModels = new BuildProgressModel[ob.BuildProgressModels.Count];
                for (int i = 0; i < BuildProgressModels.Length; ++i)
                {
                    var builderModel = ob.BuildProgressModels[i];
                    if (!string.IsNullOrEmpty(builderModel.File))
                    {
                        this.BuildProgressModels[i] = new BuildProgressModel()
                        {
                            BuildRatioUpperBound = builderModel.BuildPercentUpperBound * CriticalIntegrityRatio,
                            File = builderModel.File,
                            RandomOrientation = builderModel.RandomOrientation
                        };
                    }
                }
            }

            if (ob.GeneratedBlocks != null)
            {
                this.GeneratedBlockDefinitions = new MyDefinitionId[ob.GeneratedBlocks.Length];

                for (int i = 0; i < ob.GeneratedBlocks.Length; ++i)
                {
                    var genBlockId = ob.GeneratedBlocks[i];
                    Debug.Assert(!string.IsNullOrEmpty(genBlockId.SubtypeName));
                    Debug.Assert(!string.IsNullOrEmpty(genBlockId.TypeIdString));

                    this.GeneratedBlockDefinitions[i] = genBlockId;
                }
            }

            Skeleton = ob.Skeleton;
            if (Skeleton != null)
            {
                Bones = new Dictionary<Vector3I,Vector3>(ob.Skeleton.Count);
                foreach (var bone in Skeleton)
                {
                    Bones[bone.BonePosition] = Vector3UByte.Denormalize(bone.BoneOffset, MyDefinitionManager.Static.GetCubeSize(ob.CubeSize));
                }
            }

            IsAirTight = ob.IsAirTight;

            InitMountPoints(ob);
            InitPressurization();

            InitNavigationInfo(ob, ob.NavigationDefinition);

            CheckBuildProgressModels();
            // Components and CriticalComponent will be initialized elsewhere

            this.PrimarySound = new MySoundPair(ob.PrimarySound);
        }
Beispiel #4
0
 private void CollectBlock(MySlimBlock block, MyPhysicsOption physicsOption, IDictionary <Vector3I, HkMassElement> massResults, bool allowSegmentation = true)
 {
     if (block.BlockDefinition.HasPhysics && (block.CubeGrid != null))
     {
         if (massResults != null)
         {
             this.AddMass(block, massResults);
         }
         if (block.BlockDefinition.BlockTopology == MyBlockTopology.Cube)
         {
             MyCubeTopology topology = (block.BlockDefinition.CubeDefinition != null) ? block.BlockDefinition.CubeDefinition.CubeTopology : MyCubeTopology.Box;
             if (MyFakes.ENABLE_SIMPLE_GRID_PHYSICS)
             {
                 physicsOption = MyPhysicsOption.Box;
             }
             else if (topology == MyCubeTopology.Box)
             {
                 if (!block.ShowParts)
                 {
                     physicsOption = MyPhysicsOption.Box;
                 }
                 else if ((block.BlockDefinition.CubeDefinition != null) && block.CubeGrid.Skeleton.IsDeformed(block.Min, 0.05f, block.CubeGrid, false))
                 {
                     physicsOption = MyPhysicsOption.Convex;
                 }
             }
             if (physicsOption == MyPhysicsOption.Box)
             {
                 this.AddBoxes(block);
             }
             else if (physicsOption == MyPhysicsOption.Convex)
             {
                 this.AddConvexShape(block, block.ShowParts);
             }
         }
         else if (physicsOption != MyPhysicsOption.None)
         {
             HkShape[] havokCollisionShapes = null;
             if (block.FatBlock != null)
             {
                 havokCollisionShapes = block.FatBlock.ModelCollision.HavokCollisionShapes;
             }
             if (((havokCollisionShapes != null) && (havokCollisionShapes.Length != 0)) && !MyFakes.ENABLE_SIMPLE_GRID_PHYSICS)
             {
                 Vector3    translation;
                 Quaternion quaternion;
                 if (block.FatBlock.ModelCollision.ExportedWrong)
                 {
                     translation = (Vector3)(block.Position * block.CubeGrid.GridSize);
                 }
                 else
                 {
                     translation = block.FatBlock.PositionComp.LocalMatrix.Translation;
                 }
                 HkShape[] havokCollisionShapes = block.FatBlock.ModelCollision.HavokCollisionShapes;
                 block.Orientation.GetQuaternion(out quaternion);
                 Vector3 scale = Vector3.One * block.FatBlock.ModelCollision.ScaleFactor;
                 if ((havokCollisionShapes.Length == 1) && (havokCollisionShapes[0].ShapeType == HkShapeType.List))
                 {
                     HkListShape shape = (HkListShape)havokCollisionShapes[0];
                     for (int i = 0; i < shape.TotalChildrenCount; i++)
                     {
                         HkShape childByIndex = shape.GetChildByIndex(i);
                         this.Shapes.Add((HkShape) new HkConvexTransformShape((HkConvexShape)childByIndex, ref translation, ref quaternion, ref scale, HkReferencePolicy.None));
                     }
                 }
                 else if ((havokCollisionShapes.Length != 1) || (havokCollisionShapes[0].ShapeType != HkShapeType.Mopp))
                 {
                     for (int i = 0; i < havokCollisionShapes.Length; i++)
                     {
                         this.Shapes.Add((HkShape) new HkConvexTransformShape((HkConvexShape)havokCollisionShapes[i], ref translation, ref quaternion, ref scale, HkReferencePolicy.None));
                     }
                 }
                 else
                 {
                     HkMoppBvTreeShape shape3 = (HkMoppBvTreeShape)havokCollisionShapes[0];
                     int num2 = 0;
                     while (true)
                     {
                         HkShapeCollection shapeCollection = shape3.ShapeCollection;
                         if (num2 >= shapeCollection.ShapeCount)
                         {
                             break;
                         }
                         HkShape shape = shape3.ShapeCollection.GetShape((uint)num2, null);
                         this.Shapes.Add((HkShape) new HkConvexTransformShape((HkConvexShape)shape, ref translation, ref quaternion, ref scale, HkReferencePolicy.None));
                         num2++;
                     }
                 }
                 ShapeInfo item = new ShapeInfo {
                     Count = havokCollisionShapes.Length,
                     Min   = block.Min,
                     Max   = block.Max
                 };
                 this.ShapeInfos.Add(item);
             }
             else
             {
                 int x = block.Min.X;
                 while (x <= block.Max.X)
                 {
                     int y = block.Min.Y;
                     while (true)
                     {
                         if (y > block.Max.Y)
                         {
                             x++;
                             break;
                         }
                         int z = block.Min.Z;
                         while (true)
                         {
                             if (z > block.Max.Z)
                             {
                                 y++;
                                 break;
                             }
                             Vector3I item = new Vector3I(x, y, z);
                             if (allowSegmentation)
                             {
                                 this.m_tmpCubes.Add(item);
                             }
                             else
                             {
                                 Vector3 min = ((Vector3)(item * block.CubeGrid.GridSize)) - new Vector3(block.CubeGrid.GridSize / 2f);
                                 Vector3 max = (item * block.CubeGrid.GridSize) + new Vector3(block.CubeGrid.GridSize / 2f);
                                 this.AddBox(item, item, ref min, ref max);
                             }
                             z++;
                         }
                     }
                 }
             }
         }
     }
 }
        void CollectBlock(MySlimBlock block, MyPhysicsOption physicsOption, IDictionary<Vector3I, HkMassElement> massResults, bool allowSegmentation = true)
        {
            if (!block.HasPhysics)
                return;

            if (massResults != null)
                AddMass(block, massResults);

            if (block.BlockDefinition.BlockTopology == MyBlockTopology.Cube)
            {
                Debug.Assert(block.Min == block.Max, "Calculation assume that cube blocks have size 1x1x1");
                var cubeTopology = block.BlockDefinition.CubeDefinition.CubeTopology;
                if (MyFakes.ENABLE_SIMPLE_GRID_PHYSICS)
                {
                    physicsOption = MyPhysicsOption.Box;
                }
                else if ((cubeTopology == MyCubeTopology.Box) && block.CubeGrid.Skeleton.IsDeformed(block.Min, 0.05f, block.CubeGrid, false))
                {
                    physicsOption = MyPhysicsOption.Convex;
                }

                switch (physicsOption)
                {
                    case MyPhysicsOption.Box:
                        AddBoxes(block);
                        break;

                    case MyPhysicsOption.Convex:
                        AddConvexShape(block, true);
                        break;
                }
            }
            else
            {
                if (physicsOption != MyPhysicsOption.None)
                {
                    var havokShapes = block.FatBlock.ModelCollision.HavokCollisionShapes;

                    if ((havokShapes != null && havokShapes.Length > 0) && !MyFakes.ENABLE_SIMPLE_GRID_PHYSICS)
                    {
                        // first set of shapes goes into block.Position
                        Vector3 blockPos;
                        if (block.FatBlock.ModelCollision.ExportedWrong)
                        {
                            blockPos = block.Position * block.CubeGrid.GridSize;
                        }
                        else
                        {
                            blockPos = block.FatBlock.PositionComp.LocalMatrix.Translation;
                        }
                        HkShape[] shapes = block.FatBlock.ModelCollision.HavokCollisionShapes;
                        Quaternion blockOrientation;
                        block.Orientation.GetQuaternion(out blockOrientation);

                        if (shapes.Length == 1 && shapes[0].ShapeType == HkShapeType.List)
                        {
                            HkListShape list = (HkListShape)shapes[0];
                            for (int i = 0; i < list.TotalChildrenCount; i++)
                            {
                                HkShape child = list.GetChildByIndex(i);
                                System.Diagnostics.Debug.Assert(child.IsConvex, "Children in the list must be convex!");
                                Shapes.Add(new HkConvexTransformShape((HkConvexShape)child, ref blockPos, ref blockOrientation, ref Vector3.One, HkReferencePolicy.None));
                            }
                        }
                        else
                            if (shapes.Length == 1 && shapes[0].ShapeType == HkShapeType.Mopp)
                            {
                                HkMoppBvTreeShape list = (HkMoppBvTreeShape)shapes[0];
                                for (int i = 0; i < list.ShapeCollection.ShapeCount; i++)
                                {
                                    HkShape child = list.ShapeCollection.GetShape((uint)i, null);
                                    System.Diagnostics.Debug.Assert(child.IsConvex, "Children in the list must be convex!");
                                    Shapes.Add(new HkConvexTransformShape((HkConvexShape)child, ref blockPos, ref blockOrientation, ref Vector3.One, HkReferencePolicy.None));
                                }
                            }
                            else

                            for (int i = 0; i < shapes.Length; i++)
                            {
                                Shapes.Add(new HkConvexTransformShape((HkConvexShape)shapes[i], ref blockPos, ref blockOrientation, ref Vector3.One, HkReferencePolicy.None));
                            }
                        ShapeInfos.Add(new ShapeInfo() { Count = shapes.Length, Min = block.Min, Max = block.Max });
                    }
                    else
                    {
                        // This will add boxes
                        for (int x = block.Min.X; x <= block.Max.X; x++)
                        {
                            for (int y = block.Min.Y; y <= block.Max.Y; y++)
                            {
                                for (int z = block.Min.Z; z <= block.Max.Z; z++)
                                {
                                    var pos = new Vector3I(x, y, z);
                                    // NOTE: Disabled because it's not visually represented
                                    //if (block.CubeGrid.Skeleton.IsDeformed(pos, 0.05f) && !MyFakes.ENABLE_SIMPLE_GRID_PHYSICS)
                                    //{
                                    //    AddConvexShape(pos, block.CubeGrid.Skeleton, false);
                                    //}
                                    //else

                                    if (allowSegmentation)
                                    {
                                        m_tmpCubes.Add(pos);
                                    }
                                    else
                                    {
                                        Vector3 min = pos * block.CubeGrid.GridSize - new Vector3(block.CubeGrid.GridSize / 2.0f);
                                        Vector3 max = pos * block.CubeGrid.GridSize + new Vector3(block.CubeGrid.GridSize / 2.0f);
                                        AddBox(pos, pos, ref min, ref max);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        protected override void Init(MyObjectBuilder_DefinitionBase builder)
        {
            base.Init(builder);

            var ob = builder as MyObjectBuilder_CubeBlockDefinition;
            MyDebug.AssertDebug(ob != null);

            this.Size                  = ob.Size;
            this.Model                 = ob.Model;
            this.UseModelIntersection  = ob.UseModelIntersection;
            this.CubeSize              = ob.CubeSize;
            this.ModelOffset           = ob.ModelOffset;
            this.BlockTopology         = ob.BlockTopology;
            this.PhysicsOption         = ob.PhysicsOption;
            this.BlockPairName         = ob.BlockPairName;
            this.m_center              = ob.Center ?? ((Size - 1) / 2);
            this.m_symmetryX           = ob.MirroringX;
            this.m_symmetryY           = ob.MirroringY;
            this.m_symmetryZ           = ob.MirroringZ;
            this.DeformationRatio      = ob.DeformationRatio;
            this.SilenceableByShipSoundSystem = ob.SilenceableByShipSoundSystem;
            this.EdgeType              = ob.EdgeType;
            this.AutorotateMode        = ob.AutorotateMode;
            this.m_mirroringBlock      = ob.MirroringBlock;
            this.MultiBlock            = ob.MultiBlock;
            this.GuiVisible            = ob.GuiVisible;
            this.Rotation              = ob.Rotation;
            this.Direction             = ob.Direction;
            this.Mirrored              = ob.Mirrored;
            this.RandomRotation        = ob.RandomRotation;
            this.BuildType             = MyStringId.GetOrCompute(ob.BuildType != null ? ob.BuildType.ToLower() : null);
            this.BuildMaterial         = ob.BuildMaterial != null ? ob.BuildMaterial.ToLower() : null;
            this.BuildProgressToPlaceGeneratedBlocks = ob.BuildProgressToPlaceGeneratedBlocks;
            this.GeneratedBlockType    = MyStringId.GetOrCompute(ob.GeneratedBlockType != null ? ob.GeneratedBlockType.ToLower() : null);
            this.CompoundEnabled       = ob.CompoundEnabled;
            this.CreateFracturedPieces = ob.CreateFracturedPieces;
            this.VoxelPlacement      = ob.VoxelPlacement;

            if (ob.PhysicalMaterial != null)
            {
                this.PhysicalMaterial = MyDefinitionManager.Static.GetPhysicalMaterialDefinition(ob.PhysicalMaterial);
            }
            if (ob.Effects != null)
            {
                this.Effects = new CubeBlockEffectBase[ob.Effects.Length];
                for (int i = 0; i < ob.Effects.Length; i++)
                {
                    this.Effects[i] = new CubeBlockEffectBase(ob.Effects[i].Name, ob.Effects[i].ParameterMin, ob.Effects[i].ParameterMax);
                    if (ob.Effects[i].ParticleEffects != null && ob.Effects[i].ParticleEffects.Length > 0)
                    {
                        this.Effects[i].ParticleEffects = new CubeBlockEffect[ob.Effects[i].ParticleEffects.Length];
                        for (int j = 0; j < ob.Effects[i].ParticleEffects.Length; j++)
                        {
                            this.Effects[i].ParticleEffects[j] = new CubeBlockEffect(ob.Effects[i].ParticleEffects[j]);
                        }
                    }
                    else
                        this.Effects[i].ParticleEffects = null;
                }
            }
            if (ob.DamageEffectId != 0)
                this.DamageEffectID = ob.DamageEffectId;

            this.Points = ob.Points;
            InitEntityComponents(ob.EntityComponents);

            this.CompoundTemplates = ob.CompoundTemplates;
            Debug.Assert(this.CompoundTemplates == null || this.CompoundTemplates.Length > 0, "Wrong compound templates, array is empty");

            if (ob.SubBlockDefinitions != null)
            {
                SubBlockDefinitions = new Dictionary<string, MyDefinitionId>();

                foreach (var definition in ob.SubBlockDefinitions)
                {
                    MyDefinitionId defId;
                    if (SubBlockDefinitions.TryGetValue(definition.SubBlock, out defId))
                    {
                        MyDebug.AssertDebug(false, "Subblock definition already defined!");
                        continue;
                    }

                    defId = definition.Id;
                    SubBlockDefinitions.Add(definition.SubBlock, defId);
                }
            }

            if (ob.BlockVariants != null)
            {
                BlockStages = new MyDefinitionId[ob.BlockVariants.Length];

                for (int i = 0; i < ob.BlockVariants.Length; ++i)
                {
                    BlockStages[i] = ob.BlockVariants[i];
                }
            }

            var cubeDef = ob.CubeDefinition;
            if (cubeDef != null)
            {
                MyCubeDefinition tmp = new MyCubeDefinition();
                tmp.CubeTopology = cubeDef.CubeTopology;
                tmp.ShowEdges = cubeDef.ShowEdges;

                var sides = cubeDef.Sides;
                tmp.Model = new string[sides.Length];
                tmp.PatternSize = new Vector2I[sides.Length];
                for (int j = 0; j < sides.Length; ++j)
                {
                    var side = sides[j];
                    tmp.Model[j] = side.Model;
                    tmp.PatternSize[j] = side.PatternSize;
                }
                this.CubeDefinition = tmp;
            }

            var components = ob.Components;
            MyDebug.AssertDebug(components != null);
            MyDebug.AssertDebug(components.Length != 0);
            float mass = 0.0f;
            float criticalIntegrity = 0f;
            float ownershipIntegrity = 0f;

            MaxIntegrityRatio = 1;

            if (components != null && components.Length != 0)
            {
                Components = new MyCubeBlockDefinition.Component[components.Length];

                float integrity = 0.0f;
                int criticalTypeCounter = 0;
                for (int j = 0; j < components.Length; ++j)
                {
                    var component = components[j];

                    var definition = MyDefinitionManager.Static.GetComponentDefinition(new MyDefinitionId(component.Type, component.Subtype));
                    MyPhysicalItemDefinition deconstructDefinition = null;
                    if (!component.DeconstructId.IsNull() && !MyDefinitionManager.Static.TryGetPhysicalItemDefinition(component.DeconstructId, out deconstructDefinition))
                        deconstructDefinition = definition;

                    if (deconstructDefinition == null)
                        deconstructDefinition = definition;

                    MyCubeBlockDefinition.Component tmp = new MyCubeBlockDefinition.Component()
                    {
                        Definition = definition,
                        Count = component.Count,
                        DeconstructItem = deconstructDefinition,
                    };

                    if (component.Type == typeof(MyObjectBuilder_Component) && component.Subtype == "Computer")
                    {
                        if (ownershipIntegrity == 0)
                            ownershipIntegrity = integrity + tmp.Definition.MaxIntegrity;
                    }

                    integrity += tmp.Count * tmp.Definition.MaxIntegrity;
                    if (component.Type == ob.CriticalComponent.Type &&
                        component.Subtype == ob.CriticalComponent.Subtype)
                    {
                        if (criticalTypeCounter == ob.CriticalComponent.Index)
                        {
                            CriticalGroup = (UInt16)j;
                            criticalIntegrity = integrity-1;
                        }
                        ++criticalTypeCounter;
                    }

                    mass += tmp.Count * tmp.Definition.Mass;

                    Components[j] = tmp;
                }

                MaxIntegrity = integrity;
                IntegrityPointsPerSec = MaxIntegrity / ob.BuildTimeSeconds;
                DisassembleRatio = ob.DisassembleRatio;

                if (ob.MaxIntegrity != 0)
                {
                    // If we specify MaxIntegrity for a block, it conflicts with the original integrity
                    // So instead of overriding the MaxIntegrity, we multiply DeformationRatio so that the block
                    // behaves as if it had the integrity that we want!
                    MaxIntegrityRatio = ob.MaxIntegrity / MaxIntegrity;
                    DeformationRatio = DeformationRatio / MaxIntegrityRatio;
                }

                if(!MyPerGameSettings.Destruction)
                    Mass = mass;
            }
            else
            {
                if (ob.MaxIntegrity != 0)
                    MaxIntegrity = ob.MaxIntegrity;
            }

            CriticalIntegrityRatio = criticalIntegrity / MaxIntegrity;
            OwnershipIntegrityRatio = ownershipIntegrity / MaxIntegrity;

            if (ob.BuildProgressModels != null)
            {
                ob.BuildProgressModels.Sort((a, b) => a.BuildPercentUpperBound.CompareTo(b.BuildPercentUpperBound));
                this.BuildProgressModels = new BuildProgressModel[ob.BuildProgressModels.Count];
                for (int i = 0; i < BuildProgressModels.Length; ++i)
                {
                    var builderModel = ob.BuildProgressModels[i];
                    if (!string.IsNullOrEmpty(builderModel.File))
                    {
                        this.BuildProgressModels[i] = new BuildProgressModel()
                        {
                            BuildRatioUpperBound = builderModel.BuildPercentUpperBound * CriticalIntegrityRatio,
                            File = builderModel.File,
                            RandomOrientation = builderModel.RandomOrientation
                        };
                    }
                }
            }

            if (ob.GeneratedBlocks != null)
            {
                this.GeneratedBlockDefinitions = new MyDefinitionId[ob.GeneratedBlocks.Length];

                for (int i = 0; i < ob.GeneratedBlocks.Length; ++i)
                {
                    var genBlockId = ob.GeneratedBlocks[i];
                    Debug.Assert(!string.IsNullOrEmpty(genBlockId.SubtypeName));
                    Debug.Assert(!string.IsNullOrEmpty(genBlockId.TypeIdString));

                    this.GeneratedBlockDefinitions[i] = genBlockId;
                }
            }

            Skeleton = ob.Skeleton;
            if (Skeleton != null)
            {
                Bones = new Dictionary<Vector3I,Vector3>(ob.Skeleton.Count);
                foreach (var bone in Skeleton)
                {
                    Bones[bone.BonePosition] = Vector3UByte.Denormalize(bone.BoneOffset, MyDefinitionManager.Static.GetCubeSize(ob.CubeSize));
                }
            }

            IsAirTight = ob.IsAirTight;

            InitMountPoints(ob);
            InitPressurization();

            InitNavigationInfo(ob, ob.NavigationDefinition);

            CheckBuildProgressModels();
            // Components and CriticalComponent will be initialized elsewhere

            PrimarySound = new MySoundPair(ob.PrimarySound);
            ActionSound = new MySoundPair(ob.ActionSound);
            if (ob.DamagedSound!=null)
                DamagedSound = new MySoundPair(ob.DamagedSound);

        }