/// <summary> /// Returns true if the given small block connects to large one. /// </summary> /// <param name="smallBlock">small block</param> /// <param name="smallBlockWorldAabb">small block world AABB</param> /// <param name="largeBlock">large block</param> /// <param name="largeBlockWorldAabb">large block wotld AABB</param> /// <returns>true when connected</returns> private bool SmallBlockConnectsToLarge(MySlimBlock smallBlock, ref BoundingBoxD smallBlockWorldAabb, MySlimBlock largeBlock, ref BoundingBoxD largeBlockWorldAabb) { Debug.Assert(smallBlock.BlockDefinition.CubeSize == MyCubeSize.Small); Debug.Assert(largeBlock.BlockDefinition.CubeSize == MyCubeSize.Large); Debug.Assert(!(smallBlock.FatBlock is MyCompoundCubeBlock)); Debug.Assert(!(largeBlock.FatBlock is MyCompoundCubeBlock)); BoundingBoxD smallBlockWorldAabbReduced = smallBlockWorldAabb; smallBlockWorldAabbReduced.Inflate(-smallBlock.CubeGrid.GridSize / 4); // Small block aabb penetrates large block aabb (large timbers). bool penetratesAabbs = largeBlockWorldAabb.Contains(smallBlockWorldAabbReduced) == ContainmentType.Intersects; if (!penetratesAabbs) { Vector3D centerToCenter = smallBlockWorldAabb.Center - largeBlockWorldAabb.Center; Vector3I addDir = Base6Directions.GetIntVector(Base6Directions.GetClosestDirection(centerToCenter)); // Check small grid mount points Quaternion smallBlockRotation; smallBlock.Orientation.GetQuaternion(out smallBlockRotation); smallBlockRotation = Quaternion.CreateFromRotationMatrix(smallBlock.CubeGrid.WorldMatrix) * smallBlockRotation; if (!MyCubeGrid.CheckConnectivitySmallBlockToLargeGrid(largeBlock.CubeGrid, smallBlock.BlockDefinition, ref smallBlockRotation, ref addDir)) { return(false); } } BoundingBoxD smallBlockWorldAabbInflated = smallBlockWorldAabb; smallBlockWorldAabbInflated.Inflate(2 * smallBlock.CubeGrid.GridSize / 3); // Trim small block aabb with large block aabb. BoundingBoxD intersectedBox = smallBlockWorldAabbInflated.Intersect(largeBlockWorldAabb); Vector3D intersectedBoxCenter = intersectedBox.Center; HkShape shape = new HkBoxShape((Vector3)intersectedBox.HalfExtents); Quaternion largeRotation; largeBlock.Orientation.GetQuaternion(out largeRotation); largeRotation = Quaternion.CreateFromRotationMatrix(largeBlock.CubeGrid.WorldMatrix) * largeRotation; Vector3D largeTranslation; largeBlock.ComputeWorldCenter(out largeTranslation); bool result = false; try { if (largeBlock.FatBlock != null) { MyModel model = largeBlock.FatBlock.Model; if (model != null) { HkShape[] shapes = model.HavokCollisionShapes; if (shapes == null || shapes.Length == 0) { return(false); } for (int i = 0; i < shapes.Length; ++i) { result = MyPhysics.IsPenetratingShapeShape(shape, ref intersectedBoxCenter, ref Quaternion.Identity, shapes[i], ref largeTranslation, ref largeRotation); if (result) { break; } } } else { HkShape shapeLarge = new HkBoxShape(largeBlock.BlockDefinition.Size * largeBlock.CubeGrid.GridSize / 2); result = MyPhysics.IsPenetratingShapeShape(shape, ref intersectedBoxCenter, ref Quaternion.Identity, shapeLarge, ref largeTranslation, ref largeRotation); shapeLarge.RemoveReference(); } } else { HkShape shapeLarge = new HkBoxShape(largeBlock.BlockDefinition.Size * largeBlock.CubeGrid.GridSize / 2); result = MyPhysics.IsPenetratingShapeShape(shape, ref intersectedBoxCenter, ref Quaternion.Identity, shapeLarge, ref largeTranslation, ref largeRotation); shapeLarge.RemoveReference(); } } finally { shape.RemoveReference(); } return(result); }
private bool SmallBlockConnectsToLarge(MySlimBlock smallBlock, ref BoundingBoxD smallBlockWorldAabb, MySlimBlock largeBlock, ref BoundingBoxD largeBlockWorldAabb) { Quaternion quaternion; Vector3D vectord2; BoundingBoxD box = smallBlockWorldAabb; box.Inflate((double)(-smallBlock.CubeGrid.GridSize / 4f)); if (!largeBlockWorldAabb.Intersects(box)) { Quaternion quaternion2; Vector3I addNormal = this.GetSmallBlockAddDirection(ref smallBlockWorldAabb, ref box, ref largeBlockWorldAabb); smallBlock.Orientation.GetQuaternion(out quaternion2); quaternion2 = Quaternion.CreateFromRotationMatrix(smallBlock.CubeGrid.WorldMatrix) * quaternion2; if (!MyCubeGrid.CheckConnectivitySmallBlockToLargeGrid(largeBlock.CubeGrid, smallBlock.BlockDefinition, ref quaternion2, ref addNormal)) { return(false); } } BoundingBoxD xd2 = smallBlockWorldAabb; xd2.Inflate((double)((2f * smallBlock.CubeGrid.GridSize) / 3f)); BoundingBoxD xd3 = xd2.Intersect(largeBlockWorldAabb); Vector3D center = xd3.Center; HkShape shape = (HkShape) new HkBoxShape((Vector3)xd3.HalfExtents); largeBlock.Orientation.GetQuaternion(out quaternion); quaternion = Quaternion.CreateFromRotationMatrix(largeBlock.CubeGrid.WorldMatrix) * quaternion; largeBlock.ComputeWorldCenter(out vectord2); bool flag = false; try { if (largeBlock.FatBlock == null) { HkShape shape3 = (HkShape) new HkBoxShape((largeBlock.BlockDefinition.Size * largeBlock.CubeGrid.GridSize) / 2f); flag = MyPhysics.IsPenetratingShapeShape(shape, ref center, ref Quaternion.Identity, shape3, ref vectord2, ref quaternion); shape3.RemoveReference(); } else { MyModel model = largeBlock.FatBlock.Model; if ((model == null) || (model.HavokCollisionShapes == null)) { HkShape shape2 = (HkShape) new HkBoxShape((largeBlock.BlockDefinition.Size * largeBlock.CubeGrid.GridSize) / 2f); flag = MyPhysics.IsPenetratingShapeShape(shape, ref center, ref Quaternion.Identity, shape2, ref vectord2, ref quaternion); shape2.RemoveReference(); } else { HkShape[] havokCollisionShapes = model.HavokCollisionShapes; for (int i = 0; i < havokCollisionShapes.Length; i++) { flag = MyPhysics.IsPenetratingShapeShape(shape, ref center, ref Quaternion.Identity, havokCollisionShapes[i], ref vectord2, ref quaternion); if (flag) { break; } } } } } finally { shape.RemoveReference(); } return(flag); }