Skip to content

Instantly share code, notes, and snippets.

@BitPuffin
Created August 2, 2012 11:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BitPuffin/3236424 to your computer and use it in GitHub Desktop.
Save BitPuffin/3236424 to your computer and use it in GitHub Desktop.
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
import bpy
import bmesh
import sys, os, os.path, struct, math, string, copy
from bpy.props import *
from mathutils import *
# Material class
class Material:
def __init__(self, material, mode, blend):
self.bMaterial = material
self.mode = mode
self.blend = blend
self.id = 0
# Texture class
class Texture:
def __init__(self, texture):
self.bTexture = texture
self.id = 0
# Sub Vertex class
class SubVertex:
def __init__(self, bVert):
self.uvs = {}
self.bVert = bVert
def compare(self, vertex):
for uvLayer in self.uvs:
if not (self.uvs[uvLayer][0] == vertex.uvs[uvLayer][0] and self.uvs[uvLayer][1] == vertex.uvs[uvLayer][1]):
return 0
return 1
# BVertex class
class BVertex:
def __init__(self):
self.subIndices = []
# Display class
class Display:
def __init__(self, begin, size, material, cullFace):
self.begin = begin
self.size = size
self.material = material
self.cullFace = cullFace
# Bone
class Bone:
def __init__(self, id):
self.id = id
# Bone link class
class BoneLink:
def __init__(self, bone, weight):
self.bone = bone
self.weight = weight
# Skin class
class Skin:
def __init__(self, vertIndex):
self.vertIndex = vertIndex
self.bones = []
# Export class
class Export:
def __init__(self, filename, export_maa, export_mta, export_mma):
self.meshFilename = bpy.path.ensure_ext(filename, ".mesh")
self.maaFilename = self.meshFilename.replace(".mesh", ".maa", 1)
self.mmaFilename = self.meshFilename.replace(".mesh", ".mma", 1)
self.mtaFilename = self.meshFilename.replace(".mesh", ".mta", 1)
self.export_maa = export_maa
self.export_mta = export_mta
self.export_mma = export_mma
self.dir = os.path.dirname(self.meshFilename)
self.materialsList = {}
self.texturesList = {}
self.bonesList = {}
self.texSlotsList = {}
def getLocalPath(self, path):
if path[0] != self.dir[0]:
return path
else:
filename = bpy.path.relpath(path, self.dir)
if filename[:2] == "//":
filename = filename[2:]
return filename
def findMin(self, min, point):
_min = copy.copy(min)
if point[0] < _min[0]:
_min[0] = point[0]
if point[1] < min[1]:
_min[1] = point[1]
if point[2] < min[2]:
_min[2] = point[2]
return _min
def findMax(self, max, point):
_max = copy.copy(max)
if point[0] > _max[0]:
_max[0] = point[0]
if point[1] > _max[1]:
_max[1] = point[1]
if point[2] > _max[2]:
_max[2] = point[2]
return _max
def exportMaratis(self):
self.getMaterials()
self.getTextures()
self.getBones()
self.exportMesh()
if self.export_maa:
self.exportMAA()
if self.export_mta:
self.exportMTA()
if self.export_maa:
self.exportMMA()
def exportMesh(self):
self.file = open(self.meshFilename, "w")
self.file.write("<Maratis>\n\n")
self.file.write("<Mesh>\n\n")
self.exportAnims()
self.exportTextures()
self.exportMaterials()
self.exportBones()
self.exportMeshs()
self.file.write("</Mesh>\n\n")
self.file.write("</Maratis>")
def exportMAA(self):
num_bones = len(self.bonesList)
if num_bones > 0:
startFrame = bpy.context.scene.frame_start
endFrame = bpy.context.scene.frame_end
self.maaFile = open(self.maaFilename, "w")
self.maaFile.write("<Maratis>\n\n")
self.maaFile.write("<ArmatureAnim num=\"%d\">\n\n" % num_bones)
id = 0
obj_list = bpy.context.selected_objects
for obj in obj_list:
if obj.type == "ARMATURE":
bones = obj.pose.bones
for bone in bones:
self.maaFile.write("\t<Bone id=\"%d\">\n" % id)
posKeys = []
rotKeys = []
scaleKeys = []
for frame in range(startFrame, endFrame+1):
bpy.context.scene.frame_set(frame)
matrix = obj.matrix_world * bone.matrix
if bone.parent:
parentMatrix = obj.matrix_world * bone.parent.matrix
matrix = parentMatrix.inverted() * matrix
pos = matrix.to_translation()
rot = matrix.to_euler('XYZ')
scale = matrix.to_scale()
rot[0] = math.degrees(rot[0])
rot[1] = math.degrees(rot[1])
rot[2] = math.degrees(rot[2])
self.addKey(posKeys, (frame, pos))
self.addKey(rotKeys, (frame, rot))
self.addKey(scaleKeys, (frame, scale))
self.printKeys(self.maaFile, "position", posKeys)
self.printKeys(self.maaFile, "rotation", rotKeys)
self.printKeys(self.maaFile, "scale", scaleKeys)
self.maaFile.write("\t</Bone>\n")
id=id+1
self.maaFile.write("</ArmatureAnim>\n\n")
self.maaFile.write("</Maratis>")
def exportMTA(self):
num_textures = len(self.texturesList)
if num_textures > 0:
startFrame = bpy.context.scene.frame_start
endFrame = bpy.context.scene.frame_end
mtaFile = open(self.mtaFilename, "w")
mtaFile.write("<Maratis>\n\n")
mtaFile.write("<TextureAnim num=\"%d\">\n\n" % num_textures)
id = 0
for textureName in self.texturesList:
texture = self.texturesList[textureName]
bTexture = texture.bTexture
mtaFile.write("\t<Texture id=\"%d\">\n" % id)
translateKeys = []
#rotKeys = [] # not possible in blender ?
scaleKeys = []
for frame in range(startFrame-1, endFrame+1):
bpy.context.scene.frame_set(frame)
translate = bTexture.offset[0:2]
scale = bTexture.scale[0:2]
self.addKey(translateKeys, (frame, translate))
self.addKey(scaleKeys, (frame, scale))
self.printKeys(mtaFile, "translate", translateKeys)
self.printKeys(mtaFile, "scale", scaleKeys)
mtaFile.write("\t</Texture>\n")
id=id+1
mtaFile.write("</TextureAnim>\n\n")
mtaFile.write("</Maratis>")
def exportMMA(self):
num_materials = len(self.materialsList)
if num_materials > 0:
startFrame = bpy.context.scene.frame_start
endFrame = bpy.context.scene.frame_end
mmaFile = open(self.mmaFilename, "w")
mmaFile.write("<Maratis>\n\n")
mmaFile.write("<MaterialAnim num=\"%d\">\n\n" % num_materials)
id = 0
for materialName in self.materialsList:
material = self.materialsList[materialName]
bMaterial = material.bMaterial
mmaFile.write("\t<Material id=\"%d\">\n" % id)
opacityKeys = []
shininessKeys = []
diffuseKeys = []
specularKeys = []
emitKeys = []
for frame in range(startFrame-1, endFrame+1):
bpy.context.scene.frame_set(frame)
alpha = [bMaterial.alpha]
hardness = [bMaterial.specular_hardness]
diffuse = bMaterial.diffuse_color[0:3]
specular = copy.copy(bMaterial.specular_color)
specular[0] = specular[0] * bMaterial.specular_intensity
specular[1] = specular[1] * bMaterial.specular_intensity
specular[2] = specular[2] * bMaterial.specular_intensity
emit = copy.copy(bMaterial.diffuse_color)
emit[0] = emit[0] * bMaterial.emit
emit[1] = emit[1] * bMaterial.emit
emit[2] = emit[2] * bMaterial.emit
self.addKey(opacityKeys, (frame, alpha))
self.addKey(shininessKeys, (frame, hardness))
self.addKey(diffuseKeys, (frame, diffuse))
self.addKey(specularKeys, (frame, specular))
self.addKey(emitKeys, (frame, emit))
self.printKeys(mmaFile, "opacity", opacityKeys)
self.printKeys(mmaFile, "shininess", shininessKeys)
self.printKeys(mmaFile, "diffuseColor", diffuseKeys)
self.printKeys(mmaFile, "specularColor", specularKeys)
self.printKeys(mmaFile, "emitColor", emitKeys)
mmaFile.write("\t</Material>\n")
id=id+1
mmaFile.write("</MaterialAnim>\n\n")
mmaFile.write("</Maratis>")
def addKey(self, keys, key):
num_keys = len(keys)
num_comp = len(key[1])
if num_keys == 0:
keys.append(key)
return
for i in range(num_comp):
if key[1][i] != keys[num_keys-1][1][i]:
keys.append(key)
return
if num_keys > 1:
for i in range(num_comp):
if key[1][i] != keys[num_keys-2][1][i]:
keys.append(key)
return
keys[num_keys-1] = key
def printKeys(self, file, name, keys):
num_keys = len(keys)
if num_keys > 0:
num_comp = len(keys[0][1])
comp_names = []
if num_comp == 1:
comp_names.append("value")
else:
comp_names.append("x")
comp_names.append("y")
comp_names.append("z")
file.write("\t\t<%s num=\"%d\">\n" % (name, num_keys))
for key in keys:
file.write("\t\t\t<k t=\"%d\" " % key[0])
for i in range(num_comp):
file.write("%s=\"%f\" " % (comp_names[i], key[1][i]))
file.write("/>\n")
file.write("\t\t</%s>\n" % name)
def getMaterials(self):
obj_list = bpy.context.selected_objects
for obj in obj_list:
if obj.type == "MESH":
mesh = obj.data
if len(mesh.materials) > 0:
faces = mesh.polygons
for face in faces:
mat = face.material_index
mode = int(mesh.materials[mat].mar_mode)
blend = int(mesh.materials[mat].mar_blend_mode)
material = mesh.materials[mat]
materialName = material.name
if not materialName in self.materialsList:
self.materialsList[materialName] = Material(material, mode, blend)
else:
print("WARNING Maratis Export : Mesh needs a Material !\n")
def getTextures(self):
for materialName in self.materialsList:
material = self.materialsList[materialName]
bMaterial = material.bMaterial
mtextures = bMaterial.texture_slots
id = 0
for mtex in mtextures:
if mtex:
tex = mtex.texture
if mtex.use and tex.type == "IMAGE":
name = bMaterial.name + "." + tex.name + (".%d" % id)
self.texturesList[name] = Texture(mtex)
id = id+1
def getBones(self):
obj_list = bpy.context.selected_objects
id = 0
for obj in obj_list:
if obj.type == "ARMATURE":
bones = obj.pose.bones
for bone in bones:
self.bonesList[bone.name] = Bone(id)
id=id+1
def exportAnims(self):
sce = bpy.context.scene
mar_anim_list = sce.mar_anim_list
num_anims = len(mar_anim_list)
if num_anims > 0 and (self.export_maa or self.export_mta or self.export_mma):
self.file.write("<Animation>\n")
if self.export_maa:
self.file.write("\t<ArmatureAnim file=\"%s\" />\n" % self.getLocalPath(self.maaFilename))
if self.export_mma:
self.file.write("\t<MaterialAnim file=\"%s\" />\n" % self.getLocalPath(self.mmaFilename))
if self.export_mta:
self.file.write("\t<TextureAnim file=\"%s\" />\n" % self.getLocalPath(self.mtaFilename))
self.file.write("\t<Anims num=\"%d\">\n" % num_anims)
for i in range(num_anims):
self.file.write("\t\t<anim id=\"%d\" name=\"%s\" start=\"%d\" end=\"%d\" loops=\"%d\" />\n" % (0, "", mar_anim_list[i].my_item.start, mar_anim_list[i].my_item.end, mar_anim_list[i].my_item.loops))
self.file.write("\t</Anims>\n")
self.file.write("</Animation>\n\n")
def exportTextures(self):
texturesSize = len(self.texturesList)
if texturesSize > 0:
self.file.write("<Textures num=\"%d\">\n" % texturesSize)
id = 0
for textureName in self.texturesList:
texture = self.texturesList[textureName]
bTexture = texture.bTexture
texture.id = id
path = bpy.path.abspath(bTexture.texture.image.filepath)
filename = self.getLocalPath(path)
mipmap = bTexture.texture.use_mipmap
mapMode = 1
tile = ("repeat", "repeat")
if bTexture.texture.extension != "REPEAT":
tile = ("clamp", "clamp")
translate = bTexture.offset
scale = bTexture.scale
rotate = 0.0
self.file.write("\t<Texture id=\"%d\">\n" % id)
self.file.write("\t\t<image filename=\"%s\" mipmap=\"%d\" />\n" % (filename, mipmap))
self.file.write("\t\t<mapMode value=\"%d\" />\n" % mapMode)
self.file.write("\t\t<tile u=\"%s\" v=\"%s\" />\n" % (tile[0], tile[1]))
self.file.write("\t\t<translate x=\"%f\" y=\"%f\" />\n" % (translate[0], translate[1]))
self.file.write("\t\t<scale x=\"%f\" y=\"%f\" />\n" % (scale[0], scale[1]))
self.file.write("\t\t<rotate angle=\"%f\" />\n" % rotate)
self.file.write("\t</Texture>\n")
id = id+1
self.file.write("</Textures>\n\n")
def exportMaterials(self):
materialsSize = len(self.materialsList)
if materialsSize > 0:
self.file.write("<Materials num=\"%d\">\n" % materialsSize)
id = 0
for materialName in self.materialsList:
material = self.materialsList[materialName]
bMaterial = material.bMaterial
material.id = id
mode = material.mode
blend = material.blend
alpha = bMaterial.alpha
hardness = bMaterial.specular_hardness
diffuse = bMaterial.diffuse_color
specular = copy.copy(bMaterial.specular_color)
specular[0] = specular[0] * bMaterial.specular_intensity
specular[1] = specular[1] * bMaterial.specular_intensity
specular[2] = specular[2] * bMaterial.specular_intensity
emit = copy.copy(bMaterial.diffuse_color)
emit[0] = emit[0] * bMaterial.emit
emit[1] = emit[1] * bMaterial.emit
emit[2] = emit[2] * bMaterial.emit
self.file.write("\t<Material id=\"%d\" type=\"%d\">\n" % (id, mode))
self.file.write("\t\t<blend type=\"%d\" />\n" % blend)
self.file.write("\t\t<opacity value=\"%f\" />\n" % alpha)
self.file.write("\t\t<shininess value=\"%f\" />\n" % hardness)
self.file.write("\t\t<customValue value=\"%f\" />\n" % (0.0))
self.file.write("\t\t<diffuseColor r=\"%f\" g=\"%f\" b=\"%f\" />\n" % (diffuse[0], diffuse[1], diffuse[2]))
self.file.write("\t\t<specularColor r=\"%f\" g=\"%f\" b=\"%f\" />\n" % (specular[0], specular[1], specular[2]))
self.file.write("\t\t<emitColor r=\"%f\" g=\"%f\" b=\"%f\" />\n" % (emit[0], emit[1], emit[2]))
self.file.write("\t\t<customColor r=\"%f\" g=\"%f\" b=\"%f\" />\n" % (0.0, 0.0, 0.0))
if(mode == 2):
if(len(bMaterial.mar_vert_shad) > 0 and len(bMaterial.mar_frag_shad)):
vert = filename = self.getLocalPath(bpy.path.abspath(bMaterial.mar_vert_shad))
frag = filename = self.getLocalPath(bpy.path.abspath(bMaterial.mar_frag_shad))
self.file.write("\t\t<vertexShader file=\"%s\" />\n" % (vert))
self.file.write("\t\t<fragmentShader file=\"%s\" />\n" % (frag))
if(len(bMaterial.mar_zvert_shad) > 0 and len(bMaterial.mar_zfrag_shad)):
vert = filename = self.getLocalPath(bpy.path.abspath(bMaterial.mar_zvert_shad))
frag = filename = self.getLocalPath(bpy.path.abspath(bMaterial.mar_zfrag_shad))
self.file.write("\t\t<ZVertexShader file=\"%s\" />\n" % (vert))
self.file.write("\t\t<ZFragmentShader file=\"%s\" />\n" % (frag))
# textures pass
mtextures = bMaterial.texture_slots
numPass = 0
tPass = 0
for mtex in mtextures:
if mtex:
tex = mtex.texture
if mtex.use and tex.type == "IMAGE":
numPass = tPass+1
tPass = tPass+1
if numPass > 0:
self.file.write("\t\t<TexturesPass num=\"%d\">\n" % numPass)
tPass = 0
for mtex in mtextures:
enabledTexture = 0
if mtex:
tex = mtex.texture
if mtex.use and tex.type == "IMAGE":
name = bMaterial.name + "." + tex.name + (".%d" % tPass)
textureId = self.texturesList[name].id
mode = "modulate"
if mtex.texture.use_normal_map:
mode = "dot"
elif mtex.blend_type == "SCREEN":
mode = "replace"
elif mtex.blend_type == "ADD":
mode = "add"
elif mtex.blend_type == "SUBTRACT":
mode = "sub"
mapChannel = 0
uvlayer = mtex.uv_layer
if uvlayer:
if uvlayer in self.texSlotsList:
mapChannel = self.texSlotsList[uvlayer]
else:
mapChannel = len(self.texSlotsList)
self.texSlotsList[uvlayer] = mapChannel
self.file.write("\t\t\t<texturePass id=\"%d\" texture=\"%d\" mode=\"%s\" mapChannel=\"%d\" />\n" % (tPass, textureId, mode, mapChannel))
enabledTexture = 1
if enabledTexture == 0:
self.file.write("\t\t\t<texturePass id=\"%d\" texture=\"%d\" />\n" % (tPass, -1))
tPass = tPass+1
if tPass >= numPass:
break
self.file.write("\t\t</TexturesPass>\n")
self.file.write("\t</Material>\n")
id = id+1
self.file.write("</Materials>\n\n")
def exportBones(self):
num_bones = len(self.bonesList)
if num_bones > 0:
self.file.write("<Bones num=\"%d\">\n" % num_bones)
id = 0
obj_list = bpy.context.selected_objects
meshObjs = []
for obj in obj_list:
if obj.type == "ARMATURE":
bones = obj.pose.bones
for bone in bones:
self.file.write("\t<Bone id=\"%d\" name=\"%s\">\n" % (id, bone.name))
matrix = obj.matrix_world * bone.matrix
if bone.parent:
pBone = self.bonesList[bone.parent.name]
parentMatrix = obj.matrix_world * bone.parent.matrix
matrix = parentMatrix.inverted() * matrix
self.file.write("\t\t<parent id=\"%d\" />\n" % pBone.id)
position = matrix.to_translation()
rotation = matrix.to_euler('XYZ')
scale = matrix.to_scale()
rotation[0] = math.degrees(rotation[0])
rotation[1] = math.degrees(rotation[1])
rotation[2] = math.degrees(rotation[2])
self.file.write("\t\t<position x=\"%f\" y=\"%f\" z=\"%f\" />\n" % (position[0], position[1], position[2]))
self.file.write("\t\t<rotation x=\"%f\" y=\"%f\" z=\"%f\" />\n" % (rotation[0], rotation[1], rotation[2]))
self.file.write("\t\t<scale x=\"%f\" y=\"%f\" z=\"%f\" />\n" % (scale[0], scale[1], scale[2]))
self.file.write("\t</Bone>\n")
id=id+1
self.file.write("</Bones>\n\n")
def computeTangent(self, v1, v2, v3, uv1, uv2, uv3, n):
edge1 = v2 - v1
edge2 = v3 - v1
edge1uv = uv2 - uv1
edge2uv = uv3 - uv1
cp = edge1uv[1] * edge2uv[0] - edge1uv[0] * edge2uv[1]
if (cp != 0.0):
mul = 1.0 / cp
tangent = (edge1 * -edge2uv[1] + edge2 * edge1uv[1]) * mul
tangent = tangent.normalize()
tangent -= n * tangent.dot(n)
return tangent.normalize()
return Vector(0, 0, 0)
def exportMeshs(self):
obj_list = bpy.context.selected_objects
meshObjs = []
for obj in obj_list:
if obj.type == "MESH":
points = obj.bound_box
min = Vector((points[0][0], points[0][1], points[0][2])) * obj.matrix_world
max = copy.copy(min)
for point in points:
transPt = Vector((point[0], point[1], point[2])) * obj.matrix_world
min = self.findMin(min, transPt)
max = self.findMax(max, transPt)
meshObjs.append((obj, (min, max)))
# sub meshes
num_submeshs = len(meshObjs)
if num_submeshs > 0:
box = meshObjs[0][1]
min = box[0]
max = box[1]
for meshObj in meshObjs:
box = meshObj[1]
min = self.findMin(min, box[0])
max = self.findMax(max, box[1])
# global box
self.file.write("<BoundingBox minx=\"%f\" miny=\"%f\" minz=\"%f\" maxx=\"%f\" maxy=\"%f\" maxz=\"%f\" />\n\n" % (min[0], min[1], min[2], max[0], max[1], max[2]))
self.file.write("<SubMeshs num=\"%d\">\n" % num_submeshs)
subMeshId = 0
for meshObj in meshObjs:
obj = meshObj[0]
box = meshObj[1]
min = box[0]
max = box[1]
bvertices = {}
displays = []
indices = []
skins = []
subVertices = []
mesh = obj.data
deformed_mesh = obj.to_mesh(bpy.context.scene, True, "PREVIEW")
deformed_mesh.transform(obj.matrix_world)
deformed_mesh.calc_normals()
uvlayers = deformed_mesh.uv_textures
num_uvlayers = len(uvlayers)
# scan in order to Displays and split/sort vertices
# (we split vertices according to uvs to construct unified buffers)
for materialName in self.materialsList:
material = self.materialsList[materialName]
# display start
start = len(indices)
faces = deformed_mesh.polygons
numFaces = len(faces)
for face in faces:
# check face material and two-side
matName = mesh.materials[face.material_index].name
if matName == materialName:
verts = face.vertices
numVerts = len(verts)
subIndices = []
vertOrder = (0, 1, 2)
if numVerts == 4:
vertOrder = (0, 1, 2, 3)
# scan face points
for id in vertOrder:
index = verts[id]
vert = deformed_mesh.vertices[index]
subVert = SubVertex(vert)
# add uv layers
if num_uvlayers > 0:
for uvlayer in uvlayers:
if len(uvlayer.data) == numFaces:
subVert.uvs[uvlayer.name] = uvlayer.data[face.index].uv[id]
# scan existing point for vertex spliting
# (we compare uvs according to layers)
same = 0
if index in bvertices:
for subIndex in bvertices[index].subIndices:
if subVertices[subIndex].compare(subVert):
same = 1
subIndices.append(subIndex)
break
# add new vertex (also called sub vertex)
if not same:
subIndex = len(subVertices)
subIndices.append(subIndex)
subVertices.append(subVert)
# add BVertex (BVertex are used to fast scanning)
if not index in bvertices:
bvertices[index] = BVertex()
bvertices[index].subIndices.append(subIndex)
# add indices
indices.append(subIndices[0])
indices.append(subIndices[1])
indices.append(subIndices[2])
if numVerts == 4:
indices.append(subIndices[2])
indices.append(subIndices[3])
indices.append(subIndices[0])
# display end
size = len(indices) - start
if size > 0:
cullFace = 0
if mesh.show_double_sided:
cullFace = 2
displays.append(Display(start, size, material.id, cullFace))
# skinning
num_bones = len(self.bonesList)
if num_bones > 0:
id = 0
for subVertex in subVertices:
vert = subVertex.bVert
totalWeight = 0.0
skin = Skin(id)
for group in vert.groups:
if group.group < len(obj.vertex_groups):
groupName = obj.vertex_groups[group.group].name
if groupName in self.bonesList:
if group.weight >= 0.0:
skin.bones.append(BoneLink(self.bonesList[groupName].id, group.weight))
totalWeight += group.weight
if totalWeight > 0.0:
for bone in skin.bones:
bone.weight /= totalWeight # normalize
skins.append(skin)
id=id+1
# export
num_vertices = len(subVertices)
num_indices = len(indices)
num_displays = len(displays)
num_skins = len(skins)
if num_indices > 0 and num_displays > 0:
self.file.write("\t<SubMesh id=\"%d\">\n" % subMeshId)
# bounding box
self.file.write("\t\t<BoundingBox minx=\"%f\" miny=\"%f\" minz=\"%f\" maxx=\"%f\" maxy=\"%f\" maxz=\"%f\" />\n" % (min[0], min[1], min[2], max[0], max[1], max[2]))
# vertices
self.file.write("\t\t<Vertices num=\"%d\">\n" % num_vertices)
for subVertex in subVertices:
self.file.write("\t\t\t<vertex x=\"%f\" y=\"%f\" z=\"%f\" />\n" % (subVertex.bVert.co[0], subVertex.bVert.co[1], subVertex.bVert.co[2]))
self.file.write("\t\t</Vertices>\n")
# normals
self.file.write("\t\t<Normals num=\"%d\">\n" % num_vertices)
for subVertex in subVertices:
self.file.write("\t\t\t<normal x=\"%f\" y=\"%f\" z=\"%f\" />\n" % (subVertex.bVert.normal[0], subVertex.bVert.normal[1], subVertex.bVert.normal[2]))
self.file.write("\t\t</Normals>\n")
# texCoords
num_uvs = num_vertices*num_uvlayers
if num_uvs > 0:
# write channels infos
num_pass = 0
self.file.write("\t\t<TexCoords num=\"%d\" mapChannels=\"" % num_uvs)
for uvlayer in uvlayers:
slot = 0
if uvlayer.name in self.texSlotsList:
slot = self.texSlotsList[uvlayer.name]
else:
slot = len(self.texSlotsList)
self.texSlotsList[uvlayer.name] = slot
if num_pass > 0:
self.file.write(" ")
self.file.write("%d" % slot)
num_pass = num_pass + 1
self.file.write("\">\n")
# write coords
for uvlayer in uvlayers:
for subVertex in subVertices:
self.file.write("\t\t\t<texCoord x=\"%f\" y=\"%f\" />\n" % (subVertex.uvs[uvlayer.name][0], 1.0 - subVertex.uvs[uvlayer.name][1]))
self.file.write("\t\t</TexCoords>\n")
# indices
self.file.write("\t\t<Indices num=\"%d\">\n" % num_indices)
for index in indices:
self.file.write("\t\t\t<index value=\"%d\" />\n" % index)
self.file.write("\t\t</Indices>\n")
# skins
if num_skins > 0:
self.file.write("\t\t<Skins num=\"%d\">\n" % num_skins)
for skin in skins:
self.file.write("\t\t\t<skin vertex=\"%d\" numBones=\"%d\">\n" % (skin.vertIndex, len(skin.bones)))
for bone in skin.bones:
self.file.write("\t\t\t\t<bone id=\"%d\" weight=\"%f\" />\n" % (bone.bone, bone.weight))
self.file.write("\t\t\t</skin>\n")
self.file.write("\t\t</Skins>\n")
# displays
self.file.write("\t\t<Displays num=\"%d\">\n" % num_displays)
for display in displays:
self.file.write("\t\t\t<display primType=\"triangles\" begin=\"%d\" size=\"%d\" material=\"%d\" cullFace=\"%d\" />\n" % (display.begin, display.size, display.material, display.cullFace))
self.file.write("\t\t</Displays>\n")
self.file.write("\t</SubMesh>\n")
subMeshId = subMeshId+1
self.file.write("</SubMeshs>\n\n")
class RawExporter(bpy.types.Operator):
'''Save Maratis mesh'''
bl_idname = "export_mesh.mesh"
bl_label = "Export Maratis mesh"
filepath = StringProperty(name="File Path", description="Filepath used for exporting the mesh file", maxlen= 1024, default= "")
check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
export_maa = BoolProperty(name="Export Armature Anim", description="", default=True)
export_mta = BoolProperty(name="Export Texture Anim", description="", default=True)
export_mma = BoolProperty(name="Export Material Anim", description="", default=True)
def execute(self, context):
mesh = Export(self.filepath, self.export_maa, self.export_mta, self.export_mma)
mesh.exportMaratis()
return {'FINISHED'}
def invoke(self, context, event):
wm = context.window_manager
wm.fileselect_add(self)
return {'RUNNING_MODAL'}
###########################################################################################
# UI / Maratis "RenderEngine"
class PovrayRender(bpy.types.RenderEngine):
bl_idname = 'MARATIS_RENDER'
bl_label = "Maratis"
# render
from bl_ui import properties_render
properties_render.RENDER_PT_dimensions.COMPAT_ENGINES.add('MARATIS_RENDER')
del properties_render
# texture
from bl_ui import properties_texture
properties_texture.TEXTURE_PT_image.COMPAT_ENGINES.add('MARATIS_RENDER')
properties_texture.TEXTURE_PT_image_mapping.COMPAT_ENGINES.add('MARATIS_RENDER')
properties_texture.TEXTURE_PT_image_sampling.COMPAT_ENGINES.add('MARATIS_RENDER')
properties_texture.TEXTURE_PT_mapping.COMPAT_ENGINES.add('MARATIS_RENDER')
properties_texture.TEXTURE_PT_context_texture.COMPAT_ENGINES.add('MARATIS_RENDER')
properties_texture.TEXTURE_PT_image.COMPAT_ENGINES.add('MARATIS_RENDER')
properties_texture.TEXTURE_PT_influence.COMPAT_ENGINES.add('MARATIS_RENDER')
properties_texture.TEXTURE_PT_preview.COMPAT_ENGINES.add('MARATIS_RENDER')
del properties_texture
# material
from bl_ui import properties_material
properties_material.MATERIAL_PT_context_material.COMPAT_ENGINES.add('MARATIS_RENDER')
properties_material.MATERIAL_PT_diffuse.COMPAT_ENGINES.add('MARATIS_RENDER')
properties_material.MATERIAL_PT_preview.COMPAT_ENGINES.add('MARATIS_RENDER')
properties_material.MATERIAL_PT_shading.COMPAT_ENGINES.add('MARATIS_RENDER')
properties_material.MATERIAL_PT_specular.COMPAT_ENGINES.add('MARATIS_RENDER')
properties_material.MATERIAL_PT_transp_game.COMPAT_ENGINES.add('MARATIS_RENDER')
del properties_material
# data mesh
from bl_ui import properties_data_mesh
for member in dir(properties_data_mesh):
subclass = getattr(properties_data_mesh, member)
try:
subclass.COMPAT_ENGINES.add('MARATIS_RENDER')
except:
pass
del properties_data_mesh
# Maratis render panel
class mar_anim_list_OT_add(bpy.types.Operator):
bl_idname = 'mar_anim_list.add'
bl_label = "Add anim"
bl_description = "Add anim"
def invoke(self, context, event):
sce = context.scene
mar_anim_list = sce.mar_anim_list
mar_anim_list.add()
mar_anim_list[-1].name= "Anim%d" % (len(mar_anim_list) - 1)
return{'FINISHED'}
class mar_anim_list_OT_del(bpy.types.Operator):
bl_idname = 'mar_anim_list.remove'
bl_label = "Remove anim"
bl_description = "Remove anim"
def invoke(self, context, event):
sce = context.scene
mar_anim_list = sce.mar_anim_list
if sce.mar_anim_list_index >= 0:
mar_anim_list.remove(sce.mar_anim_list_index)
sce.mar_anim_list_index-= 1
for i in range(len(mar_anim_list)):
mar_anim_list[i].name= "Anim%d" % (i)
return{'FINISHED'}
class RenderButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "render"
@classmethod
def poll(cls, context):
rd = context.scene.render
return (rd.use_game_engine == False) and (rd.engine in cls.COMPAT_ENGINES)
class RENDER_PT_maratis(RenderButtonsPanel, bpy.types.Panel):
bl_label = "Maratis Anims"
COMPAT_ENGINES = {'MARATIS_RENDER'}
def draw(self, context):
layout= self.layout
sce= context.scene
split= layout.split()
row= split.row()
row.template_list(sce, 'mar_anim_list', sce, 'mar_anim_list_index', rows= 3)
col= row.column(align=True)
col.operator('mar_anim_list.add', text="", icon="ZOOMIN")
col.operator('mar_anim_list.remove', text="", icon="ZOOMOUT")
if sce.mar_anim_list_index >= 0 and len(sce.mar_anim_list) > 0:
list_item = sce.mar_anim_list[sce.mar_anim_list_index]
layout.separator()
layout.prop(list_item.my_item, 'start')
layout.prop(list_item.my_item, 'end')
layout.prop(list_item.my_item, 'loops')
# Maratis material panel
class MaterialButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "material"
@classmethod
def poll(cls, context):
mat = context.material
rd = context.scene.render
return mat and (rd.use_game_engine == False) and (rd.engine in cls.COMPAT_ENGINES)
class MATERIAL_PT_maratis(MaterialButtonsPanel, bpy.types.Panel):
bl_label = "Maratis"
COMPAT_ENGINES = {'MARATIS_RENDER'}
def draw(self, context):
layout = self.layout
mat = context.material
split = layout.split()
col = split.column()
col.prop(mat, "mar_mode")
col.prop(mat, "mar_blend_mode")
if mat.mar_mode == "2":
col.prop(mat, "mar_vert_shad")
col.prop(mat, "mar_frag_shad")
col.prop(mat, "mar_zvert_shad")
col.prop(mat, "mar_zfrag_shad")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment