示例#1
0
        public static MyPhysicalMaterialDefinition GetPhysicalMaterial(MyPhysicalModelDefinition modelDef, string physicalMaterial)
        {
            if (m_physicalMaterials == null)
            {
                m_physicalMaterials = new Dictionary <string, MyPhysicalMaterialDefinition>();
                foreach (var physMat in MyDefinitionManager.Static.GetPhysicalMaterialDefinitions())
                {
                    m_physicalMaterials.Add(physMat.Id.SubtypeName, physMat);
                }

                m_physicalMaterials["Default"] = new MyPhysicalMaterialDefinition()
                {
                    Density = 1920,
                    HorisontalTransmissionMultiplier = 1,
                    HorisontalFragility = 2,
                    CollisionMultiplier = 1.4f,
                    SupportMultiplier   = 1.5f,
                };
            }

            if (!string.IsNullOrEmpty(physicalMaterial))
            {
                if (m_physicalMaterials.ContainsKey(physicalMaterial))
                {
                    return(m_physicalMaterials[physicalMaterial]);
                }
                else
                {
                    string s = "ERROR: Physical material " + physicalMaterial + " does not exist!";
                    System.Diagnostics.Debug.Fail(s);
                    MyLog.Default.WriteLine(s);
                }
            }

            //MyLog.Default.WriteLine("WARNING: " + modelDef.Id.SubtypeName + " has no physical material specified, trying to autodetect from name");


            if (modelDef.Id.SubtypeName.Contains("Stone") && m_physicalMaterials.ContainsKey("Stone"))
            {
                return(m_physicalMaterials["Stone"]);
            }

            if (modelDef.Id.SubtypeName.Contains("Wood") && m_physicalMaterials.ContainsKey("Wood"))
            {
                return(m_physicalMaterials["Wood"]);
            }

            if (modelDef.Id.SubtypeName.Contains("Timber") && m_physicalMaterials.ContainsKey("Timber"))
            {
                return(m_physicalMaterials["Wood"]);
            }


            //MyLog.Default.WriteLine("WARNING: Unable to find proper physical material for " + modelDef.Id.SubtypeName + ", using Default");
            return(m_physicalMaterials["Default"]);
        }
        public short GetModelId(MyPhysicalModelDefinition def)
        {
            short id;

            if (!m_physicalModelToKey.TryGetValue(def, out id))
            {
                id = (short)m_physicalModels.Count;
                m_physicalModelToKey.Add(def, id);
                m_physicalModels.Add(def);
            }

            return(id);
        }
示例#3
0
        public void AllocateForDefinition(string model, MyPhysicalModelDefinition definition, int count)
        {
            if (string.IsNullOrEmpty(model))
            {
                return;
            }
            ProfilerShort.Begin("Clone");
            var data = VRage.Game.Models.MyModels.GetModelOnlyData(model);

            if (data.HavokBreakableShapes == null)
            {
                MyDestructionData.Static.LoadModelDestruction(model, definition, data.BoundingBoxSize);
            }

            if (data.HavokBreakableShapes != null && data.HavokBreakableShapes.Length > 0)
            {
                ConcurrentQueue <HkdBreakableShape> queue;
                using (m_poolLock.AcquireExclusiveUsing())
                {
                    if (!m_pools.ContainsKey(definition.Id))
                    {
                        m_pools[definition.Id] = new Dictionary <string, ConcurrentQueue <HkdBreakableShape> >();
                    }
                    if (!m_pools[definition.Id].ContainsKey(model))
                    {
                        m_pools[definition.Id][model] = new ConcurrentQueue <HkdBreakableShape>();
                    }
                    queue = m_pools[definition.Id][model];
                }
                for (int i = 0; i < count; i++)
                {
                    var shape = data.HavokBreakableShapes[0].Clone();
                    queue.Enqueue(shape);
                    if (i == 0)
                    {
                        var mp = new HkMassProperties();
                        shape.BuildMassProperties(ref mp);
                        if (!mp.InertiaTensor.IsValid())
                        {
                            MyLog.Default.WriteLine(string.Format("Block with wrong destruction! (q.isOk): {0}", definition.Model));
                            break;
                        }
                    }
                }
            }
            ProfilerShort.End();
        }
