Login x
User Name:
Password:
Social Links Facebook Twitter YouTube Steam RSS News Feeds

Members Online

»
0 Active | 7 Guests
Online:

LATEST FORUM THREADS

»
warfare
CoD4 Map + Mod Releases
Voting menu on maps
CoD+UO General
Hauling 911
CoDBO3 General

Forums

»

Welcome to the MODSonline.com forums. Looking for Frequently Asked Questions? Check out our FAQs section or search it out using the SEARCH link below. If you are new here, you may want to check out our rules and this great user's guide to the forums and the website.
For more mapping and modding information, see our Wiki: MODSonWiki.com

Jump To:
Forum: All Forums : Soldier of Fortune
Category: SoFII Mapping
Mapping, modeling, scripting, skinning and all forms of editing for the game Soldier of Fortune II
Moderators: foyleman, Foxhound, Mystic, StrYdeR, batistablr, Welshy, DrBiggzz, supersword
Latest Posts
Subscribed Posts
Search
Restricted Access Topic is Locked subscribe
Author Topic: custom models
[STK]Ran[)omHomicide
General Member
Since: Jun 17, 2004
Posts: 189
Last: Nov 4, 2007
[view latest posts]
Level 4
Category: SoFII Mapping
Posted: Friday, Jun. 30, 2006 04:56 am
hi all,

been along time since ive posted, as well has been the time ive worked on moding sof2. well bf2 got old and the editing for that thing is jus childishly easy. sooo i plan to revamp sof2 one of my all time favorites and still to this day the only game i know of that you can effectivly look around corners i think i played anouther but the lean was useless.... when i get done i hope to make it from top to bottom a new game and release it. well im getting all my own materials and maps together no problem even got all new menus and loading screens (no lame stuff i promise) but the first obstacle i have run into is that i cant seem to get my custom models imported into the game... i have no clue why my abilities with this are some what limited but i did what i could before i once agian pleaded for your help... i put my md3 models in folders where they belonged i made what seemed to be apropriate shaders i hear milkshape is a must to make this happen so ive imported and exported to other formats hopping this might help they sure looked right in milkshape either way im in need of some know how foyleman if your reading this (and i hope you are, you always have the best answers) good to see you around after all this time. [2guns]
Share |
[STK]Ran[)omHomicide
General Member
Since: Jun 17, 2004
Posts: 189
Last: Nov 4, 2007
[view latest posts]
Level 4
Category: SoFII Mapping
Posted: Friday, Jun. 30, 2006 05:13 am
jus want to be clear on somethings that might be helpfull might not. in the editor.... textures not showing. consold is telling me its an active shader problem.... as far as in game goes it wont even let me join thanks for anyone that can help[2guns]
Share |
kit89
General Member
Since: Aug 1, 2006
Posts: 4
Last: Oct 18, 2006
[view latest posts]
Level 0
Category: SoFII Mapping
Posted: Tuesday, Aug. 1, 2006 05:40 pm
You dont need milkshape to produce custom models. :D

I use Blender (www.blender3d.com), using this python script:

#!BPY

"""
Name: 'MD3 (+shaders)'
Blender: 234
Group: 'Export'
Tip: 'Export to Quake 3 file format. (.md3)'
"""

######################################################
# MD3 Exporter
# Original By: Bob Holcomb
# Modified By: Damien McGinnes
# Date: 23 Oct 04
# Ver: 0.2
######################################################
# This script exports a Quake 3 file (MD3), textures,
# and animations from blender for playing.
# Loader is based on MD3 loader
# from www.gametutorials.com-Thanks DigiBen! and the
# md3 blender loader by PhaethonH
######################################################

######################################################
# This exporter has been extended to write textured
# materials info as MD3 shaders.
#
# The first encountered texture in a mesh object is
# used as the shader for the whole object.
#
# Modified by: Arsenij Vodjanov
# Date: 2 Feb 2005
######################################################

import Blender
from Blender import NMesh, Object, Draw, BGL
from Blender import *
#from Blender.BGL import *
#from Blender.Draw import *
from Blender.Image import *

import sys, struct, string, math
from types import *

import os
from os import path



######################################################
# Main Body
######################################################


def asciiz (s):
n = 0
while (ord(s[n]) != 0):
n = n + 1
return s[0:n]

def apply_transform(vert, matrix):
vertCopy = Mathutils.CopyVec(vert)
vertCopy.resize4D()
return Mathutils.VecMultMat(vertCopy, matrix)



######################################################
# MD3 Model Constants
######################################################
MD3_IDENT = "IDP3"
MD3_VERSION = 15
MD3_MAX_QPATH=64
MD3_MAX_TAGS=16
MD3_MAX_SURFACES=32
MD3_MAX_FRAMES=1024
MD3_MAX_SHADERS=256
MD3_MAX_VERTICES=4096
MD3_MAX_TRIANGLES=8192
MD3_XYZ_SCALE=(1.0/64.0)

FLIP_TEX_V_ON_EXPORT=1
NUM_FRAMES = 1
EXPORT_ALL = 0 #export only selected objs, or all?

######################################################
# MD3 data structures
######################################################
class vert:
co=[]

def __init__(self):
self.co=[0]*3
self.co[0]=0.0
self.co[1]=0.0
self.co[2]=0.0

class md3_vert:
co=[]
normal=0
binary_format="<3hh"

def __init__(self):
self.co=[0]*3
self.normal=0

