READ THE RULES: Click here

Follow us on Facebook: https://www.facebook.com/xentax/ :)

Diablo III .app

Post questions about game models here, or help out others!
User avatar
TheRealMethuselah
n00b
Posts: 17
Joined: Sat Apr 12, 2014 6:19 pm
Location: Redondo Beach, CA. USA
Has thanked: 10 times
Been thanked: 1 time

Re: Diablo III .app

Post by TheRealMethuselah » Sun Apr 13, 2014 7:11 pm

Downloading Blender now.
Tested.

Perfect!
Image

You are the bomb dot com.

Hound
Image

Glorious!
Image
Last edited by TheRealMethuselah on Sun Apr 13, 2014 7:30 pm, edited 1 time in total.
"I'd love to change the world, but they won't give me the source code."

kalmiya
beginner
Posts: 22
Joined: Sun Mar 23, 2014 5:23 pm
Location: The Neverlands
Has thanked: 1 time
Been thanked: 9 times
Contact:

Re: Diablo III .app

Post by kalmiya » Sun Apr 13, 2014 7:28 pm

Nicey!

I made some modifications, can you give this version a try ?
You do not have the required permissions to view the files attached to this post.

User avatar
TheRealMethuselah
n00b
Posts: 17
Joined: Sat Apr 12, 2014 6:19 pm
Location: Redondo Beach, CA. USA
Has thanked: 10 times
Been thanked: 1 time

Re: Diablo III .app

Post by TheRealMethuselah » Sun Apr 13, 2014 7:30 pm

On it.

EDIT:
FLAWLESS VICTORY!
Image

Re-converting all of my .app files now.
Image

Thank you so much for your quick response to inquiries, kalmiya. I appreciate it, wholeheartedly.

Working perfectly.
Image

Chests!
Image

http://danielbarras.deviantart.com/art/ ... -447397488
"I'd love to change the world, but they won't give me the source code."

TehDave
advanced
Posts: 74
Joined: Tue Apr 21, 2009 5:24 am
Has thanked: 10 times
Been thanked: 5 times

Re: Diablo III .app

Post by TehDave » Thu Apr 17, 2014 3:42 am

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

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

T.
So theoretically any model I plug in to the line that defines what file I want to import should work, right?

Also, what's the workflow for getting the actual files? I feel kind of lost jumping into long threads like these.

EDIT: Just tried out that above script, doesn't seem to work with Max 2012, unfortunately, it throws errors about arrays being too large or something0. Hope taylormouse decides to update the script so we can get these out rigged with original bones.

EDIT EDIT: Just had a thought that maybe it's more the fact this script predates 2.0 and RoS that's the cause of the errors. In any case, hoping for someone to come through and get us rigged meshes.

User avatar
TheRealMethuselah
n00b
Posts: 17
Joined: Sat Apr 12, 2014 6:19 pm
Location: Redondo Beach, CA. USA
Has thanked: 10 times
Been thanked: 1 time

Re: Diablo III .app

Post by TheRealMethuselah » Mon Apr 21, 2014 1:42 am

My workflow is:

1. Use MPQEditor to extract the .app files from ClientData.mpq
Image

2. Use MPQEditor to extract the .tex files from Texture.mpq
Image

3. Use xvi32 with a textures.xsc file (below) to convert the header of the .tex files

textures.xsc

Code: Select all

ADR 0
REPLACE EF BE AD DE 2F BY EF BE AD DE 2B
batch file:

Code: Select all

@for /f "tokens=*" %%a in ('dir /b *.tex') do ( xvi32.exe "%%a" /S="textures.xsc" )
exit
4. Use D3TexConv to convert the .tex files to .dds files

Code: Select all

@for /f "tokens=*" %%a in ('dir /b *.tex') do D3TexConv.exe "%%a"
5. Use nvconvert to convert the .dds files to .png

Code: Select all

nconvert -out png *.dds
6. Use d3rs_app2obj to convert the .app to .obj files

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
7. Profit.
Image

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?
"I'd love to change the world, but they won't give me the source code."

