Page 7 of 12

Re: Diablo III .app

Posted: Wed Oct 19, 2011 7:18 am
by deltaone
ppl, how to establish connection with model and textures for creating .mtl file ?

2 TaylorMouse
for correct formatin decimal numbers witch any locale add this (i had comma separated digits - must be dot) and i think its be base problem with this converter ...
CultureInfo newCInfo = (CultureInfo)Thread.CurrentThread.CurrentCulture.Clone();
newCInfo.NumberFormat.NumberDecimalSeparator = ".";
Thread.CurrentThread.CurrentCulture = newCInfo;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

namespace d3app2obj
{
public class Convert
{
// Methods
public static string CharToString(char[] chars)
{
string str = "";
for (int i = 0; i < chars.Length; i++)
{
if (chars == '\0')
{
return str;
}
str = str + chars.ToString();
}
return str;
}

public static void DiabloIIIAppToObj(string file)
{
CultureInfo newCInfo = (CultureInfo)Thread.CurrentThread.CurrentCulture.Clone();
newCInfo.NumberFormat.NumberDecimalSeparator = ".";
Thread.CurrentThread.CurrentCulture = newCInfo;


string str = file.Substring(0, file.Length - 4) + ".obj";
Console.WriteLine(string.Format("Writing OBJ data to {0}", str));
int num = 0;
int num2 = 0;
long offset = 0L;
using (TextWriter writer = new StreamWriter(str, false))
{
writer.WriteLine(string.Format("# Diablo 3 Appearance (.app) model file exported on {0}", DateTime.Now.ToString("yyyy/MM/ddThh:mm:ss")));
writer.WriteLine("# Special thanks to Falo");
writer.WriteLine("# Written in C#.NET by Taylor Mouse");
writer.WriteLine();
writer.WriteLine("mtllib default.mtl");
writer.WriteLine();
using (BinaryReader reader = new BinaryReader(File.Open(file, FileMode.Open)))
{
reader.ReadBytes(0x10);
for (int i = 0; i < 5; i++)
{
reader.ReadUInt32();
}
int num5 = reader.ReadInt32();
int num6 = reader.ReadInt32();
reader.ReadInt32();
for (int j = 0; j < 30; j++)
{
reader.ReadInt32();
}
int num8 = reader.ReadInt32();
int num9 = reader.ReadInt32();
reader.ReadInt32();
writer.WriteLine(string.Format("# numMaterials: {0}", num8));
writer.WriteLine(string.Format("# numBones: {0}", num5));
writer.WriteLine("# ParentID\tBone");
reader.BaseStream.Seek((long)(num6 + 0x10), SeekOrigin.Begin);
for (int k = 0; k < num5; k++)
{
string str2 = CharToString(reader.ReadChars(0x40));
int num11 = reader.ReadInt32();
writer.WriteLine(string.Format("# {0}\t\t{1}", num11, str2));
for (int n = 0; n < 0x22; n++)
{
reader.ReadSingle();
}
for (int num13 = 0; num13 < 8; num13++)
{
reader.ReadInt32();
}
}
writer.WriteLine();
reader.BaseStream.Seek((long)(num9 + 0x10), SeekOrigin.Begin);
for (int m = 0; m < num8; m++)
{
reader.ReadInt32();
int num15 = reader.ReadInt32();
int num16 = reader.ReadInt32();
reader.ReadInt32();
reader.ReadInt32();
int num17 = reader.ReadInt32();
reader.ReadInt32();
reader.ReadInt32();
int num18 = reader.ReadInt32();
int num19 = reader.ReadInt32();
reader.ReadInt32();
for (int num20 = 0; num20 < 7; num20++)
{
reader.ReadInt32();
}
string str3 = CharToString(reader.ReadChars(0x80));
string str4 = CharToString(reader.ReadChars(0x80));
for (int num21 = 0; num21 < 11; num21++)
{
reader.ReadSingle();
}
offset = reader.BaseStream.Position;
writer.WriteLine(string.Format("# numVerts: {0}", num15));
writer.WriteLine(string.Format("# numFaces: {0}", num18));
reader.BaseStream.Seek((long)(num16 + 0x10), SeekOrigin.Begin);
for (int num22 = 0; num22 < num15; num22++)
{
float num23 = reader.ReadSingle();
float num24 = reader.ReadSingle();
float num25 = reader.ReadSingle();

float nx = reader.ReadByte();
float ny = reader.ReadByte();
float nz = reader.ReadByte();
float nw = reader.ReadByte();

// reader.ReadInt32();
reader.ReadInt32();
reader.ReadInt32();
float u = reader.ReadUInt16();
float v = reader.ReadUInt16();


// writer.WriteLine(string.Format("#debug {0:0.000000} {1:0.000000}", u, v));
u = (u - 32767) / 512.0f;
v = 1 - (v - 32767) / 512.0f;


// ushort num26 = reader.ReadUInt16();
// ushort num27 = reader.ReadUInt16();
reader.ReadInt32();
reader.ReadInt32();
reader.ReadInt32();
reader.ReadInt32();


// float num28 = num26;
// float num29 = num27;
// num28 -= 32767f;
// num29 -= 32767f;
// num28 /= 512f;
// num29 /= 512f;
// num29 *= -1f;
// num29++;

writer.WriteLine(string.Format("v {0:0.000000} {1:0.000000} {2:0.000000}", num23, num24, num25));

// writer.WriteLine(string.Format("vt {0} {1}", num28, num29));
writer.WriteLine(string.Format("vt {0:0.000000} {1:0.000000}", u, v));

nx = (nx - 127) / 127.0f;
ny = (ny - 127) / 127.0f;
nz = (nz - 127) / 127.0f;

writer.WriteLine(string.Format("vn {0:0.000000} {1:0.000000} {2:0.000000}", nx, ny, nz));
}
reader.BaseStream.Seek((long)(num17 + 0x10), SeekOrigin.Begin);
for (int num30 = 0; num30 < num15; num30++)
{
reader.ReadInt32();
reader.ReadSingle();
reader.ReadInt32();
reader.ReadSingle();
reader.ReadInt32();
reader.ReadSingle();
}
writer.WriteLine(string.Format("g {0}", str3));
writer.WriteLine(string.Format("usemtl {0}", str4));
reader.BaseStream.Seek((long)(num19 + 0x10), SeekOrigin.Begin);
for (int num31 = 0; num31 < (num18 / 3); num31++)
{
ushort num32 = reader.ReadUInt16();
ushort num33 = reader.ReadUInt16();
ushort num34 = reader.ReadUInt16();
writer.WriteLine(string.Format("f {0}/{1}/{2} {3}/{4}/{5} {6}/{6}/{7}", new object[] { (num + num32) + 1, (num + num32) + 1, (num + num32) + 1, (num + num33) + 1, (num + num33) + 1, (num + num33) + 1, (num + num34) + 1, (num + num34) + 1, (num + num34) + 1 }));
}
num += num15;
num2++;
reader.BaseStream.Seek(offset, SeekOrigin.Begin);
}
reader.Close();
}
writer.Close();
}
}
}




class program
{
static void Main(string[] args)
{
if(args.Length == 0)
{
Console.Write(
"Written by Taylor Mouse\nOriginal Script by Falo\nUse with blizzards Diablo III 3D Models\nExtract the .app from the Diablo III MPQ files\nAll models and assets are registered trademarks from Blizzard Ltd. all rights reserved\nThis tool is thereby for studying purposes only and may not be sold!\n\nUsage:\n\n-d [directory] :each valid .app file in the directory will be converted to a .obj file\n-f [filename] :converts the appearance file .app to a .obj file\n\n(c)2011");
}
else
{
for(int i = 0; i < args.Length; i++)
{
if(args == "-d")
{
string path = args[i + 1];
if(Directory.Exists(path))
{
string[] files = Directory.GetFiles(path, "*.app");
for(int j = 0; j < files.Length; j++)
{
if(File.Exists(files[j]))
{
Console.WriteLine(string.Format("Converting {0}", files[j]));
try
{
Convert.DiabloIIIAppToObj(files[j]);
}
catch(Exception exception)
{
Console.WriteLine(exception);
}
}
}
return;
}
Console.WriteLine(string.Format("Directory {0} does not exist!", path));
return;
}
if(args == "-f")
{
string str2 = args[i + 1];
if(File.Exists(str2))
{
Console.WriteLine(string.Format("Converting {0}", str2));
try
{
Convert.DiabloIIIAppToObj(str2);
}
catch(Exception exception2)
{
Console.WriteLine(exception2);
}
}
break;
}
}
}
}
}
}

