Ejemplo n.º 1
0
 private HkdBreakableShape AddMountForShape(HkdBreakableShape shape, Matrix transform, ref BoundingBox blockBB)
 {
     Vector4 min;
     Vector4 max;
     shape.GetShape().GetLocalAABB(0.01f, out min, out max);//.Transform(CubeGrid.PositionComp.WorldMatrix);
     var bb = new BoundingBox(new Vector3(min), new Vector3(max));
     bb = bb.Transform(transform);
     bb.Min /= CubeGrid.GridSize; //normalize for mount point
     bb.Max /= CubeGrid.GridSize;
     
     bb.Inflate(0.04f);//add tolerance (fracture shapes are smaller than block)
     bb.Min += blockBB.HalfExtents;
     bb.Max += blockBB.HalfExtents;
     
     if (blockBB.Contains(bb) == ContainmentType.Intersects)
     {
         bb.Inflate(-0.04f);
         foreach (var directionEnum in Base6Directions.EnumDirections)
         {
             int dirEnum = (int)directionEnum;
             Vector3 direction = Base6Directions.Directions[dirEnum];
             Vector3 absDir = Vector3.Abs(direction);
             var mp = new MyCubeBlockDefinition.MountPoint();
             mp.Start = bb.Min;
             mp.End = bb.Max;
             var start = mp.Start * absDir / (blockBB.HalfExtents * 2) - absDir * 0.04f;
             var end = mp.End * absDir / (blockBB.HalfExtents * 2) + absDir * 0.04f;
             bool add = false;
             bool one = false;
             if (start.Max() < 1 && end.Max() > 1 && direction.Max() > 0)
             {
                 add = true;
                 one = true;
             }
             else if (start.Min() < 0 && end.Max() > 0 && direction.Min() < 0)
             {
                 add = true;
             }
             if (!add)
             {
                 continue;
             }
             mp.Start -= mp.Start * absDir - absDir * 0.04f;
             mp.End -= mp.End * absDir + absDir * 0.04f;
             if (one)
             {
                 mp.Start += absDir * blockBB.HalfExtents * 2;
                 mp.End += absDir * blockBB.HalfExtents * 2;
             }
             mp.Start -= blockBB.HalfExtents - Vector3.One / 2;
             mp.End -= blockBB.HalfExtents - Vector3.One / 2;
             mp.Normal = new Vector3I(direction);
             MountPoints.Add(mp);
         }
     }
     return shape;
 }
        /// <summary>
        /// Fills passed lists with mount point data, which is transformed using orientation
        /// of the block.
        /// </summary>
        /// <param name="outMountPoints">Output buffer.</param>
		/// <param name="performCorrection">True when you want to have correction performed for when rotation of fractional values would have different result than integers.</param>
        public static void TransformMountPoints(List<MyCubeBlockDefinition.MountPoint> outMountPoints, MyCubeBlockDefinition def, MyCubeBlockDefinition.MountPoint[] mountPoints, ref MyBlockOrientation orientation)
        {
            Debug.Assert(outMountPoints != null);

            outMountPoints.Clear();

			if (mountPoints == null)
                return;

            Matrix rotation;
            orientation.GetMatrix(out rotation);

			var center = def.Center;
			for (int i = 0; i < mountPoints.Length; ++i)
            {
				var mountPoint = mountPoints[i];
                var mp = new MyCubeBlockDefinition.MountPoint();
				var centeredStart = mountPoint.Start - center;
				var centeredEnd = mountPoint.End - center;
				Vector3I.Transform(ref mountPoint.Normal, ref rotation, out mp.Normal);
                Vector3.Transform(ref centeredStart, ref rotation, out mp.Start);
                Vector3.Transform(ref centeredEnd, ref rotation, out mp.End);
				mp.ExclusionMask = mountPoint.ExclusionMask;
				mp.PropertiesMask = mountPoint.PropertiesMask;
				mp.Enabled = mountPoint.Enabled;

                // Correction of situations when 0.5 would get transformed to -0.5, resulting in different floor() (integer 0 is transformed to 0).
				var startICorrect = Vector3I.Floor(mountPoint.Start) - center;
				var endICorrect = Vector3I.Floor(mountPoint.End) - center;
                Vector3I.Transform(ref startICorrect, ref rotation, out startICorrect);
                Vector3I.Transform(ref endICorrect, ref rotation, out endICorrect);

                var startI = Vector3I.Floor(mp.Start);
                var endI = Vector3I.Floor(mp.End);
                var startCorrection = startICorrect - startI;
                var endCorrection = endICorrect - endI;

                mp.Start += startCorrection;
                mp.End += endCorrection;

                outMountPoints.Add(mp);
            }
        }
        static bool FindMountPoint(HkShapeCutterUtil cutter, HkShape shape, Vector3 direction, float gridSize, List<Sandbox.Definitions.MyCubeBlockDefinition.MountPoint> mountPoints)
        {
            //VRageRender.MyRenderProxy.DebugDrawLine3D(drawMatrix.Translation, Vector3D.Transform(direction, drawMatrix), Color.Green, Color.Green, false);
            //float offset = (gridSize * 0.9f) / 2.0f;
            float offset = (gridSize * 0.75f) / 2.0f; //because fracture pieces can be bit inside the cube
            Plane plane = new Plane(-direction, offset);
            float minimumSize = 0.2f;

            Vector3 min, max;
            if (cutter.Cut(shape, new Vector4(plane.Normal.X, plane.Normal.Y, plane.Normal.Z, plane.D), out min, out max))
            {
                var aabb = new BoundingBox(min, max);
                aabb.InflateToMinimum(new Vector3(minimumSize));
                float centerOffset = gridSize * 0.5f;
                //    VRageRender.MyRenderProxy.DebugDrawOBB(boxC, Color.Red, 0.02f, true, false);

                MyCubeBlockDefinition.MountPoint mountPoint = new MyCubeBlockDefinition.MountPoint();
                mountPoint.Normal = new Vector3I(direction);
                mountPoint.Start = (aabb.Min + new Vector3(centerOffset)) / gridSize;
                mountPoint.End = (aabb.Max + new Vector3(centerOffset)) / gridSize;
				mountPoint.Enabled = true;
                //because it didnt work if shape wasnt realy near the edge
                var zExt = Vector3.Abs(direction) * mountPoint.Start;
                bool add = zExt.AbsMax() > 0.5f;
                mountPoint.Start -= zExt;
                mountPoint.Start -= direction * 0.04f;
                mountPoint.End -= Vector3.Abs(direction) * mountPoint.End;
                mountPoint.End += direction * 0.04f;
                if (add)
                {
                    mountPoint.Start += Vector3.Abs(direction);
                    mountPoint.End += Vector3.Abs(direction);
                }
                mountPoints.Add(mountPoint);

                return true;
            }

            return false;
        }