private void InitInternal() { base.Init(null, m_definition.Model, null, null); Render.ColorMaskHsv = m_definition.ColorHSV; Render.Transparency = 0.25f; Render.AddRenderObjects(); List <MyTextureChange> textureChanges = new List <MyTextureChange>(); textureChanges.Add(new MyTextureChange { TextureName = m_definition.ColorMetalTexture, MaterialSlot = "ColorMetalTexture" }); textureChanges.Add(new MyTextureChange { TextureName = m_definition.AddMapsTexture, MaterialSlot = "AddMapsTexture" }); VRageRender.MyRenderProxy.ChangeMaterialTexture(Render.RenderObjectIDs[0], "BotFlag", textureChanges); // TODO: change the material name m_localActivationMatrix = MatrixD.CreateScale(this.PositionComp.LocalAABB.HalfExtents * 2.0f) * MatrixD.CreateTranslation(this.PositionComp.LocalAABB.Center); var shape = new HkBoxShape(m_localActivationMatrix.Scale); var physicsBody = new MyPhysicsBody(this, RigidBodyFlag.RBF_DISABLE_COLLISION_RESPONSE); Physics = physicsBody; physicsBody.CreateFromCollisionObject(shape, Vector3.Zero, WorldMatrix, null, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer); physicsBody.Enabled = true; Components.Add <MyPlaceArea>(new MySpherePlaceArea(10.0f, m_definition.Id.SubtypeId)); // TODO: Add radius to the definition AddHudMarker(); }
private void InitSubpartsPhysics() { var subpart = m_subpart1; if (subpart == null || CubeGrid.Physics == null) { return; } m_subpartPhysics = new MyPhysicsBody(this, CubeGrid.IsStatic ? RigidBodyFlag.RBF_STATIC : (CubeGrid.GridSizeEnum == MyCubeSize.Large ? RigidBodyFlag.RBF_DOUBLED_KINEMATIC : RigidBodyFlag.RBF_DEFAULT)); const float threshold = 0.11f; // Must be bigger than 2x convex radius HkCylinderShape shape = new HkCylinderShape(new Vector3(0, -2, 0), new Vector3(0, 2, 0), CubeGrid.GridSize / 2 - threshold, 0.05f); var mass = HkInertiaTensorComputer.ComputeCylinderVolumeMassProperties(new Vector3(0, -2, 0), new Vector3(0, 2, 0), CubeGrid.GridSize / 2, 40.0f * CubeGrid.GridSize); mass.Mass = BlockDefinition.Mass; m_subpartPhysics.CreateFromCollisionObject(shape, Vector3.Zero, subpart.WorldMatrix, mass); var info = HkGroupFilter.CalcFilterInfo(CubeGrid.Physics.RigidBody.Layer, CubeGrid.Physics.HavokCollisionSystemID, 1, 1); m_subpartPhysics.RigidBody.SetCollisionFilterInfo(info); shape.Base.RemoveReference(); if (m_subpartPhysics.RigidBody2 != null) { m_subpartPhysics.RigidBody2.Layer = MyPhysics.CollisionLayers.KinematicDoubledCollisionLayer; } CubeGrid.OnHavokSystemIDChanged += CubeGrid_OnHavokSystemIDChanged; CreateSubpartsConstraint(subpart); m_posChanged = true; }
public override void RecreatePhysics() { m_shapes.Clear(); BoundingBox aabb = new BoundingBox(-Vector3.One / 2, Vector3.One / 2); var positionComponent = Container.Get <MyPositionComponentBase>(); foreach (var pair in m_detectorInteractiveObjects) { unsafe { fixed(Vector3 *corner = m_detectorVertices) aabb.GetCornersUnsafe(corner); } for (int i = 0; i < BoundingBox.CornerCount; i++) { m_detectorVertices[i] = Vector3.Transform(m_detectorVertices[i], pair.Value.Matrix); } m_shapes.Add(new HkConvexVerticesShape(m_detectorVertices, BoundingBox.CornerCount, false, 0)); } if (m_shapes.Count > 0) { var listShape = new HkListShape(m_shapes.GetInternalArray(), m_shapes.Count, HkReferencePolicy.TakeOwnership); m_detectorPhysics = new MyPhysicsBody(Container.Entity, RigidBodyFlag.RBF_DISABLE_COLLISION_RESPONSE); m_detectorPhysics.CreateFromCollisionObject((HkShape)listShape, Vector3.Zero, positionComponent.WorldMatrix); m_detectorPhysics.Enabled = true; listShape.Base.RemoveReference(); } }
private void CreateConstraint(MyEntitySubpart subpart, ref HkConstraint constraint, ref HkFixedConstraintData constraintData) { if (subpart != null) { bool flag = !Sync.IsServer; if (subpart.Physics == null) { HkShape[] havokCollisionShapes = subpart.ModelCollision.HavokCollisionShapes; if ((havokCollisionShapes != null) && (havokCollisionShapes.Length != 0)) { MyPhysicsBody body = new MyPhysicsBody(subpart, flag ? RigidBodyFlag.RBF_STATIC : (RigidBodyFlag.RBF_UNLOCKED_SPEEDS | RigidBodyFlag.RBF_DOUBLED_KINEMATIC)) { IsSubpart = true }; subpart.Physics = body; HkShape shape = havokCollisionShapes[0]; MyPositionComponentBase positionComp = subpart.PositionComp; Vector3 center = positionComp.LocalVolume.Center; HkMassProperties properties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(positionComp.LocalAABB.HalfExtents, 100f); int collisionFilter = base.CubeGrid.IsStatic ? 9 : 0x10; body.CreateFromCollisionObject(shape, center, positionComp.WorldMatrix, new HkMassProperties?(properties), collisionFilter); } } if (flag) { subpart.Physics.Enabled = true; } else { base.CreateSubpartConstraint(subpart, out constraintData, out constraint); base.CubeGrid.Physics.AddConstraint(constraint); constraint.SetVirtualMassInverse(Vector4.Zero, Vector4.One); } } }
private void InitInternal() { float?scale = null; base.Init(null, this.m_definition.Model, null, scale, null); base.Render.ColorMaskHsv = this.m_definition.ColorHSV; base.Render.Transparency = 0.25f; base.Render.AddRenderObjects(); MyRenderProxy.ChangeMaterialTexture(base.Render.RenderObjectIDs[0], "BotFlag", this.m_definition.ColorMetalTexture, null, this.m_definition.AddMapsTexture, null); this.m_localActivationMatrix = MatrixD.CreateScale(base.PositionComp.LocalAABB.HalfExtents * 2f) * MatrixD.CreateTranslation(base.PositionComp.LocalAABB.Center); HkBoxShape shape = new HkBoxShape((Vector3)this.m_localActivationMatrix.Scale); MyPhysicsBody body = new MyPhysicsBody(this, RigidBodyFlag.RBF_DISABLE_COLLISION_RESPONSE); base.Physics = body; HkMassProperties?massProperties = null; body.CreateFromCollisionObject((HkShape)shape, Vector3.Zero, base.WorldMatrix, massProperties, 0x18); body.Enabled = true; base.Components.Add <MyPlaceArea>(new MySpherePlaceArea(10f, this.m_definition.Id.SubtypeId)); this.AddHudMarker(); }
private void InitInternal() { base.Init(null, m_definition.Model, null, null); Render.ColorMaskHsv = m_definition.ColorHSV; Render.Transparency = 0.25f; Render.AddRenderObjects(); List <MyTextureChange> textureChanges = new List <MyTextureChange>(); textureChanges.Add(new MyTextureChange { TextureName = m_definition.ColorMetalTexture, MaterialSlot = "ColorMetalTexture" }); textureChanges.Add(new MyTextureChange { TextureName = m_definition.AddMapsTexture, MaterialSlot = "AddMapsTexture" }); VRageRender.MyRenderProxy.ChangeMaterialTexture(Render.RenderObjectIDs[0], "BotFlag", textureChanges); // TODO: change the material name m_localActivationMatrix = MatrixD.CreateScale(this.PositionComp.LocalAABB.HalfExtents * 2.0f) * MatrixD.CreateTranslation(this.PositionComp.LocalAABB.Center); var shape = new HkBoxShape(m_localActivationMatrix.Scale); Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DISABLE_COLLISION_RESPONSE); Physics.CreateFromCollisionObject(shape, Vector3.Zero, WorldMatrix, null, MyPhysics.ObjectDetectionCollisionLayer); Physics.Enabled = true; Components.Add <MyPlaceArea>(new MySpherePlaceArea(10.0f, m_definition.Id.SubtypeId)); // TODO: Add radius to the definition MyHud.LocationMarkers.RegisterMarker(this, new MyHudEntityParams() { FlagsEnum = MyHudIndicatorFlagsEnum.SHOW_TEXT, Text = m_definition.DisplayNameEnum.HasValue ? MyTexts.Get(m_definition.DisplayNameEnum.Value) : new StringBuilder(), TargetMode = MyRelationsBetweenPlayerAndBlock.Neutral, MaxDistance = 200.0f, MustBeDirectlyVisible = true }); }
public void ReloadDetectors(bool refreshNetworks = true) { m_detectors.Clear(); m_detectorInteractiveObjects.Clear(); if (DetectorPhysics != null) { DetectorPhysics.Close(); } List <HkShape> shapes = new List <HkShape>(); BoundingBox aabb = new BoundingBox(-Vector3.One / 2, Vector3.One / 2); if (Render.GetModel() != null) { foreach (var dummy in Render.GetModel().Dummies) { var dummyLowerCaseKey = dummy.Key.ToLower(); const string DETECTOR_PREFIX = "detector_"; if (dummyLowerCaseKey.StartsWith(DETECTOR_PREFIX) && dummyLowerCaseKey.Length > DETECTOR_PREFIX.Length) { String[] parts = dummyLowerCaseKey.Split('_'); if (parts.Length < 2) { continue; } var dummyData = dummy.Value; List <Matrix> matrices; if (!m_detectors.TryGetValue(parts[1], out matrices)) { matrices = new List <Matrix>(); m_detectors[parts[1]] = matrices; } matrices.Add(Matrix.Invert(dummyData.Matrix)); // TODO: this should be nicer int shapeKey = shapes.Count; var interactiveObject = CreateInteractiveObject(parts[1], dummyLowerCaseKey, dummyData, shapeKey); if (interactiveObject != null) { unsafe { fixed(Vector3 *corner = m_detectorVertices) aabb.GetCornersUnsafe(corner); } for (int i = 0; i < BoundingBox.CornerCount; i++) { m_detectorVertices[i] = Vector3.Transform(m_detectorVertices[i], dummyData.Matrix); } shapes.Add(new HkConvexVerticesShape(m_detectorVertices, BoundingBox.CornerCount, false, 0)); m_detectorInteractiveObjects.Add(shapeKey, interactiveObject); } } } } if (shapes.Count > 0) { var listShape = new HkListShape(shapes.GetInternalArray(), shapes.Count, HkReferencePolicy.TakeOwnership); DetectorPhysics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DISABLE_COLLISION_RESPONSE); DetectorPhysics.CreateFromCollisionObject((HkShape)listShape, Vector3.Zero, WorldMatrix); DetectorPhysics.Enabled = true; listShape.Base.RemoveReference(); } /* * var inventoryBlock = this as IMyInventoryOwner; * if (refreshNetworks && inventoryBlock != null) * { * CubeGrid.ConveyorSystem.Remove(inventoryBlock); * CubeGrid.ConveyorSystem.Add(inventoryBlock); * }*/ }
public override void Init(MyObjectBuilder_EntityBase objectBuilder) { base.Init(objectBuilder); var ob = objectBuilder as MyObjectBuilder_FracturedPiece; if (ob.Shapes.Count == 0) { Debug.Fail("Invalid fracture piece! Dont call init without valid OB. Use pool/noinit."); throw new Exception("Fracture piece has no shapes."); //throwing exception, otherwise there is fp with null physics which can mess up somwhere else } foreach (var shape in ob.Shapes) { Render.AddPiece(shape.Name, Matrix.CreateFromQuaternion(shape.Orientation)); } OriginalBlocks.Clear(); foreach (var def in ob.BlockDefinitions) { string model = null; MyPhysicalModelDefinition mdef; if (MyDefinitionManager.Static.TryGetDefinition <MyPhysicalModelDefinition>(def, out mdef)) { model = mdef.Model; } MyCubeBlockDefinition blockDef = null; MyDefinitionManager.Static.TryGetDefinition <MyCubeBlockDefinition>(def, out blockDef); if (model == null) { Debug.Fail("Fracture piece Definition not found"); continue; } model = mdef.Model; if (VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes == null) { MyDestructionData.Static.LoadModelDestruction(model, mdef, Vector3.One); } var shape = VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes[0]; var si = new HkdShapeInstanceInfo(shape, null, null); m_children.Add(si); shape.GetChildren(m_children); if (blockDef != null && blockDef.BuildProgressModels != null) { foreach (var progress in blockDef.BuildProgressModels) { model = progress.File; if (VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes == null) { MyDestructionData.Static.LoadModelDestruction(model, blockDef, Vector3.One); } shape = VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes[0]; si = new HkdShapeInstanceInfo(shape, null, null); m_children.Add(si); shape.GetChildren(m_children); } } OriginalBlocks.Add(def); } m_shapes.AddRange(ob.Shapes); Vector3?offset = null; int shapeAtZero = 0; for (int i = 0; i < m_children.Count; i++) { var child = m_children[i]; Func <MyObjectBuilder_FracturedPiece.Shape, bool> x = s => s.Name == child.ShapeName; var result = m_shapes.Where(x); if (result.Count() > 0) { var found = result.First(); var m = Matrix.CreateFromQuaternion(found.Orientation); if (!offset.HasValue && found.Name == m_shapes[0].Name) { offset = child.GetTransform().Translation; shapeAtZero = m_shapeInfos.Count; } m.Translation = child.GetTransform().Translation; var si = new HkdShapeInstanceInfo(child.Shape.Clone(), m); if (found.Fixed) { si.Shape.SetFlagRecursively(HkdBreakableShape.Flags.IS_FIXED); } m_shapeInfos.Add(si); m_shapes.Remove(found); } else { child.GetChildren(m_children); } } if (m_shapeInfos.Count == 0) { List <string> shapesToLoad = new List <string>(); foreach (var obShape in ob.Shapes) { shapesToLoad.Add(obShape.Name); } var shapesStr = shapesToLoad.Aggregate((str1, str2) => str1 + ", " + str2); var blocksStr = OriginalBlocks.Aggregate("", (str, defId) => str + ", " + defId.ToString()); var failMsg = "No relevant shape was found for fractured piece. It was probably reexported and names changed. Shapes: " + shapesStr + ". Original blocks: " + shapesStr; Debug.Fail(failMsg); //HkdShapeInstanceInfo si = new HkdShapeInstanceInfo(new HkdBreakableShape((HkShape)new HkBoxShape(Vector3.One)), Matrix.Identity); //m_shapeInfos.Add(si); throw new Exception(failMsg); } if (offset.HasValue) { for (int i = 0; i < m_shapeInfos.Count; i++) { var m = m_shapeInfos[i].GetTransform(); m.Translation -= offset.Value; m_shapeInfos[i].SetTransform(ref m); } { var m = m_shapeInfos[shapeAtZero].GetTransform(); m.Translation = Vector3.Zero; m_shapeInfos[shapeAtZero].SetTransform(ref m); } } if (m_shapeInfos.Count > 0) { if (m_shapeInfos.Count == 1) { Shape = m_shapeInfos[0].Shape; } else { Shape = new HkdCompoundBreakableShape(null, m_shapeInfos); ((HkdCompoundBreakableShape)Shape).RecalcMassPropsFromChildren(); } Shape.SetStrenght(MyDestructionConstants.STRENGTH); var mp = new HkMassProperties(); Shape.BuildMassProperties(ref mp); Shape.SetChildrenParent(Shape); Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEBRIS); Physics.CanUpdateAccelerations = true; Physics.InitialSolverDeactivation = HkSolverDeactivation.High; Physics.CreateFromCollisionObject(Shape.GetShape(), Vector3.Zero, PositionComp.WorldMatrix, mp); Physics.BreakableBody = new HkdBreakableBody(Shape, Physics.RigidBody, MyPhysics.SingleWorld.DestructionWorld, (Matrix)PositionComp.WorldMatrix); Physics.BreakableBody.AfterReplaceBody += Physics.FracturedBody_AfterReplaceBody; if (OriginalBlocks.Count > 0) { MyPhysicalModelDefinition def; if (MyDefinitionManager.Static.TryGetDefinition <MyPhysicalModelDefinition>(OriginalBlocks[0], out def)) { Physics.MaterialType = def.PhysicalMaterial.Id.SubtypeId; } } var rigidBody = Physics.RigidBody; bool isFixed = MyDestructionHelper.IsFixed(Physics.BreakableBody.BreakableShape); if (isFixed) { rigidBody.UpdateMotionType(HkMotionType.Fixed); rigidBody.LinearVelocity = Vector3.Zero; rigidBody.AngularVelocity = Vector3.Zero; } Physics.Enabled = true; } m_children.Clear(); m_shapeInfos.Clear(); }
private void InitInternal() { // TODO: This will be fixed and made much more simple once ore models are done // https://app.asana.com/0/6594565324126/10473934569658 var itemDefinition = MyDefinitionManager.Static.GetPhysicalItemDefinition(Item.Content); m_health = itemDefinition.Health; // Setting voxel material (if applicable) VoxelMaterial = null; if (itemDefinition.VoxelMaterial != MyStringHash.NullOrEmpty) { VoxelMaterial = MyDefinitionManager.Static.GetVoxelMaterialDefinition(itemDefinition.VoxelMaterial.String); } else if (Item.Content is MyObjectBuilder_Ore) { string oreSubTypeId = itemDefinition.Id.SubtypeName; string materialName = (Item.Content as MyObjectBuilder_Ore).GetMaterialName(); bool hasMaterialName = (Item.Content as MyObjectBuilder_Ore).HasMaterialName(); foreach (var mat in MyDefinitionManager.Static.GetVoxelMaterialDefinitions()) { if ((hasMaterialName && materialName == mat.Id.SubtypeName) || (hasMaterialName == false && oreSubTypeId == mat.MinedOre)) { VoxelMaterial = mat; break; } } } // Setting the item's model string model = itemDefinition.Model; if (itemDefinition.HasModelVariants) { int modelNum = itemDefinition.Models.Length; Debug.Assert(m_modelVariant >= 0 && m_modelVariant < modelNum, "Model variant overflow. This can happen if model variants changed"); m_modelVariant = m_modelVariant % modelNum; model = itemDefinition.Models[m_modelVariant]; } else if (Item.Content is MyObjectBuilder_Ore && VoxelMaterial != null) { // Only ores without found voxel material use the defined model (otherwise, the scrap metal does not work) model = MyDebris.GetRandomDebrisVoxel(); } // Setting the scale float scale = this.Item.Scale; if (Item.Content is MyObjectBuilder_Ore) { scale *= (float)Math.Pow((float)Item.Amount * itemDefinition.Volume / MyDebris.VoxelDebrisModelVolume, 0.333f); } else { scale *= (float)Math.Pow(itemDefinition.Volume / itemDefinition.ModelVolume, 0.333f); } if (scale < 0.05f) { Close(); } else if (scale < 0.15f) { scale = 0.15f; } FormatDisplayName(m_displayedText, Item); Debug.Assert(model != null, "Floating object model is null"); Init(m_displayedText, model, null, null, null); PositionComp.Scale = scale; // Must be set after init var massProperties = new HkMassProperties(); var mass = MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(itemDefinition.Mass) : itemDefinition.Mass; mass = mass * (float)Item.Amount; HkShape shape = GetPhysicsShape(mass, scale, out massProperties); var scaleMatrix = Matrix.CreateScale(scale); if (Physics != null) { Physics.Close(); } Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEBRIS); int layer = mass > MyPerGameSettings.MinimumLargeShipCollidableMass ? MyPhysics.CollisionLayers.FloatingObjectCollisionLayer : MyPhysics.CollisionLayers.LightFloatingObjectCollisionLayer; if (VoxelMaterial != null || (shape.IsConvex && scale != 1f)) { HkConvexTransformShape transform = new HkConvexTransformShape((HkConvexShape)shape, ref scaleMatrix, HkReferencePolicy.None); Physics.CreateFromCollisionObject(transform, Vector3.Zero, MatrixD.Identity, massProperties, layer); Physics.Enabled = true; transform.Base.RemoveReference(); } else { Physics.CreateFromCollisionObject(shape, Vector3.Zero, MatrixD.Identity, massProperties, layer); Physics.Enabled = true; } Physics.MaterialType = this.EvaluatePhysicsMaterial(itemDefinition.PhysicalMaterial); Physics.PlayCollisionCueEnabled = true; Physics.RigidBody.ContactSoundCallbackEnabled = true; m_easeCollisionForce = new HkEasePenetrationAction(Physics.RigidBody, 2f); m_massChangeForCollisions = 0.010f; NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME; }
private void InitInternal() { // TODO: This will be fixed and made much more simple once ore models are done // https://app.asana.com/0/6594565324126/10473934569658 var physicalItem = MyDefinitionManager.Static.GetPhysicalItemDefinition(Item.Content); m_health = physicalItem.Health; string model = physicalItem.Model; VoxelMaterial = null; float scale = 1.0f; if (Item.Content is MyObjectBuilder_Ore) { string oreSubTypeId = physicalItem.Id.SubtypeId.ToString(); foreach (var mat in MyDefinitionManager.Static.GetVoxelMaterialDefinitions()) { if (oreSubTypeId == mat.MinedOre) { VoxelMaterial = mat; model = MyDebris.GetRandomDebrisVoxel(); scale = (float)Math.Pow((float)Item.Amount * physicalItem.Volume / MyDebris.VoxelDebrisModelVolume, 0.333f); break; } } scale = (float)Math.Pow((float)Item.Amount * physicalItem.Volume / MyDebris.VoxelDebrisModelVolume, 0.333f); } if (scale < 0.05f) { Close(); } else if (scale < 0.15f) { scale = 0.15f; } FormatDisplayName(m_displayedText, Item); Init(m_displayedText, model, null, null, null); PositionComp.Scale = scale; // Must be set after init var massProperties = new HkMassProperties(); var mass = MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(physicalItem.Mass) : physicalItem.Mass; HkShape shape = GetPhysicsShape(mass * (float)Item.Amount, scale, out massProperties); var scaleMatrix = Matrix.CreateScale(scale); if (Physics != null) { Physics.Close(); } Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEBRIS); if (VoxelMaterial != null) { HkConvexTransformShape transform = new HkConvexTransformShape((HkConvexShape)shape, ref scaleMatrix, HkReferencePolicy.None); Physics.CreateFromCollisionObject(transform, Vector3.Zero, MatrixD.Identity, massProperties, MyPhysics.FloatingObjectCollisionLayer); Physics.Enabled = true; transform.Base.RemoveReference(); } else { Physics.CreateFromCollisionObject(shape, Vector3.Zero, MatrixD.Identity, massProperties, MyPhysics.FloatingObjectCollisionLayer); Physics.Enabled = true; } Physics.MaterialType = VoxelMaterial != null ? MyMaterialType.ROCK : MyMaterialType.METAL; Physics.PlayCollisionCueEnabled = true; NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME; }