Re: Diablo III .app

Posted: Wed Oct 19, 2011 7:07 pm
by Monguron
I would say, we already should be capable to make this:

http://www.diablowiki.com/Skeleton_Arch ... blo_III%29

1) as we have a converter, that makes .obj + .tex from app files
2) then we can convert the .tex to .dds
3) the away3D engine can open .obj files easily

I've already attached an away3d action script code (in this thread), which opens an obj, puts textures onto it, and then moves a light around the model.
I just don't know why it's not working with my .obj + .dds files.

Guys, we have the knowledge together ... come on!

Re: Diablo III .app

Posted: Thu Oct 20, 2011 5:24 pm
by InsaneXo
-

Re: Diablo III .app

Posted: Fri Oct 21, 2011 3:20 pm
by Monguron
?? :)

Re: Diablo III .app

Posted: Mon Oct 24, 2011 1:51 pm
by TaylorMouse
Yeah, Monguron, do some work and add it together, cause I don not know how.

I don't seem to find a way to connect the 2 together, there is no reference to the data extracted from the app file that has any link to the material files...

T.

Re: Diablo III .app

Posted: Tue Oct 25, 2011 3:57 am
by npd2006
Your source code in C# is very nice TaylorMouse, why don't just develop it by adding some function to display the 3d mesh. C#.NET can be easily added to website, too.

