/* W3D Importer * * v1.16 * * Script by Seagle * * www.cncgenerals.com * * Edited by Sloth * */ --interface utility w3dimport "W3D Importer V1.16" ( struct chunkheader (type , size) struct hlobject (bone, name) struct texture (filename, uv = #()) global LODtoShow = 4; global matoffset = 0; -- global BoundingMat = 1; global pivots = #(); global hlods = #(); global meshes = #(); global boxes = #(); global curmesh = 1; global nummeshes = 0; global numboxes = 0; global numpivots = 0; global scalage global lodmax = 0; global skelfile global reqskelname = "unknown" global boxcolor = point3 0 255 0 global boxsize = .075 global sizeguess = 1 --Interface group "Import" ( spinner scale "Scale Object by:" align:#center range:[.0001, 10000, 1] fieldwidth:40 checkBox LoadMaterials "Load Materials In Editor" checked:true align:#center tooltip:"ATM it overwrites current materials in the editor :P" button activateImport "Load W3D Object" offset:(point2 0 6) ) group "Hierarchy Options" ( checkBox useSkel "Use External Skeleton" checked:false align:#left button SkelBut "Select Skeleton" align:#center width:100 enabled:false ) group "Display" ( checkBox showHidden "Show Hidden Meshes" checked:true align:#center checkBox showPivots "Show Pivots (Bones)" checked:true align:#center button selPivots "Select Bones" align:#center width:100 offset:(point2 0 6) dropdownlist showLODlist "Level of Detail:" align:#center items:#("All", "0", "1", "2", "3", "None") selection:1 offset: (point2 0 6) height:7 ) fn getDword instream = ( a = ReadByte instream #unsigned b = ReadByte instream #unsigned c = ReadByte instream #unsigned d = ReadByte instream #unsigned if d >= 128 then d -= 128 -- MAXScript uses 2SC number representation, --incompatible with WW's extra bit (TM) system result = d * 0x1000000 + c * 0x10000 + b * 0x100 + a ) fn getWord instream = ( a = ReadByte instream #unsigned b = ReadByte instream #unsigned if b >= 128 then b -= 128 -- MAXScript uses 2SC number representation, --incompatible with WW's extra bit (TM) system result = b * 0x100 + a ) fn ReadHeader instream = ( ch = chunkheader (getDword instream) (getDword instream) ) fn getRGB instream = ( p = Point3 (ReadByte instream #unsigned) (ReadByte instream #unsigned) (ReadByte instream #unsigned) fseek instream 1 #seek_cur return p ) fn findMeshInHlod meshindex = ( for a = 1 to hlods.count do ( for b = 1 to hlods[a].count do ( if(hlods[a][b].name == meshes[meshindex].name) then ( result = chunkheader hlods[a][b].bone a --return an array return result ) ) ) result = chunkheader 1 1 return result ) fn replaceRedundancies meshPivots = ( blackbull = #() for i = 1 to nummeshes do ( if(meshPivots[i] != 0) then ( if (meshes[i].name == pivots[meshPivots[i]].name) then --if mesh name = pivot name ( --then make mesh into pivot meshes[i].parent = pivots[meshPivots[i]].parent setUserProp meshes[i] "bone" "yes" blackbull[blackbull.count + 1] = meshPivots[i] for c = pivots[meshPivots[i]].children.count to 1 by -1 do ( --only want to rearrange the hierarchy if(pivots[meshPivots[i]].children[c] != undefined) then ( pivots[meshPivots[i]].children[c].parent = meshes[i] --not the pivot positions of the children ) ) ) ) ) --also clear out redundant box pivots... p = 1 while p <= (numpivots - 1) do ( flag = false if pivots[p] != undefined then ( for b = 1 to numboxes do ( if(boxes[b].name == pivots[p].name) then ( if(findItem blackbull p) == 0 then append blackbull p ) ) ) p += 1; ) sort blackbull for j = blackbull.count to 1 by -1 do delete pivots[blackbull[j]] ) fn hideHidden = ( max select all i = 1 while i <= selection.count do ( if (selection[i] != undefined) then ( if (getUserProp selection[i] "shadow") == "waas" then ( deselectNode selection[i] i -=1; )else ( if (getUserProp selection[i] "hidden") == "waas" then ( deselectNode selection[i] i -= 1; ) ) ) i += 1 ) max hide inv max select none ) fn hideLODs = ( max unhide all max select all i = 1 while i <= selection.count do ( if (selection[i] != undefined) then ( a = getUserProp selection[i] "LOD" if a != undefined then ( if a != LODtoShow then ( deselectNode selection[i] i -= 1; ) ) ) i += 1; ) max hide inv max select none ) fn hideBones = ( max select all i = 1; while i <= selection.count do ( if(selection[i] != undefined) then ( a = getUserProp selection[i] "bone" if a != undefined then ( if a == "yes" then ( if (getUserProp selection[i] "LOD") == undefined then --don't hide mesh bones ( deselectNode selection[i] i -= 1; ) ) ) ) i += 1; ) max hide inv max select none ) fn translateType type = ( case type of --comments on chunk types remain in w3d.h ( 0x00000000:#W3D_CHUNK_MESH 0x00000002:#W3D_CHUNK_VERTICES 0x00000003:#W3D_CHUNK_VERTEX_NORMALS 0x0000000C:#W3D_CHUNK_MESH_USER_TEXT 0x0000000E:#W3D_CHUNK_VERTEX_INFLUENCES 0x0000001F:#W3D_CHUNK_MESH_HEADER3 0x00000020:#W3D_CHUNK_TRIANGLES 0x00000022:#W3D_CHUNK_VERTEX_SHADE_INDICES 0x00000023:#W3D_CHUNK_PRELIT_UNLIT 0x00000024:#W3D_CHUNK_PRELIT_VERTEX 0x00000025:#W3D_CHUNK_PRELIT_LIGHTMAP_MULTI_PASS 0x00000026:#W3D_CHUNK_PRELIT_LIGHTMAP_MULTI_TEXTURE 0x00000028:#W3D_CHUNK_MATERIAL_INFO 0x00000029:#W3D_CHUNK_SHADERS 0x0000002A: #W3D_CHUNK_VERTEX_MATERIALS 0x0000002B: #W3D_CHUNK_VERTEX_MATERIAL 0x0000002C: #W3D_CHUNK_VERTEX_MATERIAL_NAME 0x0000002D: #W3D_CHUNK_VERTEX_MATERIAL_INFO 0x0000002E: #W3D_CHUNK_VERTEX_MAPPER_ARGS0 0x0000002F: #W3D_CHUNK_VERTEX_MAPPER_ARGS1 0x00000030:#W3D_CHUNK_TEXTURES 0x00000031: #W3D_CHUNK_TEXTURE 0x00000032: #W3D_CHUNK_TEXTURE_NAME 0x00000033: #W3D_CHUNK_TEXTURE_INFO 0x00000038:#W3D_CHUNK_MATERIAL_PASS 0x00000039: #W3D_CHUNK_VERTEX_MATERIAL_IDS 0x0000003A:#W3D_CHUNK_SHADER_IDS 0x0000003B:#W3D_CHUNK_DCG 0x0000003C:#W3D_CHUNK_DIG 0x0000003E:#W3D_CHUNK_SCG 0x00000048:#W3D_CHUNK_TEXTURE_STAGE 0x00000049: #W3D_CHUNK_TEXTURE_IDS 0x0000004A:#W3D_CHUNK_STAGE_TEXCOORDS 0x0000004B:#W3D_CHUNK_PER_FACE_TEXCOORD_IDS 0x00000058:#W3D_CHUNK_DEFORM 0x00000059:#W3D_CHUNK_DEFORM_SET 0x0000005A:#W3D_CHUNK_DEFORM_KEYFRAME 0x0000005B:#W3D_CHUNK_DEFORM_DATA 0x00000080:#W3D_CHUNK_PS2_SHADERS 0x00000090:#W3D_CHUNK_AABTREE -- #W3D_CHUNK_AABTREE_HEADER -- #W3D_CHUNK_AABTREE_POLYINDICES -- #W3D_CHUNK_AABTREE_NODES 0x00000100:#W3D_CHUNK_HIERARCHY 0x00000101:#W3D_CHUNK_HIERARCHY_HEADER 0x00000102:#W3D_CHUNK_PIVOTS 0x00000103:#W3D_CHUNK_PIVOT_FIXUPS 0x00000200:#W3D_CHUNK_ANIMATION -- #W3D_CHUNK_ANIMATION_HEADER -- #W3D_CHUNK_ANIMATION_CHANNEL -- #W3D_CHUNK_BIT_CHANNEL 0x00000280:#W3D_CHUNK_COMPRESSED_ANIMATION -- #W3D_CHUNK_COMPRESSED_ANIMATION_HEADER -- #W3D_CHUNK_COMPRESSED_ANIMATION_CHANNEL -- #W3D_CHUNK_COMPRESSED_BIT_CHANNEL 0x000002C0:#W3D_CHUNK_MORPH_ANIMATION -- #W3D_CHUNK_MORPHANIM_HEADER -- #W3D_CHUNK_MORPHANIM_CHANNEL -- #W3D_CHUNK_MORPHANIM_POSENAME -- #W3D_CHUNK_MORPHANIM_KEYDATA -- #W3D_CHUNK_MORPHANIM_PIVOTCHANNELDATA 0x00000300:#W3D_CHUNK_HMODEL -- #W3D_CHUNK_HMODEL_HEADER -- #W3D_CHUNK_NODE -- #W3D_CHUNK_COLLISION_NODE -- #W3D_CHUNK_SKIN_NODE 0x00000400:#W3D_CHUNK_LODMODEL -- #W3D_CHUNK_LODMODEL_HEADER -- #W3D_CHUNK_LOD 0x00000420:#W3D_CHUNK_COLLECTION -- #W3D_CHUNK_COLLECTION_HEADER -- #W3D_CHUNK_COLLECTION_OBJ_NAME -- #W3D_CHUNK_PLACEHOLDER -- #W3D_CHUNK_TRANSFORM_NODE 0x00000440:#W3D_CHUNK_POINTS 0x00000460:#W3D_CHUNK_LIGHT -- #W3D_CHUNK_LIGHT_INFO -- #W3D_CHUNK_SPOT_LIGHT_INFO -- #W3D_CHUNK_NEAR_ATTENUATION -- #W3D_CHUNK_FAR_ATTENUATION 0x00000500:#W3D_CHUNK_EMITTER -- #W3D_CHUNK_EMITTER_HEADER -- #W3D_CHUNK_EMITTER_USER_DATA -- #W3D_CHUNK_EMITTER_INFO -- #W3D_CHUNK_EMITTER_INFOV2 -- #W3D_CHUNK_EMITTER_PROPS -- #W3D_CHUNK_EMITTER_LINE_PROPERTIES -- #W3D_CHUNK_EMITTER_ROTATION_KEYFRAMES -- #W3D_CHUNK_EMITTER_FRAME_KEYFRAMES -- #W3D_CHUNK_EMITTER_BLUR_TIME_KEYFRAMES 0x00000600:#W3D_CHUNK_AGGREGATE -- #W3D_CHUNK_AGGREGATE_HEADER -- #W3D_CHUNK_AGGREGATE_INFO -- #W3D_CHUNK_TEXTURE_REPLACER_INFO -- #W3D_CHUNK_AGGREGATE_CLASS_INFO 0x00000700:#W3D_CHUNK_HLOD 0x00000701:#W3D_CHUNK_HLOD_HEADER 0x00000702:#W3D_CHUNK_HLOD_LOD_ARRAY 0x00000703:#W3D_CHUNK_HLOD_SUB_OBJECT_ARRAY_HEADER 0x00000704:#W3D_CHUNK_HLOD_SUB_OBJECT 0x00000705:#W3D_CHUNK_HLOD_AGGREGATE_ARRAY -- #W3D_CHUNK_HLOD_PROXY_ARRAY 0x00000740:#W3D_CHUNK_BOX -- #W3D_CHUNK_SPHERE -- #W3D_CHUNK_RING 0x00000750:#W3D_CHUNK_NULL_OBJECT 0x00000800:#W3D_CHUNK_LIGHTSCAPE -- #W3D_CHUNK_LIGHTSCAPE_LIGHT -- #W3D_CHUNK_LIGHT_TRANSFORM 0x00000900:#W3D_CHUNK_DAZZLE 0x00000901:#W3D_CHUNK_DAZZLE_NAME 0x00000902:#W3D_CHUNK_DAZZLE_TYPENAME 0x00000A00:#W3D_CHUNK_SOUNDROBJ -- #W3D_CHUNK_SOUNDROBJ_HEADER -- #W3D_CHUNK_SOUNDROBJ_DEFINITION ) ) fn findSkelName instream = ( result = "" curpos = ftell instream fseek instream 0 #seek_end local filesize = ftell instream fseek instream curpos #seek_set while (ftell instream < filesize) do ( header = ReadHeader instream chunkname = translateType header.type if(chunkname == #W3D_CHUNK_HLOD) then ( hlend = ftell instream + header.size hlheader = ReadHeader instream --HLOD Header fseek instream 24 #seek_cur --ignore everything but htreename stend = ftell instream + 16 result = ReadString instream fseek instream hlend #seek_set )else ( fseek instream header.size #seek_cur ) ) return result ) fn loadSkeleton instream = ( fseek instream 0 #seek_end sfilesize = ftell instream fseek instream 0 #seek_set while (ftell instream < sfilesize) do ( header = ReadHeader instream chunkname = translateType header.type case chunkname of ( #W3D_CHUNK_HIERARCHY: ( hheader = ReadHeader instream fseek instream 20 #seek_cur --ignore version data, name numpivots = getDword instream fseek instream 12 #seek_cur --ignore center data hheader = ReadHeader instream --skip ROOT_TRANSFORM fseek instream 60 #seek_cur for p = 1 to (numpivots - 1) do ( stend = ftell instream + 16 --16 byte string pivotname = ReadString instream fseek instream stend #seek_set parentid = (getDword instream) pivotpos = point3 (ReadFloat instream) (ReadFloat instream) (ReadFloat instream) fseek instream 12 #seek_cur pivotrot = quat (ReadFloat instream) (ReadFloat instream) (ReadFloat instream) (ReadFloat instream) -- boxmat = standardMaterial diffuse:boxcolor if (parentid != 0) then --no parent for ROOT's children ( pivots[p] = sphere name:pivotname pos:pivotpos parent:pivots[parentid] radius:boxsize material:boxmat segs:4 --pivots[p] = bone name:pivotname parent:pivots[parentid] in coordsys parent pivots[p].rotation = pivotrot in coordsys parent pivots[p].pos = pivotpos )else ( pivots[p] = sphere name:pivotname rotation:pivotrot pos:pivotpos radius:boxsize material:boxmat wirecolor:boxcolor segs:4 -- pivots[p] = bone name:pivotname rotation:pivotrot pos:pivotpos ) pivots[p].scale = scalage setUserProp pivots[p] "bone" "yes" ) ) default: ( fseek instream header.size #seek_cur ) ) ) ) fn processChunk instream = ( header = ReadHeader instream chunkname = translateType header.type curlod = 1 case chunkname of ( #W3D_CHUNK_HIERARCHY: ( hheader = ReadHeader instream fseek instream 20 #seek_cur --ignore version data, name numpivots = getDword instream fseek instream 12 #seek_cur --ignore center data hheader = ReadHeader instream --skip ROOT_TRANSFORM fseek instream 60 #seek_cur for p = 1 to (numpivots - 1) do ( stend = ftell instream + 16 --16 byte string pivotname = ReadString instream fseek instream stend #seek_set parentid = (getDword instream) pivotpos = point3 (ReadFloat instream) (ReadFloat instream) (ReadFloat instream) fseek instream 12 #seek_cur pivotrot = quat (ReadFloat instream) (ReadFloat instream) (ReadFloat instream) (ReadFloat instream) -- boxmat = standardMaterial diffuse:boxcolor if (parentid != 0) then --no parent for ROOT's children ( pivots[p] = sphere name:pivotname pos:pivotpos parent:pivots[parentid] radius:boxsize material:boxmat wirecolor:boxcolor segs:4 --pivots[p] = bone name:pivotname parent:pivots[parentid] in coordsys parent pivots[p].rotation = pivotrot in coordsys parent pivots[p].pos = pivotpos )else ( pivots[p] = sphere name:pivotname rotation:pivotrot pos:pivotpos radius:boxsize material:boxmat segs:4 -- pivots[p] = bone name:pivotname rotation:pivotrot pos:pivotpos ) pivots[p].scale = scalage setUserProp pivots[p] "bone" "yes" ) processChunk instream --ignore pivot fixups ) -- #W3D_CHUNK_HIERARCHY_HEADER: -- ( -- getHierarchyHeader(); -- ) -- #W3D_CHUNK_PIVOTS: -- ( -- getPivots(); -- ) -- #W3D_CHUNK_PIVOT_FIXUPS: ( -- ) --Dazzle super chunk #W3D_CHUNK_DAZZLE: ( processChunk instream --DAZZLE_NAME processChunk instream --DAZZLE_TYPENAME ) -- #W3D_CHUNK_DAZZLE_NAME: -- ( -- getStringofLen(myfp, myobj.mydazzles[myobj.curdazzle].name , chunkheader.size); -- ) -- #W3D_CHUNK_DAZZLE_TYPENAME: -- ( -- getStringofLen(myfp, myobj.mydazzles[myobj.curdazzle].type , chunkheader.size); -- ) --Mesh super chunk - not dealing with prelits for now #W3D_CHUNK_MESH: ( --create local mesh object, save as a global object? end = ftell instream + header.size --mesheader-- curheader = ReadHeader instream fseek instream 4 #seek_cur attributts = getDword instream stend = ftell instream + 16 meshname = ReadString instream fseek instream stend #seek_set stend = ftell instream + 16 containername = ReadString instream fseek instream stend #seek_set numtris = getDword instream numverts = getDword instream nummats = getDword instream numdamages = getDword instream sortlevel = getDword instream prelitversion = getDword instream futurecounts = getDword instream vertexchannels = getDword instream facechannels = getDword instream min = point3 (ReadFloat instream) (ReadFloat instream) (ReadFloat instream) maximum = point3 (ReadFloat instream) (ReadFloat instream) (ReadFloat instream) sphcenter = point3 (ReadFloat instream) (ReadFloat instream) (ReadFloat instream) sphradius = ReadFloat instream --keep track of approx. model size (for bone sizing) if( sphradius > sizeguess) then sizeguess = sphradius verts = #(); tris = #(); tex = #(); curtex = 1; influenced = false; while (ftell instream) < end do ( mheader = ReadHeader instream mchunkname = translateType mheader.type case mchunkname of ( #W3D_CHUNK_VERTICES: ( for v = 1 to (numverts) do ( verts[v] = point3 (ReadFloat instream) (ReadFloat instream) (ReadFloat instream) ) ) #W3D_CHUNK_TRIANGLES: ( for t = 1 to numtris do ( --Max counts from one, not zero tris[t] = point3 (getDword instream + 1) (getDword instream + 1) (getDword instream + 1) faceattributes = getDword instream fseek instream 16 #seek_cur --skip normal, dist data ) ) /* #W3D_CHUNK_VERTEX_NORMALS: ( WORD n; for(n = 0; n < myobj.mymeshes[myobj.curmesh].header.numverts ; n++) { ReadFloat(myfp, myobj.mymeshes[myobj.curmesh].vertices[n].normal.x); ReadFloat(myfp, myobj.mymeshes[myobj.curmesh].vertices[n].normal.y); ReadFloat(myfp, myobj.mymeshes[myobj.curmesh].vertices[n].normal.z); } ) #W3D_CHUNK_VERTEX_SHADE_INDICES: ( ) */ #W3D_CHUNK_VERTEX_INFLUENCES: ( influenced = true for vi = 1 to verts.count do ( vertbone = (getWORD instream) --get bone id, add one for MaxScript fseek instream 6 #seek_cur --skip pad data try ( if( vertbone != 0) then foo = bone pos:verts[vi] parent:pivots[vertbone] if( vertbone == 0) then foo = bone pos:verts[vi] ) catch ( fseek instream 0 #seek_set reqskelname = findSkelName instream messageBox ("Meshes in this model require a skeleton file. \n\n Skeleton expected by model: " + reqskelname) exit --causes gmax crash )--now die, foo! in coordsys parent foo.rotation = quat 0 0 0 0 in coordsys parent foo.pos = verts[vi] --adjust vertex in coordsys world verts[vi] = foo.pos delete foo ) ) #W3D_CHUNK_MATERIAL_INFO: ( minfoend = ftell instream + mheader.size matoffset = sceneMaterials.count global curmat = matoffset + 1 -------------------------------- Material Info ------------------- PassCount = getDword instream VertexMaterialCount = getDword instream ShaderCount = getDword instream TextureCount = getDword instream ------------------------------------------------------------------ fseek instream minfoend #seek_set --skip data (mat, pass count) ) --------------------------------------------- Material Shaders -------------- #W3D_CHUNK_SHADERS: ( shaderend = ftell instream + mheader.size while (ftell instream) < shaderend do ( DepthCompare = ReadString instream DepthMask = ReadString instream DestBlend = ReadString instream PriGradient = ReadString instream SecGradient = ReadString instream SrcBlend = ReadString instream Texturing = ReadString instream DetailColor = ReadString instream DetailAlpha = ReadString instream AlphaTest = ReadString instream fseek instream shaderend #seek_set ) if( (SrcBlend == "One") and (DestBlend == "One") and (DepthMask == "Write Disable")) then ( opacityType = 2 ) else ( opacityType = 0 ) ) ----------------------------------------------------------------------------- #W3D_CHUNK_VERTEX_MATERIALS: ( vmatend = ftell instream + mheader.size while (ftell instream) < vmatend do ( aheader = ReadHeader instream --open Vertex Material chunk matend = ftell instream + aheader.size headertoss = ReadHeader instream --open name chunk matname = ReadString instream headertoss = ReadHeader instream --open info chunk matatts = getDword instream ambient = getRGB instream diffuse = getRGB instream specular = getRGB instream --rgb format : byte R, byte G, byte B, byte garbage emissive = getRGB instream --represented as max's Point3 internally shiny = ReadFloat instream opacity = ReadFloat instream translu = ReadFloat instream curmat += 1 --skip over any narsty stuffs at the end of the chunk fseek instream matend #seek_set ) ) --lots of other mesh-type chunks inside --q, dirty function to get texture info for one of many map /* #W3D_CHUNK_PRELIT_LIGHTMAP_MULTI_TEXTURE: ( endme = mheader.size + (ftell instream) textouse = 0; while (ftell instream < endme) do ( pheader = ReadHeader instream pchunkname = translateType pheader.type case pchunkname of ( --will display the last texture stored in the file for each mesh #W3D_CHUNK_TEXTURES: ( tend = (ftell instream) + pheader.size curtex = 1 while(ftell instream < tend) do --cycle through texture chunks ( theader = ReadHeader instream --Texture chunk texcend = ftell instream + theader.size ttheader = ReadHeader instream --Texture name or Texture info chunk ttname = translateType ttheader.type if(ttname == #W3D_CHUNK_TEXTURE_NAME) then ( tex[curtex] = texture filename:(ReadString instream) curtex += 1 textouse += 1 print ("Found a texture called " + tex[1].filename + " Textouse incremented to: " + textouse as string) ) fseek instream texcend #seek_set ) fseek instream tend #seek_set ) --for now, just skim through to texture stage, load first texture #W3D_CHUNK_MATERIAL_PASS: ( chunkend = ftell instream + pheader.size while ((ftell instream) < chunkend) do ( curheader = ReadHeader instream curtype = translateType curheader.type if(curtype == #W3D_CHUNK_TEXTURE_STAGE) then ( texheader = ReadHeader instream --Texture IDs chunk texid = getDword instream + 1 fseek instream (texheader.size - 4) #seek_cur --meshes with multiple textures will have one entry here for every face texheader = ReadHeader instream --Tex coords chunk headtype = translateType texheader.type coordend = texheader.size + ftell instream if(headtype == #W3D_CHUNK_STAGE_TEXCOORDS) then ( if(tex[1] != undefined) then --apply first texture to last set of UV coords - ugly ( print ("Texid: " + texid as string + " Textouse: " + textouse as string) --if(texid == textouse) then -- ( for i = 1 to numverts do ( tex[1].uv[i] = Point3 (ReadFloat instream) (ReadFloat instream) 0 ) print ("Applied UV coords for " + tex[1].filename) -- ) ) fseek instream coordend #seek_set )else ( fseek instream texheader.size #seek_cur ) )else ( fseek instream curheader.size #seek_cur --ignore other material pass data ) ) fseek instream chunkend #seek_set textouse = 0; ) default: ( fseek instream pheader.size #seek_cur ) ) ) ) */ --format: full of W3D_CHUNK_TEXTURE chunks, each of which is a name chunk and possibly an info chunk #W3D_CHUNK_TEXTURES: ( tend = ftell instream + mheader.size while(ftell instream < tend) do --cycle through texture chunks ( theader = ReadHeader instream --Texture chunk texcend = ftell instream + theader.size ttheader = ReadHeader instream --Texture name or Texture info chunk ttname = translateType ttheader.type if(ttname == #W3D_CHUNK_TEXTURE_NAME) then ( tex[curtex] = texture filename:(ReadString instream) ) fseek instream texcend #seek_set curtex += 1 ) fseek instream tend #seek_set ) --for now, just skim through to texture stage, load first texture #W3D_CHUNK_MATERIAL_PASS: ( chunkend = ftell instream + mheader.size while (ftell instream < chunkend) do ( curheader = ReadHeader instream curtype = translateType curheader.type if(curtype == #W3D_CHUNK_TEXTURE_STAGE) then ( texheader = ReadHeader instream --Texture IDs chunk fseek instream texheader.size #seek_cur --meshes with multiple textures will have one entry here for every face texheader = ReadHeader instream --Tex coords chunk headtype = translateType texheader.type if(headtype == #W3D_CHUNK_STAGE_TEXCOORDS) then ( if(tex[1].uv[1] == undefined) then --use coords from first pass for multipass meshes ( for i = 1 to numverts do ( tex[1].uv[i] = Point3 (ReadFloat instream) (ReadFloat instream) 0 ) ) )else ( fseek instream texheader.size #seek_cur ) )else ( fseek instream curheader.size #seek_cur --ignore other material pass data ) ) fseek instream chunkend #seek_set ) /* #W3D_CHUNK_VERTEX_MATERIAL_IDS: ( ) #W3D_CHUNK_SHADERS: ( ) #W3D_CHUNK_SHADER_IDS: ( ) */ default: ( fseek instream mheader.size #seek_cur ) ) ) --create object here meshes[curmesh] = mesh vertices:verts faces:tris name:meshname --------------------------- Create Material ------------------------------------- if(sceneMaterials[matname] == undefined) then ( --now construct material & append to scene library -- matl = standardMaterial name:matname -- matl.ambient = ambient -- matl.diffuse = diffuse -- matl.specular = specular -- matl.glossiness = shiny --? -- matl.opacity = (opacity * 100) --only append if material does not already exist -- sceneMaterials[matl.name] = matl meshes[curmesh].material = standard name:matname meshes[curmesh].material.ambient = ambient meshes[curmesh].material.diffuse = diffuse meshes[curmesh].material.adLock = off meshes[curmesh].material.specular = specular meshes[curmesh].material.useSelfIllumColor = on meshes[curmesh].material.selfIllumColor = emissive meshes[curmesh].material.glossiness = shiny meshes[curmesh].material.opacity = (opacity * 100) meshes[curmesh].material.opacityType = opacityType meshes[curmesh].material = sceneMaterials[matname] ) else ( meshes[curmesh].material = sceneMaterials[matname] ) --------------------------------------------------------------------------------- --if exists, apply texture if(tex[1] != undefined) then ( if(tex[1].uv[1] != undefined) then ( setNumTverts meshes[curmesh] numverts -- setMesh meshes[curmesh] tverts:tex[1].uv buildTVFaces meshes[curmesh] texmap = bitmaptex filename:tex[1].filename texmap.apply = true; sceneMaterials[matname].maps[2] = texmap -- meshes[curmesh].material.maps[2] = texmap -- showTextureMap meshes[curmesh].material meshes[curmesh].material.maps[2] true --texcoords not active - get them enabled! (apply UVW map?) showTextureMap sceneMaterials[matname] sceneMaterials[matname].maps[2] true for v = 1 to numverts do ( --removing out-of-bounds coords fix vc = tex[1].uv[v].y /* if (tex[1].uv[v].y < 0) then ( vc = 1 + tex[1].uv[v].y ) if (tex[1].uv[v].y > 1) then ( vc = tex[1].uv[v].y - 1 )*/ uc = tex[1].uv[v].x /* if (tex[1].uv[v].x < 0) then ( uc = 1 + tex[1].uv[v].x ) if (tex[1].uv[v].x > 1) then ( uc = tex[1].uv[v].x - 1 ) */ setTVert meshes[curmesh] v (uc) (vc) (tex[1].uv[v].z) ) for f = 1 to numtris do ( setTVFace meshes[curmesh] f tris[f] ) ) ) if( influenced == false) then --assumes if one vert is influenced, all are ( meshes[curmesh].scale = scalage ) update meshes[curmesh] curmesh += 1 --check for W3D hidden, shadow meshes mhide = false; mshadow = false; if (bit.and attributts 0x00008000) == 0x00008000 then setUserProp meshes[curmesh-1] "shadow" "waas" if (bit.and attributts 0x00001000) == 0x00001000 then setUserProp meshes[curmesh-1] "hidden" "waas" if (bit.and attributts 0x00002000) == 0x00002000 then meshes[curmesh - 1].material.twoSided = true nummeshes += 1 ) --Box super chunk #W3D_CHUNK_BOX: ( fseek instream 4 #seek_cur --skip version atts = getDword instream bstend = ftell instream + 32 --32 byte string, null padded boxname = ReadString instream fseek instream bstend #seek_set thisboxcolor = getRGB instream center = point3 (ReadFloat instream) (ReadFloat instream) (ReadFloat instream) extent = point3 (ReadFloat instream) (ReadFloat instream) (ReadFloat instream) holdme = filterString boxname "." boxname = holdme[holdme.count] --adjust box center center.z = center.z - extent.z --ruthlessly make z center coord -.418 for character meshes if(useSkel.checked == true) then ( if (bit.and atts 0x00000001) != 0x00000000 then ( holdme = filterString SkelBut.caption "_" holdme = holdme[holdme.count] holdme = filterString holdme "." holdme = holdme[1] if("human" as name == holdme as name) then ( center.z = -.418 ) ) ) boxes[numboxes + 1] = box name:boxname pos:center boxes[numboxes + 1].width = 2 * abs(extent.x) boxes[numboxes + 1].length = 2 * abs(extent.y) boxes[numboxes + 1].height = 2 * abs(extent.z) setUserProp boxes[numboxes + 1] "hidden" "waas" -- if (BoundingMat == 1) then -- ( mat = standardMaterial name:"Bounding-World Box" diffuse:thisboxcolor opacity:15 -- BoundingMat += 1; -- ) boxes[numboxes + 1].material = mat numboxes += 1; ) --Hmodel chunk, replacement for hlod #W3D_CHUNK_HMODEL: ( hmend = ftell instream + header.size hchunk = ReadHeader instream fseek instream 4 #seek_cur --skip version stend = ftell instream + 16 name = ReadString instream fseek instream stend #seek_set stend += 16 reqskelname = ReadString instream fseek instream stend #seek_set fseek instream 4 #seek_cur --skip numconnections hchunk = ReadHeader instream hend = hchunk.size + ftell instream fseek instream 4 #seek_cur --skip attributes nummeshes = getWord instream fseek instream hend #seek_set --skip rest of aux data hlods[curlod] = #() --now, get nodes for i = 1 to nummeshes do ( ignore = ReadHeader instream stend = ftell instream + 16 hlname = ReadString instream fseek instream stend #seek_set hlods[curlod][i] = hlobject bone:(getWord instream) name:hlname ) curlod += 1 fseek instream hmend #seek_set ) --HLOD super chunk, not including app-specific "PROXY" chunks #W3D_CHUNK_HLOD: ( hlend = ftell instream + header.size hlheader = ReadHeader instream --HLOD Header fseek instream 4 #seek_cur --ignore version numlods = getDword instream stend = ftell instream + 16 hlname = ReadString instream fseek instream stend #seek_set stend = ftell instream + 16 reqskelname = ReadString instream fseek instream stend #seek_set while (ftell instream) < hlend do ( hlheader = ReadHeader instream headertype = translateType hlheader.type if (headertype == #W3D_CHUNK_HLOD_LOD_ARRAY) then ( hlods[curlod] = #(); hlheader = ReadHeader instream --hlod array header nummodels = getDword instream fseek instream 4 #seek_cur --skip max screen size data for hlso = 1 to nummodels do ( hlheader = ReadHeader instream chunkend = ftell instream + hlheader.size hlods[curlod][hlso] = hlobject (getDword instream) (substring (ReadString instream) (hlname.count + 2) 32) fseek instream chunkend #seek_set --skip unknown data ) --trim in case of multiple imports per session for trim = (nummodels + 1) to hlods[curlod].count do ( if (hlods[curlod][nummodels + 1] != undefined) then deleteItem hlods[curlod] trim ) curlod += 1 ) else ( --an aggregate (toss for now) fseek instream hlheader.size #seek_cur ) ) --more trimming for atrim = curlod to hlods.count do ( if(hlods[atrim] != undefined) then deleteItem hlods atrim ) ) default: ( fseek instream header.size #seek_cur ) ) ) --main import function on activateImport pressed do ( scalage = Point3 scale.value scale.value scale.value numpivots = 0; w3dfilename = getOpenFileName caption:"Import W3D" \ types:"Westwood 3D (*.w3d)|*.w3d|All Files (*.*)|*.*|" if(useSkel.checked == true) then ( if(skelfile != undefined) then ( if w3dfilename != undefined then --extra check for kind canceling ( skelstream = fopen skelfile "rb" loadSkeleton skelstream FClose skelstream ) ) ) if w3dfilename != undefined then ( filestream = fopen w3dfilename "rb" ---binary fseek filestream 0 #seek_end local filesize = ftell filestream fseek filestream 0 #seek_set curmesh = 1 nummeshes = 0; sizeguess = 1; numboxes = 0; while (ftell filestream < filesize) do ( processChunk filestream ) FClose filestream --resize bones resizeFactor = sizeguess / 2.2 for p = 1 to (numpivots - 1) do pivots[p].radius = resizeFactor * pivots[p].radius --put meshes into hierarchy tree nullpoint = point3 0 0 0 nullquat = quat 0 0 0 0 meshPivots = #() for mm = 1 to nummeshes do ( pindex = findMeshInHlod mm meshPivots[mm] = pindex.type if( pindex.type != 0) then ( meshes[mm].parent = pivots[pindex.type] in coordsys parent meshes[mm].rotation = nullquat --mesh pivot = pivot point in coordsys parent meshes[mm].pos = nullpoint )else ( meshes[mm].rotation = nullquat --mesh pivot = scene root meshes[mm].pos = nullpoint ) setUserProp meshes[mm] "LOD" pindex.size update meshes[mm] ) replaceRedundancies meshPivots -- only show given LOD if (showLODlist.selection != 1) then hideLODs() -- hide hiddens if requested if (showHidden.checked == false) then hideHidden() --hide pivots if (showPivots.checked == false) then hideBones() max views redraw ) ---------------------------------------------------------Copy Materials To Material Editor------------------ if( LoadMaterials.checked == true) then ( for temp = 1 to 24 do ( if(sceneMaterials[temp] == undefined) then ( exit ) meditMaterials[temp] = sceneMaterials[temp] ) ) actionMan.executeAction 0 "50048" -- if( curmesh <= 24) then -- ( -- meditMaterials[curmesh] = meshes[curmesh].material -- ) ------------------------------------------------------------------------------------------------------------ ) on useSkel changed state do ( if state == true then SkelBut.enabled = true else \ SkelBut.enabled = false ) on SkelBut pressed do ( skelfilename = getOpenFileName caption:"Import Skeleton" \ types:"Westwood 3D (*.w3d)|*.w3d|All Files (*.*)|*.*|" skelfile = skelfilename if skelfilename != undefined then ( holdme = filterString skelfilename "\\/" SkelBut.caption = holdme[holdme.count] ) ) on selPivots pressed do ( max unhide all max select all i = 1 while i <= selection.count do ( if (getUserProp selection[i] "bone") == undefined then ( deselectNode selection[i] i -= 1; ) i += 1; ) ) on showHidden changed state do ( if(state == true) then ( max unhide all if showLODlist.selection != 1 then hideLODs() if showPivots.checked == false then hideBones() )else ( hideHidden() ) ) on showPivots changed state do ( if(state == true) then ( max unhide all )else ( hideBones() ) ) on showLODlist selected choice do ( if choice != 1 then ( LODtoShow = hlods.count - choice + 2 hideLODs() if showHidden.checked != true then hideHidden() if showPivots.checked == false then hideBones() ) else ( max unhide all if showHidden.checked != true then hideHidden() if showPivots.checked == false then hideBones() ) ) )