private void RefreshPhysicsBody() { if (CubeGrid.CreatePhysics) { if (Physics != null) { Physics.Close(); } var detectorShape = new HkSphereShape(CubeGrid.GridSize * 0.5f); var massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(detectorShape.Radius, VirtualMass != 0 ? VirtualMass : 0.01f); Physics = new Sandbox.Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_KEYFRAMED_REPORTING); Physics.IsPhantom = false; Physics.CreateFromCollisionObject(detectorShape, Vector3.Zero, WorldMatrix, massProperties, MyPhysics.CollisionLayers.VirtualMassLayer); UpdateIsWorking(); Physics.Enabled = IsWorking && CubeGrid.Physics != null && CubeGrid.Physics.Enabled; Physics.RigidBody.Activate(); detectorShape.Base.RemoveReference(); if (CubeGrid != null && CubeGrid.Physics != null && !CubeGrid.IsStatic) { CubeGrid.Physics.UpdateMass(); } } }
/// <summary> /// Prepares data for renderer and physics. Must be called after all items has been added. /// </summary> public void PrepareItemsPhysics(HkStaticCompoundShape sectorRootShape, ref BoundingBoxD aabbWorld) { PositionComp.WorldAABB = aabbWorld; if (sectorRootShape.InstanceCount > 0) { Debug.Assert(m_physicsShapeInstanceIdToLocalId.Count > 0); Physics = new Sandbox.Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_STATIC) { MaterialType = m_definition.Material, AngularDamping = MyPerGameSettings.DefaultAngularDamping, LinearDamping = MyPerGameSettings.DefaultLinearDamping, IsStaticForCluster = true, }; sectorRootShape.Bake(); HkMassProperties massProperties = new HkMassProperties(); MatrixD matrix = MatrixD.CreateTranslation(CellsOffset); Physics.CreateFromCollisionObject((HkShape)sectorRootShape, Vector3.Zero, matrix, massProperties); Physics.ContactPointCallback += Physics_ContactPointCallback; Physics.RigidBody.ContactPointCallbackEnabled = true; sectorRootShape.Base.RemoveReference(); Physics.Enabled = true; } }
public MyCameraSpring(MyPhysicsBody attachedTo) { m_limitedVelocity = Vector3.Zero; m_physics = attachedTo; m_linearVelocity = Vector3.Zero; m_localTranslation = Vector3.Zero; }
public override void Init(MyObjectBuilder_CubeBlock objectBuilder, MyCubeGrid cubeGrid) { ResourceSink = new MyResourceSinkComponent(); ResourceSink.Init( BlockDefinition.ResourceSinkGroup, BlockDefinition.RequiredPowerInput, this.CalculateRequiredPowerInput); base.Init(objectBuilder, cubeGrid); ResourceSink.IsPoweredChanged += Receiver_IsPoweredChanged; ResourceSink.Update(); if (Physics != null) { Physics.Close(); } var detectorShape = new HkBoxShape(new Vector3(cubeGrid.GridSize / 3.0f)); var massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(detectorShape.HalfExtents, BlockDefinition.VirtualMass); Physics = new Sandbox.Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_DEFAULT); Physics.IsPhantom = false; Physics.CreateFromCollisionObject(detectorShape, Vector3.Zero, WorldMatrix, massProperties, MyPhysics.CollisionLayers.VirtualMassLayer); Physics.Enabled = IsWorking && cubeGrid.Physics != null && cubeGrid.Physics.Enabled; Physics.RigidBody.Activate(); detectorShape.Base.RemoveReference(); UpdateText(); NeedsUpdate |= MyEntityUpdateEnum.EACH_FRAME; SlimBlock.ComponentStack.IsFunctionalChanged += ComponentStack_IsFunctionalChanged; }
private void LoadDummies() { var finalModel = VRage.Game.Models.MyModels.GetModelOnlyDummies(BlockDefinition.Model); foreach (var dummy in finalModel.Dummies) { if (dummy.Key.ToLower().Contains("merge")) { var matrix = dummy.Value.Matrix; Vector3 halfExtents = matrix.Scale / 2.0f; Vector3 projectedPosition = Vector3.DominantAxisProjection(matrix.Translation / halfExtents); projectedPosition.Normalize(); m_forward = Base6Directions.GetDirection(projectedPosition); m_right = Base6Directions.GetPerpendicular(m_forward); var world = MatrixD.Normalize(matrix) * this.WorldMatrix; var detectorShape = CreateFieldShape(halfExtents); Physics = new Sandbox.Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_STATIC); Physics.IsPhantom = true; Physics.CreateFromCollisionObject(detectorShape, matrix.Translation, world, null, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer); Physics.Enabled = IsWorking; Physics.RigidBody.ContactPointCallbackEnabled = true; detectorShape.Base.RemoveReference(); break; } } }
public override void Init(MyObjectBuilder_CubeBlock objectBuilder, MyCubeGrid cubeGrid) { InitializeSinkComponent(); base.Init(objectBuilder, cubeGrid); if (CubeGrid.CreatePhysics) { // Put on my fake, because it does performance issues if (MyFakes.ENABLE_GRAVITY_PHANTOM) { var shape = CreateFieldShape(); Physics = new Sandbox.Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_KINEMATIC); Physics.IsPhantom = true; Physics.CreateFromCollisionObject(shape, PositionComp.LocalVolume.Center, WorldMatrix, null, Sandbox.Engine.Physics.MyPhysics.CollisionLayers.GravityPhantomLayer); shape.Base.RemoveReference(); Physics.Enabled = IsWorking; } NeedsUpdate |= MyEntityUpdateEnum.EACH_FRAME; SlimBlock.ComponentStack.IsFunctionalChanged += ComponentStack_IsFunctionalChanged; ResourceSink.Update(); } m_soundEmitter = new MyEntity3DSoundEmitter(this, true); m_baseIdleSound.Init("BlockGravityGen"); }
public static void SetInBodySpace(this HkFixedConstraintData data, Matrix pivotA, Matrix pivotB, MyPhysicsBody bodyA, MyPhysicsBody bodyB) { if (bodyA.IsWelded) pivotA = pivotA * bodyA.WeldInfo.Transform; if (bodyB.IsWelded) pivotB = pivotB * bodyB.WeldInfo.Transform; data.SetInBodySpaceInternal(ref pivotA, ref pivotB); }
public static void SetInBodySpace(this HkHingeConstraintData data, Vector3 posA, Vector3 posB, Vector3 axisA, Vector3 axisB, MyPhysicsBody bodyA, MyPhysicsBody bodyB) { if (bodyA.IsWelded) { posA = Vector3.Transform(posA, bodyA.WeldInfo.Transform); axisA = Vector3.TransformNormal(axisA, bodyA.WeldInfo.Transform); } if (bodyB.IsWelded) { posB = Vector3.Transform(posB, bodyB.WeldInfo.Transform); axisB = Vector3.TransformNormal(axisB, bodyB.WeldInfo.Transform); } data.SetInBodySpaceInternal(ref posA, ref posB, ref axisA, ref axisB); }
public static void SetInBodySpace(this HkWheelConstraintData data, Vector3 posA, Vector3 posB, Vector3 axisA, Vector3 axisB, Vector3 suspension, Vector3 steering, MyPhysicsBody bodyA, MyPhysicsBody bodyB) { if (bodyA.IsWelded) { posA = Vector3.Transform(posA, bodyA.WeldInfo.Transform); axisA = Vector3.TransformNormal(axisA, bodyA.WeldInfo.Transform); } if (bodyB.IsWelded) { posB = Vector3.Transform(posB, bodyB.WeldInfo.Transform); axisB = Vector3.TransformNormal(axisB, bodyB.WeldInfo.Transform); suspension = Vector3.TransformNormal(suspension, bodyB.WeldInfo.Transform); steering = Vector3.TransformNormal(steering, bodyB.WeldInfo.Transform); } data.SetInBodySpaceInternal(ref posA, ref posB, ref axisA, ref axisB, ref suspension, ref steering); }
/// <summary> /// Prepares data for renderer and physics. Must be called after all items has been added. /// </summary> public void PrepareItems(HkStaticCompoundShape sectorRootShape, ref BoundingBoxD aabbWorld) { PositionComp.LocalAABB = (BoundingBox)aabbWorld; if (sectorRootShape.InstanceCount > 0) { Debug.Assert(m_physicsShapeInstanceIdToLocalId.Count > 0); Physics = new Sandbox.Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_STATIC) { MaterialType = m_definition.Material, AngularDamping = MyPerGameSettings.DefaultAngularDamping, LinearDamping = MyPerGameSettings.DefaultLinearDamping, IsStaticForCluster = true, }; sectorRootShape.Bake(); HkMassProperties massProperties = new HkMassProperties(); Physics.CreateFromCollisionObject((HkShape)sectorRootShape, Vector3.Zero, WorldMatrix, massProperties); if (Sandbox.Game.MyPerGameSettings.Destruction) { Physics.ContactPointCallback += Physics_ContactPointCallback; Physics.RigidBody.ContactPointCallbackEnabled = true; } sectorRootShape.Base.RemoveReference(); Physics.Enabled = true; } foreach (var pair in m_sectors) { pair.Value.UpdateRenderInstanceData(); } foreach (var pair in m_sectors) { pair.Value.UpdateRenderEntitiesData(WorldMatrix, m_subtypeToModel); } }
public static void SetInBodySpace(this HkCogWheelConstraintData data, Vector3 pivotA, Vector3 rotationA, float radius1, Vector3 pivotB, Vector3 rotationB, float radius2, MyPhysicsBody bodyA, MyPhysicsBody bodyB) { if (bodyA.IsWelded) { pivotA = Vector3.Transform(pivotA, bodyA.WeldInfo.Transform); rotationA = Vector3.TransformNormal(rotationA, bodyA.WeldInfo.Transform); } if (bodyB.IsWelded) { pivotB = Vector3.Transform(pivotB, bodyB.WeldInfo.Transform); rotationB = Vector3.TransformNormal(rotationB, bodyB.WeldInfo.Transform); } data.SetInBodySpaceInternal(ref pivotA, ref rotationA, radius1, ref pivotB, ref rotationB, radius2); }
public MyCharacterProxy(bool isDynamic, bool isCapsule, float characterWidth, float characterHeight, float crouchHeight, float ladderHeight, float headSize, float headHeight, Vector3 position, Vector3 up, Vector3 forward, float mass, MyPhysicsBody body, bool isOnlyVertical, float maxSlope, float maxImpulse, float maxSpeedRelativeToShip, float?maxForce = new float?(), HkRagdoll ragDoll = null) { this.m_isDynamic = isDynamic; this.m_physicsBody = body; this.m_mass = mass; this.m_maxImpulse = maxImpulse; this.m_maxSpeedRelativeToShip = maxSpeedRelativeToShip; if (!isCapsule) { HkBoxShape shape = new HkBoxShape(new Vector3(characterWidth / 2f, characterHeight / 2f, characterWidth / 2f)); if (!this.m_isDynamic) { this.CharacterPhantom = new HkSimpleShapePhantom((HkShape)shape, 0x12); } this.m_characterShape = (HkShape)shape; } else { this.m_characterShape = CreateCharacterShape(characterHeight, characterWidth, characterHeight + headHeight, headSize, 0f, 0f, false); this.m_characterCollisionShape = CreateCharacterShape(characterHeight * 0.9f, characterWidth * 0.9f, (characterHeight * 0.9f) + headHeight, headSize * 0.9f, 0f, 0f, false); this.m_crouchShape = CreateCharacterShape(characterHeight, characterWidth, characterHeight + headHeight, headSize, 0f, 1f, false); if (!this.m_isDynamic) { this.CharacterPhantom = new HkSimpleShapePhantom(this.m_characterShape, 0x12); } } if (!this.m_isDynamic) { HkCharacterProxyCinfo characterProxyCinfo = new HkCharacterProxyCinfo { StaticFriction = 1f, DynamicFriction = 1f, ExtraDownStaticFriction = 1000f, MaxCharacterSpeedForSolver = 10000f, RefreshManifoldInCheckSupport = true, Up = up, Forward = forward, UserPlanes = 4, MaxSlope = MathHelper.ToRadians(maxSlope), Position = position, CharacterMass = mass, CharacterStrength = 100f, ShapePhantom = this.CharacterPhantom }; this.CharacterProxy = new HkCharacterProxy(characterProxyCinfo); characterProxyCinfo.Dispose(); } else { HkCharacterRigidBodyCinfo characterRigidBodyCinfo = new HkCharacterRigidBodyCinfo { Shape = this.m_characterShape, CrouchShape = this.m_crouchShape, Friction = 0f, MaxSlope = MathHelper.ToRadians(maxSlope), Up = up, Mass = mass, CollisionFilterInfo = 0x12, MaxLinearVelocity = 1000000f, MaxForce = (maxForce != null) ? maxForce.Value : 100000f, AllowedPenetrationDepth = MyFakes.ENABLE_LIMITED_CHARACTER_BODY ? 0.3f : 0.1f, JumpHeight = 0.8f }; float maxCharacterSpeed = MyGridPhysics.ShipMaxLinearVelocity() + this.m_maxSpeedRelativeToShip; this.CharacterRigidBody = new HkCharacterRigidBody(characterRigidBodyCinfo, maxCharacterSpeed, body); this.m_maxCharacterSpeedSq = maxCharacterSpeed * maxCharacterSpeed; this.CharacterRigidBody.GetRigidBody().ContactPointCallbackEnabled = true; this.CharacterRigidBody.GetRigidBody().ContactPointCallback -= new ContactPointEventHandler(this.RigidBody_ContactPointCallback); this.CharacterRigidBody.GetRigidBody().ContactPointCallback += new ContactPointEventHandler(this.RigidBody_ContactPointCallback); this.CharacterRigidBody.GetRigidBody().ContactPointCallbackDelay = 0; Matrix inertiaTensor = this.CharacterRigidBody.GetHitRigidBody().InertiaTensor; inertiaTensor.M11 = 1000f; inertiaTensor.M22 = 1000f; inertiaTensor.M33 = 1000f; this.CharacterRigidBody.GetHitRigidBody().InertiaTensor = inertiaTensor; characterRigidBodyCinfo.Dispose(); } }
public void Unweld(MyPhysicsBody other, bool insertToWorld = true, bool recreateShape = true) { Debug.Assert(other.IsWelded, "Invalid state"); if(IsWelded) { WeldInfo.Parent.Unweld(other, insertToWorld, recreateShape); return; } other.Entity.OnPhysicsChanged -= WeldedEntity_OnPhysicsChanged; other.WeldInfo.Parent = null; Debug.Assert(WeldInfo.Children.Contains(other)); WeldInfo.Children.Remove(other); var body = other.RigidBody; other.RigidBody = other.WeldedRigidBody; other.RigidBody.SetWorldMatrix(other.WeldInfo.Transform * body.GetRigidBodyMatrix()); other.RigidBody.LinearVelocity = body.LinearVelocity; if(insertToWorld) other.Activate(); if(WeldInfo.Children.Count == 0) { Entity.OnPhysicsChanged -= WeldedEntity_OnPhysicsChanged; Entity.OnClose -= Entity_OnClose; } if(RigidBody != null && recreateShape) RecreateWeldedShape(GetShape()); }
void Components_ComponentRemoved(Type t, MyEntityComponentBase c) { if (t == typeof(MyPhysicsComponentBase)) m_physics = null; else if (t == typeof(MySyncComponentBase)) m_syncObject = null; else if (t == typeof(MyGameLogicComponent)) m_gameLogic = null; else if (t == typeof(MyPositionComponentBase)) m_position = null; else if (t == typeof(MyHierarchyComponentBase)) m_hierarchy = null; else if (t == typeof(MyRenderComponentBase)) { m_render = null; } }
public override void Simulate() { if (MyFakes.PAUSE_PHYSICS && !MyFakes.STEP_PHYSICS) { return; } MyFakes.STEP_PHYSICS = false; if (!MySandboxGame.IsGameReady) { return; } AddTimestamp(); InsideSimulation = true; ProcessDestructions(); ProfilerShort.Begin("HavokWorld.Step"); foreach (HkWorld world in Clusters.GetList()) { //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(100, 100), "Constr:" + world.GetConstraintCount(), Color.Red, 0.9f); world.UnmarkForWrite(); world.StepSimulation(MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * MyFakes.SIMULATION_SPEED); world.MarkForWrite(); } ProfilerShort.End(); InsideSimulation = false; ProfilerShort.Begin("Update rigid bodies"); long activeRigidBodies = 0; foreach (HkWorld world in Clusters.GetList()) { activeRigidBodies += world.ActiveRigidBodies.Count; } VRageRender.MyPerformanceCounter.PerCameraDrawWrite["Active rigid bodies"] = activeRigidBodies; ProfilerShort.CustomValue("Active bodies", activeRigidBodies, null); foreach (HkWorld world in Clusters.GetList()) { IterateBodies(world); } //ParallelTasks.Parallel.For(0, m_iterationBodies.Count, (rb) => //{ // MyPhysicsBody body = (MyPhysicsBody)m_iterationBodies[rb].UserObject; // if (body == null) // return; // body.OnMotion(m_iterationBodies[rb], MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); //}, Math.Max(1, m_iterationBodies.Count / 16)); foreach (var rb in m_iterationBodies) { MyPhysicsBody body = (MyPhysicsBody)rb.UserObject; if (body == null) { return; } body.OnMotion(rb, MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); } foreach (HkCharacterRigidBody rb in m_characterIterationBodies) { var body = (MyPhysicsBody)rb.GetHitRigidBody().UserObject; if (body.Entity.WorldMatrix.Translation != body.GetWorldMatrix().Translation) { body.UpdateCluster(); } } m_iterationBodies.Clear(); m_characterIterationBodies.Clear(); ProfilerShort.End(); ProfilerShort.Begin("HavokWorld.StepVDB"); foreach (HkWorld world in Clusters.GetList()) { world.StepVDB(MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); } ProfilerShort.End(); }
public static void SetInBodySpace(this HkRopeConstraintData data, Vector3 pivotA, Vector3 pivotB, MyPhysicsBody bodyA, MyPhysicsBody bodyB) { if (bodyA.IsWelded) { pivotA = Vector3.Transform(pivotA, bodyA.WeldInfo.Transform); } if (bodyB.IsWelded) { pivotB = Vector3.Transform(pivotB, bodyB.WeldInfo.Transform); } data.SetInBodySpaceInternal(ref pivotA, ref pivotB); }
protected override void OnWelded(MyPhysicsBody other) { base.OnWelded(other); Shape.RefreshMass(); if (m_grid.BlocksDestructionEnabled) { if (HavokWorld != null) HavokWorld.BreakOffPartsUtil.MarkEntityBreakable(RigidBody, Shape.BreakImpulse); if (Sync.IsServer) { if (RigidBody.BreakLogicHandler == null) RigidBody.BreakLogicHandler = BreakLogicHandler; if (RigidBody.BreakPartsHandler == null) RigidBody.BreakPartsHandler = BreakPartsHandler; } } m_grid.HavokSystemIDChanged(other.HavokCollisionSystemID); }
private void RefreshPhysicsBody() { if (CubeGrid.CreatePhysics) { if (Physics != null) { Physics.Close(); } var detectorShape = new HkSphereShape(CubeGrid.GridSize * 0.5f); var massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(detectorShape.Radius, VirtualMass != 0 ? VirtualMass : 0.01f); Physics = new Sandbox.Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_KEYFRAMED_REPORTING); Physics.IsPhantom = false; Physics.CreateFromCollisionObject(detectorShape, Vector3.Zero, WorldMatrix, massProperties, MyPhysics.CollisionLayers.VirtualMassLayer); UpdateIsWorking(); Physics.Enabled = IsWorking && CubeGrid.Physics != null && CubeGrid.Physics.Enabled; Physics.RigidBody.Activate(); detectorShape.Base.RemoveReference(); if (CubeGrid != null && CubeGrid.Physics != null && !CubeGrid.IsStatic) CubeGrid.Physics.UpdateMass(); } }
public static bool IsInWorldWelded(this MyPhysicsBody body) { return(body.IsInWorld || (body.WeldInfo.Parent != null && body.WeldInfo.Parent.IsInWorld)); }
public static void DebugDrawAddForce(MyPhysicsBody physics, MyPhysicsForceType type, Vector3?force, Vector3D?position, Vector3?torque) { Matrix transform; const float scale = 0.1f; switch (type) { case MyPhysicsForceType.ADD_BODY_FORCE_AND_BODY_TORQUE: { if (physics.RigidBody != null) { transform = physics.RigidBody.GetRigidBodyMatrix(); Vector3D p = physics.CenterOfMassWorld + physics.LinearVelocity * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS; // ClusterToWorld(transform.Translation);//ClusterToWorld(transform.Translation); if (force.HasValue) { Vector3 f = Vector3.TransformNormal(force.Value, transform) * scale; MyRenderProxy.DebugDrawArrow3D(p, p + f, Color.Blue, Color.Red, false); } if (torque.HasValue) { Vector3 f = Vector3.TransformNormal(torque.Value, transform) * scale; MyRenderProxy.DebugDrawArrow3D(p, p + f, Color.Blue, Color.Purple, false); } } } break; case MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE: { Vector3D p = position.Value + physics.LinearVelocity * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS; if (force.HasValue) { MyRenderProxy.DebugDrawArrow3D(p, p + force.Value * scale, Color.Blue, Color.Red, false); } if (torque.HasValue) { MyRenderProxy.DebugDrawArrow3D(p, p + torque.Value * scale, Color.Blue, Color.Purple, false); } } break; case MyPhysicsForceType.APPLY_WORLD_FORCE: { if (position.HasValue) { Vector3D p = position.Value + physics.LinearVelocity * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS; if (force.HasValue) { MyRenderProxy.DebugDrawArrow3D(p, p + force.Value * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * scale, Color.Blue, Color.Red, false); } } } break; default: { Debug.Fail("Unhandled enum!"); } break; } }
public override void Init(MyObjectBuilder_EntityBase objectBuilder) { base.Init(objectBuilder); var ob = objectBuilder as MyObjectBuilder_FracturedPiece; if (ob.Shapes.Count == 0) { return; //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, null, (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(); }
public void ClosePhysics(MyEnvironmentItemsSpawnData data) { if (Physics != null) { Physics.Close(); Physics = null; } }
public void Weld(MyPhysicsBody other, bool recreateShape = true) { if (other.WeldInfo.Parent == this) //already welded to this { return; } if (other.IsWelded && !IsWelded) { other.Weld(this); return; } if (IsWelded) { WeldInfo.Parent.Weld(other); return; } if (other.WeldInfo.Children.Count > 0) { Debug.Fail("Welding other welded gorup"); other.UnweldAll(false); //they should end in same group and get welded } ProfilerShort.Begin("Weld"); HkShape thisShape; bool firstWelded = WeldInfo.Children.Count == 0; if (firstWelded) { //RemoveConstraints(RigidBody); WeldedRigidBody = RigidBody; thisShape = RigidBody.GetShape(); if (HavokWorld != null) { HavokWorld.RemoveRigidBody(WeldedRigidBody); } RigidBody = HkRigidBody.Clone(WeldedRigidBody); if (HavokWorld != null) { HavokWorld.AddRigidBody(RigidBody); } HkShape.SetUserData(thisShape, RigidBody); Entity.OnPhysicsChanged += WeldedEntity_OnPhysicsChanged; WeldInfo.UpdateMassProps(RigidBody); //Entity.OnClose += Entity_OnClose; } else { thisShape = GetShape(); } other.Deactivate(); //other.RemoveConstraints(other.RigidBody);//jn:TODO check if this is OK var transform = other.RigidBody.GetRigidBodyMatrix() * Matrix.Invert(RigidBody.GetRigidBodyMatrix()); other.WeldInfo.Transform = transform; other.WeldInfo.UpdateMassProps(other.RigidBody); Debug.Assert(other.WeldedRigidBody == null); other.WeldedRigidBody = other.RigidBody; other.RigidBody = RigidBody; other.WeldInfo.Parent = this; other.ClusterObjectID = ClusterObjectID; WeldInfo.Children.Add(other); //if(recreateShape) // RecreateWeldedShape(thisShape); ProfilerShort.BeginNextBlock("OnPhysicsChanged"); //(other.Entity as MyEntity).RaisePhysicsChanged(); //other.Entity.OnPhysicsChanged += WeldedEntity_OnPhysicsChanged; //Debug.Assert(other.m_constraints.Count == 0, "Constraints left in welded body"); ProfilerShort.BeginNextBlock("RemoveConstraints"); ProfilerShort.End(); OnWelded(other); other.OnWelded(this); }
private void RemovePenetratingShapes() { if (m_testPenetration != null) { var wm = RigidBody.GetRigidBodyMatrix(); var t1 = wm.Translation - RigidBody.LinearVelocity * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * 0.5f; var q1 = Quaternion.CreateFromRotationMatrix(wm.GetOrientation()); var otherWm = m_testPenetration.RigidBody.GetRigidBodyMatrix(); var t2 = otherWm.Translation; var q2 = Quaternion.CreateFromRotationMatrix(otherWm.GetOrientation()); ProfilerShort.Begin("GetPenetrations"); HavokWorld.GetPenetrationsShapeShape(m_testPenetration.RigidBody.GetShape(), ref t2, ref q2, Shape, ref t1, ref q1, m_shapePenetrations); ProfilerShort.BeginNextBlock("ApplyDamage"); int removed = 0; foreach (var pair in m_shapePenetrations) { if (!m_processedCollision.Add(pair)) continue; Vector3I? min = null; var shape = RigidBody.GetShape(); for (int i = 0; i < pair.ShapeKeyCount; i++) { if (shape.ShapeType == HkShapeType.BvTree) { Vector3I min2; ((HkGridShape)shape).GetShapeMin(pair.GetShapeKey(i), out min2); min = min2; break; } if (shape.IsContainer()) { var shape2 = shape.GetContainer().GetShape(pair.GetShapeKey(i)); if (shape2.IsValid) shape = shape2; else break; } } if (!min.HasValue) continue; var block = m_grid.GetCubeBlock(min.Value); if (block != null) { m_grid.ApplyDestructionDeformation(block); removed++; } } ProfilerShort.End(m_shapePenetrations.Count); ProfilerShort.CustomValue("PenetrationsCount", m_shapePenetrations.Count, 0); m_shapePenetrations.Clear(); m_processedCollision.Clear(); m_testPenetration = null; } }
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); 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(); HkShape shape = GetPhysicsShape(physicalItem.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; }
protected override void OnUnwelded(MyPhysicsBody other) { base.OnUnwelded(other); Shape.RefreshMass(); m_grid.HavokSystemIDChanged(HavokCollisionSystemID); if(m_grid.IsStatic == false) { m_grid.RecalculateGravity(); } }
public static void SetInBodySpace(this HkFixedConstraintData data, Matrix pivotA, Matrix pivotB, MyPhysicsBody bodyA, MyPhysicsBody bodyB) { if (bodyA.IsWelded) { pivotA = pivotA * bodyA.WeldInfo.Transform; } if (bodyB.IsWelded) { pivotB = pivotB * bodyB.WeldInfo.Transform; } data.SetInBodySpaceInternal(ref pivotA, ref pivotB); }
private void CheckChangesOnCharacter() { //if (MyFakes.ENABLE_RAGDOLL_DEBUG) Debug.WriteLine("RagdollComponent.CheckChangesOnCharacter"); if (MyPerGameSettings.EnableRagdollInJetpack) { if (Character.CurrentWeapon != m_previousWeapon) { DeactivateJetpackRagdoll(); ActivateJetpackRagdoll(); } m_previousWeapon = Character.CurrentWeapon; var movementState = Character.GetCurrentMovementState(); var jetpack = Character.JetpackComp; if ((jetpack != null && jetpack.TurnedOn) && movementState == Common.ObjectBuilders.MyCharacterMovementEnum.Flying && Character.Physics.Enabled) { if (!IsRagdollActivated || !RagdollMapper.IsActive) { DeactivateJetpackRagdoll(); ActivateJetpackRagdoll(); } } else if (RagdollMapper != null && RagdollMapper.IsPartiallySimulated) { DeactivateJetpackRagdoll(); } } if (Character.Physics != m_previousPhysics) { UpdateCharacterPhysics(); } m_previousPhysics = Character.Physics; if (Character.IsDead && !IsRagdollActivated && Character.Physics.Enabled) { InitDeadBodyPhysics(); } }
/// <summary> /// Try add object to some subspace. /// Create new subspace if allowed (!SingleCluster.HasValue) and needed (object is outside of existing subspaces). /// If not allowed, mark object as left the world. /// </summary> /// <param name="bbox"></param> /// <param name="velocity"></param> /// <param name="activationHandler"></param> /// <param name="customId"></param> /// <returns></returns> public static ulong AddObject(BoundingBoxD bbox, Vector3 velocity, MyPhysicsBody activationHandler, ulong? customId) { ulong tmp = Clusters.AddObject(bbox, velocity, activationHandler, customId); if (tmp == MyHavokCluster.CLUSTERED_OBJECT_ID_UNITIALIZED) { HavokWorld_EntityLeftWorld(activationHandler.RigidBody); return MyHavokCluster.CLUSTERED_OBJECT_ID_UNITIALIZED; } return tmp; }
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 } ); }
private void LoadDummies() { var finalModel = Engine.Models.MyModels.GetModelOnlyDummies(BlockDefinition.Model); foreach (var dummy in finalModel.Dummies) { bool isConnector = dummy.Key.ToLower().Contains("connector"); bool isEjector = isConnector || dummy.Key.ToLower().Contains("ejector"); if (!isConnector && !isEjector) continue; MatrixD dummyLocal = MatrixD.Normalize(dummy.Value.Matrix); m_connectionPosition = dummyLocal.Translation; dummyLocal *= this.PositionComp.LocalMatrix; Vector3 halfExtents = dummy.Value.Matrix.Scale / 2.0f; halfExtents = new Vector3(halfExtents.Z, halfExtents.X, halfExtents.Y); m_detectorRadius = halfExtents.AbsMax(); Vector3 center = dummy.Value.Matrix.Translation; if (isConnector) m_connectorDummy = CreatePhysicsBody(Mode.Connector, ref dummyLocal, ref center, ref halfExtents); if (isEjector) Physics = CreatePhysicsBody(Mode.Ejector, ref dummyLocal, ref center, ref halfExtents); if (isConnector) m_connectorMode = Mode.Connector; else m_connectorMode = Mode.Ejector; break; } }
private void ProcessBatch() { foreach (var removedItem in m_batchedRemoveItems) RemoveItem(removedItem.LocalId, false, false); foreach (var modifyModel in m_batchedModifyItems) ModifyItemModel(modifyModel.LocalId, modifyModel.SubtypeId, false, false); if (Physics != null) { if(Sync.IsServer) Physics.ContactPointCallback -= Physics_ContactPointCallback; Physics.Close(); Physics = null; } BoundingBoxD aabbWorld = BoundingBoxD.CreateInvalid(); Dictionary<MyStringHash, HkShape> subtypeIdToShape = new Dictionary<MyStringHash, HkShape>(MyStringHash.Comparer); HkStaticCompoundShape sectorRootShape = new HkStaticCompoundShape(HkReferencePolicy.None); m_physicsShapeInstanceIdToLocalId.Clear(); m_localIdToPhysicsShapeInstanceId.Clear(); foreach (var item in m_itemsData) { if (!item.Value.Enabled) continue; int modelId = m_subtypeToModels[item.Value.SubtypeId]; MyModel model = VRage.Game.Models.MyModels.GetModelOnlyData(MyModel.GetById(modelId)); var matrix = item.Value.Transform.TransformMatrix; aabbWorld.Include(model.BoundingBox.Transform(matrix)); } foreach (var item in m_batchedAddItems) { var matrix = MatrixD.CreateWorld(item.Position, Vector3D.Forward, Vector3D.Up); var definition = m_definition.GetItemDefinition(item.SubtypeId); AddItem(definition, ref matrix, ref aabbWorld); } PrepareItemsPhysics(sectorRootShape, ref aabbWorld,subtypeIdToShape); PrepareItemsGraphics(); foreach (var pair in subtypeIdToShape) { pair.Value.RemoveReference(); } subtypeIdToShape.Clear(); }
public static void SetInBodySpace(this HkPrismaticConstraintData data, Vector3 posA, Vector3 posB, Vector3 axisA, Vector3 axisB, Vector3 axisAPerp, Vector3 axisBPerp, MyPhysicsBody bodyA, MyPhysicsBody bodyB) { if (bodyA.IsWelded) { posA = Vector3.Transform(posA, bodyA.WeldInfo.Transform); axisA = Vector3.TransformNormal(axisA, bodyA.WeldInfo.Transform); axisAPerp = Vector3.TransformNormal(axisAPerp, bodyA.WeldInfo.Transform); } if (bodyB.IsWelded) { posB = Vector3.Transform(posB, bodyB.WeldInfo.Transform); axisB = Vector3.TransformNormal(axisB, bodyB.WeldInfo.Transform); axisBPerp = Vector3.TransformNormal(axisBPerp, bodyA.WeldInfo.Transform); } data.SetInBodySpaceInternal(ref posA, ref posB, ref axisA, ref axisB, ref axisAPerp, ref axisBPerp); }
/// <summary> /// Prepares data for renderer and physics. Must be called after all items has been added. /// </summary> private void PrepareItemsPhysics(HkStaticCompoundShape sectorRootShape, ref BoundingBoxD aabbWorld, Dictionary<MyStringHash, HkShape> subtypeIdToShape) { foreach (var item in m_itemsData) { if (!item.Value.Enabled) continue; int physicsShapeInstanceId; MatrixD transform = item.Value.Transform.TransformMatrix; if (AddPhysicsShape(item.Value.SubtypeId, item.Value.Model, ref transform, sectorRootShape, subtypeIdToShape, out physicsShapeInstanceId)) { // Map to data index - note that itemData is added after this to its list! m_physicsShapeInstanceIdToLocalId[physicsShapeInstanceId] = item.Value.Id; m_localIdToPhysicsShapeInstanceId[item.Value.Id] = physicsShapeInstanceId; } } PositionComp.WorldAABB = aabbWorld; if (sectorRootShape.InstanceCount > 0) { Debug.Assert(m_physicsShapeInstanceIdToLocalId.Count > 0); Physics = new Sandbox.Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_STATIC) { MaterialType = m_definition.Material, AngularDamping = MyPerGameSettings.DefaultAngularDamping, LinearDamping = MyPerGameSettings.DefaultLinearDamping, IsStaticForCluster = true, }; sectorRootShape.Bake(); HkMassProperties massProperties = new HkMassProperties(); MatrixD matrix = MatrixD.CreateTranslation(CellsOffset); Physics.CreateFromCollisionObject((HkShape)sectorRootShape, Vector3.Zero, matrix, massProperties); Physics.ContactPointCallback += Physics_ContactPointCallback; Physics.RigidBody.ContactPointCallbackEnabled = true; Physics.Enabled = true; } }
public MyCharacterProxy(bool isDynamic, bool isCapsule, float characterWidth, float characterHeight, float crouchHeight, float ladderHeight, float headSize, float headHeight, Vector3 position, Vector3 up, Vector3 forward, float mass, MyPhysicsBody body, bool isOnlyVertical, float maxSlope, float maxImpulse, HkRagdoll ragDoll = null) { m_isDynamic = isDynamic; m_physicsBody = body; m_mass = mass; m_maxImpulse = maxImpulse; if (isCapsule) { m_characterShape = CreateCharacterShape(characterHeight, characterWidth, characterHeight + headHeight, headSize, 0, 0); m_characterCollisionShape = CreateCharacterShape(characterHeight * 0.9f, characterWidth * 0.9f, characterHeight * 0.9f + headHeight, headSize * 0.9f, 0, 0); m_crouchShape = CreateCharacterShape(characterHeight, characterWidth, characterHeight + headHeight, headSize, 0.0f, 1.0f); if (!m_isDynamic) { CharacterPhantom = new HkSimpleShapePhantom(m_characterShape, MyPhysics.CharacterCollisionLayer); } } else { HkBoxShape box = new HkBoxShape(new Vector3(characterWidth / 2.0f, characterHeight / 2.0f, characterWidth / 2.0f)); if (!m_isDynamic) { CharacterPhantom = new HkSimpleShapePhantom((HkShape)box, MyPhysics.CharacterCollisionLayer); } m_characterShape = box; } if (!m_isDynamic) { HkCharacterProxyCinfo characterProxyInfo = new HkCharacterProxyCinfo(); characterProxyInfo.StaticFriction = 1; characterProxyInfo.DynamicFriction = 1; characterProxyInfo.ExtraDownStaticFriction = 1000; //characterProxyInfo.ContactAngleSensitivity = 20; //characterProxyInfo.KeepContactTolerance = 1f; characterProxyInfo.MaxCharacterSpeedForSolver = 10000; characterProxyInfo.RefreshManifoldInCheckSupport = true; characterProxyInfo.Up = up; characterProxyInfo.Forward = forward; characterProxyInfo.UserPlanes = 4; characterProxyInfo.MaxSlope = MathHelper.ToRadians(maxSlope); characterProxyInfo.Position = position; characterProxyInfo.CharacterMass = mass; characterProxyInfo.CharacterStrength = 100; characterProxyInfo.ShapePhantom = CharacterPhantom; CharacterProxy = new HkCharacterProxy(characterProxyInfo); characterProxyInfo.Dispose(); } else { HkCharacterRigidBodyCinfo characterRBCInfo = new HkCharacterRigidBodyCinfo(); characterRBCInfo.Shape = m_characterShape; characterRBCInfo.CrouchShape = m_crouchShape; characterRBCInfo.Friction = 0; characterRBCInfo.MaxSlope = MathHelper.ToRadians(maxSlope); characterRBCInfo.Up = up; characterRBCInfo.Mass = mass; characterRBCInfo.CollisionFilterInfo = MyPhysics.CharacterCollisionLayer; //characterRBCInfo.UnweldingHeightOffsetFactor = 100; characterRBCInfo.MaxLinearVelocity = 1000000; characterRBCInfo.MaxForce = 100000; characterRBCInfo.AllowedPenetrationDepth = 0.1f; characterRBCInfo.JumpHeight = 0.8f; CharacterRigidBody = new HkCharacterRigidBody(characterRBCInfo, MyGridPhysics.ShipMaxLinearVelocity(), body, isOnlyVertical); CharacterRigidBody.GetRigidBody().ContactPointCallbackEnabled = true; CharacterRigidBody.GetRigidBody().ContactPointCallback += RigidBody_ContactPointCallback; CharacterRigidBody.GetRigidBody().ContactPointCallbackDelay = 0; //CharacterRigidBody.GetHitRigidBody().ContactPointCallbackEnabled = true; //CharacterRigidBody.GetHitRigidBody().ContactPointCallback += RigidBody_ContactPointCallback; //CharacterRigidBody.GetHitRigidBody().ContactPointCallbackDelay = 0; //CharacterRigidBody.SetSupportDistance(10); //CharacterRigidBody.SetHardSupportDistance(10); characterRBCInfo.Dispose(); } }
void Components_ComponentAdded(Type t, MyEntityComponentBase c) { if (t == typeof(MyPhysicsComponentBase)) m_physics = c as MyPhysicsBody; else if (t == typeof(MySyncComponentBase)) m_syncObject = c as MySyncComponentBase; else if (t == typeof(MyGameLogicComponent)) m_gameLogic = c as MyGameLogicComponent; else if (t == typeof(MyPositionComponentBase)) m_position = c as MyPositionComponentBase; else if (t == typeof(MyHierarchyComponentBase)) m_hierarchy = c as MyHierarchyComponentBase; else if (t == typeof(MyRenderComponentBase)) { m_render = c as MyRenderComponentBase; } }
protected override void OnUnwelded(MyPhysicsBody other) { base.OnUnwelded(other); Shape.RefreshMass(); m_grid.HavokSystemIDChanged(HavokCollisionSystemID); }
public void Weld(MyPhysicsBody other, bool recreateShape = true) { if (other.WeldInfo.Parent == this) //already welded to this return; if(other.IsWelded && !IsWelded) { other.Weld(this); return; } if(IsWelded) { WeldInfo.Parent.Weld(other); return; } HkShape thisShape; if (WeldInfo.Children.Count == 0) { thisShape = RigidBody.GetShape(); HkShape.SetUserData(thisShape, RigidBody); Entity.OnPhysicsChanged += WeldedEntity_OnPhysicsChanged; //Entity.OnClose += Entity_OnClose; } else thisShape = GetShape(); other.Deactivate(); var transform = other.RigidBody.GetRigidBodyMatrix() * Matrix.Invert(RigidBody.GetRigidBodyMatrix()); other.WeldInfo.Transform = transform; other.WeldedRigidBody = other.RigidBody; other.RigidBody = RigidBody; other.WeldInfo.Parent = this; WeldInfo.Children.Add(other); if(recreateShape) RecreateWeldedShape(thisShape); other.Entity.OnPhysicsChanged += WeldedEntity_OnPhysicsChanged; }
public void Unweld(MyPhysicsBody other, bool insertToWorld = true, bool recreateShape = true) { Debug.Assert(other.IsWelded && RigidBody != null && other.WeldedRigidBody != null, "Invalid welding state!"); if (IsWelded) { WeldInfo.Parent.Unweld(other, insertToWorld, recreateShape); Debug.Assert(other.IsWelded); return; } if (other.IsInWorld || RigidBody == null || other.WeldedRigidBody == null) { WeldInfo.Children.Remove(other); return; } var rbWorldMatrix = RigidBody.GetRigidBodyMatrix(); //other.Entity.OnPhysicsChanged -= WeldedEntity_OnPhysicsChanged; other.WeldInfo.Parent = null; Debug.Assert(WeldInfo.Children.Contains(other)); WeldInfo.Children.Remove(other); var body = other.RigidBody; Debug.Assert(body == RigidBody); other.RigidBody = other.WeldedRigidBody; other.WeldedRigidBody = null; if (!other.RigidBody.IsDisposed) { other.RigidBody.SetWorldMatrix(other.WeldInfo.Transform * rbWorldMatrix); other.RigidBody.LinearVelocity = body.LinearVelocity; other.WeldInfo.MassElement.Tranform = Matrix.Identity; other.WeldInfo.Transform = Matrix.Identity; } else { Debug.Fail("Disposed welded body"); } //RemoveConstraints(other.RigidBody); other.ClusterObjectID = MyHavokCluster.CLUSTERED_OBJECT_ID_UNITIALIZED; if (insertToWorld) { other.Activate(); other.OnMotion(other.RigidBody, 0); } if (WeldInfo.Children.Count == 0) { recreateShape = false; Entity.OnPhysicsChanged -= WeldedEntity_OnPhysicsChanged; Entity.OnClose -= Entity_OnClose; WeldedRigidBody.LinearVelocity = RigidBody.LinearVelocity; WeldedRigidBody.AngularVelocity = RigidBody.AngularVelocity; if (HavokWorld != null) { HavokWorld.RemoveRigidBody(RigidBody); } RigidBody.Dispose(); RigidBody = WeldedRigidBody; WeldedRigidBody = null; RigidBody.SetWorldMatrix(rbWorldMatrix); WeldInfo.Transform = Matrix.Identity; if (HavokWorld != null) { HavokWorld.AddRigidBody(RigidBody); } else if (!Entity.MarkedForClose) { Activate(); } if (RigidBody2 != null) { RigidBody2.SetShape(RigidBody.GetShape()); } } if (RigidBody != null && recreateShape) { RecreateWeldedShape(GetShape()); } OnUnwelded(other); other.OnUnwelded(this); Debug.Assert(!other.IsWelded); }
private void InitDeadBodyPhysics() { Vector3 velocity = Vector3.Zero; RadioBroadcaster.BroadcastRadius = 5; if (Physics != null) { velocity = Physics.LinearVelocity; Physics.Enabled = false; Physics.Close(); Physics = null; } //if (Physics == null) { var massProperties = new HkMassProperties(); massProperties.Mass = 500; HkShape shape; // CH: Need to rethink this. It does not belong here, but I don't want to add "DeadCharacterBodyCenterOfMass" to the character definition either... // MZ: See ticket "Correct dying for characters", https://app.asana.com/0/64822442925263/75411538582998 // dead body shape can now be specified in character's SBC if (Definition.DeadBodyShape != null) { HkBoxShape bshape = new HkBoxShape(PositionComp.LocalAABB.HalfExtents * Definition.DeadBodyShape.BoxShapeScale); massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(bshape.HalfExtents, massProperties.Mass); massProperties.CenterOfMass = bshape.HalfExtents * Definition.DeadBodyShape.RelativeCenterOfMass; shape = bshape; Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEFAULT); Vector3D offset = PositionComp.LocalAABB.HalfExtents * Definition.DeadBodyShape.RelativeShapeTranslation; MatrixD pos = MatrixD.CreateTranslation(offset); Physics.CreateFromCollisionObject(shape, PositionComp.LocalVolume.Center + offset, pos, massProperties, MyPhysics.CollisionLayers.FloatingObjectCollisionLayer); Physics.Friction = Definition.DeadBodyShape.Friction; Physics.RigidBody.MaxAngularVelocity = MathHelper.PiOver2; Physics.LinearVelocity = velocity; shape.RemoveReference(); Physics.Enabled = true; } else // no special definition => use AABB { HkBoxShape bshape = new HkBoxShape(PositionComp.LocalAABB.HalfExtents); massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(bshape.HalfExtents, massProperties.Mass); massProperties.CenterOfMass = new Vector3(bshape.HalfExtents.X, 0, 0); shape = bshape; Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEFAULT); Physics.CreateFromCollisionObject(shape, PositionComp.LocalVolume.Center, MatrixD.Identity, massProperties, MyPhysics.CollisionLayers.FloatingObjectCollisionLayer); Physics.Friction = 0.5f; Physics.RigidBody.MaxAngularVelocity = MathHelper.PiOver2; Physics.LinearVelocity = velocity; shape.RemoveReference(); Physics.Enabled = true; } } NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME; }
protected virtual void OnUnwelded(MyPhysicsBody other) { }
private static bool IsCharacter(HkRigidBody rb, MyPhysicsBody character) { if (character == null) return false; var c = character.Entity as MyCharacter; if (c == null) return false; if (c.Physics == null) return false; // Physics may have been already released / Entity removed from the world? if (c.Physics.CharacterProxy != null) return c.Physics.CharacterProxy.GetHitRigidBody() == rb; return (c.Physics.RigidBody == rb); // Otherwise we do proper check }
public void UpdateMassFromInventories(HashSet<MySlimBlock> blocks, MyPhysicsBody rb) { if (rb.RigidBody.IsFixedOrKeyframed) return; ProfilerShort.Begin("GridShape.UpdateMassFromInv"); Debug.Assert(BreakableShape.IsValid(), "This routine works with breakable shape mass properties."); foreach (var block in blocks) { var owner = block.FatBlock as IMyInventoryOwner; if (owner == null) continue; float mass = 0; for (int i = 0; i < owner.InventoryCount; i++) { mass += (float)owner.GetInventory(i).CurrentMass; } var size = (block.Max - block.Min + Vector3I.One) * block.CubeGrid.GridSize; var center = (block.Min + block.Max) * 0.5f * block.CubeGrid.GridSize; HkMassProperties massProperties = new HkMassProperties(); massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(size / 2, mass); m_tmpElements.Add(new HkMassElement() { Properties = massProperties, Tranform = Matrix.CreateTranslation(center) }); } HkMassProperties originalMp = new HkMassProperties(); BreakableShape.BuildMassProperties(ref originalMp); m_tmpElements.Add(new HkMassElement() { Properties = originalMp, Tranform = Matrix.Identity }); var mp = HkInertiaTensorComputer.CombineMassProperties(m_tmpElements); m_tmpElements.Clear(); rb.RigidBody.SetMassProperties(ref mp); if (!rb.RigidBody.IsActive) rb.RigidBody.Activate(); ProfilerShort.End(); }
public static void TriggerDestruction(float destructionImpact, MyPhysicsBody body, Vector3D position, Vector3 normal, float maxDestructionRadius) { if (body.BreakableBody != null) { float collidingMass = body.Mass;// == 0 ? Mass : body.Mass; //fall on voxel float destructionRadius = Math.Min(destructionImpact / 8000, maxDestructionRadius); float destructionImpulse = MyDestructionConstants.STRENGTH + destructionImpact / 10000; float expandVelocity = Math.Min(destructionImpact / 10000, 3); MyPhysics.FractureImpactDetails destruction; HkdFractureImpactDetails details; details = HkdFractureImpactDetails.Create(); details.SetBreakingBody(body.RigidBody); details.SetContactPoint(body.WorldToCluster(position)); details.SetDestructionRadius(destructionRadius); details.SetBreakingImpulse(destructionImpulse); details.SetParticleExpandVelocity(expandVelocity); //details.SetParticleVelocity(contactVelocity); details.SetParticlePosition(body.WorldToCluster(position - normal * 0.25f)); details.SetParticleMass(10000000);//collidingMass); details.ZeroCollidingParticleVelocity(); details.Flag = details.Flag | HkdFractureImpactDetails.Flags.FLAG_DONT_RECURSE | HkdFractureImpactDetails.Flags.FLAG_TRIGGERED_DESTRUCTION; destruction = new MyPhysics.FractureImpactDetails(); destruction.Details = details; destruction.World = body.HavokWorld; destruction.ContactInWorld = position; destruction.Entity = (MyEntity)body.Entity; MyPhysics.EnqueueDestruction(destruction); } }
public override void Simulate() { if (MyFakes.PAUSE_PHYSICS && !MyFakes.STEP_PHYSICS) { return; } MyFakes.STEP_PHYSICS = false; if (!MySandboxGame.IsGameReady) { return; } AddTimestamp(); InsideSimulation = true; ProcessDestructions(); ProfilerShort.Begin("HavokWorld.Step"); if (MyFakes.CLIENTS_SIMULATE_SINGLE_WORLD && !Sync.IsServer) { var world = Clusters.GetClusterForPosition(MySector.MainCamera.Position); if (world != null) { StepWorld((HkWorld)world); } } else { foreach (HkWorld world in Clusters.GetList()) { StepWorld(world); } } ProfilerShort.End(); InsideSimulation = false; ProfilerShort.Begin("Update rigid bodies"); long activeRigidBodies = 0; foreach (HkWorld world in Clusters.GetList()) { activeRigidBodies += world.ActiveRigidBodies.Count; } VRageRender.MyPerformanceCounter.PerCameraDrawWrite["Active rigid bodies"] = activeRigidBodies; ProfilerShort.CustomValue("Active bodies", activeRigidBodies, null); foreach (HkWorld world in Clusters.GetList()) { IterateBodies(world); } //ParallelTasks.Parallel.For(0, m_iterationBodies.Count, (rb) => //{ // MyPhysicsBody body = (MyPhysicsBody)m_iterationBodies[rb].UserObject; // if (body == null) // return; // body.OnMotion(m_iterationBodies[rb], MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); //}, Math.Max(1, m_iterationBodies.Count / 16)); foreach (var rb in m_iterationBodies) { MyPhysicsBody body = (MyPhysicsBody)rb.UserObject; if (body == null) { return; } body.OnMotion(rb, MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); } foreach (HkCharacterRigidBody rb in m_characterIterationBodies) { var body = (MyPhysicsBody)rb.GetHitRigidBody().UserObject; if (body.Entity.WorldMatrix.Translation != body.GetWorldMatrix().Translation) { body.UpdateCluster(); } } m_iterationBodies.Clear(); m_characterIterationBodies.Clear(); ProfilerShort.End(); ProfilerShort.Begin("HavokWorld.StepVDB"); foreach (HkWorld world in Clusters.GetList()) { //if (MySession.ControlledEntity.Entity.GetTopMostParent().Physics.HavokWorld == world) world.StepVDB(MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); } ProfilerShort.End(); }