public float GetBlockMass(MyCubeBlockDefinition def)
        {
            var sh   = BlockShapePool.GetBreakableShape(def);
            var mass = sh.GetMass();

            BlockShapePool.EnqueShape(def.Id, sh);
            return(mass);
        }
示例#2
0
        public float GetBlockMass(string model, MyCubeBlockDefinition def)
        {
            var sh   = BlockShapePool.GetBreakableShape(model, def);
            var mass = sh.GetMass();

            BlockShapePool.EnqueShape(model, def.Id, sh);
            return(mass);    // (OM) NOTE: this currently returns havok mass, we use MyDestructionHelper.MassFromHavok to recompute, if you change to use it here, check this method usage, whether this is not already converted somewhere
        }
        protected override void UnloadData()
        {
            TemporaryWorld.MarkForWrite(); //must be marked for write when deleting
            Storage.Dispose();
            Storage = null;
            TemporaryWorld.DestructionWorld.Dispose();

            TemporaryWorld.Dispose();
            TemporaryWorld = null;

            BlockShapePool.Free();
            BlockShapePool = null;

            Static = null;
        }
 public override void UpdateAfterSimulation()
 {
     base.UpdateAfterSimulation();
     BlockShapePool.RefillPools();
 }
        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!
            }
        }