protected bool GetBlockAddPosition(float gridSize, bool placingSmallGridOnLargeStatic, out MySlimBlock intersectedBlock, out Vector3D intersectedBlockPos, out Vector3D intersectExactPos,
                                           out Vector3I addPositionBlock, out Vector3I addDirectionBlock, out ushort?compoundBlockId)
        {
            intersectedBlock    = null;
            intersectedBlockPos = new Vector3D();
            intersectExactPos   = new Vector3();
            addDirectionBlock   = new Vector3I();
            addPositionBlock    = new Vector3I();
            compoundBlockId     = null;

            if (CurrentVoxelBase != null)
            {
                Vector3 hitInfoNormal = m_hitInfo.Value.HkHitInfo.Normal;
                Base6Directions.Direction closestDir = Base6Directions.GetClosestDirection(hitInfoNormal);
                Vector3I hitNormal = Base6Directions.GetIntVector(closestDir);

                double distance = IntersectionDistance * m_hitInfo.Value.HkHitInfo.HitFraction;

                Vector3D rayStart     = IntersectionStart;
                Vector3D rayDir       = Vector3D.Normalize(IntersectionDirection);
                Vector3D intersection = rayStart + distance * rayDir;

                // Get cube block placement position (add little threshold to hit normal direction to avoid wavy surfaces).
                addPositionBlock    = MyCubeGrid.StaticGlobalGrid_WorldToUGInt(intersection + 0.1f * Vector3.Half * hitNormal * gridSize, gridSize, CubeBuilderDefinition.BuildingSettings.StaticGridAlignToCenter);
                addDirectionBlock   = hitNormal;
                intersectedBlockPos = addPositionBlock - hitNormal;

                // Exact intersection in uniform grid coords.
                intersectExactPos = MyCubeGrid.StaticGlobalGrid_WorldToUG(intersection, gridSize, CubeBuilderDefinition.BuildingSettings.StaticGridAlignToCenter);
                // Project exact intersection to cube face of intersected block.
                intersectExactPos = ((Vector3.One - Vector3.Abs(hitNormal)) * intersectExactPos) + ((intersectedBlockPos + 0.5f * hitNormal) * Vector3.Abs(hitNormal));

                return(true);
            }

            Vector3D?intersectedObjectPos = GetIntersectedBlockData(ref m_invGridWorldMatrix, out intersectExactPos, out intersectedBlock, out compoundBlockId);

            if (intersectedObjectPos == null)
            {
                return(false);
            }

            intersectedBlockPos = intersectedObjectPos.Value;

            Vector3I removePos;

            if (!GetCubeAddAndRemovePositions(Vector3I.Round(intersectedBlockPos), placingSmallGridOnLargeStatic, out addPositionBlock, out addDirectionBlock, out removePos))
            {
                return(false);
            }

            if (!placingSmallGridOnLargeStatic)
            {
                if (MyFakes.ENABLE_BLOCK_PLACING_ON_INTERSECTED_POSITION)
                {
                    Vector3I newRemovepos = Vector3I.Round(intersectedBlockPos);

                    if (newRemovepos != removePos)
                    {
                        if (m_hitInfo.HasValue)
                        {
                            Vector3 hitInfoNormal = m_hitInfo.Value.HkHitInfo.Normal;
                            Base6Directions.Direction closestDir = Base6Directions.GetClosestDirection(hitInfoNormal);
                            Vector3I hitNormal = Base6Directions.GetIntVector(closestDir);
                            addDirectionBlock = hitNormal;
                        }
                        removePos        = newRemovepos;
                        addPositionBlock = removePos + addDirectionBlock;
                    }
                }
                else
                {
                    if (CurrentGrid.CubeExists(addPositionBlock))
                    {
                        return(false);
                    }
                }
            }

            if (placingSmallGridOnLargeStatic)
            {
                removePos = Vector3I.Round(intersectedBlockPos);
            }

            intersectedBlockPos = removePos;
            intersectedBlock    = CurrentGrid.GetCubeBlock(removePos);
            if (intersectedBlock == null)
            {
                Debug.Assert(false, "No intersected block");
                return(false);
            }

            return(true);
        }
