protected void SerializeInternal(MyObjectBuilder_FractureComponentBase ob) { Debug.Assert(m_tmpChildren.Count == 0); if (string.IsNullOrEmpty(Shape.Name) || Shape.IsCompound() || Shape.GetChildrenCount() > 0) { Shape.GetChildren(m_tmpChildren); foreach (var child in m_tmpChildren) { var shape = new MyObjectBuilder_FractureComponentCubeBlock.FracturedShape() { Name = child.ShapeName, Fixed = MyDestructionHelper.IsFixed(child.Shape) }; ob.Shapes.Add(shape); } m_tmpChildren.Clear(); } else { ob.Shapes.Add(new MyObjectBuilder_FractureComponentCubeBlock.FracturedShape() { Name = Shape.Name }); } }
private static void ConvertAllShapesToFractureComponentShapeBuilder(HkdBreakableShape shape, ref Matrix shapeRotation, MyBlockOrientation blockOrientation, HashSet <string> names, MyObjectBuilder_FractureComponentCubeBlock fractureComponentBuilder) { var name = shape.Name; if (names.Contains(name)) { MyBlockOrientation shapeOrientation = new MyBlockOrientation(ref shapeRotation); if (shapeOrientation == blockOrientation) { MyObjectBuilder_FractureComponentCubeBlock.FracturedShape builderShape = new MyObjectBuilder_FractureComponentBase.FracturedShape(); builderShape.Name = name; builderShape.Fixed = MyDestructionHelper.IsFixed(shape); fractureComponentBuilder.Shapes.Add(builderShape); } } if (shape.GetChildrenCount() > 0) { List <HkdShapeInstanceInfo> children = new List <HkdShapeInstanceInfo>(); shape.GetChildren(children); foreach (var child in children) { var childShapeRotation = child.GetTransform(); ConvertAllShapesToFractureComponentShapeBuilder(child.Shape, ref childShapeRotation, blockOrientation, names, fractureComponentBuilder); } } }
public override MyObjectBuilder_EntityBase GetObjectBuilder(bool copy = false) { var old = base.GetObjectBuilder(copy); var ob = old as MyObjectBuilder_FracturedPiece; foreach (var def in OriginalBlocks) { ob.BlockDefinitions.Add(def); } if (Physics == null) { Debug.Assert(m_shapes.Count > 0, "Saving invalid piece!"); foreach (var shape in m_shapes) { ob.Shapes.Add(new MyObjectBuilder_FracturedPiece.Shape() { Name = shape.Name, Orientation = shape.Orientation }); } return(ob); } if (Physics.BreakableBody.BreakableShape.IsCompound() || string.IsNullOrEmpty(Physics.BreakableBody.BreakableShape.Name)) { Physics.BreakableBody.BreakableShape.GetChildren(m_children); if (m_children.Count == 0) { Debug.Fail("Saiving invalid piece!"); return(ob); } foreach (var child in m_children) { var shape = new MyObjectBuilder_FracturedPiece.Shape() { Name = child.ShapeName, Orientation = Quaternion.CreateFromRotationMatrix(child.GetTransform().GetOrientation()), Fixed = MyDestructionHelper.IsFixed(child.Shape) }; ob.Shapes.Add(shape); } if (Physics.IsInWorld) { var fixedPosition = Physics.ClusterToWorld(Vector3.Transform(m_children[0].GetTransform().Translation, Physics.RigidBody.GetRigidBodyMatrix())); var posOr = ob.PositionAndOrientation.Value; posOr.Position = fixedPosition; ob.PositionAndOrientation = posOr; } m_children.Clear(); } else { ob.Shapes.Add(new MyObjectBuilder_FracturedPiece.Shape() { Name = Physics.BreakableBody.BreakableShape.Name }); } Debug.Assert(ob.Shapes.Count > 0, "Saiving invalid piece!"); return(ob); }
public override MyObjectBuilder_CubeBlock GetObjectBuilderCubeBlock(bool copy = false) { Debug.Assert(!MyFakes.ENABLE_FRACTURE_COMPONENT, "Fractured block saved with fracture components enabled"); var ob = base.GetObjectBuilderCubeBlock(copy) as MyObjectBuilder_FracturedBlock; if (string.IsNullOrEmpty(Shape.Name) || Shape.IsCompound()) { Shape.GetChildren(m_children); foreach (var child in m_children) { var shape = new MyObjectBuilder_FracturedBlock.ShapeB() { Name = child.ShapeName, Orientation = Quaternion.CreateFromRotationMatrix(child.GetTransform().GetOrientation()), Fixed = MyDestructionHelper.IsFixed(child.Shape) }; ob.Shapes.Add(shape); } m_children.Clear(); } else { ob.Shapes.Add(new MyObjectBuilder_FracturedBlock.ShapeB() { Name = Shape.Name }); } foreach (var def in OriginalBlocks) { ob.BlockDefinitions.Add(def); } foreach (var or in Orientations) { ob.BlockOrientations.Add(or); } if (MultiBlocks != null) { foreach (var mbpart in MultiBlocks) { if (mbpart != null) { ob.MultiBlocks.Add(new MyObjectBuilder_FracturedBlock.MyMultiBlockPart() { MultiBlockDefinition = mbpart.MultiBlockDefinition, MultiBlockId = mbpart.MultiBlockId }); } else { ob.MultiBlocks.Add(null); } } } return(ob); }
private void SectorOnContactPoint(int itemId, MyEntity other, ref MyPhysics.MyContactPointEvent e) { // if item is already disabled: puff // We get multiple contact points so this is for that if (m_sector.DataView.Items[itemId].ModelIndex < 0) { return; } var vel = Math.Abs(e.ContactPointEvent.SeparatingVelocity); if (other == null || other.Physics == null || other is MyFloatingObject) { return; } if (other is IMyHandheldGunObject <MyDeviceBase> ) { return; } // Prevent debris from breaking trees. // Debris flies in unpredictable ways and this could cause out of sync tree destruction which would is bad. if (other.Physics.RigidBody != null && other.Physics.RigidBody.Layer == MyPhysics.CollisionLayers.DebrisCollisionLayer) { return; } // On objects held in manipulation tool, Havok returns high velocities, after this contact is fired by contraint solver. // Therefore we disable damage from objects connected by constraint to character if (MyManipulationTool.IsEntityManipulated(other)) { return; } float otherMass = MyDestructionHelper.MassFromHavok(other.Physics.Mass); double impactEnergy = vel * vel * otherMass; // TODO: per item max impact energy if (impactEnergy > ItemResilience(itemId)) { var normal = e.ContactPointEvent.ContactPoint.Normal; impactEnergy = MathHelper.Clamp(impactEnergy, 0, ItemResilience(itemId) * 10); Impact impact = new Impact(e.Position, normal, impactEnergy); m_sector.RaiseItemEvent(this, itemId, impact); DisableItemAndCreateDebris(ref impact, itemId); } // Meteor destroy always if (other is MyMeteor) { m_sector.EnableItem(itemId, false); } }
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); } } }
public override MyObjectBuilder_CubeBlock GetObjectBuilderCubeBlock(bool copy = false) { MyObjectBuilder_FracturedBlock.ShapeB eb2; MyObjectBuilder_FracturedBlock objectBuilderCubeBlock = base.GetObjectBuilderCubeBlock(copy) as MyObjectBuilder_FracturedBlock; if (!string.IsNullOrEmpty(this.Shape.Name) && !this.Shape.IsCompound()) { eb2 = new MyObjectBuilder_FracturedBlock.ShapeB { Name = this.Shape.Name }; objectBuilderCubeBlock.Shapes.Add(eb2); } else { this.Shape.GetChildren(m_children); foreach (HkdShapeInstanceInfo info in m_children) { eb2 = new MyObjectBuilder_FracturedBlock.ShapeB { Name = info.ShapeName }; eb2.Orientation = Quaternion.CreateFromRotationMatrix(info.GetTransform().GetOrientation()); eb2.Fixed = MyDestructionHelper.IsFixed(info.Shape); MyObjectBuilder_FracturedBlock.ShapeB item = eb2; objectBuilderCubeBlock.Shapes.Add(item); } m_children.Clear(); } foreach (MyDefinitionId id in this.OriginalBlocks) { objectBuilderCubeBlock.BlockDefinitions.Add((SerializableDefinitionId)id); } foreach (MyBlockOrientation orientation in this.Orientations) { objectBuilderCubeBlock.BlockOrientations.Add(orientation); } if (this.MultiBlocks != null) { foreach (MultiBlockPartInfo info2 in this.MultiBlocks) { if (info2 == null) { objectBuilderCubeBlock.MultiBlocks.Add(null); continue; } MyObjectBuilder_FracturedBlock.MyMultiBlockPart item = new MyObjectBuilder_FracturedBlock.MyMultiBlockPart(); item.MultiBlockDefinition = (SerializableDefinitionId)info2.MultiBlockDefinition; item.MultiBlockId = info2.MultiBlockId; objectBuilderCubeBlock.MultiBlocks.Add(item); } } return(objectBuilderCubeBlock); }
private static void ConvertAllShapesToFractureComponentShapeBuilder(HkdBreakableShape shape, ref Matrix shapeRotation, MyBlockOrientation blockOrientation, HashSet <Tuple <string, float> > namesAndBuildProgress, MyObjectBuilder_FractureComponentCubeBlock fractureComponentBuilder, out float buildProgress) { buildProgress = 1f; var name = shape.Name; Tuple <string, float> foundTuple = null; foreach (var tuple in namesAndBuildProgress) { if (tuple.Item1 == name) { foundTuple = tuple; break; } } if (foundTuple != null) { MyBlockOrientation shapeOrientation = new MyBlockOrientation(ref shapeRotation); if (shapeOrientation == blockOrientation) { MyObjectBuilder_FractureComponentCubeBlock.FracturedShape builderShape = new MyObjectBuilder_FractureComponentBase.FracturedShape(); builderShape.Name = name; builderShape.Fixed = MyDestructionHelper.IsFixed(shape); fractureComponentBuilder.Shapes.Add(builderShape); buildProgress = foundTuple.Item2; } } if (shape.GetChildrenCount() > 0) { List <HkdShapeInstanceInfo> children = new List <HkdShapeInstanceInfo>(); shape.GetChildren(children); foreach (var child in children) { var childShapeRotation = child.GetTransform(); float localBuildProgress; ConvertAllShapesToFractureComponentShapeBuilder(child.Shape, ref childShapeRotation, blockOrientation, namesAndBuildProgress, fractureComponentBuilder, out localBuildProgress); if (foundTuple == null) { buildProgress = localBuildProgress; } } } }
public override void HandleInput() { if ((this.m_isActive && (MyScreenManager.GetScreenWithFocus() is MyGuiScreenGamePlay)) && ((MyInput.Static.ENABLE_DEVELOPER_KEYS || !MySession.Static.SurvivalMode) || MySession.Static.IsUserAdmin(Sync.MyId))) { base.HandleInput(); if (MyControllerHelper.IsControl(MySpaceBindingCreator.CX_CHARACTER, MyControlsSpace.PRIMARY_TOOL_ACTION, MyControlStateType.NEW_PRESSED, false)) { this.m_startTime = MySandboxGame.TotalGamePlayTimeInMilliseconds; } if (MyControllerHelper.IsControl(MySpaceBindingCreator.CX_CHARACTER, MyControlsSpace.PRIMARY_TOOL_ACTION, MyControlStateType.NEW_RELEASED, false)) { MyObjectBuilder_CubeGrid[] gridPrefab = MyPrefabManager.Static.GetGridPrefab(this.CurrentDefinition.PrefabToThrow); Vector3D zero = Vector3D.Zero; Vector3D forward = Vector3D.Zero; if (USE_SPECTATOR_FOR_THROW) { zero = MySpectator.Static.Position; forward = MySpectator.Static.Orientation.Forward; } else if ((MySession.Static.GetCameraControllerEnum() != MyCameraControllerEnum.ThirdPersonSpectator) && (MySession.Static.GetCameraControllerEnum() != MyCameraControllerEnum.Entity)) { zero = MySector.MainCamera.Position; forward = MySector.MainCamera.WorldMatrix.Forward; } else { if (MySession.Static.ControlledEntity == null) { return; } zero = MySession.Static.ControlledEntity.GetHeadMatrix(true, true, false, false).Translation; forward = MySession.Static.ControlledEntity.GetHeadMatrix(true, true, false, false).Forward; } Vector3D vectord3 = zero + forward; Vector3D vectord4 = (forward * MathHelper.Clamp(((((float)(MySandboxGame.TotalGamePlayTimeInMilliseconds - this.m_startTime)) / 1000f) / this.CurrentDefinition.PushTime) * this.CurrentDefinition.MaxSpeed, this.CurrentDefinition.MinSpeed, this.CurrentDefinition.MaxSpeed)) + MySession.Static.ControlledEntity.Entity.Physics.LinearVelocity; float num2 = 0f; if (this.CurrentDefinition.Mass != null) { num2 = MyDestructionHelper.MassToHavok(this.CurrentDefinition.Mass.Value); } gridPrefab[0].EntityId = MyEntityIdentifier.AllocateId(MyEntityIdentifier.ID_OBJECT_TYPE.ENTITY, MyEntityIdentifier.ID_ALLOCATION_METHOD.RANDOM); EndpointId targetEndpoint = new EndpointId(); Vector3D? position = null; MyMultiplayer.RaiseStaticEvent <MyObjectBuilder_CubeGrid, Vector3D, Vector3D, float, MyCueId>(s => new Action <MyObjectBuilder_CubeGrid, Vector3D, Vector3D, float, MyCueId>(MySessionComponentThrower.OnThrowMessageSuccess), gridPrefab[0], vectord3, vectord4, num2, this.CurrentDefinition.ThrowSound, targetEndpoint, position); this.m_startTime = 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); } } }
void Physics_ContactPointCallback(ref MyPhysics.MyContactPointEvent e) { var vel = Math.Abs(e.ContactPointEvent.SeparatingVelocity); var other = e.ContactPointEvent.GetOtherEntity(this); if (other == null || other.Physics == null) { return; } float otherMass = MyDestructionHelper.MassFromHavok(other.Physics.Mass); if (other is Sandbox.Game.Entities.Character.MyCharacter) { otherMass = other.Physics.Mass; } float impactEnergy = vel * vel * otherMass; // If environment item is hit by a gun, nothing happens here. If you want a weapon damage to env. items, call DoDamage there if (impactEnergy > 350000 && !(other is IMyHandheldGunObject <MyDeviceBase>)) { int bodyId = e.ContactPointEvent.Base.BodyA.GetEntity() == this ? 0 : 1; var shapeKey = e.ContactPointEvent.GetShapeKey(bodyId); var position = Physics.ClusterToWorld(e.ContactPointEvent.ContactPoint.Position); var sectorId = MyEnvironmentSector.GetSectorId(position, m_definition.SectorSize); HkStaticCompoundShape shape = (HkStaticCompoundShape)Physics.RigidBody.GetShape(); int physicsInstanceId; uint childKey; if (shapeKey == uint.MaxValue) //jn: TODO find out why this happens, there is ticket for it https://app.asana.com/0/9887996365574/26645443970236 { ProfilerShort.End(); return; } shape.DecomposeShapeKey(shapeKey, out physicsInstanceId, out childKey); int itemInstanceId; if (m_physicsShapeInstanceIdToLocalId.TryGetValue(physicsInstanceId, out itemInstanceId)) { DoDamage(1.0f, itemInstanceId, e.Position, -e.ContactPointEvent.ContactPoint.Normal); } } }
private static void ConvertAllShapesToFractureComponentShapeBuilder(HkdBreakableShape shape, ref Matrix shapeRotation, MyBlockOrientation blockOrientation, HashSet <Tuple <string, float> > namesAndBuildProgress, MyObjectBuilder_FractureComponentCubeBlock fractureComponentBuilder, out float buildProgress) { buildProgress = 1f; string name = shape.Name; Tuple <string, float> tuple = null; foreach (Tuple <string, float> tuple2 in namesAndBuildProgress) { if (tuple2.Item1 == name) { tuple = tuple2; break; } } if ((tuple != null) && (new MyBlockOrientation(ref shapeRotation) == blockOrientation)) { MyObjectBuilder_FractureComponentBase.FracturedShape item = new MyObjectBuilder_FractureComponentBase.FracturedShape { Name = name, Fixed = MyDestructionHelper.IsFixed(shape) }; fractureComponentBuilder.Shapes.Add(item); buildProgress = tuple.Item2; } if (shape.GetChildrenCount() > 0) { List <HkdShapeInstanceInfo> list = new List <HkdShapeInstanceInfo>(); shape.GetChildren(list); foreach (HkdShapeInstanceInfo info in list) { float num; Matrix transform = info.GetTransform(); ConvertAllShapesToFractureComponentShapeBuilder(info.Shape, ref transform, blockOrientation, namesAndBuildProgress, fractureComponentBuilder, out num); if (tuple == null) { buildProgress = num; } } } }
public override MyObjectBuilder_CubeBlock GetObjectBuilderCubeBlock(bool copy = false) { var ob = base.GetObjectBuilderCubeBlock(copy) as MyObjectBuilder_FracturedBlock; if (string.IsNullOrEmpty(Shape.Name) || Shape.IsCompound()) { Shape.GetChildren(m_children); foreach (var child in m_children) { var shape = new MyObjectBuilder_FracturedBlock.ShapeB() { Name = child.ShapeName, Orientation = Quaternion.CreateFromRotationMatrix(child.GetTransform().GetOrientation()), Fixed = MyDestructionHelper.IsFixed(child.Shape) }; ob.Shapes.Add(shape); } m_children.Clear(); } else { ob.Shapes.Add(new MyObjectBuilder_FracturedBlock.ShapeB() { Name = Shape.Name }); } foreach (var def in OriginalBlocks) { ob.BlockDefinitions.Add(def); } foreach (var or in Orientations) { ob.BlockOrientations.Add(or); } return(ob); }
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! } }
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; }
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(); }
internal void InitFromBreakableBody(HkdBreakableBody b, MatrixD worldMatrix, MyCubeBlock block) { ProfilerShort.Begin("RemoveGen&SetFixed"); OriginalBlocks.Clear(); if (block != null) { if (block is MyCompoundCubeBlock) { foreach (var block2 in (block as MyCompoundCubeBlock).GetBlocks()) { OriginalBlocks.Add(block2.BlockDefinition.Id); } } else if (block is MyFracturedBlock) { OriginalBlocks.AddRange((block as MyFracturedBlock).OriginalBlocks); } else { OriginalBlocks.Add(block.BlockDefinition.Id); } } var rigidBody = b.GetRigidBody(); bool isFixed = MyDestructionHelper.IsFixed(b.BreakableShape); if (isFixed) { rigidBody.UpdateMotionType(HkMotionType.Fixed); rigidBody.LinearVelocity = Vector3.Zero; rigidBody.AngularVelocity = Vector3.Zero; } ProfilerShort.Begin("Sync"); if (SyncFlag) { CreateSync(); } ProfilerShort.End(); PositionComp.WorldMatrix = worldMatrix; Physics.Flags = isFixed ? RigidBodyFlag.RBF_STATIC : RigidBodyFlag.RBF_DEBRIS; Physics.BreakableBody = b; rigidBody.UserObject = Physics; if (!isFixed) { rigidBody.Motion.SetDeactivationClass(HkSolverDeactivation.High); rigidBody.EnableDeactivation = true; if (MyFakes.REDUCE_FRACTURES_COUNT) { if (b.BreakableShape.Volume < 1 && MyRandom.Instance.Next(6) > 1) { rigidBody.Layer = MyFracturedPiecesManager.FakePieceLayer; } else { rigidBody.Layer = MyPhysics.CollisionLayers.DefaultCollisionLayer; } } else { rigidBody.Layer = MyPhysics.CollisionLayers.DefaultCollisionLayer; } } else { rigidBody.Layer = MyPhysics.CollisionLayers.StaticCollisionLayer; } 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; } } ProfilerShort.BeginNextBlock("Enable"); Physics.Enabled = true; MyDestructionHelper.FixPosition(this); SetDataFromHavok(b.BreakableShape); var coml = b.GetRigidBody().CenterOfMassLocal; var comw = b.GetRigidBody().CenterOfMassWorld; var com = b.BreakableShape.CoM; b.GetRigidBody().CenterOfMassLocal = com; b.BreakableShape.RemoveReference(); ProfilerShort.End(); }
private static float GetRealMass(float physicsMass) { return(MyDestructionHelper.MassFromHavok(physicsMass)); }
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 bool CreateOwnerVirtualPhysics() { if (Owner == null) { return(false); } OwnerVirtualPhysics = new MyCharacterVirtualPhysicsBody(Owner, RigidBodyFlag.RBF_KINEMATIC); var massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(0.1f, MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(Owner.Definition.Mass) : Owner.Definition.Mass); HkShape sh = new HkSphereShape(0.1f); OwnerVirtualPhysics.InitialSolverDeactivation = HkSolverDeactivation.Off; MatrixD headWorldMatrix = Owner.GetHeadMatrix(false, forceHeadBone: true); OwnerVirtualPhysics.CreateFromCollisionObject(sh, Vector3.Zero, headWorldMatrix, massProperties, Sandbox.Engine.Physics.MyPhysics.NoCollisionLayer); OwnerVirtualPhysics.RigidBody.EnableDeactivation = false; // Character ray casts includes also NoCollision layer shapes so setup property for ignoring the body OwnerVirtualPhysics.RigidBody.SetProperty(HkCharacterRigidBody.MANIPULATED_OBJECT, 0); sh.RemoveReference(); OwnerVirtualPhysics.Enabled = true; return(true); }
public bool InitRagdoll() { if (MyFakes.ENABLE_RAGDOLL_DEBUG) { MyLog.Default.WriteLine("RagdollComponent.InitRagdoll"); } if (base.Character.Physics.Ragdoll != null) { base.Character.Physics.CloseRagdollMode(); base.Character.Physics.Ragdoll.ResetToRigPose(); base.Character.Physics.Ragdoll.SetToKeyframed(); return(true); } base.Character.Physics.Ragdoll = new HkRagdoll(); bool flag = false; if ((base.Character.Model.HavokData != null) && (base.Character.Model.HavokData.Length != 0)) { try { flag = base.Character.Physics.Ragdoll.LoadRagdollFromBuffer(base.Character.Model.HavokData); } catch (Exception) { base.Character.Physics.CloseRagdoll(); base.Character.Physics.Ragdoll = null; } } else if (base.Character.Definition.RagdollDataFile != null) { string path = Path.Combine(MyFileSystem.ContentPath, base.Character.Definition.RagdollDataFile); if (File.Exists(path)) { flag = base.Character.Physics.Ragdoll.LoadRagdollFromFile(path); } } if (base.Character.Definition.RagdollRootBody != string.Empty) { base.Character.Physics.Ragdoll.SetRootBody(base.Character.Definition.RagdollRootBody); } if (!flag) { base.Character.Physics.Ragdoll.Dispose(); base.Character.Physics.Ragdoll = null; } using (List <HkRigidBody> .Enumerator enumerator = base.Character.Physics.Ragdoll.RigidBodies.GetEnumerator()) { while (enumerator.MoveNext()) { enumerator.Current.UserObject = base.Character; } } if ((base.Character.Physics.Ragdoll != null) && MyPerGameSettings.Destruction) { base.Character.Physics.Ragdoll.SetToDynamic(); HkMassProperties properties = new HkMassProperties(); foreach (HkRigidBody body in base.Character.Physics.Ragdoll.RigidBodies) { properties.Mass = MyDestructionHelper.MassToHavok(body.Mass); properties.InertiaTensor = Matrix.CreateScale((float)0.04f) * body.InertiaTensor; body.SetMassProperties(ref properties); } base.Character.Physics.Ragdoll.SetToKeyframed(); } if ((base.Character.Physics.Ragdoll != null) && MyFakes.ENABLE_RAGDOLL_DEFAULT_PROPERTIES) { base.Character.Physics.SetRagdollDefaults(); } if (MyFakes.ENABLE_RAGDOLL_DEBUG) { MyLog.Default.WriteLine("RagdollComponent.InitRagdoll - FINISHED"); } return(flag); }
public override bool HandleInput() { if (base.HandleInput()) { return(true); } bool handled = false; if (MyInput.Static.IsAnyCtrlKeyPressed() && MyInput.Static.IsNewLeftMouseReleased()) { Hammer(); } if (MyInput.Static.IsNewKeyPressed(MyKeys.NumPad1)) { ApplyMassMultiplier = !ApplyMassMultiplier; handled = true; } var mul = 1; if (MyInput.Static.IsKeyPress(MyKeys.N)) { mul = 10; } if (MyInput.Static.IsKeyPress(MyKeys.B)) { mul = 100; } if (MyInput.Static.IsNewKeyPressed(MyKeys.OemQuotes)) { if (MassMultiplier > 1) { MassMultiplier += mul; } else { MassMultiplier *= mul; } handled = true; } if (MyInput.Static.IsNewKeyPressed(MyKeys.OemSemicolon)) { if (MassMultiplier > 1) { MassMultiplier -= mul; } else { MassMultiplier /= mul; } handled = true; } if (MySector.MainCamera != null) { List <MyPhysics.HitInfo> lst = new List <MyPhysics.HitInfo>(); MyPhysics.CastRay(MySector.MainCamera.Position, MySector.MainCamera.Position + MySector.MainCamera.ForwardVector * 100, lst); foreach (var hit in lst) { VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(600, 10), hit.HkHitInfo.Body.GetEntity().ToString() + " " + MyDestructionHelper.MassFromHavok(hit.HkHitInfo.Body.Mass), Color.White, 0.8f); VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(600, 30), "Layer: " + hit.HkHitInfo.Body.Layer, Color.White, 0.8f); if (hit.HkHitInfo.Body.GetEntity() is MyCubeGrid) { var grid = hit.HkHitInfo.Body.GetEntity() as MyCubeGrid; var det = grid.GetBlocks().FirstElement().FatBlock.UseObjectsComponent.DetectorPhysics; //var layer = det.RigidBody.Layer; } break; } } if (MyInput.Static.IsNewKeyPressed(MyKeys.NumPad9)) { MyScriptManager.Static.LoadData(); } if (MyAudio.Static != null) { foreach (var em in MyAudio.Static.Get3DSounds()) { VRageRender.MyRenderProxy.DebugDrawSphere(em.SourcePosition, 0.1f, Color.Red, 1, false); } } return(handled); }
private void InitInternal() { MyPhysicalItemDefinition physicalItemDefinition = MyDefinitionManager.Static.GetPhysicalItemDefinition(this.Item.Content); this.m_health = physicalItemDefinition.Health; this.VoxelMaterial = null; if (physicalItemDefinition.VoxelMaterial != MyStringHash.NullOrEmpty) { this.VoxelMaterial = MyDefinitionManager.Static.GetVoxelMaterialDefinition(physicalItemDefinition.VoxelMaterial.String); } else if (this.Item.Content is MyObjectBuilder_Ore) { string subtypeName = physicalItemDefinition.Id.SubtypeName; string materialName = (this.Item.Content as MyObjectBuilder_Ore).GetMaterialName(); bool flag = (this.Item.Content as MyObjectBuilder_Ore).HasMaterialName(); foreach (MyVoxelMaterialDefinition definition2 in MyDefinitionManager.Static.GetVoxelMaterialDefinitions()) { if ((flag && (materialName == definition2.Id.SubtypeName)) || (!flag && (subtypeName == definition2.MinedOre))) { this.VoxelMaterial = definition2; break; } } } if ((this.VoxelMaterial != null) && (this.VoxelMaterial.DamagedMaterial != MyStringHash.NullOrEmpty)) { this.VoxelMaterial = MyDefinitionManager.Static.GetVoxelMaterialDefinition(this.VoxelMaterial.DamagedMaterial.ToString()); } string model = physicalItemDefinition.Model; if (physicalItemDefinition.HasModelVariants) { int length = physicalItemDefinition.Models.Length; this.m_modelVariant = this.m_modelVariant % length; model = physicalItemDefinition.Models[this.m_modelVariant]; } else if ((this.Item.Content is MyObjectBuilder_Ore) && (this.VoxelMaterial != null)) { float num5 = 50f; model = MyDebris.GetAmountBasedDebrisVoxel(Math.Max((float)this.Item.Amount, num5)); } float scale = 0.7f; this.FormatDisplayName(this.m_displayedText, this.Item); float?nullable = null; this.Init(this.m_displayedText, model, null, nullable, null); HkMassProperties massProperties = new HkMassProperties(); float mass = MathHelper.Clamp((float)((MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(physicalItemDefinition.Mass) : physicalItemDefinition.Mass) * ((float)this.Item.Amount)), (float)3f, (float)100000f); HkShape shape = this.GetPhysicsShape(mass, scale, out massProperties); massProperties.Mass = mass; Matrix identity = Matrix.Identity; if (this.Physics != null) { this.Physics.Close(); } this.Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEBRIS); int collisionFilter = (mass > MyPerGameSettings.MinimumLargeShipCollidableMass) ? 0x17 : 10; this.Physics.LinearDamping = 0.1f; this.Physics.AngularDamping = 2f; if (!shape.IsConvex || (shape.ShapeType == HkShapeType.Sphere)) { this.Physics.CreateFromCollisionObject(shape, Vector3.Zero, MatrixD.Identity, new HkMassProperties?(massProperties), collisionFilter); this.Physics.Enabled = true; } else { HkConvexTransformShape shape2 = new HkConvexTransformShape((HkConvexShape)shape, ref identity, HkReferencePolicy.None); this.Physics.CreateFromCollisionObject((HkShape)shape2, Vector3.Zero, MatrixD.Identity, new HkMassProperties?(massProperties), collisionFilter); this.Physics.Enabled = true; shape2.Base.RemoveReference(); } this.Physics.Friction = 2f; this.Physics.MaterialType = this.EvaluatePhysicsMaterial(physicalItemDefinition.PhysicalMaterial); this.Physics.PlayCollisionCueEnabled = true; this.Physics.RigidBody.ContactSoundCallbackEnabled = true; base.NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME; this.Physics.RigidBody.SetProperty(HkCharacterRigidBody.FLOATING_OBJECT, 0f); this.Physics.RigidBody.CenterOfMassLocal = Vector3.Zero; HkMassChangerUtil.Create(this.Physics.RigidBody, 0x10200, 1f, 0f); }
public override void UpdateBeforeSimulation() { //if (MyFakes.ENABLE_RAGDOLL_DEBUG) Debug.WriteLine("RagdollComponent.UpdateBeforeSimulation"); base.UpdateBeforeSimulation(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Update Ragdoll"); UpdateRagdoll(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); // TODO: This should be changed so the ragdoll gets registered in the generators, now for SE, apply gravity explictly // Apply Gravity on Ragdoll // OM: This should be called only in SE, in ME this is handled by world! if (Character.Physics != null && Character.Physics.Ragdoll != null && Character.Physics.Ragdoll.InWorld && (!Character.Physics.Ragdoll.IsKeyframed || RagdollMapper.IsPartiallySimulated) && (IsRagdollMoving || m_gravityTimer > 0)) { Vector3 gravity = MyGravityProviderSystem.CalculateTotalGravityInPoint(Character.PositionComp.WorldAABB.Center) + Character.GetPhysicsBody().HavokWorld.Gravity *MyPerGameSettings.CharacterGravityMultiplier; Character.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_FORCE, gravity * (MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(Character.Definition.Mass) : Character.Definition.Mass), null, null); m_gravityTimer = IsRagdollMoving ? GRAVITY_DELAY : m_gravityTimer - 1; } if (Character.Physics != null && Character.Physics.Ragdoll != null && IsRagdollMoving) { m_lastPosition = Character.Physics.Ragdoll.WorldMatrix.Translation; } }
public override void UpdateBeforeSimulation() { //if (MyFakes.ENABLE_RAGDOLL_DEBUG) Debug.WriteLine("RagdollComponent.UpdateBeforeSimulation"); base.UpdateBeforeSimulation(); // TODO: This should be changed so the ragdoll gets registered in the generators, now for SE, apply gravity explictly // Apply Gravity on Ragdoll // OM: This should be called only in SE, in ME this is handled by world! if (Character.Physics.Ragdoll != null && Character.Physics.Ragdoll.InWorld && (!Character.Physics.Ragdoll.IsKeyframed || RagdollMapper.IsPartiallySimulated) && (MyPerGameSettings.Game == GameEnum.SE_GAME)) { Vector3 gravity = MyGravityProviderSystem.CalculateTotalGravityInPoint(Character.PositionComp.WorldAABB.Center) + Character.Physics.HavokWorld.Gravity * MyCharacter.CHARACTER_GRAVITY_MULTIPLIER; Character.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_FORCE, gravity * (MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(Character.Definition.Mass) : Character.Definition.Mass), null, null); } VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Update Ragdoll"); UpdateRagdoll(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); }
void Physics_ContactPointCallback(ref Engine.Physics.MyPhysics.MyContactPointEvent e) { // RestoreDynamicMasses(); //if (m_frameCounter > DYNAMIC_UPDATE_DELAY) // m_frameCounter = 0; //else // return; if (m_lastFrameCollision != m_frameCounter) { DynamicWeights.Clear(); } MyGridContactInfo info = new MyGridContactInfo(ref e.ContactPointEvent, m_grid); if (info.CollidingEntity.Physics.IsStatic) { return; } float speed = info.CollidingEntity.Physics.LinearVelocity.Length(); if (speed < 0.1f) { return; } Vector3I blockPos = m_grid.WorldToGridInteger(info.ContactPosition + Vector3.Up * 0.25f); float dot = Vector3.Dot(Vector3.Normalize(info.CollidingEntity.Physics.LinearVelocity), Vector3.Down); float collidingMass = 0; m_constrainedGrid.Clear(); MyCubeGrid collidingGrid = info.CollidingEntity as MyCubeGrid; if (collidingGrid != null) { m_constrainedGrid.Add(collidingGrid); AddConstrainedGrids(collidingGrid); foreach (var grid in m_constrainedGrid) { collidingMass += grid.Physics.Mass; } } else { collidingMass = info.CollidingEntity.Physics.Mass; } collidingMass = info.CollidingEntity is Sandbox.Game.Entities.Character.MyCharacter ? MassToSI(collidingMass) : MassToSI(MyDestructionHelper.MassFromHavok(collidingMass)); float siMass = collidingMass * MyPetaInputComponent.SI_DYNAMICS_MULTIPLIER; //if (dot < 0) //impact from downside // return; float impact = siMass * speed * dot + siMass; if (impact < 0) { return; } if (m_grid.GridSizeEnum == MyCubeSize.Large) { } DynamicWeights[blockPos] = impact; m_needsRecalc = true; m_lastFrameCollision = m_frameCounter; if (!m_collidingEntities.ContainsKey(info.CollidingEntity)) { m_collidingEntities.Add(info.CollidingEntity, new CollidingEntityInfo() { Position = blockPos, FrameTime = m_frameCounter }); info.CollidingEntity.PositionComp.OnPositionChanged += PositionComp_OnPositionChanged; } else { m_collidingEntities[info.CollidingEntity].FrameTime = m_frameCounter; } }
/// <summary> /// Loads Ragdoll data /// </summary> /// <param name="ragDollFile"></param> public bool InitRagdoll() { if (MyFakes.ENABLE_RAGDOLL_DEBUG) { Debug.WriteLine("RagdollComponent.InitRagdoll"); MyLog.Default.WriteLine("RagdollComponent.InitRagdoll"); } if (Character.Physics.Ragdoll != null) { Character.Physics.CloseRagdollMode(); Character.Physics.Ragdoll.ResetToRigPose(); Character.Physics.Ragdoll.SetToKeyframed(); return(true); } Character.Physics.Ragdoll = new HkRagdoll(); bool dataLoaded = false; if (Character.Model.HavokData != null && Character.Model.HavokData.Length > 0) { try { dataLoaded = Character.Physics.Ragdoll.LoadRagdollFromBuffer(Character.Model.HavokData); } catch (Exception e) { Debug.Fail("Error loading ragdoll from buffer: " + e.Message); Character.Physics.CloseRagdoll(); Character.Physics.Ragdoll = null; } } else if (Character.Definition.RagdollDataFile != null) { String ragDollFile = System.IO.Path.Combine(MyFileSystem.ContentPath, Character.Definition.RagdollDataFile); if (System.IO.File.Exists(ragDollFile)) { dataLoaded = Character.Physics.Ragdoll.LoadRagdollFromFile(ragDollFile); } else { System.Diagnostics.Debug.Fail("Cannot find ragdoll file: " + ragDollFile); } } if (Character.Definition.RagdollRootBody != String.Empty) { if (!Character.Physics.Ragdoll.SetRootBody(Character.Definition.RagdollRootBody)) { Debug.Fail("Can not set root body with name: " + Character.Definition.RagdollRootBody + " on model " + Character.ModelName + ". Please check your definitions."); } } if (!dataLoaded) { Character.Physics.Ragdoll.Dispose(); Character.Physics.Ragdoll = null; } foreach (var body in Character.Physics.Ragdoll.RigidBodies) { body.UserObject = Character; } if (Character.Physics.Ragdoll != null && MyPerGameSettings.Destruction) //scaling weights and IT { Character.Physics.Ragdoll.SetToDynamic(); var mp = new HkMassProperties(); foreach (var body in Character.Physics.Ragdoll.RigidBodies) { mp.Mass = MyDestructionHelper.MassToHavok(body.Mass); mp.InertiaTensor = Matrix.CreateScale(1.0f / 25.0f) * body.InertiaTensor; body.SetMassProperties(ref mp); } Character.Physics.Ragdoll.SetToKeyframed(); } if (Character.Physics.Ragdoll != null && MyFakes.ENABLE_RAGDOLL_DEFAULT_PROPERTIES) { Character.Physics.SetRagdollDefaults(); } if (MyFakes.ENABLE_RAGDOLL_DEBUG) { Debug.WriteLine("RagdollComponent.InitRagdoll - FINISHED"); MyLog.Default.WriteLine("RagdollComponent.InitRagdoll - FINISHED"); } return(dataLoaded); }
public void InitFromDefinition(MyObjectBuilder_EntityBase entityBuilder, MyDefinitionId definitionId) { Debug.Assert(entityBuilder != null, "Invalid arguments!"); MyPhysicalItemDefinition entityDefinition; if (!MyDefinitionManager.Static.TryGetDefinition(definitionId, out entityDefinition)) { Debug.Fail("Definition: " + DefinitionId.ToString() + " was not found!"); return; } DefinitionId = definitionId; Flags |= EntityFlags.Visible | EntityFlags.NeedsDraw | EntityFlags.Sync | EntityFlags.InvalidateOnMove; StringBuilder name = new StringBuilder(entityDefinition.DisplayNameText); Init(name, entityDefinition.Model, null, null, null); CreateSync(); if (entityBuilder.PositionAndOrientation.HasValue) { MatrixD worldMatrix = MatrixD.CreateWorld( (Vector3D)entityBuilder.PositionAndOrientation.Value.Position, (Vector3)entityBuilder.PositionAndOrientation.Value.Forward, (Vector3)entityBuilder.PositionAndOrientation.Value.Up); PositionComp.SetWorldMatrix(worldMatrix); } Name = name.Append("_(").Append(entityBuilder.EntityId).Append(")").ToString(); Render.UpdateRenderObject(true); Physics = new Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_DEFAULT); if (ModelCollision != null && ModelCollision.HavokCollisionShapes.Length >= 1) { HkMassProperties massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(entityDefinition.Size / 2, (MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(entityDefinition.Mass) : entityDefinition.Mass));; Physics.CreateFromCollisionObject(ModelCollision.HavokCollisionShapes[0], Vector3.Zero, WorldMatrix, massProperties); Physics.RigidBody.AngularDamping = 2; Physics.RigidBody.LinearDamping = 1; } Physics.Enabled = true; EntityId = entityBuilder.EntityId; }