示例#4
0
 public void AllocateForDefinition(string model, MyPhysicalModelDefinition definition, int count)
 {
     if (!string.IsNullOrEmpty(model))
     {
         MyModel modelOnlyData = MyModels.GetModelOnlyData(model);
         if (modelOnlyData.HavokBreakableShapes == null)
         {
             MyDestructionData.Static.LoadModelDestruction(model, definition, modelOnlyData.BoundingBoxSize, true, false);
         }
         if ((modelOnlyData.HavokBreakableShapes != null) && (modelOnlyData.HavokBreakableShapes.Length != 0))
         {
             ConcurrentQueue <HkdBreakableShape> queue;
             using (this.m_poolLock.AcquireExclusiveUsing())
             {
                 if (!this.m_pools.ContainsKey(definition.Id))
                 {
                     this.m_pools[definition.Id] = new Dictionary <string, ConcurrentQueue <HkdBreakableShape> >();
                 }
                 if (!this.m_pools[definition.Id].ContainsKey(model))
                 {
                     this.m_pools[definition.Id][model] = new ConcurrentQueue <HkdBreakableShape>();
                 }
                 queue = this.m_pools[definition.Id][model];
             }
             for (int i = 0; i < count; i++)
             {
                 HkdBreakableShape item = modelOnlyData.HavokBreakableShapes[0].Clone();
                 queue.Enqueue(item);
                 if (i == 0)
                 {
                     HkMassProperties massProperties = new HkMassProperties();
                     item.BuildMassProperties(ref massProperties);
                     if (!massProperties.InertiaTensor.IsValid())
                     {
                         MyLog.Default.WriteLine($"Block with wrong destruction! (q.isOk): {definition.Model}");
                         return;
                     }
                 }
             }
         }
     }
 }
        public void AllocateForDefinition(MyPhysicalModelDefinition definition, int count)
        {
            if (string.IsNullOrEmpty(definition.Model))
            {
                return;
            }
            ProfilerShort.Begin("Clone");
            var data = MyModels.GetModelOnlyData(definition.Model);

            if (MyFakes.LAZY_LOAD_DESTRUCTION && data.HavokBreakableShapes == null)
            {
                MyDestructionData.Static.LoadModelDestruction(definition, false, data.BoundingBoxSize);
            }
            if (data.HavokBreakableShapes != null && data.HavokBreakableShapes.Length > 0)
            {
                if (!m_pools.ContainsKey(definition.Id))
                {
                    m_pools[definition.Id] = new ConcurrentQueue <HkdBreakableShape>();
                }
                var queue = m_pools[definition.Id];
                for (int i = 0; i < count; i++)
                {
                    var shape = data.HavokBreakableShapes[0].Clone();
                    queue.Enqueue(shape);
                    if (i == 0)
                    {
                        var mp = new HkMassProperties();
                        shape.BuildMassProperties(ref mp);
                        if (!mp.InertiaTensor.IsValid())
                        {
                            MyLog.Default.WriteLine(string.Format("Block with wrong destruction! (q.isOk): {0}", definition.Model));
                            break;
                        }
                    }
                }
            }
            ProfilerShort.End();
        }
示例#6
0
        public void Add(MyDefinitionId modelDef, int item)
        {
            ModelList itemsForModel;

            if (!m_modelPerItemDefinition.TryGetValue(modelDef, out itemsForModel))
            {
                itemsForModel.Items = new List <int>();

                if (modelDef.TypeId.IsNull)
                {
                    itemsForModel.Model = -1;
                }
                else
                {
                    MyPhysicalModelDefinition model = MyDefinitionManager.Static.GetDefinition <MyPhysicalModelDefinition>(modelDef);
                    itemsForModel.Model = model != null?m_owner.GetModelId(model) : (short)-1;
                }

                m_modelPerItemDefinition[modelDef] = itemsForModel;
            }

            itemsForModel.Items.Add(item);
        }
        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!
            }
        }
        void CreateBreakableShapeFromCollisionShapes(MyModel model, Vector3 defaultSize, MyPhysicalModelDefinition modelDef)
        {
            // Make box half edge length of the grid so fractured block is smaller than not fractured, also good for compounds
            HkShape shape;

            if (model.HavokCollisionShapes != null && model.HavokCollisionShapes.Length > 0)
            {
                if (model.HavokCollisionShapes.Length > 1)
                {
                    shape = HkListShape.Create(model.HavokCollisionShapes, model.HavokCollisionShapes.Length, HkReferencePolicy.None);
                }
                else
                {
                    shape = model.HavokCollisionShapes[0];
                    shape.AddReference();
                }
            }
            else
            {
                //modelDef.Size * (modelDef.CubeSize == MyCubeSize.Large ? 2.5f : 0.25f)
                shape = new HkBoxShape(defaultSize * 0.5f, MyPerGameSettings.PhysicsConvexRadius);
            }

            var boxBreakable = new HkdBreakableShape(shape);

            boxBreakable.Name = model.AssetName;
            boxBreakable.SetMass(modelDef.Mass);
            model.HavokBreakableShapes = new HkdBreakableShape[] { boxBreakable };
            shape.RemoveReference();
        }