def getsize(self):
return struct.calcsize(self.binary_format)

#copied from PhaethonH md3.py
def decode (self, latlng):
#Decode 16-bit latitude-longitude value into a normal vector.
#Code ripped from q3toosl/q3map/misc_model.c:
# // decode the lat/lng normal to a 3 float normal
# lat = ( xyz->normal >> 8 ) & 0xff;
# lng = ( xyz->normal & 0xff );
# lat *= Q_PI/128;
# lng *= Q_PI/128;
#
# temp[0] = cos(lat) * sin(lng);
# temp[1] = sin(lat) * sin(lng);
# temp[2] = cos(lng);
lat = (latlng >> 8) & 0xFF;
lng = (latlng) & 0xFF;
lat *= math.pi/128;
lng *= math.pi/128;
x = math.cos(lat) * math.sin(lng)
y = math.sin(lat) * math.sin(lng)
z = math.cos(lng)
retval = [ x, y, z ]
return retval

#copied from PhaethonH md3.py
#modified so hopefully it will work ;)
def encode (self, normal):
#Encode a normal vector into a 16-bit latitude-longitude value.
x, y, z = normal
#normalise
l = math.sqrt((x*x) + (y*y) + (z*z))
if l == 0:
return 0
x = x/l
y = y/l
z = z/l

if (x == 0.0) & (y == 0.0) :
if z > 0.0:
return 0
else:
return (128 << 8)

lng = math.acos(z) * 255 / (2 * math.pi)
lat = math.atan2(y, x) * 255 / (2 * math.pi)
retval = ((int(lat) & 0xFF) << 8) | (int(lng) & 0xFF)
return retval

def load(self,file):
temp_data=file.read(struct.calcsize(self.binary_format))
data=struct.unpack(self.binary_format, temp_data)
self.co[0:3]=data[0:3]
self.normal=data[3]
return self

def save(self, file):
temp_data=[0]*4
temp_data[0]=self.co[0]/MD3_XYZ_SCALE
temp_data[1]=self.co[1]/MD3_XYZ_SCALE
temp_data[2]=self.co[2]/MD3_XYZ_SCALE
temp_data[3]=self.normal
data=struct.pack(self.binary_format, temp_data[0], temp_data[1], temp_data[2], temp_data[3])
file.write(data)
#print "Wrote MD3 Vertex: "
#self.dump()

def dump(self):
print "MD3 Vertex Structure"
print "X: ", self.co[0]/MD3_XYZ_SCALE
print "Y: ", self.co[1]/MD3_XYZ_SCALE
print "Z: ", self.co[2]/MD3_XYZ_SCALE
print "Normal: ", self.normal
print ""

class md3_tex_coord:
u=0.0
v=0.0

binary_format="<2f"

def __init__(self):
self.u=0.0
self.v=0.0

def getsize(self):
return struct.calcsize(self.binary_format)

def load (self, file):
temp_data=file.read(struct.calcsize(self.binary_format))
data=struct.unpack(self.binary_format, temp_data)
self.u=data[0]
self.v=data[1]
return self

def save(self, file):
temp_data=[0]*2
temp_data[0]=self.u
if FLIP_TEX_V_ON_EXPORT:
temp_data[1]=1.0 - self.v
else:
temp_data[1]=self.v
data=struct.pack(self.binary_format, temp_data[0], temp_data[1])
file.write(data)
#print "wrote MD3 texture coordinate structure: "
#self.dump()

def dump (self):
print "MD3 Texture Coordinate Structure"
print "texture coordinate u: ",self.u
print "texture coordinate v: ",self.v
print ""


class md3_triangle:
vertex_index=[]

binary_format="<3i"

def __init__(self):
self.vertex_index = [ 0, 0, 0 ]

def getsize(self):
return struct.calcsize(self.binary_format)

def load (self, file):
temp_data=file.read(struct.calcsize(self.binary_format))
data=struct.unpack(self.binary_format, temp_data)
self.vertex_index[0:3]=data[0:3]
return self

def save(self, file):
temp_data=[0]*3
temp_data[0]=self.vertex_index[0]
temp_data[1]=self.vertex_index[2] #reverse
temp_data[2]=self.vertex_index[1] #reverse
data=struct.pack(self.binary_format,temp_data[0],temp_data[1],temp_data[2])
file.write(data)
#print "wrote MD3 tri structure: "
#self.dump()

def dump (self):
print "MD3 Triangle Structure"
print "vertex index: ", self.vertex_index[0]
print "vertex index: ", self.vertex_index[2] #reverse
print "vertex index: ", self.vertex_index[1] #reverse
print ""


class md3_shader:
name=""
index=0

binary_format="<%dsi" % MD3_MAX_QPATH

def __init__(self):
self.name=""
self.index=0

def getsize(self):
return struct.calcsize(self.binary_format)

def load (self, file):
temp_data=file.read(struct.calcsize(self.binary_format))
data=struct.unpack(self.binary_format, temp_data)
self.name=asciiz(data[0])
self.index=data[1]
return self

def save(self, file):
temp_data=[0]*2
temp_data[0]=self.name
temp_data[1]=self.index
data=struct.pack(self.binary_format, temp_data[0], temp_data[1])
file.write(data)
#print "wrote MD3 shader structure: "
#self.dump()

def dump (self):
print "MD3 Shader"
print "shader name: ",self.name
print "shader index: ",self.index
print ""


