Пример #1
0
        private static void CheckModelConsistency(MyEnvironmentItemDefinition itemDefinition)
        {
            List <int> savedModelsId;

            if (m_subtypeToModels.TryGetValue(itemDefinition.Id.SubtypeId, out savedModelsId))
            {
                Debug.Assert(savedModelsId.Count == itemDefinition.Models.Length, "Mismatch of amount of models for given env item");
                if (savedModelsId.Count == itemDefinition.Models.Length)
                {
                    for (int i = 0; i < itemDefinition.Models.Length; i++)
                    {
                        Debug.Assert(savedModelsId[i] == MyModel.GetId(itemDefinition.Models[i]), "Environment item subtype id maps to a different model id than it used to!");
                    }
                }
            }
            else
            {
                savedModelsId = new List <int>(itemDefinition.Models.Length);
                for (int i = 0; i < itemDefinition.Models.Length; i++)
                {
                    if (!string.IsNullOrEmpty(itemDefinition.Models[i]))
                    {
                        savedModelsId.Add(MyModel.GetId(itemDefinition.Models[i]));
                    }
                }
                m_subtypeToModels.Add(itemDefinition.Id.SubtypeId, savedModelsId);
            }
        }
Пример #2
0
        private void CreateBreakableShape(MyEnvironmentItemDefinition itemDefinition, ref MyEnvironmentItems.MyEnvironmentItemData itemData, ref Vector3D hitWorldPosition, Vector3 hitNormal, float forceMultiplier, string fallSound = "")
        {
            HkdBreakableShape oldBreakableShape = MyModels.GetModelOnlyData(itemDefinition.Model).HavokBreakableShapes[0].Clone();
            MatrixD           transformMatrix   = itemData.Transform.TransformMatrix;

            oldBreakableShape.SetMassRecursively(500f);
            oldBreakableShape.SetStrenghtRecursively(5000f, 0.7f);
            oldBreakableShape.GetChildren(base.m_childrenTmp);
            HkdBreakableShape[] havokBreakableShapes = MyModels.GetModelOnlyData(itemDefinition.Model).HavokBreakableShapes;
            Vector3D.Transform(hitWorldPosition, MatrixD.Normalize(MatrixD.Invert(transformMatrix)));
            float num = (float)(hitWorldPosition.Y - itemData.Transform.Position.Y);
            List <HkdShapeInstanceInfo> shapeList = new List <HkdShapeInstanceInfo>();
            List <HkdShapeInstanceInfo> list2     = new List <HkdShapeInstanceInfo>();
            HkdShapeInstanceInfo?       nullable  = null;

            foreach (HkdShapeInstanceInfo info in base.m_childrenTmp)
            {
                if ((nullable == null) || (info.CoM.Y < nullable.Value.CoM.Y))
                {
                    nullable = new HkdShapeInstanceInfo?(info);
                }
                if (info.CoM.Y > num)
                {
                    list2.Add(info);
                }
                else
                {
                    shapeList.Add(info);
                }
            }
            if (shapeList.Count != 2)
            {
                if ((shapeList.Count == 0) && list2.Remove(nullable.Value))
                {
                    shapeList.Add(nullable.Value);
                }
            }
            else if ((shapeList[0].CoM.Y < shapeList[1].CoM.Y) && (num < (shapeList[1].CoM.Y + 1.25f)))
            {
                list2.Insert(0, shapeList[1]);
                shapeList.RemoveAt(1);
            }
            else if ((shapeList[0].CoM.Y > shapeList[1].CoM.Y) && (num < (shapeList[0].CoM.Y + 1.25f)))
            {
                list2.Insert(0, shapeList[0]);
                shapeList.RemoveAt(0);
            }
            if (shapeList.Count > 0)
            {
                CreateFracturePiece(itemDefinition, oldBreakableShape, transformMatrix, hitNormal, shapeList, forceMultiplier, true, "");
            }
            if (list2.Count > 0)
            {
                CreateFracturePiece(itemDefinition, oldBreakableShape, transformMatrix, hitNormal, list2, forceMultiplier, false, fallSound);
            }
            base.m_childrenTmp.Clear();
        }
Пример #3
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);
                }
            }
        }
