コード例 #1
0
ファイル: Graphics.cs プロジェクト: carriercomm/CubeWorld
        static public RaycastTileResult RaycastTile(World.CubeWorld world, Vector3 from, Vector3 fwd, float maxDistance, bool ignoreNonSolid, bool ignoreNonClickable)
        {
            Vector3 pos = from;

            RaycastTileResult result = new RaycastTileResult();
			
			TileManager tileManager = world.tileManager;

            while (true)
            {
                Vector3 near = pos;

                //Find near planes
                for (int d = 0; d < 3; d++)
                {
                    near[d] = (float) Math.Round(near[d] / Graphics.TILE_SIZE) * Graphics.TILE_SIZE;
                    near[d] += Graphics.HALF_TILE_SIZE * Math.Sign(fwd[d]);
                }

                //Calculate nearest plane
                float[] ns = new float[3];

                for (int d = 0; d < 3; d++)
                {
                    if (fwd[d] != 0.0f)
                        ns[d] = (near[d] - pos[d]) / fwd[d];
                    else
                        ns[d] = 1.0f;
                }

                float minN = ns[0];
                int lockedAxis = 0;

                for (int d = 1; d < 3; d++)
                {
                    if (ns[d] < minN)
                    {
                        minN = ns[d];
                        lockedAxis = d;
                    }
                }

                //Advance until the border of the nearest plane
                pos += fwd * minN;

                if ((pos - from).magnitude >= maxDistance)
                    break;

                //See what tile is there
                Vector3 d2 = new Vector3();
                d2[lockedAxis] = Math.Sign(fwd[lockedAxis]) * Graphics.QUART_TILE_SIZE;

                TilePosition cursorPosition = Graphics.Vector3ToTilePosition(pos + d2);

                //Advance a little to stop the next loop from selecting the same tile / border
                pos += fwd * Graphics.TILE_SIZE * 0.0001f;


                //Now validate what to do :-)

                if (tileManager.IsValidTile(cursorPosition))
                {
                    byte tileType = tileManager.GetTileType(cursorPosition);

                    if (tileType != TileDefinition.EMPTY_TILE_TYPE &&
                        ((ignoreNonSolid == false || tileManager.GetTileSolid(cursorPosition) == true) ||
                        (ignoreNonClickable == false && 
                         tileManager.GetTileDefinition(tileType).GetRulesForAction(TileActionRule.ActionType.CLICKED) != null)))
                    {
                        switch (lockedAxis)
                        {
                            case 0:
                                if (Math.Sign(fwd[lockedAxis]) > 0)
                                    result.face = Faces.Left;
                                else
                                    result.face = Faces.Right;
                                break;
                            case 1:
                                if (Math.Sign(fwd[lockedAxis]) > 0)
                                    result.face = Faces.Bottom;
                                else
                                    result.face = Faces.Top;
                                break;
                            case 2:
                                if (Math.Sign(fwd[lockedAxis]) > 0)
                                    result.face = Faces.Front;
                                else
                                    result.face = Faces.Back;
                                break;
                        }

                        result.position = cursorPosition;
                        result.hit = true;
                        result.tile = tileManager.GetTile(cursorPosition);
                        break;
                    }
                }
            }

            return result;
        }
コード例 #2
0
        static public RaycastTileResult RaycastTile(World.CubeWorld world, Vector3 from, Vector3 fwd, float maxDistance, bool ignoreNonSolid, bool ignoreNonClickable)
        {
            Vector3 pos = from;

            RaycastTileResult result = new RaycastTileResult();

            TileManager tileManager = world.tileManager;

            while (true)
            {
                Vector3 near = pos;

                //Find near planes
                for (int d = 0; d < 3; d++)
                {
                    near[d]  = (float)Math.Round(near[d] / Graphics.TILE_SIZE) * Graphics.TILE_SIZE;
                    near[d] += Graphics.HALF_TILE_SIZE * Math.Sign(fwd[d]);
                }

                //Calculate nearest plane
                float[] ns = new float[3];

                for (int d = 0; d < 3; d++)
                {
                    if (fwd[d] != 0.0f)
                    {
                        ns[d] = (near[d] - pos[d]) / fwd[d];
                    }
                    else
                    {
                        ns[d] = 1.0f;
                    }
                }

                float minN       = ns[0];
                int   lockedAxis = 0;

                for (int d = 1; d < 3; d++)
                {
                    if (ns[d] < minN)
                    {
                        minN       = ns[d];
                        lockedAxis = d;
                    }
                }

                //Advance until the border of the nearest plane
                pos += fwd * minN;

                if ((pos - from).magnitude >= maxDistance)
                {
                    break;
                }

                //See what tile is there
                Vector3 d2 = new Vector3();
                d2[lockedAxis] = Math.Sign(fwd[lockedAxis]) * Graphics.QUART_TILE_SIZE;

                TilePosition cursorPosition = Graphics.Vector3ToTilePosition(pos + d2);

                //Advance a little to stop the next loop from selecting the same tile / border
                pos += fwd * Graphics.TILE_SIZE * 0.0001f;


                //Now validate what to do :-)

                if (tileManager.IsValidTile(cursorPosition))
                {
                    byte tileType = tileManager.GetTileType(cursorPosition);

                    if (tileType != TileDefinition.EMPTY_TILE_TYPE &&
                        ((ignoreNonSolid == false || tileManager.GetTileSolid(cursorPosition) == true) ||
                         (ignoreNonClickable == false &&
                          tileManager.GetTileDefinition(tileType).GetRulesForAction(TileActionRule.ActionType.CLICKED) != null)))
                    {
                        switch (lockedAxis)
                        {
                        case 0:
                            if (Math.Sign(fwd[lockedAxis]) > 0)
                            {
                                result.face = Faces.Left;
                            }
                            else
                            {
                                result.face = Faces.Right;
                            }
                            break;

                        case 1:
                            if (Math.Sign(fwd[lockedAxis]) > 0)
                            {
                                result.face = Faces.Bottom;
                            }
                            else
                            {
                                result.face = Faces.Top;
                            }
                            break;

                        case 2:
                            if (Math.Sign(fwd[lockedAxis]) > 0)
                            {
                                result.face = Faces.Front;
                            }
                            else
                            {
                                result.face = Faces.Back;
                            }
                            break;
                        }

                        result.position = cursorPosition;
                        result.hit      = true;
                        result.tile     = tileManager.GetTile(cursorPosition);
                        break;
                    }
                }
            }

            return(result);
        }