class md3_surface:
ident=""
name=""
flags=0
num_frames=0
num_shaders=0
num_verts=0
num_tris=0
offset_tris=0
offset_shaders=0
offset_uv=0
offset_verts=0
offset_end=0
shaders=[]
tris=[]
uv=[]
verts=[]

binary_format="<4s%ds10i" % MD3_MAX_QPATH #1 int, name, then 10 ints

def __init__(self):
self.ident=""
self.name=""
self.flags=0
self.num_frames=0
self.num_shaders=0
self.num_verts=0
self.num_tris=0
self.offset_tris=0
self.offset_shaders=0
self.offset_uv=0
self.offset_verts=0
self.offset_end
self.shaders=[]
self.tris=[]
self.uv=[]
self.verts=[]

def getsize(self):
sz =struct.calcsize(self.binary_format)
self.offset_tris = sz
for t in self.tris:
sz += t.getsize()
self.offset_shaders = sz
for s in self.shaders:
sz += s.getsize()
self.offset_uv = sz
for u in self.uv:
sz += u.getsize()
self.offset_verts = sz
for v in self.verts:
sz += v.getsize()
self.offset_end = sz
return self.offset_end

def load (self, file):
#where are we in the file (for calculating real offsets)
offset_begin=file.tell()
temp_data=file.read(struct.calcsize(self.binary_format))
data=struct.unpack(self.binary_format, temp_data)
self.ident=data[0]
self.name=asciiz(data[1])
self.flags=data[2]
self.num_frames=data[3]
self.num_shaders=data[4]
self.num_verts=data[5]
self.num_tris=data[6]
self.offset_tris=data[7]
self.offset_shaders=data[8]
self.offset_uv=data[9]
self.offset_verts=data[10]
self.offset_end=data[11]

#load the tri info
file.seek(offset_begin+self.offset_tris,0)
for i in range(0, self.num_tris):
self.tris.append(md3_triangle())
self.tris.load(file)
#self.tris.dump()

#load the shader info
file.seek(offset_begin+self.offset_shaders,0)
for i in range(0, self.num_shaders):
self.shaders.append(md3_shader())
self.shaders.load(file)
#self.shaders.dump()

#load the uv info
file.seek(offset_begin+self.offset_uv,0)
for i in range(0, self.num_tris*3):
self.uv.append(md3_tex_coord())
self.uv.load(file)
#self.uv.dump()

#load the verts info
file.seek(offset_begin+self.offset_verts,0)
for i in range(0, self.num_verts):
self.verts.append(md3_vert())
self.verts.load(file)
#self.verts.dump()

#go to the end of this structure
file.seek(offset_begin+self.offset_end, 0)

return self

def save(self, file):
self.getsize()

temp_data=[0]*12
temp_data[0]=self.ident
temp_data[1]=self.name
temp_data[2]=self.flags
temp_data[3]=self.num_frames
temp_data[4]=self.num_shaders
temp_data[5]=self.num_verts
temp_data[6]=self.num_tris
temp_data[7]=self.offset_tris
temp_data[8]=self.offset_shaders
temp_data[9]=self.offset_uv
temp_data[10]=self.offset_verts
temp_data[11]=self.offset_end
data=struct.pack(self.binary_format, temp_data[0],temp_data[1],temp_data[2],temp_data[3],temp_data[4],temp_data[5],temp_data[6],temp_data[7],temp_data[8],temp_data[9],temp_data[10],temp_data[11])
file.write(data)

dat = struct.unpack(self.binary_format, data)
#write the tri data
for t in self.tris:
t.save(file)

#save the shader coordinates
for s in self.shaders:
s.save(file)

#save the uv info
for u in self.uv:
u.save(file)

#save the verts
for v in self.verts:
v.save(file)

#print "finished writing md3 surf"
#self.dump()

def dump (self):
#for s in self.shaders:
# s.dump()
print "MD3 Surface"
print "Ident: ", self.ident
print "Name: ", self.name
print "Flags: ", self.flags
print "Number of Frames: ", self.num_frames
print "Number of Shaders: ", self.num_shaders, "len shaders", len(self.shaders)
print "Number of Verts: ", self.num_verts, "len uvs:", len(self.uv), "len verts:", len(self.verts)
print "Number of Triangles: ", self.num_tris, "len tris:", len(self.tris)
print "Offset to Triangles: ",self.offset_tris
print "Offset to Shaders: ",self.offset_shaders
print "Offset to UV: ", self.offset_uv
print "Offset to Verts: ", self.offset_verts
print "Offset to end: ", self.offset_end
print ""


class md3_tag:
name=""
origin=[]
axis=[]

binary_format="<%ds3f9f" % MD3_MAX_QPATH

def __init__(self):
self.name=""
self.origin=vert()
self.axis=[vert()]*3

def getsize(self):
return struct.calcsize(self.binary_format)

def load(self, file):
temp_data=file.read(struct.calcsize(self.binary_format))
data=struct.unpack(self.binary_format, temp_data)
self.name=asciiz(data[0])
self.origin.co[0:3]=data[1:4]
self.axis[0].co[0:3]=data[4:7]
self.axis[1].co[0:3]=data[7:10]
self.axis[2].co[0:3]=data[10:13]
return self