Пример #4
0
        private static void CheckModelConsistency(MyEnvironmentItemDefinition itemDefinition)
        {
            int modelId = MyModel.GetId(itemDefinition.Model);
            int savedModelId;

            if (m_subtypeToModel.TryGetValue(itemDefinition.Id.SubtypeId, out savedModelId))
            {
                Debug.Assert(modelId == savedModelId, "Environment item subtype id maps to a different model id than it used to!");
            }
            else
            {
                m_subtypeToModel.Add(itemDefinition.Id.SubtypeId, modelId);
            }
        }
Пример #5
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);
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Spawn environment item with the definition subtype on world position.
        /// </summary>
        public static bool SpawnItem(MyEnvironmentItemsSpawnData spawnData, MyEnvironmentItemDefinition itemDefinition, Vector3D position, Vector3D up)
        {
            if (!MyFakes.ENABLE_ENVIRONMENT_ITEMS)
            {
                return(true);
            }

            Debug.Assert(spawnData != null && spawnData.EnvironmentItems != null);
            Debug.Assert(itemDefinition != null);
            if (spawnData == null || spawnData.EnvironmentItems == null || itemDefinition == null)
            {
                return(false);
            }

            Vector3D forward     = MyUtils.GetRandomPerpendicularVector(ref up);
            MatrixD  worldMatrix = MatrixD.CreateWorld(position, forward, up);

            return(spawnData.EnvironmentItems.AddItem(itemDefinition, ref worldMatrix, ref spawnData.AabbWorld, spawnData.SectorRootShape, spawnData.SubtypeToShapes));
        }
Пример #7
0
        private void CreateBreakableShape(MyEnvironmentItemDefinition itemDefinition, ref MyEnvironmentItemData itemData, ref Vector3D hitWorldPosition, Vector3 hitNormal, float forceMultiplier, string fallSound = "")
        {
            var     breakableShape = VRage.Game.Models.MyModels.GetModelOnlyData(itemDefinition.Model).HavokBreakableShapes[0].Clone();
            MatrixD world          = itemData.Transform.TransformMatrix;

            breakableShape.SetMassRecursively(500);
            breakableShape.SetStrenghtRecursively(5000, 0.7f);

            breakableShape.GetChildren(m_childrenTmp);

            var test = VRage.Game.Models.MyModels.GetModelOnlyData(itemDefinition.Model).HavokBreakableShapes;

            Vector3 hitLocalPosition  = Vector3D.Transform(hitWorldPosition, MatrixD.Normalize(MatrixD.Invert(world)));
            float   cutLocalYPosition = (float)(hitWorldPosition.Y - (double)itemData.Transform.Position.Y);
            List <HkdShapeInstanceInfo> childrenBelow     = new List <HkdShapeInstanceInfo>();
            List <HkdShapeInstanceInfo> childrenAbove     = new List <HkdShapeInstanceInfo>();
            HkdShapeInstanceInfo?       stumpInstanceInfo = null;

            foreach (var shapeInst in m_childrenTmp)
            {
                // The first child shape in the breakable shape should be the stump!
                if (stumpInstanceInfo == null || shapeInst.CoM.Y < stumpInstanceInfo.Value.CoM.Y)
                {
                    stumpInstanceInfo = shapeInst;
                }

                if (shapeInst.CoM.Y > cutLocalYPosition)
                {
                    childrenAbove.Add(shapeInst);
                }
                else
                {
                    childrenBelow.Add(shapeInst);
                }
            }

            // Resolve stump - if we have 2 children bellow then move one to above list
            if (childrenBelow.Count == 2)
            {
                if (childrenBelow[0].CoM.Y < childrenBelow[1].CoM.Y && cutLocalYPosition < childrenBelow[1].CoM.Y + 1.25f)
                {
                    childrenAbove.Insert(0, childrenBelow[1]);
                    childrenBelow.RemoveAt(1);
                }
                else if (childrenBelow[0].CoM.Y > childrenBelow[1].CoM.Y && cutLocalYPosition < childrenBelow[0].CoM.Y + 1.25f)
                {
                    childrenAbove.Insert(0, childrenBelow[0]);
                    childrenBelow.RemoveAt(0);
                }
            }
            else if (childrenBelow.Count == 0)
            {
                if (childrenAbove.Remove(stumpInstanceInfo.Value))
                {
                    childrenBelow.Add(stumpInstanceInfo.Value);
                }
                else
                {
                    Debug.Fail("Cannot remove shape instance from collection");
                }
            }

            if (childrenBelow.Count > 0)
            {
                CreateFracturePiece(itemDefinition, breakableShape, world, hitNormal, childrenBelow, forceMultiplier, true);
            }

            if (childrenAbove.Count > 0)
            {
                CreateFracturePiece(itemDefinition, breakableShape, world, hitNormal, childrenAbove, forceMultiplier, false, fallSound);
            }

            m_childrenTmp.Clear();
        }
