public MyEnvironmentItemDefinition GetItemDefinition(MyStringHash subtypeId) { MyEnvironmentItemDefinition definition = null; MyDefinitionId defId = new MyDefinitionId(this.m_itemDefinitionType, subtypeId); MyDefinitionManager.Static.TryGetDefinition <MyEnvironmentItemDefinition>(defId, out definition); return(definition); }
public MyEnvironmentItemDefinition GetItemDefinition(MyStringHash subtypeId) { MyEnvironmentItemDefinition retval = null; MyDefinitionId defId = new MyDefinitionId(m_itemDefinitionType, subtypeId); MyDefinitionManager.Static.TryGetDefinition(defId, out retval); Debug.Assert(retval != null, "Could not find environment item with definition id " + defId); return(retval); }
public static void CreateFracturePiece(MyEnvironmentItemDefinition itemDefinition, HkdBreakableShape oldBreakableShape, MatrixD worldMatrix, Vector3 hitNormal, List<HkdShapeInstanceInfo> shapeList, float forceMultiplier, bool canContainFixedChildren) { 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.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(); } }
private void CreateBreakableShape(MyEnvironmentItemDefinition itemDefinition, ref MyEnvironmentItemData itemData, ref Vector3D hitWorldPosition, Vector3 hitNormal, float forceMultiplier) { var breakableShape = 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 = 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); m_childrenTmp.Clear(); }
private static void CheckModelConsistency(MyEnvironmentItemDefinition itemDefinition) { int savedModelId; if (m_subtypeToModels.TryGetValue(itemDefinition.Id.SubtypeId, out savedModelId)) { Debug.Assert(savedModelId == MyModel.GetId(itemDefinition.Model), "Environment item subtype id maps to a different model id than it used to!"); } else { if (itemDefinition.Model != null) m_subtypeToModels.Add(itemDefinition.Id.SubtypeId, MyModel.GetId(itemDefinition.Model)); } }
/// <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, bool silentOverlaps = false) { 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); 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(); if (m_itemsData.ContainsKey(localId)) { if (!silentOverlaps) { Debug.Fail("More items on same place! " + worldMatrix.Translation.ToString()); MyLog.Default.WriteLine("WARNING: items are on the same place."); } return false; } MyEnvironmentItemData data = new MyEnvironmentItemData() { Id = localId, SubtypeId = itemDefinition.Id.SubtypeId, Transform = new MyTransformD(ref worldMatrix), Enabled = true, SectorInstanceId = -1, Model = model, }; //Preload split planes //VRageRender.MyRenderProxy.PreloadMaterials(model.AssetName); aabbWorld.Include(model.BoundingBox.Transform(worldMatrix)); MatrixD transform = data.Transform.TransformMatrix; float sectorSize = MyFakes.ENVIRONMENT_ITEMS_ONE_INSTANCEBUFFER ? 20000 : m_definition.SectorSize; Vector3I sectorId = MyEnvironmentSector.GetSectorId(transform.Translation - CellsOffset, sectorSize); MyEnvironmentSector sector; if (!m_sectors.TryGetValue(sectorId, out sector)) { sector = new MyEnvironmentSector(sectorId, sectorId * sectorSize + CellsOffset); m_sectors.Add(sectorId, sector); } // Adds instance of the given model. Local matrix specified might be changed internally in renderer. MatrixD sectorOffsetInv = MatrixD.CreateTranslation(-sectorId * sectorSize - CellsOffset); Matrix transformL = (Matrix)(data.Transform.TransformMatrix * sectorOffsetInv); data.SectorInstanceId = sector.AddInstance(itemDefinition.Id.SubtypeId, modelId, localId, ref transformL, model.BoundingBox, m_instanceFlags, m_definition.MaxViewDistance); data.Transform = new MyTransformD(transform); m_itemsData.Add(localId, data); if (ItemAdded != null) { ItemAdded(this, new ItemInfo() { LocalId = localId, SubtypeId = data.SubtypeId, Transform = data.Transform, }); } return true; }
/// <summary> /// Spawn environment item with the definition subtype on world position. /// </summary> public static bool SpawnItem(MyEnvironmentItemsSpawnData spawnData, MyEnvironmentItemDefinition itemDefinition, Vector3D position, Vector3D up, bool silentOverlaps = true) { 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, silentOverlaps); }
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); } }
/// <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; }
public bool ContainsItemDefinition(MyEnvironmentItemDefinition itemDefinition) { return itemDefinition.Id.TypeId == m_itemDefinitionType && ContainsItemDefinition(itemDefinition.Id.SubtypeId); }
public bool ContainsItemDefinition(MyEnvironmentItemDefinition itemDefinition) { return(ContainsItemDefinition(itemDefinition.Id)); }
public bool ContainsItemDefinition(MyEnvironmentItemDefinition itemDefinition) { return(itemDefinition.Id.TypeId == m_itemDefinitionType && ContainsItemDefinition(itemDefinition.Id.SubtypeId)); }
public bool ContainsItemDefinition(MyEnvironmentItemDefinition itemDefinition) => this.ContainsItemDefinition(itemDefinition.Id);
public bool ContainsItemDefinition(MyEnvironmentItemDefinition itemDefinition) { return ContainsItemDefinition(itemDefinition.Id); }