Difference between revisions of "User:Pedro Oval/GIMP Layers to SL Animated Texture"

From Second Life Wiki
Jump to navigation Jump to search
(Update to 1.1pre3)
(Main updated to 2.0; no news here)
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
== Development version ==
== Development version ==
<scheme>
; Layers to SL Texture Animation, version 1.1pre3.
;
; Written by Pedro Oval, 2010-12-04.
; Donated to the public domain.
; Thanks to Digital Dharma for the suggestions.


(define (script-fu-layers-to-sl-anim curimg curdrawable xframes yframes showscript fps)
No changes with respect to the [[GIMP Layers to SL Animated Texture|stable version]] yet.
 
  ; Read the layer IDs and the total number of layers from the original image.
  (define layerset (gimp-image-get-layers curimg))
  (define numframes (car layerset))
  (set! layerset (cadr layerset))
 
  ; The frame size X and Y is the size of the original image.
  (define framesizex (car (gimp-image-width curimg)))
  (define framesizey (car (gimp-image-height curimg)))
 
  ; Get the image type; indexed images need special treatment.
  (define imgtype (car (gimp-image-base-type curimg)))
 
  ; Check if the given number of horizontal x vertical frames matches
  ; the number of layers in the original image. If yes, proceed; if not,
  ; show an error message.
  (if (= numframes (* xframes yframes))
    (begin
      ; New image
      (define img (car (gimp-image-new (* framesizex xframes) (* framesizey yframes) imgtype)))
      ; We don't touch the original image, so we start a new undo group
      ; for the new image instead.
      (gimp-image-undo-group-start img)
 
      (if (= imgtype INDEXED)
        (begin
          ; Indexed images need the palette to be copied to the new image.
          (define palette (gimp-image-get-colormap curimg))
          (gimp-image-set-colormap img (car palette) (cadr palette))))
 
      ; Loop betwen 0 and numframes - 1.
      (define frame 0)
      (while (< frame numframes)
        ; For each layer/frame:
        (begin
 
          ; Show progress as the current frame relative to the number of frames.
          (gimp-progress-update (/ frame numframes))
 
          ; Read the individual layer ID, starting from the bottom.
          (define oldlayer (vector-ref layerset (- numframes frame 1)))
 
          ; Create new layer as a copy of this one and add it to the image.
          (define newlayer (car (gimp-layer-new-from-drawable oldlayer img)))
          (gimp-image-add-layer img newlayer -1)
 
          ; Add alpha if the layer doesn't have it.
          (if (= (car (gimp-drawable-has-alpha newlayer)) FALSE)
            (gimp-layer-add-alpha newlayer))
 
          ; Calculate the offsets and crop size.
          (define offsets (gimp-drawable-offsets oldlayer))
          (define newsizex (car (gimp-drawable-width oldlayer)))
          (define newsizey (car (gimp-drawable-height oldlayer)))
          (define offsetx (car offsets))
          (define offsety (cadr offsets))
          (if (< offsetx 0)
            (begin
              (set! newsizex (+ newsizex offsetx))
              (set! offsetx 0)))
          (if (< offsety 0)
            (begin
              (set! newsizey (+ newsizey offsety))
              (set! offsety 0)))
          (if (> (+ offsetx newsizex) framesizex)
            (set! newsizex (- framesizex offsetx)))
          (if (> (+ offsety newsizey) framesizey)
            (set! newsizey (- framesizey offsety)))
 
          ; Calculate frame position X and Y.
          (define framey (truncate (/ frame xframes)))
          (define framex (- frame (* framey xframes)))
          (set! framex (* framex framesizex))
          (set! framey (* framey framesizey))
 
          ; Resize and place the layer.
          (gimp-layer-resize newlayer
                            newsizex
                            newsizey
                            (- (car offsets) offsetx)
                            (- (cadr offsets) offsety))
          (gimp-layer-set-offsets newlayer (+ framex offsetx) (+ framey offsety))
 
          ; Force it visible.
          (gimp-drawable-set-visible newlayer TRUE)
 
          ; All done. Next loop iteration.
          (set! frame (+ frame 1))))
 
      ; Progress 100%
      (gimp-progress-update 1.0)
 
      ; Merge visible layers (all are visible now).
      (define mergedlayer (car (gimp-image-merge-visible-layers img CLIP-TO-IMAGE)))
 
      ; Make the new layer the size of the image.
      (gimp-layer-resize-to-image-size mergedlayer)
 
      ; Convert the image to RGB if it is not already.
      (if (not (= imgtype RGB))
        (gimp-image-convert-rgb img))
 
      ; All done - close the undo group and add a display for the new image.
      (gimp-image-undo-group-end img)
      (gimp-display-new img)
 
      ; Show the script if requested
      (if (= showscript TRUE)
        (gimp-message (string-append "default\n{\n    state_entry()\n    {\n"
                                    "        llSetTextureAnim(ANIM_ON | LOOP, "
                                    (number->string xframes)
                                    ", "
                                    (number->string yframes)
                                    ", 0.0, "
                                    (number->string (* xframes yframes))
                                    ".0, "
                                    (number->string fps)
                                    ");\n    }\n}\n"))))
 
    ; If the frame counts didn't match...
    (gimp-message "Error: Number of layers doesn't match horizontal x vertical frames")))
 
; Register the function.
(script-fu-register "script-fu-layers-to-sl-anim"
                    _"<Image>/Script-Fu/SecondLife/Frames to texture..."
                    _"Convert a set of layers (frames) to a texture suitable for llSetTextureAnim."
                    "Pedro Oval"
                    _"Public Domain"
                    "2010-12-04"
                    "RGB*, GRAY*, INDEXED*"
                    SF-IMAGE        "Image"        0
                    SF-DRAWABLE    "Drawable"    0
                    SF-ADJUSTMENT  _"# of horizontal frames" '(2 1 1024 1 10 0 1)
                    SF-ADJUSTMENT  _"# of vertical frames"  '(2 1 1024 1 10 0 1)
                    SF-TOGGLE      _"Generate LSL script?"  TRUE
                    SF-VALUE        _"Frames per second (for script):" "10.0")
</scheme>
 
New in this version with respect to the stable one:
 
* Add progress indicator.
* Clip each layer to its rectangle.
* Respect the original offsets of layers.
* Do the merge down in the correct order.
* Add alpha to the layers that lack it.
* Set the final layer's size to the image's size.
* Extensively commented.
* Generate the LSL script.


== TODO list ==
== TODO list ==


* Automatically remove alpha from the final image if not needed.
* Perhaps change the strategy to use gimp-image-duplicate to simplify the process.
* Perhaps change the strategy to use gimp-image-duplicate to simplify the process.
* Add the opposite conversion: given an animated texture, split it into layers.
* Add the opposite conversion: given an animated texture, split it into layers.
* Read the layer name to see if it includes the word "(combine)", and if so, combine it.

Latest revision as of 17:44, 21 December 2010

Development version

No changes with respect to the stable version yet.

TODO list

  • Perhaps change the strategy to use gimp-image-duplicate to simplify the process.
  • Add the opposite conversion: given an animated texture, split it into layers.