I wrote a short script (at the end of this thread) that has about half (maybe 1/3 is a better estimate) the functionality of what you’re asking for. I could fix it up some more so that it renders you’re key frames like you ask (I got busy with all sorts of projects, and kind of lost track of that script).
The moshing together might be better done by an external script, but since its from Blender, might as well do it there I suppose.
Edit:
import Blender
from Blender import BGL, Camera, Constraint, Image, Mathutils, Object
import bpy
try:
import math
cos = math.cos
sin = math.sin
PI = math.pi
except:
print 'A full python install is required to run this script'
####################################
#
# User Params
#
####################################
# Object to Track To (for camera to follow)
trackOb = 'Suzanne'
# Path to render file, excluding filename
renderPath = '/users/yourplace/rendersomething/' # Must have this end slash!
# Filename to render to
filename = 'temp.png'
XYSteps = 4 #Number of steps in the x-y plane (circular steps)
YZSteps = 1 #Number of steps in the y-z plane, not really currently used, just leave at 1 for now...
startLoc = Mathutils.Vector([4, 0, 0])
# Key Framing
startFrame = 1
endFrame = 11
frameStep = 5
#####################################
def blitImage(dest, source, start):
sourceSize = source.getSize()
for i in xrange(sourceSize[0]):
for j in xrange(sourceSize[1]):
dest.setPixelF(start[0]+i, start[1]+j, source.getPixelF(i, j))
class SceneObject(object):
def __init__(self, scene):
self.scene = scene
def addToScene(self, data, name):
self.ob = self.scene.objects.new(data, name)
return self.ob
def removeFromScene(self):
self.scene.objects.unlink(self.ob)
def setLocation(self, loc):
self.ob.setLocation(*list(loc))
class TrackedCamera(SceneObject):
def __init__(self, scn, type):
SceneObject.__init__(self, scn)
self.__cam = Camera.New(type, 'TrackedCam')
self.__camOb = self.addToScene(self.__cam, 'TrackedCam')
def __del__(self):
self.removeFromScene()
def trackToObject(self, object, track = Constraint.Settings.TRACKNEGZ, up = Constraint.Settings.UPY):
con = self.__camOb.constraints.append(Constraint.Type.TRACKTO)
con[Constraint.Settings.TARGET] = object
con[Constraint.Settings.TRACK] = track
con[Constraint.Settings.UP] = up
def makeActive(self):
self.scene.objects.camera = self.__camOb
########################################
scn = bpy.data.scenes.active
TWOPI = 2*PI
xyStepSize = TWOPI / XYSteps
radius = (startLoc[0]*startLoc[0] + startLoc[1]*startLoc[1])**0.5
tc = TrackedCamera(scn, 'persp')
ob = Object.Get(trackOb)
tc.trackToObject(ob)
tc.setLocation(startLoc)
tc.makeActive()
curXYTheta = Mathutils.AngleBetweenVecs(Mathutils.Vector(radius, 0), Mathutils.Vector(startLoc[0], startLoc[1]))
curXYTheta *= PI/180
rc = tc.scene.getRenderingContext()
xR = rc.imageSizeX()
yR = rc.imageSizeY()
rc.setRenderPath(renderPath)
imageSave = Image.New('Output', xR * (int(((endFrame-startFrame) / frameStep)) + 1), yR * XYSteps, 32)
curXPix = 0
curYPix = 0
curFrame = startFrame
while curFrame <= endFrame:
Blender.Set('curframe', curFrame)
for i in xrange(YZSteps):
zLoc = startLoc[2]
for j in xrange(XYSteps):
xLoc = radius * cos(curXYTheta)
yLoc = radius * sin(curXYTheta)
tc.setLocation([xLoc, yLoc, zLoc])
rc.render()
rc.saveRenderedImage(filename)
rend = Image.Load(renderPath+filename)
rend.reload()
blitImage(imageSave, rend, [curXPix, curYPix])
curXYTheta += xyStepSize
curYPix += yR
curYPix = 0
curXPix += xR
curFrame += frameStep
del tc
imageSave.makeCurrent()
Blender.Redraw(-1)
Should do about what you want. The sprites are stored across for each frame instead of down. It would be possible to change it, though.
Hopefully the parameters are well self-explanatory enough, if not let me know and I’ll be glad to elaborate. Note that it uses the current render size and calculates everything from there. So if you want it 32x32, just set that the normal way. And one more note, you’ll have to save out the image it generates on your own…
Perhaps one day I’ll make GUI and make a proper script of this…