protected override bool CanPlaceRotor(MyMotorRotor rotorBlock, long builtBy) { BoundingSphereD sphere = rotorBlock.Model.BoundingSphere; sphere.Center = Vector3D.Transform(sphere.Center, rotorBlock.WorldMatrix); CubeGrid.GetBlocksInsideSphere(ref sphere, m_tmpSet); HkSphereShape spShape = new HkSphereShape((float)sphere.Radius); Quaternion q = Quaternion.Identity;//Quaternion.CreateFromForwardUp(rotorBlock.WorldMatrix.Forward, rotorBlock.WorldMatrix.Up); var position = rotorBlock.WorldMatrix.Translation; MyPhysics.GetPenetrationsShape(spShape, ref position, ref q, m_tmpList, MyPhysics.CharacterNetworkCollisionLayer); if (m_tmpSet.Count > 1 || m_tmpList.Count > 0) { m_tmpList.Clear(); m_tmpSet.Clear(); if (builtBy == MySession.LocalPlayerId) { MyHud.Notifications.Add(MyNotificationSingletons.WheelNotPlaced); } return(false); } m_tmpList.Clear(); m_tmpSet.Clear(); return(true); }
public void GetFracturesInBox(ref BoundingBoxD searchBox, List <MyFracturedPiece> output) { var activeFractures = m_piecesTimesOfDeath.Keys; Debug.Assert(m_rigidList.Count == 0); m_rigidList.Clear(); HkShape shape = new HkBoxShape(searchBox.HalfExtents); try { var center = searchBox.Center; MyPhysics.GetPenetrationsShape(shape, ref center, ref Quaternion.Identity, m_rigidList, MyPhysics.CollisionLayers.NotCollideWithStaticLayer); foreach (var rigidBody in m_rigidList) { var fracture = rigidBody.GetCollisionEntity() as MyFracturedPiece; if (fracture != null && m_piecesTimesOfDeath.ContainsKey(fracture)) { output.Add(fracture); } } } finally { m_rigidList.Clear(); shape.RemoveReference(); } }
protected override bool IsPositionValid(MyTransformD clientDelta) { if (m_character.Physics != null && m_character.Physics.CharacterProxy != null) { float offset = 2 * MyPerGameSettings.PhysicsConvexRadius + 0.03f; float width = (m_character.Definition.CharacterCollisionWidth * m_character.Definition.CharacterCollisionScale) - offset; float height = (m_character.Definition.CharacterCollisionHeight - m_character.Definition.CharacterCollisionWidth * m_character.Definition.CharacterCollisionScale) - offset; HkCapsuleShape capsule = new HkCapsuleShape(Vector3.Up * height / 2.0f, Vector3.Down * height / 2.0f, width / 2.0f); m_results.Clear(); clientDelta.Position = clientDelta.Position + m_character.WorldMatrix.Up * (m_character.Definition.CharacterCollisionHeight / 2 + offset); MyPhysics.GetPenetrationsShape(capsule, ref clientDelta.Position, ref clientDelta.Rotation, m_results, MyPhysics.CollisionLayers.DefaultCollisionLayer); bool otherFound = false; foreach (var colision in m_results) { if (colision.Body.Quality == HkCollidableQualityType.Character) { continue; } otherFound = true; } return(!otherFound); } return(false); }
public void GetFracturesInSphere(ref BoundingSphereD searchSphere, ref List <MyFracturedPiece> output) { var activeFractures = m_piecesTimesOfDeath.Keys; HkShape shape = new HkSphereShape((float)searchSphere.Radius); try { MyPhysics.GetPenetrationsShape(shape, ref searchSphere.Center, ref Quaternion.Identity, m_rigidList, MyPhysics.CollisionLayers.NotCollideWithStaticLayer); foreach (var rigidBody in m_rigidList) { var fracture = rigidBody.GetCollisionEntity() as MyFracturedPiece; if (fracture != null) { output.Add(fracture); } } } finally { m_rigidList.Clear(); shape.RemoveReference(); } }
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); } } }
protected override bool CanPlaceRotor(MyAttachableTopBlockBase rotorBlock, long builtBy) { // Compute the rough actual position for the wheel, this improves the detection if it can be placed float wheelDistance = BlockDefinition.Size.Y * CubeGrid.GridSize - 0.2f * CubeGrid.GridSize; Vector3D wheelPosition = this.WorldMatrix.Translation + this.WorldMatrix.Up * wheelDistance; float wheelRadius = rotorBlock.ModelCollision.HavokCollisionShapes[0].ConvexRadius * 0.9f; // First test if we intersect any blocks of our own grid BoundingSphereD sphere = rotorBlock.Model.BoundingSphere; sphere.Center = wheelPosition; sphere.Radius = wheelRadius; CubeGrid.GetBlocksInsideSphere(ref sphere, m_tmpSet); // If we intersect more than 1 block (because wheel sometimes intersects suspension), don't add wheel if (m_tmpSet.Count > 1) { m_tmpSet.Clear(); if (builtBy == MySession.Static.LocalPlayerId) { MyHud.Notifications.Add(MyNotificationSingletons.WheelNotPlaced); } return(false); } m_tmpSet.Clear(); // Next test if we intersect any physics objects HkSphereShape spShape = new HkSphereShape(wheelRadius); Quaternion q = Quaternion.Identity; MyPhysics.GetPenetrationsShape(rotorBlock.ModelCollision.HavokCollisionShapes[0], ref wheelPosition, ref q, m_tmpList, MyPhysics.CollisionLayers.DefaultCollisionLayer); // If we have any collisions with anything other than our own grid, don't add the wheel // We already checked for inner-grid collisions in the previous case for (int i = 0; i < m_tmpList.Count; i++) { MyCubeGrid grid = m_tmpList[i].GetCollisionEntity() as MyCubeGrid; if (grid == null || grid != CubeGrid) { m_tmpList.Clear(); if (builtBy == MySession.Static.LocalPlayerId) { MyHud.Notifications.Add(MyNotificationSingletons.WheelNotPlaced); } return(false); } } m_tmpList.Clear(); return(true); }
protected virtual bool CanPlaceTop(MyAttachableTopBlockBase topBlock, long builtBy) { // Compute the rough actual position for the head, this improves the detection if it can be placed float topDistance = (Subpart3.Model.BoundingBoxSize.Y); Vector3D topPosition = this.Subpart3.WorldMatrix.Translation + this.WorldMatrix.Up * topDistance; float topRadius = topBlock.ModelCollision.HavokCollisionShapes[0].ConvexRadius * 0.9f; // First test if we intersect any blocks of our own grid BoundingSphereD sphere = topBlock.Model.BoundingSphere; sphere.Center = topPosition; sphere.Radius = topRadius; CubeGrid.GetBlocksInsideSphere(ref sphere, m_tmpSet); // If we intersect more than 1 block (because top sometimes intersects piston), don't add top if (m_tmpSet.Count > 1) { m_tmpSet.Clear(); if (builtBy == MySession.Static.LocalPlayerId) { MyHud.Notifications.Add(MyNotificationSingletons.HeadNotPlaced); } return(false); } m_tmpSet.Clear(); // Next test if we intersect any physics objects HkSphereShape spShape = new HkSphereShape(topRadius); Quaternion q = Quaternion.Identity; MyPhysics.GetPenetrationsShape(topBlock.ModelCollision.HavokCollisionShapes[0], ref topPosition, ref q, m_penetrations, MyPhysics.CollisionLayers.DefaultCollisionLayer); // If we have any collisions with anything other than our own grid, don't add the head // We already checked for inner-grid collisions in the previous case for (int i = 0; i < m_penetrations.Count; i++) { MyCubeGrid grid = m_penetrations[i].GetCollisionEntity().GetTopMostParent() as MyCubeGrid; if (grid == null || grid != CubeGrid) { m_penetrations.Clear(); if (builtBy == MySession.Static.LocalPlayerId) { MyHud.Notifications.Add(MyNotificationSingletons.HeadNotPlaced); } return(false); } } m_penetrations.Clear(); return(true); }
public override void AccumulateCorrection(ref Vector3 correction, ref float weight) { if (base.Parent.Speed >= 0.01) { MatrixD positionAndOrientation = base.Parent.PositionAndOrientation; Vector3D translation = positionAndOrientation.Translation; Quaternion identity = Quaternion.Identity; MyPhysics.GetPenetrationsShape((HkShape) new HkSphereShape(6f), ref translation, ref identity, this.m_trees, 9); foreach (HkBodyCollision collision in this.m_trees) { if (collision.Body == null) { continue; } MyPhysicsBody userObject = collision.Body.UserObject as MyPhysicsBody; if (userObject != null) { HkShape shape = collision.Body.GetShape(); if (shape.ShapeType == HkShapeType.StaticCompound) { int num; uint num2; HkStaticCompoundShape shape2 = (HkStaticCompoundShape)shape; shape2.DecomposeShapeKey(collision.ShapeKey, out num, out num2); Vector3D vectord2 = shape2.GetInstanceTransform(num).Translation + userObject.GetWorldMatrix().Translation; Vector3D direction = vectord2 - translation; double num3 = direction.Normalize(); direction = Vector3D.Reject(base.Parent.ForwardVector, direction); direction.Y = 0.0; if (((direction.Z * direction.Z) + (direction.X * direction.X)) < 0.1) { direction = translation - vectord2; direction = Vector3D.Cross(Vector3D.Up, direction); if (Vector3D.TransformNormal(direction, base.Parent.PositionAndOrientationInverted).X < 0.0) { direction = -direction; } } direction.Normalize(); correction += ((6.0 - num3) * base.Weight) * direction; if (!correction.IsValid()) { Debugger.Break(); } } } } this.m_trees.Clear(); weight += base.Weight; } }
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); } } }
private bool TargetEntityPenetratesCharacterInHeadPivotPosition(MyEntity entity, ref MatrixD shapeTransform) { HkShape shape = entity.Physics.RigidBody.GetShape(); Vector3D translation = shapeTransform.Translation; Quaternion rotation = Quaternion.CreateFromRotationMatrix(shapeTransform); m_tmpBodies.Clear(); MyPhysics.GetPenetrationsShape(shape, ref translation, ref rotation, m_tmpBodies, MyPhysics.ObjectDetectionCollisionLayer); foreach (var rigidBody in m_tmpBodies) { if (rigidBody.GetEntity() == Owner) { return(false); } } return(true); }
private bool TestPlacement() { return(true); /// yaay for (int i = 0; i < m_previewFloatingObjects.Count; ++i) { var floatingObject = m_previewFloatingObjects[i]; var rotation = Quaternion.CreateFromRotationMatrix(floatingObject.WorldMatrix); var position = floatingObject.PositionComp.GetPosition() + Vector3D.Transform(floatingObject.PositionComp.LocalVolume.Center, rotation); var bodies = new List <HkRigidBody>(); MyPhysics.GetPenetrationsShape(floatingObject.Physics.RigidBody.GetShape(), ref position, ref rotation, bodies, MyPhysics.FloatingObjectCollisionLayer); foreach (var body in bodies) { var ent = body.GetEntity(); if (ent != null && !ent.Closed) { return(false); } } } return(true); }
private void ThrustDamage() { if (m_flames.Count > 0 && MySession.Static.ThrusterDamage && Sync.IsServer && IsWorking && CubeGrid.InScene && CubeGrid.Physics != null && CubeGrid.Physics.Enabled) { if (CurrentStrength == 0 && !MyFakes.INACTIVE_THRUSTER_DMG) { return; } UpdateThrustFlame(); foreach (var flameInfo in m_flames) { var l = GetDamageCapsuleLine(flameInfo); HkShape shape; if (l.Length != 0) { shape = new HkCapsuleShape(Vector3.Zero, l.To - l.From, flameInfo.Radius * m_thrustDefinition.FlameDamageLengthScale); } else { shape = new HkSphereShape(flameInfo.Radius * m_thrustDefinition.FlameDamageLengthScale); } MyPhysics.GetPenetrationsShape(shape, ref l.From, ref Quaternion.Identity, m_flameCollisionsList, 0); shape.RemoveReference(); foreach (var obj in m_flameCollisionsList) { var entity = obj.GetEntity(); if (entity == null) { continue; } if (entity.Equals(this)) { continue; } if (!(entity is MyCharacter)) { entity = entity.GetTopMostParent(); } if (m_damagedEntities.Contains(entity)) { continue; } else { m_damagedEntities.Add(entity); } if (entity is IMyDestroyableObject) { (entity as IMyDestroyableObject).DoDamage(flameInfo.Radius * m_thrustDefinition.FlameDamage * 10, MyDamageType.Environment, true); } else if (entity is MyCubeGrid && MySession.Static.DestructibleBlocks) { DamageGrid(flameInfo, l, entity as MyCubeGrid); } } m_damagedEntities.Clear(); m_flameCollisionsList.Clear(); } } }
public override void AccumulateCorrection(ref VRageMath.Vector3 correction, ref float weight) { // Don't do any correction if we're not moving if (Parent.Speed < 0.01) { return; } Vector3D position = Parent.PositionAndOrientation.Translation; // Find trees Quaternion rotation = Quaternion.Identity; HkShape sphereShape = new HkSphereShape(6); MyPhysics.GetPenetrationsShape(sphereShape, ref position, ref rotation, m_trees, MyPhysics.CollisionLayers.NoVoxelCollisionLayer); foreach (var tree in m_trees) { // Make sure the tree is actually a tree if (tree.Body == null) { continue; } MyPhysicsBody physicsBody = tree.Body.UserObject as MyPhysicsBody; if (physicsBody == null) { continue; } HkShape bodyShape = tree.Body.GetShape(); if (bodyShape.ShapeType != HkShapeType.StaticCompound) { continue; } // Get the static compound shape HkStaticCompoundShape staticCompoundShape = (HkStaticCompoundShape)bodyShape; int instanceId; uint childKey; staticCompoundShape.DecomposeShapeKey(tree.ShapeKey, out instanceId, out childKey); // Get the local shape position, and add entity world position Vector3D item = staticCompoundShape.GetInstanceTransform(instanceId).Translation; item += physicsBody.GetWorldMatrix().Translation; // Avoid tree Vector3D dir = item - position; var dist = dir.Normalize(); dir = Vector3D.Reject(Parent.ForwardVector, dir); dir.Y = 0.0f; if (dir.Z * dir.Z + dir.X * dir.X < 0.1) { Vector3D dirLocal = Vector3D.TransformNormal(dir, Parent.PositionAndOrientationInverted); dir = position - item; dir = Vector3D.Cross(Vector3D.Up, dir); if (dirLocal.X < 0) { dir = -dir; } } dir.Normalize(); correction += (6f - dist) * Weight * dir; if (!correction.IsValid()) { System.Diagnostics.Debugger.Break(); } } m_trees.Clear(); weight += Weight; }