コード例 #1
0
        static bool RayTrace(Game game, Vector3 origin, Vector3 dir, float reach,
                             PickedPos pos, bool clipMode)
        {
            t.SetVectors(origin, dir);
            double   reachSq   = reach * reach;
            Vector3I pOrigin   = Vector3I.Floor(origin);
            bool     insideMap = game.World.IsValidPos(pOrigin);

            Vector3 coords;

            for (int i = 0; i < 10000; i++)
            {
                int x = t.X, y = t.Y, z = t.Z;
                coords.X = x; coords.Y = y; coords.Z = z;
                t.Block  = insideMap ?
                           InsideGetBlock(game.World, x, y, z) : OutsideGetBlock(game.World, x, y, z, pOrigin);

                Vector3I coords2 = new Vector3I(t.X, t.Y, t.Z);

                //Vector3 min = coords + BlockInfo.RenderMinBB[t.Block];
                //Vector3 max = coords + BlockInfo.RenderMaxBB[t.Block];
                Vector3 min = coords + BlockInfo.GetMinBB(game, t.Block, coords2);
                Vector3 max = coords + BlockInfo.GetMaxBB(game, t.Block, coords2);

                double dx = Math.Min(Math.Abs(origin.X - min.X), Math.Abs(origin.X - max.X));
                double dy = Math.Min(Math.Abs(origin.Y - min.Y), Math.Abs(origin.Y - max.Y));
                double dz = Math.Min(Math.Abs(origin.Z - min.Z), Math.Abs(origin.Z - max.Z));
                if (dx * dx + dy * dy + dz * dz > reachSq)
                {
                    return(false);
                }

                t.Min = min; t.Max = max;
                bool intersect = clipMode ? CameraClip(game, pos) : PickBlock(game, pos);
                if (intersect)
                {
                    return(true);
                }
                t.Step();
            }

            throw new InvalidOperationException("did over 10000 iterations in CalculatePickedBlock(). " +
                                                "Something has gone wrong. (dir: " + dir + ")");
        }