Creating a Sprite Rotation Map with Gimp

25-Feb-2020 01:20AM

So, I used the Gimp Script-Fu stuff, and it's hard/easy. The easy part, thankfully is using it. Like any Lisp language it's ridiculously powerful and defining new syntax is cheaper than chips. The hard part is the lack of quality documentation on it's use/api.

The documentation on the gimp website is mostly just a Scheme[1] tutorial which doesn't really give enough information on how to use it properly, and while browsing through the inbuilt script-fu console will be your go-to on working out how to do something, there is some vagueness on questions like "How does script-fu implement image layers?[2]", "What is a drawable?[3]", "What is the difference between a drawable and a layer?[4]"

So here is the important part. The code will only work if your image is a square big enough so your image can rotate without losing the edges, but it will create a very wide image with 360 different rotation angles on it. (This was all I needed for the project I was using, so I couldn't be bothered to make it dynamic. If anyone makes an improved version of this, poke me so I can link to it.)

;;As scheme doesn't have a Pi function, I just used the magic number for 2Pi
(define (degrees->radians degrees)
  (* 6.28318530717959 (/ degrees 360.0)))

(define (sprite-rotation-map inImage inLayer)
  ;;Declare a bunch of variables
  (let* ((width (car (gimp-image-width inImage)))
         (mid (/ width 2))
         (degrees 1)
         (newlayer 0))

  (gimp-image-resize inImage (* 360 width) (car (gimp-image-height inImage)) 0 0)

  ;;Draw many rotated boats
  (while (< degrees 360)
    ;;Copy the first image layer and add the copy to the image
    (set! newlayer (car (gimp-layer-copy inLayer TRUE)))
    (gimp-image-add-layer inImage newlayer -1)
    ;;Rotate the layer to the correct angle
    (gimp-drawable-transform-rotate newlayer (degrees->radians degrees) FALSE mid mid TRANSFORM-FORWARD INTERPOLATION-LINEAR TRUE 3 TRANSFORM-RESIZE-CLIP)
    ;;Move the layer to the correct position
    (gimp-layer-set-offsets newlayer (* degrees width) 0)
    ;;Increment the iterator
    (set! degrees (+ 1 degrees)))))

;;Register the function so it's accessible from the Filters menu
(script-fu-register "sprite-rotation-map"
      "<img />/Filters/_danielkeogh.com/_SpriteRotationMap"
      "Multiple smaller copies of image arranged in a spiral"
      "Daniel Keogh"
      "(c) Daniel Keogh"
      "Feb 2012"
      "RGB*"
      SF-IMAGE "Image"  0
      SF-DRAWABLE "Drawable" 0)
`Feel free to copy this code and abuse it however you will. Credit me if you want, but I'm not that hung up on credit anyways.

Peace out.

[1]: For those not in the know-how, Scheme is a dialect of a programming language called Lisp.

[2]: Each layer is represented by an enumeration, which pretty much means some positive integer. The bottom layer is 0, and respective layers are 1+ on top of that.

[3]: A "drawable" is one of those funny boxes surrounded by dotted lines that show's the area that can be drawn on for a particular layer/image. Layers are "drawable" by default, but only the part of the layer that has an image on it.

[4]: As a newb, I'm not totally sure about this. All layers are drawable's, but possibly not vice versa. What I can say before, is if you manipulate the contents of a drawable, you're only manipulating the area inside the little selector box thingy, but if you manipulate a layer, it can affect the whole image.