#-*- coding: UTF-8 -*-
import os
from string import Template
import re
texture = Template("""
<texture name=\"$NAME\">
<file>$FILE</file>
</texture>
""")
material = Template("""
<material name=\"$NAME\">
<texture>$TEXTURE</texture>
$OPTIONS
</material>
""")
library = Template("""
<library>
$FACTORIES
</library>
""")
world = Template("""
<world>
<textures>
$TEXTURES
</textures>
<materials>
$MATERIALS
</materials>
$LIBARIES
$FACTORIES
<settings>
<clearzbuf>yes</clearzbuf>
<clearscreen>yes</clearscreen>
</settings>
<start name=\"Camera\">
<sector>Scene</sector>
<position x=\"0\" y=\"0\" z=\"-5\" />
</start>
<sector name=\"Scene\">
$OBJECTS
<light name=\"Lamp\">
<center x=\"0\" y=\"5\" z=\"0\" />
<color red=\"0.9\" green=\"0.9\" blue=\"1.0\" />
<radius>50</radius>
<attenuation c=\"0\" l=\"0\" q=\"0.1\" />
</light>
</sector>
</world>
""")
factory = Template("""
<meshfact name=\"$NAME\">
<plugin>$PLUGIN</plugin>
<params>
$PARAMS
</params>
</meshfact>
""")
object = Template("""
<meshobj name=\"$NAME\">
<plugin>$PLUGIN</plugin>
<params>
<factory>$FACTORY</factory>
</params>
</meshobj>
""")
renderbuffer = Template("""
<$TAG name=\"$NAME\" $EXTRA components=\"$NR\" type=\"$TYPE\">
$CONTENTS
</$TAG>
""")
def RenderBuffer(name, nr, type, contents, extra="checkelementcount=\"no\"", tag="renderbuffer"):
text = ""
for c in contents:
text += c + "\n"
return renderbuffer.substitute(NAME=name, NR=nr, TYPE=type, CONTENTS=text, EXTRA=extra, TAG=tag)
def IndexBuffer(contents, tag="indexbuffer"):
text = ""
for c in contents:
text += c + "\n"
return renderbuffer.substitute(NAME="index", NR=1, TYPE="uint", CONTENTS=text, EXTRA="indices=\"yes\"", TAG=tag)
def Element(v):
text = "<e "
for i,e in enumerate(v):
text += "c"+str(i)+"=\"" + str(e) + "\" "
return text + "/>"
def Factory(name, plugin, params):
text = factory.substitute(NAME=str(name), PLUGIN=plugin, PARAMS=params)
return text
def Object(name, plugin, factory):
plugin = plugin.replace(".factory", "")
text = object.substitute(NAME=str(name), PLUGIN=plugin, FACTORY=factory)
return text
def Change(bool, name):
def blah(*args):
if bool:
args = args + ("", name, )
return RenderBuffer(*args)
return blah
def group(lst, n):
import itertools
"""group([0,3,4,10,2,3], 2) => iterator
Group an iterable into an n-tuples iterable. Incomplete tuples
are discarded e.g.
>>> list(group(range(10), 3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]
"""
return itertools.izip(*[itertools.islice(lst, i, None, n) for i in range(n)])
def main():
model = open("data/3dobjs/base.obj", 'r')
plugin = "crystalspace.mesh.loader.factory.animesh"
textures = ""
materials = ""
factories = ""
objects = ""
size = [0.25, 0.25, 0.25]
vertices=[]
tc=[]
tcnew=[]
currentsub = "main"
indicess={}
for line in model.readlines():
if line.startswith('v '):
m = re.findall("[+-]?\d+\.\d+", line)
m = [s*float(v) for v,s in zip(m, size)]
vertices.append(Element(m))
elif line.startswith('vt '):
m = re.findall("[+-]?\d+\.\d+", line)
tc.append(Element(m))
elif line.startswith('g '):
#currentsub = line.split(" ")[1] # disabled submeshes, put everything in 'main' submesh
if currentsub not in indicess.keys():
indicess[currentsub] = []
elif line.startswith('f '):
m = re.findall("\d+", line)
m = group(m, 2)
m = [(int(x)-1, int(y)-1) for x, y in m] # obj is 1 based, cs is 0 based, so -1
if len(tcnew) < len(tc):
tcnew = len(tc)*['<e c0="0.0" c1="0.0" />']
for v, t in m:
tcnew[v] = tc[t]
#triangulate
tt = [0,1,2] if len(m)==3 else [0, 1, 2, 3, 0, 2]
for i in tt:
e = m[i][0]
indicess[currentsub].append(Element([e]))
data = ""
RenderBufferP = Change(True, "vertex")
data += RenderBufferP("position", 3, "float", vertices)
RenderBufferP = Change(True, "texcoord")
data += RenderBufferP("texture coordinate 0", 2, "float", tcnew)
data += "<boneinfluences>\n"
for i in range(len(vertices)*4):
data += ' <bi bone="%d" weight="%.4f"/>\n' % (0, 0.0)
data += "</boneinfluences>\n"
for name in indicess:
data += "<submesh name=\""+name.strip()+"\">" + "<material>skin</material>" + IndexBuffer(indicess[name],"index") +"</submesh>\n"
data += "<skeleton>rig</skeleton>"
morphtargets={}
import os, glob
for target in glob.glob( os.path.join('data/targets/macrodetails/', 'universal-*.target') ):
name = os.path.splitext(os.path.basename(target))[0]
targetf = open(target, 'r')
print "Converting target:", target
morphtargets[name] = len(vertices)*['<e c0="0.0" c1="0.0" c2="0.0" />']
for line in targetf.readlines():
i = int(re.findall("\d+", line)[0])
m = re.findall("[+-]?\d+\.\d+", line)
m = [s*float(v) for v,s in zip(m, size)]
morphtargets[name][i] = Element(m)
targetf.close()
RenderBufferP = Change(True, "offsets")
for name in morphtargets:
data += "<morphtarget name=\""+name.strip()+"\">" + RenderBufferP("", 3, "float", morphtargets[name]) +"</morphtarget>\n"
factories += "<textures><texture name=\"skin\"><file>skin.png</file></texture></textures>"
factories += "<materials><material name=\"skin\"><texture>skin</texture></material></materials>"
factories += "<library>rig</library>\n"
factories += Factory("testf", plugin, data) + "\n"
objects += Object("test", plugin, "testf") + "\n"
text = library.substitute(FACTORIES=factories)
f = open('factory', 'w')
f.write(text)
f.close()
libaries = "<library>factory</library>"
text = world.substitute(TEXTURES=textures, MATERIALS=materials, LIBARIES=libaries, OBJECTS=objects, FACTORIES="")
f = open('world', 'w')
f.write(text)
f.close()
if __name__ == "__main__":
main()