def save(self, file):
temp_data=[0]*13
temp_data[0]=self.name
temp_data[1:4]=float(self.origin.co[0:3])
temp_data[4:7]=float(self.axis[0].co[0:3])
temp_data[7:10]=float(self.axis[1].co[0:3])
temp_data[10:13]=float(self.axis[2].co[0:3])
data=struct.pack(self.binary_format, temp_data[0],temp_data[1],temp_data[2],temp_data[3],temp_data[4],temp_data[5],temp_data[6], temp_data[7], temp_data[8], temp_data[9], temp_data[10], temp_data[11], temp_data[12])
file.write(data)
#print "wrote MD3 Tag structure: "
#self.dump()

def dump(self):
print "MD3 Tag"
print "Name: ", self.name
print "Origin: ",self.origin.co
print "Axis: ",self.axis[0].co, self.axis[1].co, self.axis[2].co
print ""

class md3_frame:
min_bounds=0
max_bounds=0
local_origin=0
radius=0.0
name=""

binary_format="<3f3f3ff16s"

def __init__(self):
self.min_bounds=vert()
self.max_bounds=vert()
self.local_origin=vert()
self.radius=0.0
self.name=""

def getsize(self):
return struct.calcsize(self.binary_format)

def load (self, file):
temp_data=file.read(struct.calcsize(self.binary_format))
data=struct.unpack(self.binary_format, temp_data)
self.min_bounds.co[0:3]=data[0:3]
self.max_bounds.co[0:3]=data[3:6]
self.local_origin.co[0:3]=data[6:9]
self.radius=data[9]
self.name=asciiz(data[10])
return self

def save(self, file):
temp_data=[0]*11
temp_data[0:3]=self.min_bounds.co[0:3]
temp_data[3:6]=self.max_bounds.co[0:3]
temp_data[6:9]=self.local_origin.co[0:3]
temp_data[9]=self.radius
temp_data[10]=self.name
data=struct.pack(self.binary_format, temp_data[0],temp_data[1],temp_data[2],temp_data[3],temp_data[4],temp_data[5],temp_data[6],temp_data[7], temp_data[8], temp_data[9], temp_data[10])
file.write(data)
#print "wrote MD3 frame structure: "
#self.dump()

def dump (self):
print "MD3 Frame"
print "Min Bounds: ",self.min_bounds.co
print "Max Bounds: ",self.max_bounds.co
print "Local Origin: ",self.local_origin.co
print "Radius: ",self.radius
print "Name: ",self.name
print ""

class md3_obj:
#Header Structure
ident="" #This is used to identify the file (must be IDP3)
version=0 #The version number of the file (Must be 15)
name=""
flags=0
num_frames=0
num_tags=0
num_surfaces=0
num_skins=0 #don't think this is used, but here anyways
offset_frames=0
offset_tags=0
offset_surfaces=0
offset_end=0
frames=[]
tags=[]
surfaces=[]

binary_format="<4si%ds9i" % MD3_MAX_QPATH #little-endian (<), 17 integers (17i)

def __init__ (self):
self.ident=""
self.version=0
self.name=""
self.flags=0
self.num_frames=0
self.num_tags=0
self.num_surfaces=0
self.num_skins=0
self.offset_frames=0
self.offset_tags=0
self.offset_surfaces=0
self.offset_end=0
self.frames=[]
self.tags=[]
self.surfaces=[]

def getsize(self):
self.offset_frames = struct.calcsize(self.binary_format)
self.offset_tags = self.offset_frames
for f in self.frames:
self.offset_tags += f.getsize()
self.offset_surfaces += self.offset_tags
for t in self.tags:
self.offset_surfaces += t.getsize()
self.offset_end = self.offset_surfaces
for s in self.surfaces:
self.offset_end += s.getsize()
return self.offset_end

def load (self, file):
temp_data = file.read(struct.calcsize(self.binary_format))
data = struct.unpack(self.binary_format, temp_data)

self.ident=data[0]
self.version=data[1]

if (self.ident!="IDP3" or self.version!=15):
print "Not a valid MD3 file"
print "Ident=", self.ident
print "Version=",self.version
Exit()

self.name=asciiz(data[2])
self.flags=data[3]
self.num_frames=data[4]
self.num_tags=data[5]
self.num_surfaces=data[6]
self.num_skins=data[7]
self.offset_frames=data[8]
self.offset_tags=data[9]
self.offset_surfaces=data[10]
self.offset_end=data[11]

#load the frame info
file.seek(self.offset_frames,0)
for i in range(0, self.num_frames):
self.frames.append(md3_frame())
self.frames.load(file)
#self.frames.dump()

#load the tags info
file.seek(self.offset_tags,0)
for i in range(0, self.num_tags):
self.tags.append(md3_tag())
self.tags.load(file)
#self.tags.dump()

#load the surface info
file.seek(self.offset_surfaces,0)
for i in range(0, self.num_surfaces):
self.surfaces.append(md3_surface())
self.surfaces.load(file)
self.surfaces.dump()
return self

def save(self, file):
self.getsize()
temp_data=[0]*12
temp_data[0]=self.ident
temp_data[1]=self.version
temp_data[2]=self.name
temp_data[3]=self.flags
temp_data[4]=self.num_frames
temp_data[5]=self.num_tags
temp_data[6]=self.num_surfaces
temp_data[7]=self.num_skins
temp_data[8]=self.offset_frames
temp_data[9]=self.offset_tags
temp_data[10]=self.offset_surfaces
temp_data[11]=self.offset_end

