Find X,Y,Z coordinates from index

Python 3, 150 140 bytes

def f(n):
 a=b=x=y=z=0
 for i in range(n):
  a=x-~x<y--~z//2*6+z%2
  b=z<y//6+-~y//6
  x=-~x*a
  y+=not(a|b)
  z+=b>a
  z*=a|b
 return x,y,z

Try it online!

Has \$O(n)\$ complexity. TIO footer prints first 720 values in about 0.5 seconds.

Thanks to @ElPedro and @PrincePolka for each saving 5 bytes!


Jelly, 31 bytes

5,1ṁ9ĖŒṙṚḊḊḊ$Ƭz0ZUṬ€€ỊŒṪ’ṙÞ1ị@‘

A monadic link accepting an integer in \$[0,719]\$ which yields a list of three integers \$[X, Y, Z]\$.

Try it online!

Or see the test-suite (which completes in around 12-20s on TIO)

How?

Builds a lookup table and indexes into it:

5,1ṁ9ĖŒṙṚḊḊḊ$Ƭz0ZUṬ€€ỊŒṪ’ṙÞ1ị@‘ - Link: integer, n
5,1                             - pair literal = [5,1]
   ṁ9                           - mould like 9 = [5,1,5,1,5,1,5,1,5]
     Ė                          - enumerate = [[1,5],[2,1],[3,5],[4,1],[5,5],[6,1],[7,5],[8,1],[9,5]]
      Œṙ                        - run-length-decode = [1,1,1,1,1,2,3,...,7,7,7,7,7,8,9,9,9,9,9]
        Ṛ                       - reverse = [9,9,9,9,9,8,7,7,7,7,7,...,3,2,1,1,1,1,1]
         Ḋ                      - dequeue = [9,9,9,9,8,7,7,7,7,7,...,3,2,1,1,1,1,1]
             Ƭ                  - collect until a fixed-point:
            $                   -   last two links as a monad:
          Ḋ                     -     dequeue
           Ḋ                    -     dequeue
                                - } = [[9,9,9,9,8,7,7,7,7,7,...,3,2,1,1,1,1,1],[9,9,8,7,...],[8,7,...],...,[1,1],[]]
              z0                - transpose with filler zero
                Z               - transpose
                 U              - reverse each list
                  Ṭ€€           - un-truth each int (e.g. 5 -> [0,0,0,0,1])
                     Ị          - insignificant? (abs(x)<=1) (e.g. [0,0,0,0,1]->[1,1,1,1,1])
                      ŒṪ        - truthy multi-dimensional 1-indexed indices
                        ’       - decrement (i.e. all the [X,Y,Z] values)
                          Þ     - sort by:
                         ṙ 1    -   the list value rotated left by one (i.e. by [Y,Z,X])
                              ‘ - increment (n) (since Jelly is 1-indexed)
                             @  - with swapped arguments:
                            ị   -   index into

JavaScript, 93 85 bytes

A port of Nick's Python solution.

n=>(g=x=>n--?g(x<y+~z/2n*6n+z%2n>>1n?++x:z<y/6n-~y/6n?++z-z:z=++y-y):[x,y,z])(y=z=0n)

Try It Online!

Saved 8 bytes thank to Arnauld's suggestion of using BigInts, plus a couple of other tweaks.