Tested.
Perfect!

You are the bomb dot com.
Hound

Glorious!

So theoretically any model I plug in to the line that defines what file I want to import should work, right?TaylorMouse wrote:Hey guys, been pretty busy the last couple of days, certainly with the D3 Expansion coming along.
I've taken every piece of code I could find, dropped it into a max script and now I'm able to import the app files into max, completely rigged and skinned.
It took quit some time to figure out how to apply all these things in Max, cause exporting it to obj does not involve bones, vertex weights etc...
it's not completed yet, just a wip..
I need some way to find the texture/material
in the code I took the example of Adria, so if you want to use the script ( as of Max 2011) you need to change the hard coded file of adria.app and here dds files to make it work
T.Code: Select all
/* Import Diablo III App format by Taylor Mouse (c) 12.2013 */ /* CLEAN UP */ ClearListener() max select all max delete /********************/ /* Helper functions */ /********************/ fn ReadBytes stream val = ( for i=1 to val do ReadByte stream ) fn ReadFixedString stream val = ( local str = "" for i=1 to val do ( s= bit.IntAsChar(ReadByte stream) if(s!="\0") then str+=s ) return str ) /********************/ /* STRUCTS */ /********************/ struct AABB ( A, B ) struct D3Bone ( ID, Name, ParentID, Position, TheBone ) struct GeoSet ( Name, theMesh, Verts, VertexWeights, Normals, UVWs, Indices, nVerts, ofVerts, sizeVerts, ofVertexWeights, sizeWeights, nIndices, ofIndices, sizeIndices ) struct VertexWeight --> Influence ( BoneID1,Weight1, BoneID2,Weight2, BoneID3,Weight3 ) /********************/ /********************/ file = @"..\Exported\Appearance\Adria.app" stream = fOpen file "rb" -- Skip 36 bytes ReadBytes stream 36 -- Bones nBones = ReadLong stream ofBones = ReadLong stream sizeBones = ReadLong stream -- Skip 120 bytes ReadBytes stream 120 -- Subsets nSubset = ReadLong stream ofSubset = ReadLong stream sizeSubset = ReadLong stream -- Skip 36 bytes ReadBytes stream 36 -- Collision Sphere sph = sphere pos:[ReadFloat stream , ReadFloat stream , ReadFloat stream] radius:(ReadFloat stream) name:"CollisionSphere" sph.xray = true -- Colission Capsules nCollCap = ReadLong stream offCollCap = ReadLong stream sizeCollCap = ReadLong stream allBones = #() /* BONES */ if(ofBones > 0 ) then ( fSeek stream (ofBones + 16) #seek_set for b=1 to nBones do ( aBone = D3Bone() aBone.ID = b aBone.Name = ReadFixedString stream 64 aBone.ParentID = (ReadLong stream) + 1 --> 0 is the root -- Bounding Boxes ab = AABB() ab.A = [ReadFloat stream , ReadFloat stream , ReadFloat stream] ab.B = [ReadFloat stream , ReadFloat stream , ReadFloat stream] x = ab.A.X - ab.B.X y = ab.A.Y - ab.B.Y z = ab.A.Z - ab.B.Z -- Box length:x width:y height:z wirecolor:(color c 0 0) -- Bounding Spheres radius = ReadFloat stream position = [ReadFloat stream , ReadFloat stream , ReadFloat stream] -- Sphere radius:0.2 pos:position wirecolor:(Color 0 c 0) -- PRSTransform q1 = quat (ReadFloat stream) (ReadFloat stream) (ReadFloat stream) (ReadFloat stream) v1 = Point3 (ReadFloat stream) (ReadFloat stream) (ReadFloat stream) aBone.Position = v1 append allBones aBone ReadBytes stream 100 ---> not required,... yet ) /* Build the bones*/ for b=1 to nBones do ( if( allBones[b].ParentID == 0 ) then ( allBones[b].TheBone = BoneSys.CreateBone allBones[b].Position allBones[b].Position [0,0,1] ) else ( parentID = allBones[b].ParentID allBones[b].TheBone = BoneSys.CreateBone allBones[b].Position allBones[b].Position [0,0,1] allBones[b].TheBone.Parent = allBones[parentID].TheBone ) allBones[b].TheBone.Name = allBones[b].Name allBones[b].TheBone.ShowLinks = true allBones[b].TheBone.Width = 0.05 allBones[b].TheBone.Height = 0.05 ) ) /* GEOSETS */ fSeek stream (ofSubset + 16) #seek_set geosets= #() for subset=1 to nSubset do ( g = GeoSet() ReadLong stream -- ? g.nVerts = ReadLong stream g.ofVerts = ReadLong stream g.sizeVerts = ReadLong stream ReadLong stream -- ? g.ofVertexWeights = ReadLong stream g.sizeWeights = ReadLong stream ReadLong stream -- ? g.nIndices = ReadLong stream g.ofIndices = ReadLong stream g.sizeIndices = ReadLong stream ReadBytes stream 28 g.name = ReadFixedString stream 128 name2 = ReadFixedString stream 128 ReadBytes stream 44 append geosets g ) /* GEO Data */ for i=1 to nSubset do ( verts = #() vertexWeights = #() normals = #() uvws = #() indices = #() /* Vertices, normals, texture coordinates */ fSeek stream ( geosets[i].ofVerts + 16 ) #seek_set for v=1 to geosets[i].nVerts do ( -- vertex vert = [ ReadFloat stream, ReadFloat stream, ReadFloat stream ] append verts vert -- normal nx = ReadByte stream ny = ReadByte stream nz = ReadByte stream ReadBytes stream 9 rnx = (nx - 127.0)/127.0 rny = (ny - 127.0)/127.0 rnz = (nz - 127.0)/127.0 normal = [rnx, rny, rnz] append normals normal -- Texture Coordinate texU = ReadShort stream #unsigned texV = ReadShort stream #unsigned ReadBytes stream 16 tu = float tv = float tu = 32767.0 - texU tv = 32767.0 - texV tu /= 512.0 tv /= 512.0 tv +=1.0 tu *=-1.0 uv = [tu, tv, 0.0] append uvws uv ) /* Vertex Weights */ fSeek stream ( geosets[i].ofVertexWeights + 16 ) #seek_set for v=1 to geosets[i].nVerts do ( vw = VertexWeight() vw.BoneID1 = ReadLong stream vw.Weight1 = ReadFloat stream vw.BoneID2 = ReadLong stream vw.Weight2 = ReadFloat stream vw.BoneID3 = ReadLong stream vw.Weight3 = ReadFloat stream append vertexWeights vw ) /* Indices */ fSeek stream ( geosets[i].ofIndices + 16 ) #seek_set for f=1 to geosets[i].nIndices / 3 do ( index = [ReadShort stream #unsigned +1 , ReadShort stream #unsigned + 1, ReadShort stream #unsigned + 1] append indices index ) geosets[i].Verts = verts geosets[i].UVWs = uvws geosets[i].Normals = normals geosets[i].Indices = indices geosets[i].VertexWeights = vertexWeights ) /* BUILD THE MESHES */ for i=1 to nSubset do ( -- Create the mesh theMesh = mesh vertices:geosets[i].Verts faces:geosets[i].Indices name:geosets[i].Name tverts:geosets[i].UVWs vnorms:geosets[i].Normals meshOp.setMapSupport theMesh 1 true for t = 1 to geosets[i].Verts.count do meshop.setMapVert theMesh 1 t geosets[i].UVWs[t] update theMesh -- create the materials meditMaterials[i] = Standard() meditMaterials[i].name = geosets[i].Name meditMaterials[i].diffuseMapEnable = on meditMaterials[i].selfillumMapEnable = on meditMaterials[i].useSelfIllumColor = on meditMaterials[i].opacityMapEnable = on meditMaterials[i].specularLevel = 50 meditMaterials[i].selfIllumColor = color 255 255 255 meditMaterials[i].diffuseMap = Bitmaptexture fileName:"..\Adria_A_DiffCON.dds" meditMaterials[i].specularMap = Bitmaptexture fileName:"..\Adria_A_SpecCON.dds" meditMaterials[i].selfillumMap = Bitmaptexture fileName:"..\Adria_A_SpecCON.dds" meditMaterials[i].opacityMap = Bitmaptexture fileName:"..\Adria_A_DiffCON.dds" meditMaterials[i].opacityMap.monooutput = 1 showTextureMap meditMaterials[i] true theMesh.material = meditMaterials[i] update theMesh geosets[i].theMesh = theMesh /* TODO: Find the matching texture using an algorithm */ ) for i=1 to nSubset do ( msh = geosets[i].theMesh -- Apply skin modifier select msh max modify mode --> VERY IMPORTANT!!! modPanel.addModToSelection(skin()) skinMod = msh.Modifiers["skin"] modPanel.setCurrentObject skinMod -- add all the bones for b=1 to nBones do ( skinOps.addBone skinMod allBones[b].TheBone 0 ) update msh -- Apply vertex weights --disableSceneRedraw() select msh max modify mode bones_total_count = skinops.getnumberbones skinMod vertex_count = getNumverts msh for v = 1 to vertex_count do ( --vertex_bone_count = skinOps.GetVertexWeightCount msh.modifiers[#skin] v for b = 1 to bones_total_count do ( boneId1 = geosets[i].VertexWeights[v].BoneId1 + 1 weight1 = geosets[i].VertexWeights[v].Weight1 boneId2 = geosets[i].VertexWeights[v].BoneId2 + 1 weight2 = geosets[i].VertexWeights[v].Weight2 boneId3 = geosets[i].VertexWeights[v].BoneId3 + 1 weight3 = geosets[i].VertexWeights[v].Weight3 if (b == boneId1) then skinOps.ReplaceVertexWeights skinMod v boneId1 weight1 else if (b == boneId2) then skinOps.SetVertexWeights skinMod v boneId2 weight2 else if (b == boneId3) then skinOps.SetVertexWeights skinMod v boneId3 weight3 ) -- apply the new bone weights update msh ) --enableSceneRedraw() update msh redrawviews() ) /* Clean up */ fFlush stream fClose stream clearselection() GC() /* Zoom into the selected model */ max zoomext sel all
Code: Select all
ADR 0
REPLACE EF BE AD DE 2F BY EF BE AD DE 2B
Code: Select all
@for /f "tokens=*" %%a in ('dir /b *.tex') do ( xvi32.exe "%%a" /S="textures.xsc" )
exit
Code: Select all
@for /f "tokens=*" %%a in ('dir /b *.tex') do D3TexConv.exe "%%a"
Code: Select all
nconvert -out png *.dds
Code: Select all
@for /f "tokens=*" %%a in ('dir /b *.app') do d3rs_app2obj.exe "%%a" "%%a.obj"
REN *.app.obj ??????????????????????????????.obj
DEL *.app /q
@1: The problem is with how 3dsmax imports it. Apparently 3dsmax only imports it correctly if the triangles are in 1 contiguous block. But that apparently broke the grouping. I might have an idea, will take a look. Update: Try the attachment ( completely untested ^^ )TheRealMethuselah wrote:My workflow is:
EDIT: kalmiya, in the previous iterations of the converter, I was able to select certain portions of it, be it wings, etc, and delete them. In this current version it looks as though it is simply one piece. Is there a way to extract the model with the pieces in tact?
EDIT 2: As TehDave mentioned. If there is any way to extract WITH the bones, you would make us all very happy.
EDIT 3: You've been uber generous. I've been racking my brain on the animation thread, trying to figure out how you view the animations... would you PLEASE give me a heads up or step-by-step?