data=struct.pack(self.binary_format, temp_data[0],temp_data[1],temp_data[2],temp_data[3],temp_data[4],temp_data[5],temp_data[6],temp_data[7], temp_data[8], temp_data[9], temp_data[10], temp_data[11])
file.write(data)

for f in self.frames:
f.save(file)
for t in self.tags:
t.save(file)
for s in self.surfaces:
s.save(file)


def dump (self):
#for s in self.surfaces:
# s.dump()
print "Header Information"
print "ident: ", self.ident
print "version: ", self.version
print "Name: ", self.name
print "Flags: ", self.flags
print "Number of Frames: ",self.num_frames, "len frames", len(self.frames)
print "Number of Tags: ", self.num_tags, "len tags:", len(self.tags)
print "Number of Surfaces: ", self.num_surfaces, "len surfaces:", len(self.surfaces)
print "Number of Skins: ", self.num_skins
print "Offset Frames: ", self.offset_frames
print "Offset Tags: ", self.offset_tags
print "Offset Surfaces: ", self.offset_surfaces
print "Offset end: ", self.offset_end
print ""

######################################################
# Export functions
######################################################

def updateFrameData(v, f):
min_bounds=0
max_bounds=0
local_origin=0
radius=0.0
name=""

for i in range(0,3):
f.min_bounds.co = min(v, f.min_bounds.co)
for i in range(0,3):
f.max_bounds.co = max(v, f.min_bounds.co)


def process_surface(mesh_obj, md3):
#because md3 doesnt suppoort faceUVs like blender, we need to duplicate
#any vertex that has multiple uv coords

global md3_uinfo, md3_strip_ext, md3_set_tga

vert_dict={}
index_dict={} #maps a vertex index to the revised index after duplicating to account for uv
vert_list=[] #list of vertices ordered by revised index
vert_count=0
tex_list=[] #list of tex coords ordered by revised index
face_list=[] #list of faces (they index into vert_list)
face_count=0

Blender.Set("curframe", 1)

#get access to the mesh data (as at frame #1)
mesh=NMesh.GetRawFromObject(mesh_obj.name)
matrix = mesh_obj.getMatrix('worldspace')

surf = md3_surface()
surf.num_frames = md3.num_frames
surf.name = mesh_obj.getName()
surf.ident = MD3_IDENT

# Find the index of the first referenced texture-mode material
texmat_index = -1
texmat_found = 0
m_index = 0
for material in mesh.materials:
print "---Found material \'%s\'for surface " % material.getName(), surf.name
if (material.getMode() & Material.Modes.TEXFACE) and (texmat_index == -1):
print "---The material has texture image, will use it"
texmat_index = m_index
texmat_found = 1
m_index += 1


# create default shader for surface
surf.shaders.append(md3_shader())
surf.num_shaders =+ 1
surf.shaders[0].index = 0

if m_index==0: # no materials
surf.shaders[0].name = md3_uinfo[2] + "_".join(surf.name.split("."))
else:
surf.shaders[0].name = md3_uinfo[2] + mesh.materials[texmat_index].name

#process each face in the mesh
for face in mesh.faces:

# see if this face uses the texture-mode material
if (face.materialIndex == texmat_index) and (texmat_found==1):
print "Found face using texmat w/ index ", texmat_index
texmat_found = 0 # prevent creation of more shaders
if (face.image):
surf.shaders[0].name = face.image.getFilename()
splitlist = []
if (surf.shaders[0].name.find("\\")!=-1):
splitlist = surf.shaders[0].name.split("\\")
if (surf.shaders[0].name.find("/")!=-1):
splitlist = surf.shaders[0].name.split("/")
splitlist = splitlist[len(splitlist)-1].split(".")
ext = ""
if len(splitlist)>1 and md3_strip_ext==0:
if md3_set_tga==1: ext = "tga"
else: ext = splitlist[len(splitlist)-1]
del splitlist[len(splitlist)-1]
surf.shaders[0].name = md3_uinfo[2] + ".".join(splitlist) + "." + ext
# done with shaders

tris_in_this_face=[] #to handle quads and up...
#this makes a list of indices for each tri in this face. a quad will be [[0,1,1],[0,2,3]]
for vi in range(1, len(face.v)-1):
tris_in_this_face.append([0, vi, vi+1])

#loop across each tri in the face, then each vertex in the tri
for this_tri in tris_in_this_face:
face_count += 1
tri = md3_triangle()
tri_ind = 0
for i in this_tri:
#get the vertex index, coords and uv coords
index = face.v.index
v = face.v.co
if mesh.hasFaceUV():
uv = face.uv
elif mesh.hasVertexUV():
uv = (face.v.uvco[0], face.v.uvco[1])
else:
uv = (0.0, 0.0) #handle case with no tex coords


if vert_dict.has_key((index, uv)):
# if we've seen this exact vertex before, simply add it
# to the tris list of vertex indices
tri.vertex_index[tri_ind] = vert_dict[(index, uv)]
else:
# havent seen this tri before
# (or its uv coord is different, so we need to duplicate it)

vert_dict[(index, uv)]=vert_count

# put the uv coord into the list
# (uv coord are directly related to each vertex)
tex = md3_tex_coord()
tex.u = uv[0]
tex.v = uv[1]
tex_list.append(tex)

tri.vertex_index[tri_ind] = vert_count