Re: Diablo III .app

Posted: Tue Oct 25, 2011 9:49 am
by TaylorMouse
Thnx,

the code actually looks even nicer, because that code has been taken using Reflector.NET

the only problem is that I don't know how to easily display 3D models using C# :/

Any suggestions?

T.

Re: Diablo III .app

Posted: Tue Oct 25, 2011 7:56 pm
by Monguron
Hey Guys,

many days passed since I could check the forum... (perhaps 4 or 5 :))

so ...

As I've said I could load a model in flash, but the texturing is a different story...

I try to do my best, and will tell you if I have any progress.

Re: Diablo III .app

Posted: Tue Oct 25, 2011 9:05 pm
by Monguron
I converted the Adria_A_diff.dds and Adria_A_spec.dds files to .png format, so there is an improvement, but it seems there are some texturing problems...

1) I'm using this code in away3d

[Embed(source="/../embeds/adria/Adria_A_diff.png")]
private var Albedo : Class;

[Embed(source="/../embeds/adria/Adria_A_spec.png")]
private var Specular : Class;


But It seems the spec.png is not on the object, and also the original diff.png is misaligned in some parts, or ....?

any idea?

Re: Diablo III .app

Posted: Tue Oct 25, 2011 10:46 pm
by TaylorMouse
When you convert them to png ? are they rotated by 360° , I ask this because some formats of dds have the nasty habit of being internally rotated up side down. :/

I know, I don't know why :?


T.

Re: Diablo III .app

Posted: Wed Oct 26, 2011 8:47 am
by TaylorMouse
Well, if you use a decent 3D modeling program like 3DStudio in stead of some freeware :P

then it builds the normals automatically :D

T.

Re: Diablo III .app

Posted: Wed Oct 26, 2011 8:50 am
by Monguron
Hmm perhaps you say something, but I think you wanted to write 180° and not 360° ... :)

The situation with the model:
- When I load the model in Maya, it must be rotated by -90 degrees around both the Y and the Z axises
- When I load it in 3D studio, it's OK
- When I load it in the flash (away3D), it's misaligned as well, as in Maya

So I rotated the model in Maya and wanted to export it in .obj format, but Maya can make other formats :(

Then I wanted to load the model in 3DS, but it was originally good. Or should I rotate it anyway, and then it will be improper in 3DS, but properly aligned in Maya and in flash (away3D).

Re: Diablo III .app

Posted: Wed Oct 26, 2011 8:56 am
by TaylorMouse
Anyway, as said before, the normals are not exported apperantly, and therefor in 3D Max it works just fine, since after the import, MAX does a recalc of the normals

T.

Re: Diablo III .app

Posted: Wed Oct 26, 2011 9:29 am
by npd2006
the only problem is that I don't know how to easily display 3D models using C# :/

Any suggestions?
Can we use Microsoft XNA, an engine game, written by C# to make the model viewer?
You can see the tutorial here
http://msdn.microsoft.com/en-us/library ... 31%29.aspx

XNA naturally support .fbx and .dds, so we need the plugin to read .obj
http://www.roastedamoeba.com/blog/archi ... rs-for-xna

Re: Diablo III .app

Posted: Wed Oct 26, 2011 9:33 am
by npd2006
But It seems the spec.png is not on the object, and also the original diff.png is misaligned in some parts, or ....?

any idea?
You get a wrong UV. May be you need to flip it.