ibeckman671
ultra-n00b
Posts: 2
Joined: Wed Apr 16, 2014 3:16 am

Re: Diablo III .app

Post by ibeckman671 » Tue Apr 22, 2014 1:17 am

I wish d3rs_app2obj converted some of the models correctly. It seems the main characters and Tyrael come out blotchy. Here is the Monk for example. What am I doing wrong?
You do not have the required permissions to view the files attached to this post.

User avatar
TheRealMethuselah
n00b
Posts: 17
Joined: Sat Apr 12, 2014 6:19 pm
Location: Redondo Beach, CA. USA
Has thanked: 10 times
Been thanked: 1 time

Re: Diablo III .app

Post by TheRealMethuselah » Tue Apr 22, 2014 4:45 am

You're doing nothing wrong.

It seems that the models for the players have all of the items equipped, but that they are separate pieces.

That goes back to my question earlier. In previous iterations, you could remove those pieces. Now, it's just one big piece.

Same goes for Tyrael, there is some model pieces over his face.
Image

As for the Barbarian, he's got everything on him too.
Image
"I'd love to change the world, but they won't give me the source code."

kalmiya
beginner
Posts: 22
Joined: Sun Mar 23, 2014 5:23 pm
Location: The Neverlands
Has thanked: 1 time
Been thanked: 9 times
Contact:

Re: Diablo III .app

Post by kalmiya » Wed Apr 23, 2014 11:06 pm

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?
@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 ^^ )

@2: I can extract the bone-data in my parser, the problem is that the .obj fileformat is quite primitive (which makes it easy to export meshes) but it just does not support bone-information. I was looking for alternatives, only text-format I know is collada ( which is a real pain, and I was actually rewriting my engine to directly import .blend files instead of collada, before I got curious about the d3 fileformat ).

@3: I don't know how to import it into 3dsmax - I'm a software developer, not a graphics-guy ^^ There are some max-scripts in the d3-threads - I think by TailorMouse and ZeroGravity - I guess it should be possible with those. I'd actually be interested in a step-by-step tutorial on how to load it into 3dsmax.

As a background: I'm trying to use the bone-data to "magically" transform the vertices in my little sandbox engine.
So here goes a question of my own: If I look in the .app file, there also is bone-information. What is it intended for? Should that be applied to the mesh-vertices first - to bring the model in the "t-pose" as the starting-point for applying a keyframe from the .ani ?

For example, for the chest the .app contains the following info:

# model bone-structure
# [0] id=0 'Root_Joint' - parent-id=-1 (no parent)
# - q( 0.000, 0.000, 1.000, 0.000) p(-1.591, 0.000,-0.000) s( 1.00)
# - q(-0.000,-0.000, 1.000,-0.000) p( 1.591, 0.000, 0.000) s( 1.00)
# - q( 0.000, 0.000, 1.000, 0.000) p(-1.591, 0.000,-0.000) s( 1.00)
# - q( 0.000, 0.000, 1.000, 0.000) p(-1.591, 0.000,-0.000) s( 1.00)
# - q(-0.000,-0.000, 1.000,-0.000) p( 1.591, 0.000, 0.000) s( 1.00)
# [1] id=1 'Hinge - parent-id=0 ' (="Root_Joint")
# - q( 0.000, 0.000, 1.000, 0.000) p(-1.302,-0.052, 1.552) s( 1.00)
# - q(-0.000,-0.000, 1.000,-0.000) p( 1.302, 0.052,-1.552) s( 1.00)
# - q( 0.000, 0.000, 1.000, 0.000) p( 0.290,-0.052, 1.552) s( 1.00)
# - q( 0.000, 0.000, 1.000, 0.000) p(-1.302,-0.052, 1.552) s( 1.00)
# - q(-0.000,-0.000, 1.000,-0.000) p( 1.302, 0.052,-1.552) s( 1.00)
You do not have the required permissions to view the files attached to this post.