# now because we have created a new index,
# we need a way to link it to the index that
# blender returns for NMVert.index
if index_dict.has_key(index):
# already there - each of the entries against
# this key represents the same vertex with a
# different uv value
ilist = index_dict[index]
ilist.append(vert_count)
index_dict[index] = ilist
else:
#this is a new one
index_dict[index] = [vert_count]

vert_count += 1
tri_ind +=1
face_list.append(tri)


# we're done with faces and uv coords
for t in tex_list:
surf.uv.append(t)

for f in face_list:
surf.tris.append(f)

surf.num_tris = len(face_list)
surf.num_verts = vert_count

# now vertices are stored as frames -
# all vertices for frame 1, all vertices for frame 2...., all vertices for frame n
# so we need to iterate across blender's frames, and copy out each vertex
for frnum in range(1, md3.num_frames+1):
Blender.Set("curframe", frnum)

m=NMesh.GetRawFromObject(mesh_obj.name)

vlist = [0]*vert_count
for vertex in m.verts:
try:
vindices = index_dict[vertex.index]
except:
print "warning found a vertex in %s that is not part of a face" % mesh_obj.name
continue

vTx = apply_transform(vertex.co, matrix)
nTx = apply_transform(vertex.no, matrix)
updateFrameData(vTx, md3.frames[frnum-1])
vert = md3_vert()
vert.co = vTx[0:3]
vert.normal = vert.encode(nTx[0:3])
for ind in vindices: #apply the position to all the duplicated vertices
vlist[ind] = vert

for vl in vlist:
surf.verts.append(vl)

surf.dump()
md3.surfaces.append(surf)
md3.num_surfaces+=1


def save_md3 (md3_filename):
md3 = md3_obj()
md3.ident=MD3_IDENT
md3.version=MD3_VERSION

md3.name = md3_uinfo[0] + md3_uinfo[1]

tag_list=[]

Blender.Set("curframe", 1)

#create a bunch of blank frames, they'll be filled in by 'process_surface'
md3.num_frames=NUM_FRAMES
for i in range(1, NUM_FRAMES+1):
fr = md3_frame()
fr.name = "FRAME"+str(i)
md3.frames.append(fr)

#do we export all objects or just the selected ones?
if EXPORT_ALL:
objlist = Blender.Object.Get()
else:
objlist = Blender.Object.GetSelected()


#process each object for the export
for obj in objlist:
#check if it's a mesh object
if obj.getType()=="Mesh":
print "processing surface", obj.name
if len(md3.surfaces) == MD3_MAX_SURFACES:
print "hit md3 limit (%i) for number of surfaces, skipping" % MD3_MAX_SURFACES , obj.getName()
else:
process_surface(obj,md3)
elif obj.getType()=="Empty": #for tags, we just put em in a list so we can process them all together
if obj.name[0:4] == "tag_":
print "processing tag", obj.name
tag_list.append(obj)
md3.num_tags+=1
else:
print "Skipping non mesh object", obj.name

#work out the transforms for the tags for each frame of the export
for fr in range(1, NUM_FRAMES+1):
Blender.Set("curframe", fr)
for tag in tag_list:
t = md3_tag()
matrix = tag.getMatrix('worldspace')
for i in range(0,3):
t.axis[0].co = matrix[0]
t.axis[1].co = matrix[1]
t.axis[2].co = matrix[2]
t.origin.co = matrix[3]
t.name = obj.name[4:]
md3.tags.append(t)

#export!
file=open(md3_filename,"wb")
md3.save(file)
file.close()
md3.dump()





#***********************************************
# MAIN
#***********************************************

#
def my_callback(filename):
if(filename.find('.md3', -4) <= 0):
filename += '.md3'
print "Exporting MD3 format to ", filename
save_md3(filename)



#***********************************************
# MD3 info that must be provided by the user
#***********************************************

# individual shader path storage -- not implemented
#md3_shader_dict = {} # image name -> index
#md3_shader_paths = {} # index -> path string

# input fields
md3_uinfo = [0]*3
md3_uinfo[0] = "models/mapobjects/mymodel/" # md3 model path
md3_uinfo[1] = "mymodel.md3" # md3 model name
md3_uinfo[2] = "models/mapobjects/mymodel/" # md3 shader path (for selected shader)

md3_set_tga = 0 # replace texture extensions with '.tga'
md3_strip_ext = 0 # strip all texture extensions

#
gui_samepath = 1 # use same path for shaders and model

#***********************************************
# GUI
#***********************************************

#
gui_num_components = 3 # number of components that can have keyboard focus
#
gui_infocus = 0 # Index of the input component that has keyboard focus. -1 = none
#
# gui_menu_active = 0 # Draw the shader selection menu? -- not implemented
#
# gui_active_shader = -1 # Index of the currently selected shader. -1 = none -- not implemented


#
def gui_done():
global md3_uinfo

if len(md3_uinfo[0])>0 and md3_uinfo[0][len(md3_uinfo[0])-1]!='/':
md3_uinfo[0] += '/'
if len(md3_uinfo[2])>0 and md3_uinfo[2][len(md3_uinfo[2])-1]!='/':
md3_uinfo[2] += '/'
if md3_uinfo[1].find('.md3', -4) <= 0:
md3_uinfo[1] += '.md3'

print "MD3 options:"
print "Set TGA ext: ", md3_set_tga
print "Strip ext: ", md3_strip_ext
print "MD3 model: ", md3_uinfo[0] + md3_uinfo[1]
print "Shader path: ", md3_uinfo[2]

