コード例 #1
0
        /// <summary>
        /// Calculates exact intersection point (in uniform grid coordinates) from stored havok's hit info object obtained during FindClosest grid.
        /// Returns position of intersected object in uniform grid coordinates.
        /// </summary>
        protected Vector3D?GetIntersectedBlockData(ref MatrixD inverseGridWorldMatrix, out Vector3D intersection, out MySlimBlock intersectedBlock, out ushort?compoundBlockId)
        {
            Debug.Assert(m_hitInfo != null);
            Debug.Assert(m_hitInfo.Value.HkHitInfo.Body.GetEntity() == CurrentGrid);

            intersection     = Vector3D.Zero;
            intersectedBlock = null;
            compoundBlockId  = null;

            double   distance             = double.MaxValue;
            Vector3D?intersectedObjectPos = null;

            var      line     = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * IntersectionDistance);
            Vector3I position = Vector3I.Zero;

            if (!CurrentGrid.GetLineIntersectionExactGrid(ref line, ref position, ref distance, m_hitInfo.Value))
            {
                return(null);
            }

            distance             = Math.Sqrt(distance);
            intersectedObjectPos = position;

            intersectedBlock = CurrentGrid.GetCubeBlock(position);
            if (intersectedBlock == null)
            {
                return(null);
            }

            // Compound block - get index of internal block for removing
            if (intersectedBlock.FatBlock is MyCompoundCubeBlock)
            {
                MyCompoundCubeBlock compoundBlock = intersectedBlock.FatBlock as MyCompoundCubeBlock;
                ushort?idInCompound = null;

                ushort blockId;
                MyIntersectionResultLineTriangleEx?triIntersection;

                if (compoundBlock.GetIntersectionWithLine(ref line, out triIntersection, out blockId))
                {
                    idInCompound = blockId;
                }
                else if (compoundBlock.GetBlocksCount() == 1) // If not intersecting with any internal block and there is only one then set the index to it
                {
                    idInCompound = compoundBlock.GetBlockId(compoundBlock.GetBlocks()[0]);
                }

                compoundBlockId = idInCompound;
            }

            Debug.Assert(intersectedObjectPos != null);
            Vector3D rayStart = Vector3D.Transform(IntersectionStart, inverseGridWorldMatrix);
            Vector3D rayDir   = Vector3D.Normalize(Vector3D.TransformNormal(IntersectionDirection, inverseGridWorldMatrix));

            intersection  = rayStart + distance * rayDir;
            intersection *= 1.0f / CurrentGrid.GridSize;

            return(intersectedObjectPos);
        }
コード例 #2
0
        /// <summary>
        /// Calculates exact intersection point (in uniform grid coordinates) from stored havok's hit info object obtained during FindClosest grid.
        /// Returns position of intersected object in uniform grid coordinates.
        /// </summary>
        protected Vector3D?GetIntersectedBlockData(ref MatrixD inverseGridWorldMatrix, out Vector3D intersection, out MySlimBlock intersectedBlock, out ushort?compoundBlockId)
        {
            Debug.Assert(m_hitInfo != null);
            Debug.Assert(m_hitInfo.Value.HkHitInfo.Body.GetEntity() == CurrentGrid);

            intersection     = Vector3D.Zero;
            intersectedBlock = null;
            compoundBlockId  = null;

            double   distance             = double.MaxValue;
            Vector3D?intersectedObjectPos = null;

            var      line     = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * IntersectionDistance);
            Vector3I position = Vector3I.Zero;

            if (!CurrentGrid.GetLineIntersectionExactGrid(ref line, ref position, ref distance, m_hitInfo.Value))
            {
                return(null);
            }

            distance             = Math.Sqrt(distance);
            intersectedObjectPos = position;

            intersectedBlock = CurrentGrid.GetCubeBlock(position);
            if (intersectedBlock == null)
            {
                return(null);
            }

            // Compound block - get index of internal block for removing
            if (intersectedBlock.FatBlock is MyCompoundCubeBlock)
            {
                MyCompoundCubeBlock      compoundBlock        = intersectedBlock.FatBlock as MyCompoundCubeBlock;
                ListReader <MySlimBlock> slimBlocksInCompound = compoundBlock.GetBlocks();
                double distanceSquaredInCompound = double.MaxValue;
                ushort?idInCompound = null;
                for (int i = 0; i < slimBlocksInCompound.Count; ++i)
                {
                    MySlimBlock cmpSlimBlock = slimBlocksInCompound.ItemAt(i);
                    MyIntersectionResultLineTriangleEx?intersectionTriResult;
                    if (cmpSlimBlock.FatBlock.GetIntersectionWithLine(ref line, out intersectionTriResult) && intersectionTriResult != null)
                    {
                        Vector3D startToIntersection = intersectionTriResult.Value.IntersectionPointInWorldSpace - IntersectionStart;
                        double   instrDistanceSq     = startToIntersection.LengthSquared();
                        if (instrDistanceSq < distanceSquaredInCompound)
                        {
                            distanceSquaredInCompound = instrDistanceSq;
                            idInCompound = compoundBlock.GetBlockId(cmpSlimBlock);
                        }
                    }
                }

                // If not intersecting with any internal block and there is only one then set the index to it
                if (idInCompound == null && compoundBlock.GetBlocksCount() == 1)
                {
                    idInCompound = compoundBlock.GetBlockId(compoundBlock.GetBlocks()[0]);
                }

                compoundBlockId = idInCompound;
            }

            Debug.Assert(intersectedObjectPos != null);
            Vector3D rayStart = Vector3D.Transform(IntersectionStart, inverseGridWorldMatrix);
            Vector3D rayDir   = Vector3D.Normalize(Vector3D.TransformNormal(IntersectionDirection, inverseGridWorldMatrix));

            intersection  = rayStart + distance * rayDir;
            intersection *= 1.0f / CurrentGrid.GridSize;

            return(intersectedObjectPos);
        }