Guest User

vdrift-track

a guest
Aug 30th, 2010
117
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!BPY
  2. """
  3. Name: 'TRK'
  4. Blender: 249
  5. Group: 'Export'
  6. Tip: 'Export VDrift race track. (.trk)'
  7. """
  8. ######################################################
  9. # VDrift Track Exporter
  10. # Date: 13 JAN 10
  11. # Ver: 0.1
  12. ######################################################
  13. import Blender
  14. from Blender import *
  15. import bpy
  16.  
  17. ######################################################
  18. # Bezier Patch
  19. ######################################################
  20. class bpatch:
  21.    
  22.     def __init__(self, (fl, fr, bl, br)):
  23.         # 4x4 array
  24.         self.points = [[None] * 4 for i in range(4)]
  25.         # corners
  26.         self.points[0][0] = fl
  27.         self.points[0][3] = fr
  28.         self.points[3][0] = bl
  29.         self.points[3][3] = br
  30.         # intermediate front and back points
  31.         temp = fr - fl
  32.         self.points[0][1] = fl + temp * 1.0 / 3.0
  33.         self.points[0][2] = fl + temp * 2.0 / 3.0
  34.         temp = br - bl
  35.         self.points[3][1] = bl + temp * 1.0 / 3.0
  36.         self.points[3][2] = bl + temp * 2.0 / 3.0
  37.         # intermediate left and right points
  38.         for i in range(4):
  39.             temp = self.points[3][i] - self.points[0][i]
  40.             self.points[1][i] = self.points[0][i] + temp * 1.0 / 3.0
  41.             self.points[2][i] = self.points[0][i] + temp * 2.0 / 3.0       
  42.    
  43.     def attach(self, other):
  44.         for x in range(4):
  45.             slope = (other.points[0][x] - self.points[3][x]).normalize()
  46.             print slope
  47.             otherlen = (other.points[0][x] - other.points[3][x]).length
  48.             mylen = (self.points[0][x] - self.points[3][x]).length
  49.             meanlen = min(otherlen, mylen)
  50.             other.points[2][x] = other.points[3][x] + slope * meanlen / 3.0
  51.             self.points[1][x] = self.points[0][x] - slope * meanlen / 3.0
  52.    
  53.     def string(self):
  54.         patch_str = ""
  55.         for x in range(4):
  56.             for y in range(4):
  57.                 p = self.points[x][y]
  58.                 #patch_str += str(p.x) + " " + str(p.y) + " " + str(p.z) + "\n"
  59.                 patch_str += str(p.y) + " " + str(p.z) + " " + str(p.x) + "\n"
  60.         return patch_str
  61.  
  62. ######################################################
  63. # main
  64. ######################################################
  65.  
  66. # the edge is the key, and a list of faces that use it are the value
  67. def edge_faces_dict(mesh):
  68.     edge_faces = dict([(edge.key, []) for edge in mesh.edges])
  69.     for face in mesh.faces:
  70.         for key in face.edge_keys:
  71.             edge_faces[key].append(face)
  72.     return edge_faces
  73.  
  74. # get next face that shares an edge
  75. def next_face_key(face, prev_key, edge_faces):
  76.     for key in face.edge_keys:
  77.         if key != prev_key:
  78.             faces = edge_faces[key]
  79.             if len(faces) == 2:
  80.                 if faces[0] == face:
  81.                     return faces[1], key
  82.                 else:
  83.                     return faces[0], key
  84.     return face, prev_key
  85.  
  86. # get back left, back right, front left, front right vertices
  87. # key0 is back edge, key1 is front edge
  88. def face_verts(key0, key1, mesh):
  89.     fl = mesh.verts[key1[0]].co
  90.     fr = mesh.verts[key1[1]].co
  91.     bl = mesh.verts[key0[0]].co
  92.     br = mesh.verts[key0[1]].co
  93.     f = fl - bl
  94.     if (br - bl).cross(f).z < 0: #z is up-axis!!!
  95.         bl, br = br, bl
  96.     if (fr - fl).cross(f).z < 0: #z is up-axis!!!
  97.         fl, fr = fr, fl
  98.     return fl, fr, bl, br
  99.  
  100. # closed loop track only atm ;)
  101. def create_track(mesh):
  102.     patches = []
  103.     edge_faces = edge_faces_dict(mesh)
  104.     for key, faces in edge_faces.iteritems():
  105.         if len(faces) == 2: break
  106.     f0, k0 = faces[0], key # first track face(closed loop track)
  107.     while 1:
  108.         f1, k1 = next_face_key(f0, k0, edge_faces)
  109.         if k1 == k0:
  110.             print "end of track\n"
  111.             break # end of track, oops
  112.         verts = face_verts(k0, k1, mesh)
  113.         patches.append(bpatch(verts))
  114.         f0, k0 = f1, k1
  115.         if k1 == key: break # loop closed, done
  116.     for i in range(len(patches)):
  117.         patches[i-1].attach(patches[i]) # closed loop track
  118.     return patches
  119.  
  120. # tracks are quad strip loop meshes named "track n" (n number of the track)
  121. def export_tracks(filepath):
  122.     # export tracks
  123.     trk = file(filepath, 'w')
  124.     editmode = Window.EditMode()
  125.     if editmode: Window.EditMode(0)
  126.     tracks = filter(lambda o: o.getType()=="Mesh" and o.name.startswith("track") , bpy.data.scenes.active.objects)
  127.     if len(tracks):
  128.         trk.write(str(len(tracks)) + "\n\n") #number of tracks
  129.     mesh = bpy.data.meshes.new('temp') # temporary mesh to hold actual (modified) mesh data
  130.     for track in tracks:
  131.         mesh.getFromObject(track)
  132.         mesh.transform(track.matrixWorld)
  133.         patches = create_track(mesh)
  134.         if len(patches):
  135.             trk.write(str(len(patches)) + "\n\n") #number of patches
  136.         for patch in patches:
  137.             trk.write(patch.string() + "\n")
  138.     if editmode: Window.EditMode(1)
  139.     trk.close()
  140.     # export start positions, lap segments(start/finich line)
  141.     txt = file(filepath + ".txt", 'w')
  142.     txt.write("cull faces = on\n")
  143.     txt.write("non-treaded friction coefficient = 1.0\n")
  144.     txt.write("treaded friction coefficient = 0.9\n")
  145.     lap = filter(lambda o: o.name.startswith("lap sequence "), bpy.data.scenes.active.objects)
  146.     txt.write("lap sequences = " + str(len(lap)) + "\n")
  147.     for l in lap:
  148.         #txt.write(l.name + " = " + str(l.LocX) + "," + str(l.LocY) + "," + str(l.LocZ) +"\n")
  149.         txt.write(l.name + " = " + str(l.LocY) + "," + str(l.LocZ) + "," + str(l.LocX) +"\n")
  150.     pos = filter(lambda ob: ob.name.startswith("start position "), bpy.data.scenes.active.objects)
  151.     for p in pos:
  152.         id = p.name.rsplit(' ', 1)[1]
  153.         q = p.mat.toQuat()
  154.         print str(q)
  155.         #txt.write(p.name + " = " + str(p.LocX) + "," + str(p.LocY) + "," + str(p.LocZ) + "\n")
  156.         txt.write(p.name + " = " + str(p.LocY) + "," + str(p.LocZ) + "," + str(p.LocX) + "\n")
  157.         txt.write("start orientation-xyz " + id + " = " + str(q[2]) + "," + str(q[0]) + "," + str(q[1]) + "\n")
  158.         txt.write("start orientation-w " + id + " = " + str(q[3]) + "\n")
  159.     txt.close()
  160.  
  161. Window.FileSelector(export_tracks, "Export TRK")
RAW Paste Data