Blender.Window.FileSelector(my_callback, "Export MD3", md3_uinfo[1])
#


#
def event(evt, val): # the function to handle input events
global md3_uinfo, gui_infocus, gui_samepath, gui_num_components #, gui_active_shader

if not val: # val = 0: it's a key/mbutton release
if evt in [Draw.LEFTMOUSE, Draw.MIDDLEMOUSE, Draw.RIGHTMOUSE]:
Draw.Redraw(1)
return

if evt == Draw.ESCKEY:
Draw.Exit() # exit when user presses ESC
return

elif evt == Draw.TABKEY:
gui_infocus += 1
if gui_infocus>=gui_num_components: gui_infocus = 0
Draw.Redraw(1)
# if gui_infocus==2 and gui_active_shader==-1: gui_infocus = 0
#Draw.Register(gui, event, button_event)
return

if Draw.AKEY <= evt <= Draw.ZKEY: md3_uinfo[gui_infocus] += chr(evt)
elif Draw.ZEROKEY <= evt <= Draw.NINEKEY: md3_uinfo[gui_infocus] += chr(evt)
elif evt == Draw.MINUSKEY: md3_uinfo[gui_infocus] += '-'
elif evt == Draw.SPACEKEY: md3_uinfo[gui_infocus] += '_'
elif evt == Draw.PERIODKEY and gui_infocus==1: md3_uinfo[gui_infocus] += ".md3"
elif (evt == Draw.SLASHKEY or evt == Draw.BACKSLASHKEY) and gui_infocus!=1:
if len(md3_uinfo[gui_infocus]) and md3_uinfo[gui_infocus][len(md3_uinfo[gui_infocus])-1] != '/': md3_uinfo[gui_infocus] += '/'
elif evt == Draw.BACKSPACEKEY and len(md3_uinfo[gui_infocus]): md3_uinfo[gui_infocus] = md3_uinfo[gui_infocus][:-1]
else: return # this is important: only re-register if an event was caught

if len(md3_uinfo[gui_infocus])>55:
md3_uinfo[gui_infocus] = md3_uinfo[gui_infocus][:-1]

if (gui_infocus==0 or gui_infocus==2) and gui_samepath==1:
md3_uinfo[2-gui_infocus] = md3_uinfo[gui_infocus]

Draw.Redraw(1)
# Draw.Register(gui, event, button_event) # re-register to stay in the loop

#
def button_event(evt): # the function to handle Draw Button events
global md3_uinfo, md3_set_tga, md3_strip_ext, gui_infocus, gui_samepath, gui_num_components # , gui_active_shader
if evt == 1: # accept
Draw.Exit()
gui_done()
return
elif evt == 2: # cancel
Draw.Exit()
return
#
elif evt == 10: # set focus to input 0
gui_infocus = 0
elif evt == 11:
gui_infocus = 1
elif evt == 12: # and gui_active_shader!=-1:
gui_infocus = 2
#
elif evt == 20: # All-tga toggle
md3_set_tga = 1 - md3_set_tga
if md3_set_tga==1: md3_strip_ext = 0
elif evt == 21: # Strip-extension toggle
md3_strip_ext = 1 - md3_strip_ext
if md3_strip_ext==1: md3_set_tga = 0
#
elif evt == 30: # Same-path toggle
gui_samepath = 1 - gui_samepath
else:
return
Draw.Redraw(1)
# Draw.Register(gui, event, button_event)


#
def gui(): # the function to draw the screen
global md3_uinfo, md3_set_tga, md3_strip_ext, gui_samepath, gui_infocus, gui_num_components #, gui_active_shader
BGL.glClearColor(0.1,0.1,0.1,1)
BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)

BGL.glColor4f(0.4,0.4,0.4, 0.25)
BGL.glBegin(BGL.GL_POLYGON)
BGL.glVertex2i(5, 5)
BGL.glVertex2i(795, 5)
BGL.glVertex2i(795, 450)
BGL.glVertex2i(5, 450)
BGL.glEnd()

BGL.glColor3f(0,0,0)
BGL.glRasterPos2i(186, 410)
Draw.Text("MD3 EXPORTER")
BGL.glColor3f(1,1,1)
BGL.glRasterPos2i(185, 411)
Draw.Text("MD3 EXPORTER")

BGL.glColor4f(0.35,0.35,0.35, 0.25)
BGL.glBegin(BGL.GL_POLYGON)
BGL.glVertex2i(460, 380)
BGL.glVertex2i(760, 380)
BGL.glVertex2i(760, 90)
BGL.glVertex2i(460, 90)
BGL.glEnd()

BGL.glColor3f(0.4,0.7,0.5)
BGL.glRasterPos2i(470, 360)
Draw.Text("* Use TAB to move cursor between input fields.")
BGL.glRasterPos2i(470, 340)
Draw.Text("* Spaces are converted to underscores.")
BGL.glRasterPos2i(470, 320)
Draw.Text("* Paths should be relative to the game's base")
BGL.glRasterPos2i(470, 300)
Draw.Text("directory, e.g.: \'models/mapobjects/my_model\'")
BGL.glRasterPos2i(470, 280)
Draw.Text("* Combined path and filename must be less than")
BGL.glRasterPos2i(470, 260)
Draw.Text("64 characters in length.")
BGL.glRasterPos2i(470, 240)
Draw.Text("* It is usually a good idea to have the same path")
BGL.glRasterPos2i(470, 220)
Draw.Text("for model and shaders. Use different paths if")
BGL.glRasterPos2i(470, 200)
Draw.Text("the textures do not reside in the same directory")
BGL.glRasterPos2i(470, 180)
Draw.Text("as the MD3 itself.")
BGL.glRasterPos2i(470, 160)
Draw.Text("")
BGL.glRasterPos2i(470, 140)
Draw.Text("NOTE: It is currently not possible to set")
BGL.glRasterPos2i(470, 120)
Draw.Text("different paths for individual textures,")
BGL.glRasterPos2i(470, 100)
Draw.Text("although the MD3 file format allows it.")

