Attempting to create custom exporter

Hey.

I’m no stranger to progamming, but I’ve never used Python, I’m a C++ developer. I’m trying to write my own exporter for a custom format that I’m using in my game. I’ve got all of the indicies exported, as faces and UV co-ordinates too, so far everything is great.

But now, I’m trying to implement animation. I’m just writing out a list of verticies for each frame but keeping the indicies the same. (Similar to MD2). The problem is, when I try to output, all of the vertex data for each frame is exactly the same, as if the model isn’t moving. I’ve made sure that it is, creating my own animation in blender where the gun just moves around for 20 frames. Anyway, here’s my code, any ideas?

import sys, struct, string, math

from types import *

import os
from os import path

import Blender
from Blender import *

import bpy


def write_jmdl(filepath):
    out = file(filepath, 'w')

        totalFrames = Blender.Get("endframe")

        #get the object
        mesh_objs = Blender.Object.GetSelected()

        if len(mesh_objs)==0:
                print "Found nothing"
                result=Blender.Draw.PupMenu("Must select an object to export%t|OK")
                return
            
        obj = mesh_objs[0];
        
        mesh = obj.getData(False,True)
        mesh.getFromObject(obj.name)

        Blender.Set("curframe", 1)



        a = 0
        for vert in mesh.verts:
                a = a + 1
        out.write('%i 
' % (a))
    
        a = 0
        for face in mesh.faces:
                a = a + 1
        out.write('%i 
' % (a))

        out.write('%i 
' % (totalFrames))
         
        for face in mesh.faces:

                a = 0
                for vert in face.v:
                        a = a + 1
                out.write('%i ' % (a))

                v = 0
                for vert in face.v:
                        out.write('%i' % (vert.index))
                        
                        if mesh.vertexUV:
                                out.write( ' %f %f ' % (mesh.verts[vert.index].uvco[0], mesh.verts[vert.index].uvco[1]))
                        elif mesh.faceUV:
                                uv = face.uv[v]
                                out.write( ' %f %f ' % (uv[0], uv[1]))
                        else:
                                out.write( ' %f %f ' % (0, 0))
                        
                        v = v + 1
                                
                out.write('
')

        for frameNum in range(1, totalFrames):
                Blender.Set("curframe", frameNum)

                mesh.getFromObject(obj.name)

                for verta in mesh.verts:
                        out.write( '%f %f %f 
' % (verta.co.x, verta.co.y, verta.co.z))    
                                
                            

    out.close()
Blender.Window.FileSelector(write_jmdl, "Export")

I assume you’re using keyframes/IPO to move the object around? In that case, the vertices stay in their position, locally speaking. That means, from the object center point of view, the vertices arent moving; but the object center itself is moving. Therefore the v.co’s are all the same.
You need to add the object’s coordinations (obj.LocX/LocY/LocZ or obj.getLocation()) to the vertice (or find another way to get the global position of the vertices instead of the local position).

[edit:
instead of looping through a list and using a to count, you can just get the length with len( listname )… so


        a = 0
        for vert in mesh.verts:
                a = a + 1

is the same as:

        a = len( mesh.verts )

Python has a lot of those shortcuts (don’t know about C++ but as far as i know C doesnt have as much).

Right, but what if different parts of the same object are moving differently in the animation? How would I get the correct position of these if I’m just taking the position of the whole object?

If I recall correctly, and you’re trying to do vertex based animation, then you’ll need to grab the raw mesh, i.e. using the NMesh module (despite it being deprecated), for each frame, rather than using Mesh as you seem to be doing now, since that just stores local coordinates.

If you’re doing full object animation (i.e. you only move the object, not the vertexes within via shape-key animation), then it should be enough to grab whatever parameters you need from the IPOs or objects, construct them into a matrix and then apply them to your vertexes.

If using armatures and bones, it will be similar to doing it for the object, just with a little more math involved.

I’ve made modifications for vertex based animation, but still no animation. I’m doing it like so:

        for frameNum in range(1, totalFrames):
                Blender.Set("curframe", frameNum)

                mesh = NMesh.GetRawFromObject(obj.name)

                for verta in mesh.verts:
                        out.write( '%f %f %f 
' % (verta.co.x, verta.co.y, verta.co.z))

This is really starting to jack me off now, I’ve spent way too long on this bloody thing.

I’m now taking the raw mesh data as per the code in the post above and still nothing?! All of the verticies for all the frames are coming out the same, :frowning:

import bpy

scn = bpy.data.scenes.active    #get current scene
ob = scn.objects.active         #get active object
me = ob.getData(mesh = True)    #get the object's mesh
verts = me.verts[:]             #make a copy of its verts
me.transform(ob.matrix)         #transform the verts to world space
for v in me.verts:
    print v                     #print the transformed verts
me.verts = verts                #reset the scene to original data

Great. That’s working. Thanks. :smiley:

A few questions. Isn’t that only doing animation per object? As in, if I was to move individual verticies between key frames would they move? I need per-vertex animation.

Also, why does this make my object a bunch smaller?

EDIT: On top of that, in Blender how do I animate per-vertex in the first place? Say If I want to move like a leg separately from a body? But without buggering about with bones?

A few answers:

It does give you information on vertex-animation. The code above simply prints the information of all verts at the frame you execute it.

I’ve got no idea why it makes your object smaller. I can’t replicate that behaviour, so perhaps you could explain a bit further what is happening?

Per vertex animation: shapekeys. But if you’re talking about moving an entire leg (as in walking) I would recommend to use bones.

imho, you should bugger about with bones one of these days :slight_smile: object global loc/rot/scale and shapekeys are great, but you’ll encounter a limitation in some case (an object that explode in different parts, a simple door…) moreover you can also lead the whole object and shapekeys with bones and action.
you could look at the import BVH script (read/write bone and action datas - import motion cap datas to actions) for usage.