diff options
author | Robert Holcomb <bob_holcomb@hotmail.com> | 2007-01-29 03:11:18 +0300 |
---|---|---|
committer | Robert Holcomb <bob_holcomb@hotmail.com> | 2007-01-29 03:11:18 +0300 |
commit | 2133d87d2141ce779e6c08c537ba3de5232b19b7 (patch) | |
tree | bd1031b61634df14bc2f6a38403dd754f715b1b8 /release/scripts/md2_export.py | |
parent | aa8b917587754abdc3d9634c83199cecf4d36cc5 (diff) |
Fixed accelerated openGL command list tri-strip generation for geometry. UV coordinates are still off a bit. Fixed bad frame list loading. I'm sleepy and need a snack.
Diffstat (limited to 'release/scripts/md2_export.py')
-rw-r--r-- | release/scripts/md2_export.py | 397 |
1 files changed, 190 insertions, 207 deletions
diff --git a/release/scripts/md2_export.py b/release/scripts/md2_export.py index 18bf5d5ff81..7eb16f0a480 100644 --- a/release/scripts/md2_export.py +++ b/release/scripts/md2_export.py @@ -2,15 +2,15 @@ """ Name: 'MD2 (.md2)' -Blender: 241 +Blender: 243 Group: 'Export' Tooltip: 'Export to Quake file format (.md2).' """ __author__ = 'Bob Holcomb' -__version__ = '0.17.5' +__version__ = '0.18' __url__ = ["Bob's site, http://bane.servebeer.com", - "Support forum, http://scourage.servebeer.com/phpbb/", "blender", "elysiun"] + "Support forum, http://bane.servebeer.com", "blender", "elysiun"] __email__ = ["Bob Holcomb, bob_holcomb:hotmail*com", "scripts"] __bpydoc__ = """\ This script Exports a Quake 2 file (MD2). @@ -120,7 +120,7 @@ def draw_gui(): ########## Scale slider-default is 1/8 which is a good scale for md2->blender g_scale= Slider("Scale Factor: ", EVENT_NOEVENT, 10, 95, 210, 18, - 1.0, 0.001, 10.0, 1, "Scale factor for obj Model"); + 1.0, 0.001, 10.0, 1, "Scale factor for object Model"); ######### Draw and Exit Buttons Button("Export",EVENT_SAVE_MD2 , 10, 10, 80, 18) @@ -615,21 +615,22 @@ def validation(object): global user_frame_list #move the object to the origin if it's not already there - if object.loc!=(0.0, 0.0, 0.0): + if object.getLocation('worldspace')!=(0.0, 0.0, 0.0): object.setLocation(0.0,0.0,0.0) print "Model not centered at origin-Centering" - result=Blender.Draw.PupMenu("Model not centered at origin-Centering") + result=Blender.Draw.PupMenu("Model not centered at origin-Centering for you") #resize the object in case it is not the right size - if object.size!=(1.0,1.0,1.0): + if object.getSize('worldspace')!=(1.0,1.0,1.0): object.setSize(1.0,1.0,1.0) print "Object is scaled-You should scale the mesh verts, not the object" - result=Blender.Draw.PupMenu("Object is scaled-You should scale the mesh verts, not the object") + result=Blender.Draw.PupMenu("Object is scaled-You should scale the mesh verts, not the object-fixing for you") - if object.rot!=(0.0,0.0,0.0): - object.rot=(0.0,0.0,0.0) + if object.getEuler('worldspace')!=Blender.Mathutils.Euler(0.0,0.0,0.0): + print "object.rot: ", object.getEuler('worldspace') + object.setEuler([0.0,0.0,0.0]) print "Object is rotated-You should rotate the mesh verts, not the object" - result=Blender.Draw.PupMenu("Object is rotated-You should rotate the mesh verts, not the object") + result=Blender.Draw.PupMenu("Object is rotated-You should rotate the mesh verts, not the object-fixing for you") #get access to the mesh data mesh=object.getData(False, True) #get the object (not just name) and the Mesh, not NMesh @@ -806,7 +807,7 @@ def fill_md2(md2, object): Blender.Window.DrawProgressBar(0.5, "Computing GL Commands") #compute GL commands - md2.num_GL_commands=build_GL_commands(md2) + md2.num_GL_commands=build_GL_commands(md2, mesh) #get the frame data #calculate 1 frame size + (1 vert size*num_verts) @@ -841,24 +842,26 @@ def fill_md2(md2, object): #to figure this out once per frame #we need to start with the bounding box - bounding_box=object.getBoundBox() #uses the object, not the mesh data + #bounding_box=object.getBoundBox() #uses the object, not the mesh data #initialize with the first vertex for both min and max. X and Y are swapped for MD2 format - point=bounding_box[0] - frame_min_x=point[1] - frame_max_x=point[1] - frame_min_y=point[0] - frame_max_y=point[0] - frame_min_z=point[2] - frame_max_z=point[2] - #find min/max values - for point in bounding_box: - if frame_min_x>point[1]: frame_min_x=point[1] - if frame_max_x<point[1]: frame_max_x=point[1] - if frame_min_y>point[0]: frame_min_y=point[0] - if frame_max_y<point[0]: frame_max_y=point[0] - if frame_min_z>point[2]: frame_min_z=point[2] - if frame_max_z<point[2]: frame_max_z=point[2] - + + #initialize + frame_min_x=100000.0 + frame_max_x=-100000.0 + frame_min_y=100000.0 + frame_max_y=-100000.0 + frame_min_z=100000.0 + frame_max_z=-100000.0 + + for face in mesh.faces: + for vert in face.verts: + if frame_min_x>vert.co[1]: frame_min_x=vert.co[1] + if frame_max_x<vert.co[1]: frame_max_x=vert.co[1] + if frame_min_y>vert.co[0]: frame_min_y=vert.co[0] + if frame_max_y<vert.co[0]: frame_max_y=vert.co[0] + if frame_min_z>vert.co[2]: frame_min_z=vert.co[2] + if frame_max_z<vert.co[2]: frame_max_z=vert.co[2] + #the scale is the difference between the min and max (on that axis) / 255 frame_scale_x=(frame_max_x-frame_min_x)/255 frame_scale_y=(frame_max_y-frame_min_y)/255 @@ -880,6 +883,7 @@ def fill_md2(md2, object): #figure out the new coords based on scale and transform #then translates the point so it's not less than 0 #then scale it so it's between 0..255 + #print "frame scale : ", frame_scale_x, " ", frame_scale_y, " ", frame_scale_z new_x=int((mesh.verts[vert_counter].co[1]-frame_trans_x)/frame_scale_x) new_y=int((mesh.verts[vert_counter].co[0]-frame_trans_y)/frame_scale_y) new_z=int((mesh.verts[vert_counter].co[2]-frame_trans_z)/frame_scale_z) @@ -890,9 +894,10 @@ def fill_md2(md2, object): maxdot = -999999.0; maxdotindex = -1; + for j in range(0,162): - #dot = (x[0]*y[0]+x[1]*y[1]+x[2]*y[2]) - #swap y and x for difference in axis orientation + dot = (x[0]*y[0]+x[1]*y[1]+x[2]*y[2]) + swap y and x for difference in axis orientation x1=-mesh.verts[vert_counter].no[1] y1=mesh.verts[vert_counter].no[0] z1=mesh.verts[vert_counter].no[2] @@ -903,7 +908,7 @@ def fill_md2(md2, object): maxdot = dot; maxdotindex = j; - md2.frames[frame_counter].vertices[vert_counter].lightnormalindex=maxdotindex + md2.frames[frame_counter].vertices[vert_counter].lightnormalindex=maxdotindex+2 del maxdot, maxdotindex del new_x, new_y, new_z @@ -951,7 +956,7 @@ def get_frame_list(): file.close() #check header (first line) - if lines[0]<>"# MD2 Frame Name List": + if lines[0].stip()<>"# MD2 Frame Name List": print "its not a valid file" result=Blender.Draw.PupMenu("This is not a valid frame definition file-using default%t|OK") return MD2_FRAME_NAME_LIST @@ -959,7 +964,7 @@ def get_frame_list(): #read in the data num_frames=0 for counter in range(1, len(lines)): - current_line=lines[counter] + current_line=lines[counter].strip() if current_line[0]=="#": #found a comment pass @@ -977,225 +982,203 @@ def get_frame_list(): # Globals for GL command list calculations ###################################################### used_tris=[] +edge_dict={} strip_verts=[] strip_st=[] strip_tris=[] -strip_count=0 +strip_first_run=True +odd=False ###################################################### -# Tri-Strip/Tri-Fan functions +# Find Strip length function ###################################################### -def find_strip_length(md2, start_tri, start_vert): - print "Finding strip length" +def find_strip_length(mesh, start_tri, edge_key): + #print "Finding strip length" - global used - global strip_verts - global strip_st + global used_tris + global edge_dict global strip_tris - - m1=m2=0 - - used[start_tri]=2 + global strip_st + global strip_verts + global strip_first_run + global odd - strip_verts=[0]*0 - strip_tris=[0]*0 - strip_st=[0]*0 + used_tris[start_tri]=2 + strip_tris.append(start_tri) #add this tri to the potential list of tri-strip - strip_verts.append(md2.faces[start_tri].vertex_index[start_vert%3]) - strip_verts.append(md2.faces[start_tri].vertex_index[(start_vert+2)%3]) - strip_verts.append(md2.faces[start_tri].vertex_index[(start_vert+1)%3]) + #print "I am face: ", start_tri + #print "Using edge Key: ", edge_key - strip_st.append(md2.faces[start_tri].texture_index[start_vert%3]) - strip_st.append(md2.faces[start_tri].texture_index[(start_vert+2)%3]) - strip_st.append(md2.faces[start_tri].texture_index[(start_vert+1)%3]) - - strip_count=1 - strip_tris.append(start_tri) - - m1=md2.faces[start_tri].vertex_index[(start_vert+2)%3] - m2=md2.faces[start_tri].vertex_index[(start_vert+1)%3] - - for tri_counter in range(start_tri+1, md2.num_faces): - for k in range(0,3): - if(md2.faces[tri_counter].vertex_index[k]!=m1) or (md2.faces[tri_counter].vertex_index[(k+1)%3]!=m2): + faces=edge_dict[edge_key] #get list of face indexes that share this edge + if (len(faces)==0): + #print "Cant find edge with key: ", edge_key + + #print "Faces sharing this edge: ", faces + for face_index in faces: + face=mesh.faces[face_index] + if face_index==start_tri: #don't want to check myself + #print "I found myself, continuing" + pass + else: + if used_tris[face_index]!=0: #found a used tri-move along + #print "Found a used tri: ", face_index pass - else: - #found a matching edge - print "Found a triangle with a matching edge: ", tri_counter - if(used[tri_counter]!=0): - print "Poop! I can't use it!" + else: + #find non-shared vert + for vert_counter in range(0,3): + if (face.verts[vert_counter].index!=edge_key[0] and face.verts[vert_counter].index!=edge_key[1]): + next_vert=vert_counter + + if(odd==False): + #print "Found a suitable even connecting tri: ", face_index + used_tris[face_index]=2 #mark as dirty for this rum + odd=True + + #find the new edge + if(face.verts[next_vert].index < face.verts[(next_vert+2)%3].index): + temp_key=(face.verts[next_vert].index,face.verts[(next_vert+2)%3].index) + else: + temp_key=(face.verts[(next_vert+2)%3].index, face.verts[next_vert].index) + #print "temp key: ", temp_key + temp_faces=edge_dict[temp_key] + if(len(temp_faces)==0): + print "Can't find any other faces with key: ", temp_key + else: + #search the new edge + #print "found other faces, searching them" + find_strip_length(mesh, face_index, temp_key) #recursive greedy-takes first tri it finds as best + break; else: - print "Yeah! I can use it" - - if(strip_count%2==1): #is this an odd tri - print "odd triangle" - m2=md2.faces[tri_counter].vertex_index[(k+2)%3] + #print "Found a suitable odd connecting tri: ", face_index + used_tris[face_index]=2 #mark as dirty for this rum + odd=False + + #find the new edge + if(face.verts[next_vert].index < face.verts[(next_vert+1)%3].index): + temp_key=(face.verts[next_vert].index,face.verts[(next_vert+1)%3].index) else: - print "even triangle" - m1=md2.faces[tri_counter].vertex_index[(k+2)%3] - - strip_verts.append(md2.faces[tri_counter].vertex_index[(k+2)%3]) - strip_st.append(md2.faces[tri_counter].texture_index[(k+2)%3]) - strip_count+=1 - strip_tris.append(tri_counter) - - used[tri_counter]=2 - tri_counter=start_tri+1 # restart looking + temp_key=(face.verts[(next_vert+1)%3].index, face.verts[next_vert].index) + #print "temp key: ", temp_key + temp_faces=edge_dict[temp_key] + if(len(temp_faces)==0): + print "Can't find any other faces with key: ", temp_key + else: + #search the new edge + #print "found other faces, searching them" + find_strip_length(mesh, face_index, temp_key) #recursive greedy-takes first tri it finds as best + break; - #clear used counter - for used_counter in range(0, md2.num_faces): - if used[used_counter]==2: - used[used_counter]=0 + return len(strip_tris) - return strip_count -#*********************************************** -def find_fan_length(md2, start_tri, start_vert): - print "Finding fan length" - - global used - global strip_verts +###################################################### +# Tri-Stripify function +###################################################### +def stripify_tri_list(mesh, edge_key): + global edge_dict global strip_tris global strip_st + global strip_verts - strip_verts=[0]*0 - strip_tris=[0]*0 - strip_st=[0]*0 - - m1=m2=0 - - used[start_tri]=2 - - strip_verts.append(md2.faces[start_tri].vertex_index[start_vert%3]) - strip_verts.append(md2.faces[start_tri].vertex_index[(start_vert+2)%3]) - strip_verts.append(md2.faces[start_tri].vertex_index[(start_vert+1)%3]) + shared_edge=[] + key=[] - strip_st.append(md2.faces[start_tri].texture_index[start_vert%3]) - strip_st.append(md2.faces[start_tri].texture_index[(start_vert+2)%3]) - strip_st.append(md2.faces[start_tri].texture_index[(start_vert+1)%3]) - - strip_count=1 - strip_tris.append(start_tri) - - m1=md2.faces[start_tri].vertex_index[(start_vert)] - m2=md2.faces[start_tri].vertex_index[(start_vert+1)%3] + #print "*****Stripify the triangle list*******" + #print "strip tris: ", strip_tris + #print "strip_tri length: ", len(strip_tris) + + for tri_counter in range(0, len(strip_tris)): + face=mesh.faces[strip_tris[tri_counter]] + if (tri_counter==0): #first one only + #find non-edge vert + for vert_counter in range(0,3): + if (face.verts[vert_counter].index!=edge_key[0] and face.verts[vert_counter].index!=edge_key[1]): + start_vert=vert_counter + strip_verts.append(face.verts[start_vert].index) + strip_st.append(face.uv[start_vert]) + + strip_verts.append(face.verts[(start_vert+2)%3].index) + strip_st.append(face.uv[(start_vert+2)%3]) - for tri_counter in range(start_tri+1, md2.num_faces): - for k in range(0,3): - if (md2.faces[tri_counter].vertex_index[k]!=m1) or (md2.faces[tri_counter].vertex_index[(k+1)%3]!=m2): - pass - else: - #found a matching edge - print "Found a triangle with a matching edge: ", tri_counter - if(used[tri_counter]!=0): - print "Poop! I can't use it!" - else: - print "Yeah! I can use it" - - m2=md2.faces[tri_counter].vertex_index[(k+1)%3] - - strip_verts.append(md2.faces[tri_counter].vertex_index[(k+1)%3]) - strip_st.append(md2.faces[tri_counter].texture_index[(k+1)%3]) - - strip_count+=1 - strip_tris.append(tri_counter) - - used[tri_counter]=2 - tri_counter=start_tri+1 #restart looking - - #clear used counter - for used_counter in range(0, md2.num_faces): - if used[used_counter]==2: - used[used_counter]=0 - - return strip_count + strip_verts.append(face.verts[(start_vert+1)%3].index) + strip_st.append(face.uv[(start_vert+1)%3]) + else: + for vert_counter in range(0,3): + if(face.verts[vert_counter].index!=strip_verts[-1] and face.verts[vert_counter].index!=strip_verts[-2]): + strip_verts.append(face.verts[vert_counter].index) + strip_st.append(face.uv[vert_counter]) + break + + ###################################################### # Build GL command List ###################################################### -def build_GL_commands(md2): +def build_GL_commands(md2, mesh): print "Building GL Commands" - global used + global used_tris + global edge_dict global strip_verts global strip_tris global strip_st #globals initialization - used=[0]*md2.num_faces - print "Used: ", used + used_tris=[0]*len(mesh.faces) + #print "Used: ", used_tris num_commands=0 + + #edge dictionary generation + edge_dict=dict([(ed.key,[]) for ed in mesh.edges]) + for face in (mesh.faces): + for key in face.edge_keys: + edge_dict[key].append(face.index) + + #print "edge Dict: ", edge_dict - for tri_counter in range(0,md2.num_faces): - if used[tri_counter]!=0: - print "Found a used triangle: ", tri_counter + for tri_counter in range(0,len(mesh.faces)): + if used_tris[tri_counter]!=0: + #print "Found a used triangle: ", tri_counter + pass else: - print "Found an unused triangle: ", tri_counter + #print "Found an unused triangle: ", tri_counter #intialization - best_length=0 - best_type=0 - best_verts=[0]*0 - best_tris=[0]*0 - best_st=[0]*0 + strip_tris=[0]*0 + strip_verts=[0]*0 + strip_st=[0]*0 + strip_first_run=True + odd=True - - for start_vert in range(0,3): - fan_length=find_fan_length(md2, tri_counter, start_vert) - #fan_length=0 - print "Triangle: ", tri_counter, " Vertex: ", start_vert, " Fan Length: ", fan_length - - if (fan_length>best_length): - best_type=1 - best_length=fan_length - best_verts=strip_verts - best_tris=strip_tris - best_st=strip_st - - #strip_length=find_strip_length(md2, tri_counter, start_vert) - strip_length=0 - print "Triangle: ", tri_counter, " Vertex: ", start_vert, " Strip Length: ", strip_length - - if (strip_length>best_length): - best_type=0 - best_length=strip_length - best_verts=strip_verts - best_tris=strip_tris - best_st=strip_st - - print "Best length for this triangle is: ", best_length - print "Best type is: ", best_type - print "Best Tris are: ", best_tris - print "Best Verts are: ", best_verts - print "Best ST are: ", best_st - + #find the strip length + strip_length=find_strip_length(mesh, tri_counter, mesh.faces[tri_counter].edge_keys[0]) #mark tris as used - for used_counter in range(0,best_length): - used[best_tris[used_counter]]=1 + for used_counter in range(0,strip_length): + used_tris[strip_tris[used_counter]]=1 + + stripify_tri_list(mesh, mesh.faces[tri_counter].edge_keys[0]) #create command list cmd_list=md2_GL_cmd_list() - if best_type==0: - cmd_list.num=(-(best_length+2)) - else: - cmd_list.num=best_length+2 - + #number of commands in this list + print "strip length: ", strip_length + cmd_list.num=(len(strip_tris)+2) #positive for strips, fans would be negative, but not supported yet num_commands+=1 - for command_counter in range(0,best_length+2): - cmd=md2_GL_command() - s=md2.tex_coords[best_st[command_counter]].u - t=md2.tex_coords[best_st[command_counter]].v - cmd.s=s/float(md2.skin_width) - cmd.t=t/float(md2.skin_height) - cmd.vert_index=best_verts[command_counter] + + #add s,t,vert for this command list + for command_counter in range(0, len(strip_tris)+2): + cmd=md2_GL_command() + cmd.s=strip_st[command_counter][0] + cmd.t=1.0-strip_st[command_counter][1] #flip upside down + cmd.vert_index=strip_verts[command_counter] num_commands+=3 cmd_list.cmd_list.append(cmd) - cmd_list.dump() - md2.GL_commands.append(cmd_list) - - print "Used: ", used + print "Cmd List length: ", len(cmd_list.cmd_list) + print "Cmd list num: ", cmd_list.num + print "Cmd List: ", cmd_list.dump() + md2.GL_commands.append(cmd_list) #add the null command at the end temp_cmdlist=md2_GL_cmd_list() @@ -1204,7 +1187,7 @@ def build_GL_commands(md2): num_commands+=1 #cleanup and return - used=best_vert=best_st=best_tris=strip_vert=strip_st=strip_tris=0 + used=strip_vert=strip_st=strip_tris=0 return num_commands @@ -1260,4 +1243,4 @@ def save_md2(filename): #cleanup md2=0 - print "Closed the file" + print "Closed the file"
\ No newline at end of file |