Пример #2
0
        protected bool GetBlockAddPosition(float gridSize, bool placingSmallGridOnLargeStatic, out MySlimBlock intersectedBlock, out Vector3D intersectedBlockPos, out Vector3D intersectExactPos, out Vector3I addPositionBlock, out Vector3I addDirectionBlock, out ushort?compoundBlockId)
        {
            Vector3I vectori;

            intersectedBlock    = null;
            intersectedBlockPos = new Vector3D();
            Vector3 vector = new Vector3();

            intersectExactPos = vector;
            addDirectionBlock = new Vector3I();
            addPositionBlock  = new Vector3I();
            compoundBlockId   = 0;
            if (this.CurrentVoxelBase != null)
            {
                Vector3I intVector = Base6Directions.GetIntVector(Base6Directions.GetClosestDirection(this.m_hitInfo.Value.HkHitInfo.Normal));
                Vector3D worldPos  = IntersectionStart + ((IntersectionDistance * this.m_hitInfo.Value.HkHitInfo.HitFraction) * Vector3D.Normalize(IntersectionDirection));
                addPositionBlock    = MyCubeGrid.StaticGlobalGrid_WorldToUGInt(worldPos + (((0.1f * Vector3.Half) * intVector) * gridSize), gridSize, CubeBuilderDefinition.BuildingSettings.StaticGridAlignToCenter);
                addDirectionBlock   = intVector;
                intersectedBlockPos = (Vector3D)(addPositionBlock - intVector);
                intersectExactPos   = MyCubeGrid.StaticGlobalGrid_WorldToUG(worldPos, gridSize, CubeBuilderDefinition.BuildingSettings.StaticGridAlignToCenter);
                intersectExactPos   = ((Vector3D.One - Vector3.Abs((Vector3)intVector)) * intersectExactPos) + ((intersectedBlockPos + (0.5f * intVector)) * Vector3.Abs((Vector3)intVector));
                return(true);
            }
            Vector3D?nullable = this.GetIntersectedBlockData(ref this.m_invGridWorldMatrix, out intersectExactPos, out intersectedBlock, out compoundBlockId);

            if (nullable == null)
            {
                return(false);
            }
            intersectedBlockPos = nullable.Value;
            if (!this.GetCubeAddAndRemovePositions(Vector3I.Round(intersectedBlockPos), placingSmallGridOnLargeStatic, out addPositionBlock, out addDirectionBlock, out vectori))
            {
                return(false);
            }
            if (!placingSmallGridOnLargeStatic)
            {
                if (!MyFakes.ENABLE_BLOCK_PLACING_ON_INTERSECTED_POSITION)
                {
                    if (this.CurrentGrid.CubeExists(addPositionBlock))
                    {
                        return(false);
                    }
                }
                else
                {
                    Vector3I vectori3 = Vector3I.Round(intersectedBlockPos);
                    if (vectori3 != vectori)
                    {
                        if (this.m_hitInfo != null)
                        {
                            Vector3I intVector = Base6Directions.GetIntVector(Base6Directions.GetClosestDirection(this.m_hitInfo.Value.HkHitInfo.Normal));
                            addDirectionBlock = intVector;
                        }
                        vectori          = vectori3;
                        addPositionBlock = (Vector3I)(vectori + addDirectionBlock);
                    }
                }
            }
            if (placingSmallGridOnLargeStatic)
            {
                vectori = Vector3I.Round(intersectedBlockPos);
            }
            intersectedBlockPos = (Vector3D)vectori;
            intersectedBlock    = this.CurrentGrid.GetCubeBlock(vectori);
            return(intersectedBlock != null);
        }