BGL.glColor3f(0.35,0.35,0.35)
BGL.glBegin(BGL.GL_POLYGON)
BGL.glVertex2i( 5, 380)
BGL.glVertex2i(450, 380)
BGL.glVertex2i(450, 290)
BGL.glVertex2i( 5, 290)
BGL.glEnd()

BGL.glColor3f(1,1,1)
BGL.glRasterPos2i(10, 360)
Draw.Text("Shaders/Textures export options")

BGL.glColor3f(0.25,0.25,0.75)
Draw.Toggle("", 20, 20,326, 15,14, md3_set_tga, "")
BGL.glColor3f(0.8,1,0.8)
BGL.glRasterPos2i(40, 330)
Draw.Text("Replace all texture extensions with \'.tga\' in MD3")

BGL.glColor3f(0.25,0.25,0.75)
Draw.Toggle("", 21, 20,306, 15,14, md3_strip_ext, "")
BGL.glColor3f(0.8,1,0.8)
BGL.glRasterPos2i(40, 310)
Draw.Text("Strip extensions from all texture filenames in MD3")

BGL.glColor3f(0.35,0.35,0.35)
BGL.glBegin(BGL.GL_POLYGON)
BGL.glVertex2i( 5, 270)
BGL.glVertex2i(450, 270)
BGL.glVertex2i(450, 90)
BGL.glVertex2i( 5, 90)
BGL.glEnd()

BGL.glColor3f(1,1,1)
BGL.glRasterPos2i(10, 250)
Draw.Text("Internal directory paths (in MD3 file)")

BGL.glColor3f(0.25,0.25,0.75)
Draw.Toggle("", 30, 20,216, 15,14, gui_samepath, "Toggle on/off")
BGL.glColor3f(0.8,1,0.8)
BGL.glRasterPos2i(40, 220)
Draw.Text("Shaders/textures and the model use the same path")

BGL.glColor3f(1,1,0)
BGL.glRasterPos2i(20, 190)
Draw.Text("MD3 model directory prefix:")
BGL.glColor3f(1,0.9,0.9)
BGL.glRasterPos2i(40, 170)
xlen0 = Draw.Text(md3_uinfo[0])

BGL.glColor3f(1,1,0)
BGL.glRasterPos2i(300, 190)
Draw.Text("Internal model name:")
BGL.glColor3f(1,0.9,0.9)
BGL.glRasterPos2i(320, 170)
xlen1 = Draw.Text(md3_uinfo[1])

BGL.glColor3f(1,1,0)
BGL.glRasterPos2i(20, 140)
Draw.Text("Shaders/textures directory prefix:")
BGL.glColor3f(1,0.9,0.9)
BGL.glRasterPos2i(40, 120)
# if gui_active_shader != -1:
xlen2 = Draw.Text(md3_uinfo[2])

# focus toggle button state
togup0=0
togup1=0
togup2=0

BGL.glColor3f(1,0.1,0.1) # focus cursor color

if gui_infocus==0:
BGL.glRasterPos2i(40+xlen0, 170)
Draw.Text("||")
togup0 = 1
elif gui_infocus==1:
BGL.glRasterPos2i(320+xlen1, 170)
Draw.Text("||")
togup1 = 1
elif gui_infocus==2: # and gui_active_shader!=-1:
BGL.glRasterPos2i(40+xlen2, 120)
Draw.Text("||")
togup2 = 1

BGL.glColor3f(0.25,0.25,0.75)
Draw.Toggle(">", 10, 20, 166, 15,14, togup0, "Set keyboard input focus here")
Draw.Toggle(">", 11, 300,166, 15,14, togup1, "Set keyboard input focus here")
Draw.Toggle(">", 12, 20, 116, 15,14, togup2, "Set keyboard input focus here")

BGL.glColor3f(0.75,1,0.75)
Draw.Button("Accept", 1, 20, 50, 70,30,"Proceed to output filename selection")
BGL.glColor3f(1,0.75,0.75)
Draw.Button("Cancel", 2, 120,50, 70,30,"Cancel exporting operation")


#
print "****"
Draw.Register(gui, event, button_event) # registering the 3 callbacks

The website I got this script from seems to be down atm, just copy the above into a text editor and save it as: "md3-export-0.2-lgt.py".

Hope this helps you. :)
Share |
Restricted Access Topic is Locked subscribe
MODSonline.com Forums : Soldier of Fortune : SoFII Mapping

Latest Syndicated News

»
Codutility.com up and runn...
Nice, and there still using the logo and template for the screenshots, which...
Codutility.com up and runn...
dundy writes...Quote:Call of Duty modding and mapping is barly alive only a ...
Codutility.com up and runn...
Mystic writes...Quote:It seems to me the like the site is completely dead? ...
Codutility.com up and runn...
It seems to me the like the site is completely dead?

Partners & Friends

»