User avatar
TheRealMethuselah
n00b
Posts: 17
Joined: Sat Apr 12, 2014 6:19 pm
Location: Redondo Beach, CA. USA
Has thanked: 10 times
Been thanked: 1 time

Re: Diablo III .app

Post by TheRealMethuselah » Wed Apr 23, 2014 11:50 pm

Ok, I see. I'll try a few things here and there.

Adria (Adria_idle_01 34 frames)
Image

Adria new with animation frame. (Click to enlarge 1920x1080)
Image

Mallet Lord with animation frame. (Click to enlarge 1920x1080)
Image
I think I've got enough data to animate to get some good model poses. Thank you again.

Image

Image
"I'd love to change the world, but they won't give me the source code."

User avatar
TaylorMouse
ultra-veteran
ultra-veteran
Posts: 335
Joined: Mon Sep 26, 2011 12:51 pm
Has thanked: 11 times
Been thanked: 79 times

Re: Diablo III .app

Post by TaylorMouse » Sat May 03, 2014 9:32 am

I redid the script, you can download them from here:

http://www.sc2mapster.com/assets/sc1-ra ... rt-script/

Also, if you put them in your startup script, the first time you run them it could throw an error ( don't know why ) just re-evaluate the script and it should work

Animation script included

T.

User avatar
TaylorMouse
ultra-veteran
ultra-veteran
Posts: 335
Joined: Mon Sep 26, 2011 12:51 pm
Has thanked: 11 times
Been thanked: 79 times

Re: Diablo III .app

Post by TaylorMouse » Sat May 03, 2014 9:08 pm

Btw TheRealMethuselah, where did you get the devil circle in the backgrounds from ?

T.

kalmiya
beginner
Posts: 22
Joined: Sun Mar 23, 2014 5:23 pm
Location: The Neverlands
Has thanked: 1 time
Been thanked: 9 times
Contact:

Re: Diablo III .app

Post by kalmiya » Sun May 04, 2014 5:12 pm

Trying the new script (from 2 posts ago) - it does load the adria-rs-model, but when trying to load the adria-rs-run/walk-animation I get a messagebox displaying "Maxscript rollout handler exception: --type error: Call needs function or class, got: undefined"... ? Also tried with a rs-chest. Anyone else got that problem?

[Update]: Seems that 3dsmax doesn't like "echo".

User avatar
TheRealMethuselah
n00b
Posts: 17
Joined: Sat Apr 12, 2014 6:19 pm
Location: Redondo Beach, CA. USA
Has thanked: 10 times
Been thanked: 1 time

Re: Diablo III .app

Post by TheRealMethuselah » Tue May 06, 2014 4:52 am

Here ya go, TaylorMouse:
Image


Here's my new gallery.
http://danielbarras.deviantart.com/gallery/


Grotesque (Stitch)
Image

Adria Animation run
Image
You do not have the required permissions to view the files attached to this post.
Last edited by TheRealMethuselah on Sun May 11, 2014 5:37 pm, edited 1 time in total.
"I'd love to change the world, but they won't give me the source code."

User avatar
TaylorMouse
ultra-veteran
ultra-veteran
Posts: 335
Joined: Mon Sep 26, 2011 12:51 pm
Has thanked: 11 times
Been thanked: 79 times

Re: Diablo III .app

Post by TaylorMouse » Thu May 08, 2014 7:16 pm

Thnx, don't forget to turn on the two sided faces for the texture

T.

User avatar
TheRealMethuselah
n00b
Posts: 17
Joined: Sat Apr 12, 2014 6:19 pm
Location: Redondo Beach, CA. USA
Has thanked: 10 times
Been thanked: 1 time

Re: Diablo III .app

Post by TheRealMethuselah » Fri May 09, 2014 1:08 am

Got it! Fixed.


ibeckman, so there were a few pieces of Tyrael you had to get past:
Image

A_restored_cloth
A_normal_mat
A_restored_mat
A_skeleton_mat

It now loads just fine.
"I'd love to change the world, but they won't give me the source code."

Post Reply