i really could use some help on the virtualight export script!
#!BPY
"""
Name: '3Dvirtualight'
Blender: 232
Group: 'Export'
Tip: 'Export to virtualight'
"""
#
# bruteforce (Tm) VirtauLight exporter for Blender v2.12
# version 1.3
# by jano lukac, [email protected]
# edit by peter lammers, [email protected]
# The latest version can be found here:
# here
import Blender
from Blender import NMesh, Scene, Object, Material
import os, re, sys
from math import *
from string import lower
#
# Quick start:
#
# 1. Modify the two variables below: savePath and outFile.
# Please make sure savePath exists, and do not put extensions
# to the outFile
# 2. Open this in Blender (if you haven't done so already)
# 3. Press alt-p over this script in Blender
# 4. Go to savePath dir and type vlight <outFile> -a 8
# 5. While you wait, read through these comments and the VirtuaLight
# documentation
# 6. For the "GI" look, use a hemi-lamp with Y rotations:
# -90 <= rotY => 90
# Read the Lights section below for more info
savePath = "c:/vl/"
outFile = "file"
#
# Comments, Docs, Notes
#
# I highly recommend you edit the output .vib and .vs files.
# See a little further down for help with lights.
# I expect you to read these comments.. if you don't, well, TS.
# Running this script in blender will produce in your savePath:
# 1. $outFile.vib # the scene
# 2. $outFile.vs # materials
# 3. $filePath/Meshes/$mesh$appendor.vib # mesh structure
# Python notes:
# If you use python > 2.0, change the "re" module to "pre" at all
# occurances (i.e. search and replace).
# Notes on supported Blender Objects
# Camera:
# If everything seems a bit skewed, change the FOV setting in this script.
# Meshes:
# All meshes export as TriangularPatches now, to maintain UV coords.
# If you have stray vertices in a mesh (i.e. vertices but no face), you
# will risk the chance of either having stray faces in the output
# VIB or an empty Solid[] structure. The empty Solid[] struct
# will also result with a "Parse Error". I currently have no way
# to fix this, so you will have to do it manually.
# If you get weird results, try to first "apply size/rot" to the mesh.
# If you get a "parse error" in your .vib files, first check for an
# empty Solid[] structure in the vib, then try renaming the
# mesh in Blender.. stuff like "Box", "Plane", and "Sphere" are
# reserved in VirtuaLight, and will cause these errors.
# I made a basic attempt to fix this by prepending a "X" to every
# name. It's ugly, but it works -- can be changed in the Optional
# Mods sections below.
# SetSmooth works on both triangles and qauds; however, to make it work,
# I had to manually convert quads to tris. If you don't trust this,
# please convert your mesh to triangles first.
# If you have SetSmooth on quads, and have UV textures, then UV Textures
# will be exported, but if you have problems, ctrl-t the mesh first.
# Materials:
# I default to PlainSurfaces, and just use basic settings, because,
# although the settings are available in blender, I cannot get to
# them via python. You can manually transcribe them.
# If you want to use textures, use FaceSelect mode in blender
# to assign UV coordinates. Then read how to apply textures
# in the VirtauLight sepcifications PDF included with said program
# No access to blender's SpTr yet, so use alpha to determine Kt. I
# default to an Index of Refraction to 1.3333 (glass), and use the
# material "Mir" RGB sliders to affect the colors.
# You can change specularity type in the Optional mods section below
# Lights:
# This is the fun one. VirtuaLight has SO MANY lights, it's not even
# funny. I chose the corresponding lights based on functionality,
# but *NOT* on name -- it's a bit confusing at fist, but you'll get
# used to it. Here is how I translate between VirtuaLight and Blender:
# AreaLight(bulb): Lamp + sphere
# AreaLight(plane): Lamp + square (not implemented yet)
# BlackHole: Lamp + negative
# DirectionalLight: Sun
# PointLight: Lamp
# SkyLight+Sunlight: Hemi
# SpotLight: Spot
# Note that "ClipEnd" will adjust VirtualLight's Falloff variable
# (i.e. I couldn't find a suibtable value in blender)
# The QUAD button in lights (f2) will make certain lamps Quadratic
# instead of linear.
# SunLight can be incredibly bright, consider commenting it out in the
# scene vib file and using other lights instead. The Dist value
# affects the SunLight shadow; energy affects SkyLight intensity.
# BlackHole element "Density" is set by lamp's Distance in blender.
#
# KnownBugs with output mechanism:
# The script itself should always work; however, the ouput may cause
# parse errors with VirtuaLight (I handle most of them).
# Stray vertices will cause either a parse error (due to an empty Solid[]
# or extra faces in the output. Cannot be fixed without change in
# Blender's python API.
# I *think* VirtuaLight will work properly if Material and Mesh names
# are identical. If you want to be on the safe side, make sure
# all names in blender are unique before you export.
#
# Changes since 1.1:
# - added initialization for abNormals variable, as it caused fluke
# in some cases. Thanks to bladesman for finding it.
# Changes since 1.0:
# - allow for unsmoothed quads and tris to retain UV coords by exporting
# all mesh as TriangularPatches instead of Polygon.
# - divide by zero fix
# - documentation fix
#
# Todo:
# - Possible nurbs (blender api pending?)
# - Possible metaballs (blender api pending?)
# - Mini gui to modify stuff like lights, change mesh type, etc.
# - Handle basic animations
# - Someone with programming experience could convert some
# blender procedural textures to VirtuaLight shaders
# - Find work.. if anyone needs a Sysadmin or Network Admin in
# the southern california area, please contact me ;]
#
#
# Optional Modifications
#
# I default rounding numbers to 4. If you want more precision, change this
# But you NEED rounding, otherwise you might get numbers with "e" in them
# and VirtuaLight doesn't handle that.
r = 4
# Change "specType" to tell what type of Specular Highlights you want default
# in your materials. I default to "Phong" because I like to say,
# "BUI TUI PHONG!"
specType = 0
specHighlight = ["Phong", "Blinn", "Cook", "Reitz", "Gaussian"]
# Change append symbol.. use only [a-z][A-Z][0-9] and/or _
# This symbol is appended to all meshes and materials
appendor = "X"
#
# read further.. if you dare [maniacle laughter]
#
#
# sub functions - yes, I come from PERL
#
def multiply3x3(A, B):
C = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
for i in range(3):
for j in range(3):
for k in range(3):
C[i][j] = C[i][j] + A[i][k]*B[k][j]
return C
def multiply3x1(A, B):
C = [0,0,0]
for i in range(3):
for j in range(3):
C[i] = C[i] + A[i][j]*B[j]
return C
def parallelVector(rotX, rotY, rotZ, oAxis):
# convert to radians
rotX = rotX * pi/180
rotY = rotY * pi/180
rotZ = rotZ * pi/180
# counterclockwise rotations about given axis through angle)
Tx = [[1, 0, 0], [0, cos(rotX), -sin(rotX)], [0, sin(rotX), cos(rotX)]]
Ty = [[cos(rotY), 0, sin(rotY)], [0, 1, 0], [-sin(rotY), 0, cos(rotY)]]
Tz = [[cos(rotZ), -sin(rotZ), 0], [sin(rotZ), cos(rotZ), 0], [0, 0, 1]]
Tm = multiply3x3(multiply3x3(Tz, Ty), Tx)
return multiply3x1(Tm, oAxis)
def calcNormal(face, verts, n):
# If it's a quad, calculate normal from diagonal instead
# Assume verts are sorted in circular fasion (i.e. next to each other)
m = (3 * n) | 1 # when n=0 (tri), m=1; when n=1 (quad), m=3
vectorU = [verts[face[0]][0] - verts[face[2]][0],
verts[face[0]][1] - verts[face[2]][1],
verts[face[0]][2] - verts[face[2]][2]]
vectorV = [verts[face[n]][0] - verts[face[m]][0],
verts[face[n]][1] - verts[face[m]][1],
verts[face[n]][2] - verts[face[m]][2]]
normal = [(vectorU[1] * vectorV[2]) - (vectorU[2] * vectorV[1]),
(vectorU[2] * vectorV[0]) - (vectorU[0] * vectorV[2]),
(vectorU[0] * vectorV[1]) - (vectorU[1] * vectorV[0])]
nLength = sqrt((normal[0] ** 2) + (normal[1] ** 2) + (normal[2] ** 2))
# divide by zero check
if not nLength: return "stray"
else: return (normal[0]/nLength, normal[1]/nLength, normal[2]/nLength)
def removeDot(name, printResults = 1):
# Blender automatically names duped objects with "." Virtual light
# does not play well with either that or other non-word characters.
p = re.compile("\W")
fixedName = p.sub("_", name)
if p.search(name):
if printResults:
print "%s renamed to %s..." % (name, fixedName)
return fixedName
def prepareName(name, list, printResults = 1):
# I felt bad for not handling reserved names, so this basically takes
# care of that. Just prepend a "X" to every name, and if it alread
# exists, do it again.. hah, my first successful recursive function!
m = re.compile("(.*?)(%s+$)" % appendor).search(name)
if m: fixedName = lower(m.group(1)) + m.group(2)
else: fixedName = lower(name)
fixedName = "%s%s" % (fixedName, appendor)
try:
list.index(fixedName)
fixedName = prepareName(fixedName, list, printResults)
except:
if printResults:
print "%s renamed to %s..." % (name, fixedName)
return fixedName
# variables
meshList = []
lampList = []
materialList = []
fixedMatList = []
fixedMeshList = []
#
# "Main"
#
scene = Blender.Scene.GetCurrent()
# Setup Scene VIB File
if not os.path.isdir(savePath):
print "#
# Sorry path %s does not exist" % savePath
print "# Please make sure the path is there
#"
print "You will now see an error message:"
vibFileName = "%s%s.vib" % (savePath, outFile)
VIBFILE = open(vibFileName, "w")
VIBFILE.write("// Scene file converted from Blender by bruteforce
")
# Setup Material VS File
vsFileName = "%s%s.vs" % (savePath, outFile)
VSFILE = open(vsFileName, "w")
VSFILE.write("// Shader file converted from Blender by bruteforce
")
VSFILE.write("ReadArchive \"statics.vib\"
")
# Setup Meshes directory, files handled later
meshPath = "%sMeshes" % (savePath)
if not os.path.isdir(meshPath):
os.mkdir(meshPath)
print "%s does not exist, creating" % meshPath
#
# camera export
#
camob = Blender.Scene.getCurrent().getCurrentCamera()
cam = camObj.getData()
camname = cam.name
#camname = "Camera"
display = Blender.getDisplaySettings()
aspect = display.yResolution / float(display.xResolution)
print "Writing camera..."
VIBFILE.write("Camera [
")
VIBFILE.write(" (%s,%s,%s), " % (round(cameraObj.loc[0],r),
round(cameraObj.loc[1],r),
round(cameraObj.loc[2],r)))
lookAt = parallelVector(cameraObj.rot[0], cameraObj.rot[1], cameraObj.rot[2], (0,0,-1))
# (a,b,c) = (x,y,z) + t(parallel vector) where t is some factor, I use 1
lookAt = [cameraObj.loc[0] + lookAt[0], cameraObj.loc[1] + lookAt[1], cameraObj.loc[2] + lookAt[2]]
VIBFILE.write("(%s,%s,%s), " % (round(lookAt[0],r),
round(lookAt[1],r),
round(lookAt[2],r)))
upAxis = parallelVector(cameraObj.rot[0], cameraObj.rot[1], cameraObj.rot[2], (0,1,0))
VIBFILE.write("(%s,%s,%s)
" % (round(upAxis[0],r),
round(upAxis[1],r),
round(upAxis[2],r)))
# which FoV is it, dammit!?
VIBFILE.write(" FieldOfView %s
" % (360 * atan(aspect * 16 / camera.Lens) / pi))
#VIBFILE.write(" FieldOfView %s
" % camera.Lens)
VIBFILE.write(" Format(%s,%s)
" % (display.xResolution, display.yResolution))
# negative frame aspect ratio to prevent a mirrored image!
# Thanks to Stephane Marty (virtualight author!) for this tip
VIBFILE.write(" FrameAspectRatio -%s/%s
" % (display.xResolution, display.yResolution))
VIBFILE.write(" Clipping(%s,%s)
" % (round(camera.ClSta,r), round(camera.ClEnd,r)))
VIBFILE.write("]
")
# separate mesh and lights to nicely organize output files
# Note: materials are accessed different, wait until I'm inside the mesh export
Objects = Object.GetSelected()
if Objects == []:
print("You have not selected an object!")
returncode = 4
else:
for object in Objects:
MtlList = []
if len(Objects) > 1 or exporttype > 1:
Transform = CreateMatrix(object, Transform)
multiflag = 1
mesh = NMesh.GetRawFromObject(object.name)
ObjName = mesh.name
has_uvco = mesh.hasVertexUV()
VIBFILE.write("# Meshname: %s
" % ObjName)
# Blender.NMesh.Get(name):
# meshList.append(name)
# Blender.isLamp(name):
# lampList.append(name)
#
# lamp export
#
for name in lampList:
print "Writing lamp %s..." % name
# define lights -- there's prolly a better way to do this
vlights = ["AreaLight", "BlackHole", "DirectionalLight", "PointLight", "SkyLight", "SpotLight"]
blights = {"Lamp": 3, "Spot": 5, "Sun": 2, "Hemi": 4}
lampObj = Blender210.getObject(name)
lamp = Blender210.getLamp(lampObj.data)
lampType = blights[lamp.type]
# note that Lamp Mode will take precedence over Lamp Type
if lamp.mode[1] == "1": lampType = 0 # sphere->arealight+bulb
if lamp.mode[7] == "1": lampType = 0 # square->arealight+plane
if lamp.mode[5] == "1": lampType = 1 # negative
# begin writing -- some will have to change
VIBFILE.write("// Lamp: %s
" % name) # Thanks to JamesK for this one
if lampType == 1:
VIBFILE.write("%s (" % vlights[lampType])
VIBFILE.write("(%s,%s,%s), %s, " % (round(lampObj.loc[0],r),
round(lampObj.loc[1],r),
round(lampObj.loc[2],r),
lamp.Dist))
VIBFILE.write("'%s,%s,%s'" % (1 - lamp.R, 1 - lamp.G, 1 - lamp.B))
VIBFILE.write("*%s)
" % lamp.Energ)
if lampType == 4:
VIBFILE.write("%s (" % vlights[lampType])
VIBFILE.write("%s, " % (lamp.Dist * 5))
VIBFILE.write("'%s,%s,%s', " % (lamp.R, lamp.G, lamp.B))
VIBFILE.write("%s)
" % lamp.Energ)
# calculate sun light
if lampObj.rot[1] <= 90 and lampObj.rot[1] >= -90:
degrees = round(lampObj.rot[1],r)
hours = 12 - int(degrees / 15)
minutes = 2 * int(degrees % 30)
VIBFILE.write("SunLight(%02d:%02d, %s)
" % (hours, minutes, lamp.Dist))
else: VIBFILE.write("
")
else:
VIBFILE.write("%s [
" % vlights[lampType])
# separate the differences
if lampType == 0:
if lamp.mode[7] == "0":
VIBFILE.write(" Bulb ((%s,%s,%s), %s)
" % (round(lampObj.loc[0],r),
round(lampObj.loc[1],r),
round(lampObj.loc[2],r),
lamp.Dist))
elif lampType == 2:
lightFrom = parallelVector(lampObj.rot[0], lampObj.rot[1], lampObj.rot[2], (0,0,-1))
VIBFILE.write(" (%s,%s,%s)
" % (round(lightFrom[0],r),
round(lightFrom[1],r),
round(lightFrom[2],r)))
elif lampType == 3:
VIBFILE.write(" (%s,%s,%s)
" % (round(lampObj.loc[0],r),
round(lampObj.loc[1],r),
round(lampObj.loc[2],r)))
elif lampType == 5:
VIBFILE.write(" (%s,%s,%s), " % (round(lampObj.loc[0],r),
round(lampObj.loc[1],r),
round(lampObj.loc[2],r)))
lightFrom = parallelVector(lampObj.rot[0], lampObj.rot[1], lampObj.rot[2], (0,0,-1))
VIBFILE.write("(%s,%s,%s), " % (round(lightFrom[0],r),
round(lightFrom[1],r),
round(lightFrom[2],r)))
VIBFILE.write("%s, " % lamp.SpoSi)
# NOTE: this value is supposed to be "Falloff," but I couldn't find
# a suibtable replacement in blender for it -- so using clipEnd for now
VIBFILE.write("%s, " % lamp.ClipEnd)
VIBFILE.write("%s
" % round(lamp.SpoBl,r))
# put all similar attribs together here
VIBFILE.write(" Intensity '%s,%s,%s'*%s
" % (lamp.R, lamp.G, lamp.B, lamp.Energ))
# This one sets the quadratic thingy -- take a look at
# equation in blender for the quad1 and quad2 settings,
# maybe important to add as factor to INTENSITY
if lamp.mode[0] == "1":
VIBFILE.write(" Decay QUADRATIC
")
if lamp.mode[6] == "1":
VIBFILE.write(" LightingAttributes SHADOW
")
elif lamp.mode[6] == "0" and lamp.mode[2] == "0":
VIBFILE.write(" LightingAttributes SPECULAR
")
if lamp.mode[7] == "0":
VIBFILE.write(" MediaInteraction
")
if lampType != 5 and lamp.mode[3] == "1":
VIBFILE.write(" Glow %s
" % lamp.HaInt)
VIBFILE.write("]
")
#
# mesh export
#
for name in meshList:
# Check for empty meshes
meshObj = Blender.getObject(name)
mesh = Blender.getMesh(meshObj.data)
faces = mesh.faces
if not faces: continue
# Check for "." in name, then make sure name is unique
fixedName = removeDot(name)
fixedName = prepareName(fixedName, fixedMeshList)
fixedMeshList.append(fixedName)
print "Writing mesh %s as %s..." % (name, fixedName)
meshFileName = ("%s/%s.vib" % (meshPath, fixedName))
MESHFILE = open(meshFileName, "w")
MESHFILE.write("// Mesh Structure exported from Blender by bruteforce
")
MESHFILE.write("Declare %s = Solid [
" % fixedName)
VIBFILE.write("ReadArchive \"%s\"
" % meshFileName)
VIBFILE.write("%s [
" % fixedName)
materials = meshObj.materials
vertices = mesh.vertices
vnormals = mesh.normals
texcoords = mesh.texcoords
abNormals = 0
# get a list of materials for later
for material in materials:
try:
materialList.index(material)
except:
if material: materialList.append(material)
# You have to add textures yourself
if mesh.texture:
VSFILE.write("// Mesh %s has UV Coords applied to it. If you wish to add textures,
" % name)
VSFILE.write("// please read the VirtauLight docs for more info on adding UV Textures
")
print "Please read the VirtuaLight docs for adding UV Textures"
# the j is to keep track what iteration I'm on in the
# "for face in faces" loop so I can make sure I'm on the
# right set of UV coords
j = 0
totalFaces = len(faces) - 1
for face in faces:
if face[3]: totalVerts = 4
else: totalVerts = 3
# gets us a normalized face normal
if not face[4]:
normals = calcNormal(face, vertices, totalVerts - 3)
# if we have a divide by zero in normal calculation,
# then we absolutley have a stray vertex or two
if normals == "stray":
totalFaces = totalFaces - 1
abNormals = 1
print "WARNING: stray vertices found"
print "WARNING: output may not be as expected"
continue
# triangles
if not (totalVerts - 3):
MESHFILE.write(" Shape [TriangularPatch (")
for i in range(totalVerts):
MESHFILE.write("(%s,%s,%s), " % (round(vertices[face[i]][0],r),
round(vertices[face[i]][1],r),
round(vertices[face[i]][2],r)))
# use vertex normals if smoothed, else print face normal
if face[4]:
MESHFILE.write("(%s,%s,%s)" % (round(vnormals[face[i]][0],r),
round(vnormals[face[i]][1],r),
round(vnormals[face[i]][2],r)))
else:
MESHFILE.write("(%s,%s,%s)" % (round(normals[0],r),
round(normals[1],r),
round(normals[2],r)))
# add texcoords, if any
if texcoords:
MESHFILE.write(" UV=%s,%s" % (round(texcoords[j][i][0],r),
round(texcoords[j][i][1],r)))
if i != totalVerts - 1: MESHFILE.write(", ")
# create triangle if face is QUAD
# So who's your daddy now?
else:
MESHFILE.write(" Shape [TriangularPatch (")
for i in range(totalVerts - 1):
MESHFILE.write("(%s,%s,%s), " % (round(vertices[face[i]][0],r),
round(vertices[face[i]][1],r),
round(vertices[face[i]][2],r)))
# use vertex normals if smoothed, else print face normal
if face[4]:
MESHFILE.write("(%s,%s,%s)" % (round(vnormals[face[i]][0],r),
round(vnormals[face[i]][1],r),
round(vnormals[face[i]][2],r)))
else:
MESHFILE.write("(%s,%s,%s)" % (round(normals[0],r),
round(normals[1],r),
round(normals[2],r)))
# add texcoords, if any
if texcoords:
MESHFILE.write(" UV=%s,%s" % (round(texcoords[j][i][0],r),
round(texcoords[j][i][1],r)))
if i != totalVerts - 2:
MESHFILE.write(", ")
else:
if materials and materials[face[5]]:
fixedMatName = removeDot(materials[face[5]], 0)
fixedMatName = prepareName(fixedMatName, materialList, 0)
MESHFILE.write(") %s ]+
" % fixedMatName)
else:
MESHFILE.write(") ]+
")
MESHFILE.write(" Shape [TriangularPatch (")
for i in range(totalVerts - 1):
I = i + 2
if I > (totalVerts - 1): I = 0
MESHFILE.write("(%s,%s,%s), " % (round(vertices[face[I]][0],r),
round(vertices[face[I]][1],r),
round(vertices[face[I]][2],r)))
# use vertex normals if smoothed, else print face normal
if face[4]:
MESHFILE.write("(%s,%s,%s)" % (round(vnormals[face[I]][0],r),
round(vnormals[face[I]][1],r),
round(vnormals[face[I]][2],r)))
else:
MESHFILE.write("(%s,%s,%s)" % (round(normals[0],r),
round(normals[1],r),
round(normals[2],r)))
# add texcoords, if any
if texcoords:
MESHFILE.write(" UV=%s,%s" % (round(texcoords[j][I][0],r),
round(texcoords[j][I][1],r)))
if I != 0: MESHFILE.write(", ")
# if the face has material, add it here
if materials and materials[face[5]]:
fixedMatName = removeDot(materials[face[5]], 0)
fixedMatName = prepareName(fixedMatName, materialList, 0)
MESHFILE.write(") %s ]" % fixedMatName)
else: MESHFILE.write(") ]")
# if faces still exist, csg them with (+)
if j == totalFaces: MESHFILE.write("
")
elif j == totalFaces - 1 and abNormals: MESHFILE.write("
")
else: MESHFILE.write("+
")
j = j + 1
abNormals = 0
# Prints out the final material
MESHFILE.write("]
")
MESHFILE.close()
# I apply the transformations DIRECT, rather than using Blender's "loc, rot, size"
# because I was getting some weird ass results. *shrug*
#VIBFILE.write(" TransformationStack [
")
VIBFILE.write(" Transform (
%s,%s,%s,%s," \
"
%s,%s,%s,%s," \
"
%s,%s,%s,%s," \
"
%s,%s,%s,%s" \
"
)" % (
round(meshObj.matrix[0][0],r),
round(meshObj.matrix[0][1],r),
round(meshObj.matrix[0][2],r),
round(meshObj.matrix[0][3],r),
round(meshObj.matrix[1][0],r),
round(meshObj.matrix[1][1],r),
round(meshObj.matrix[1][2],r),
round(meshObj.matrix[1][3],r),
round(meshObj.matrix[2][0],r),
round(meshObj.matrix[2][1],r),
round(meshObj.matrix[2][2],r),
round(meshObj.matrix[2][3],r),
round(meshObj.matrix[3][0],r),
round(meshObj.matrix[3][1],r),
round(meshObj.matrix[3][2],r),
round(meshObj.matrix[3][3],r)))
#VIBFILE.write(" ]
")
VIBFILE.write("]
")
#
# material export
#
materialList.sort()
for name in materialList:
# Check for "." in name, then make sure name is unique
fixedName = removeDot(name)
fixedName = prepareName(fixedName, fixedMatList)
fixedMatList.append(fixedName)
print "Writing material %s as %s..." % (name, fixedName)
material = Blender210.getMaterial(name)
VSFILE.write("Declare %s = Shader [ PlainSurface [
" % fixedName)
VSFILE.write(" Color '%s,%s,%s'
" % (material.R, material.G, material.B))
if material.Emit >= 0.1:
VSFILE.write(" Ka %s
" % material.Emit)
VSFILE.write(" Kd %s
" % material.Ref)
VSFILE.write(" Ks (%s, '%s,%s,%s')
" % (material.Spec, material.SpecR, material.SpecG, material.SpecB))
VSFILE.write(" %sSpecularBRDF %s
" % (specHighlight[specType], (-45*material.Hard)/254 + (45*255)/254))
VSFILE.write(" Kt (%s, %s, '%s,%s,%s')
" % (1.0 - material.Alpha, 1.333, material.MirR, material.MirG, material.MirB))
VSFILE.write(" ]
]
")
VIBFILE.close()
VSFILE.close()
print "GI Blender... complete
"
sys.stdout.flush()
i cant get it working any clues?