/// <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); }
/// <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); }