Пример #8
0
        /// <summary>
        /// Adds environment item to internal collections. Creates render and physics data.
        /// </summary>
        /// <returns>True if successfully added, otherwise false.</returns>
        private bool AddItem(
            MyEnvironmentItemDefinition itemDefinition,
            ref MatrixD worldMatrix,
            ref BoundingBoxD aabbWorld,
            HkStaticCompoundShape sectorRootShape,
            Dictionary <MyStringHash, HkShape> subtypeIdToShape,
            int localModelId = MAIN_MODEL_LOCAL_ID)
        {
            if (!MyFakes.ENABLE_ENVIRONMENT_ITEMS)
            {
                return(true);
            }

            Debug.Assert(m_definition.ContainsItemDefinition(itemDefinition),
                         String.Format("Environment item with definition '{0}' not found in class '{1}'", itemDefinition.Id, m_definition.Id));
            if (!m_definition.ContainsItemDefinition(itemDefinition))
            {
                return(false);
            }

            if (itemDefinition.Model == null)
            {
                return(false);
            }

            //MyDefinitionId defId = new MyDefinitionId(envItemObjectBuilderType, subtypeId.ToString());
            int    modelId   = MyEnvironmentItems.GetModelId(itemDefinition.Id.SubtypeId, localModelId);
            string modelName = MyModel.GetById(modelId);

            MyModel model = MyModels.GetModelOnlyData(modelName);

            if (model == null)
            {
                //Debug.Fail(String.Format("Environment item model of '{0}' not found, skipping the item...", itemDefinition.Id));
                return(false);
            }

            CheckModelConsistency(itemDefinition);

            int localId = worldMatrix.Translation.GetHashCode();

            MyEnvironmentItemData data = new MyEnvironmentItemData()
            {
                Id               = localId,
                SubtypeId        = itemDefinition.Id.SubtypeId,
                Transform        = new MyTransformD(ref worldMatrix),
                Enabled          = true,
                SectorInstanceId = -1,
                ModelId          = modelId,
            };

            //Preload split planes
            //VRageRender.MyRenderProxy.PreloadMaterials(model.AssetName);

            aabbWorld.Include(model.BoundingBox.Transform(worldMatrix));

            MatrixD transform = data.Transform.TransformMatrix;

            Vector3I            sectorId = MyEnvironmentSector.GetSectorId(transform.Translation - CellsOffset, m_definition.SectorSize);
            MyEnvironmentSector sector;

            if (!m_sectors.TryGetValue(sectorId, out sector))
            {
                sector = new MyEnvironmentSector(sectorId, sectorId * m_definition.SectorSize + CellsOffset);
                m_sectors.Add(sectorId, sector);
            }

            // Adds instance of the given model. Local matrix specified might be changed internally in renderer.

            MatrixD sectorOffset = MatrixD.CreateTranslation(-sectorId * m_definition.SectorSize - CellsOffset);
            Matrix  transformL   = (Matrix)(transform * sectorOffset);

            data.SectorInstanceId = sector.AddInstance(itemDefinition.Id.SubtypeId, data.ModelId, localId, ref transformL, model.BoundingBox, m_instanceFlags, m_definition.MaxViewDistance);

            int physicsShapeInstanceId;

            if (AddPhysicsShape(data.SubtypeId, model, ref transform, sectorRootShape, subtypeIdToShape, out physicsShapeInstanceId))
            {
                // Map to data index - note that itemData is added after this to its list!
                m_physicsShapeInstanceIdToLocalId[physicsShapeInstanceId] = localId;
                m_localIdToPhysicsShapeInstanceId[localId] = physicsShapeInstanceId;
            }

            data.Transform = new MyTransformD(transform);

            if (m_itemsData.ContainsKey(localId))
            {
                //Debug.Fail("More items on same place! " + transform.Translation.ToString());
            }
            else
            {
                m_itemsData.Add(localId, data);
            }

            if (ItemAdded != null)
            {
                ItemAdded(this,
                          new ItemInfo()
                {
                    LocalId   = localId,
                    SubtypeId = data.SubtypeId,
                    Transform = data.Transform,
                });
            }

            return(true);
        }