Important information: this site is currently scheduled to go offline indefinitely by end of the year.

Kung Fu Strike: The Warriors Rise (*.a3d)

Post questions about game models here, or help out others!
Post Reply
User avatar
TaylorMouse
ultra-veteran
ultra-veteran
Posts: 348
Joined: Mon Sep 26, 2011 12:51 pm
Has thanked: 11 times
Been thanked: 89 times

Kung Fu Strike: The Warriors Rise (*.a3d)

Post by TaylorMouse »

Find the way to unpack the dat files here:
viewtopic.php?f=10&t=9387&p=77136#p77136

What I found so far

Code: Select all

4 bytes			-> always A3D.
4 bytes 		-> always 0A D7 83 3F
4 bytes 		-> nbr of Submeshes
4 bytes			-> unk ??
FF FF FF FF 	-> delimiter ??

6 * 4 bytes		-> always 00 00 00 00
4 * 4 bytes		-> always 00 00 80 3F ??
FF FF FF FF 	-> delimiter ??


4 bytes 		-> nbr of submeshes

4 bytes			-> length of the name of the submesh
chars[]			-> name of the submesh

4 bytes			-> nbr of submesh
4 bytes			-> always 00 00 00 00
4 bytes			-> nbr Indices  -> chunk size => * 2
4 bytes			-> nbr Vertices -> chunk size => * 4 * 3 

read the indices [i1, i2, i3]

4 bytes			-> unk
4 bytes			-> unk
4 bytes			-> size of the next chunk

read the vertices [f1, f2, f3]

4 bytes			-> unk
4 bytes			-> unk
4 bytes			-> size of the next chunk

-> zero delimited... ?? every fourth float = 0?

4 bytes			-> unk
4 bytes			-> unk
4 bytes			-> size of the next chunk

-> another weird chunk.. every first 2 bytes of 4 bytes is FF ??
T.
finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 307 times

Re: Kung Fu Strike: The Warriors Rise (*.a3d)

Post by finale00 »

Samples?
User avatar
TaylorMouse
ultra-veteran
ultra-veteran
Posts: 348
Joined: Mon Sep 26, 2011 12:51 pm
Has thanked: 11 times
Been thanked: 89 times

Re: Kung Fu Strike: The Warriors Rise (*.a3d)

Post by TaylorMouse »

Here are some samples

T.
You do not have the required permissions to view the files attached to this post.
User avatar
TaylorMouse
ultra-veteran
ultra-veteran
Posts: 348
Joined: Mon Sep 26, 2011 12:51 pm
Has thanked: 11 times
Been thanked: 89 times

Re: Kung Fu Strike: The Warriors Rise (*.a3d)

Post by TaylorMouse »

Attempt on a single mesh file:

Image


here is the c# class:

Code: Select all

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Threading;
using System.Globalization;

namespace ModelToObj
{
    public static class KungFuStrike
    {
        public static void Convert(string fileIn, string fileOut)
        {
            string decimalChar = Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencyDecimalSeparator;

            if (decimalChar == ",")
            {
                Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-us");
                decimalChar = Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencyDecimalSeparator;
            }

            List<Vector3> vertices = new List<Vector3>();
            List<Indices> faces = new List<Indices>();
            uint nVerts = 0;
            uint chunkFaces = 0;

            using (BinaryReader br = new BinaryReader(new FileStream(fileIn, FileMode.Open, FileAccess.Read)))
            {
                char[] header = br.ReadChars(4); // A3D.
                br.ReadUInt32();
                int nbrMeshes = (int)br.ReadUInt32();

                if (nbrMeshes == 1)
                    br.BaseStream.Seek(72, SeekOrigin.Begin);
                if (nbrMeshes == 2)
                    br.BaseStream.Seek(132, SeekOrigin.Begin);

                nbrMeshes = (int)br.ReadUInt32(); // again ?

                for (int i = 0; i < nbrMeshes; i++)
                {
                    int len = (int)br.ReadUInt32();
                    string meshName = Helper.CharToString(br.ReadChars(len));
                    Debug.WriteLine(meshName);
                }
                br.ReadUInt32(); // 2 or 1
                br.ReadUInt32(); // 00 00 00 00

                nVerts = br.ReadUInt32();
                chunkFaces = br.ReadUInt32() * 2;
                uint nFaces = chunkFaces / 6;
                
                for (int i = 0; i < nFaces; i++)
                {
                    faces.Add(new Indices()
                    {
                        a = (int)br.ReadUInt16(),
                        b = (int)br.ReadUInt16(),
                        c = (int)br.ReadUInt16()
                    });
                }
                br.ReadUInt32();
                br.ReadUInt32();
                br.ReadUInt32();
                br.ReadUInt32();
                
                for (int i = 0; i < nVerts; i++)
                {
                    vertices.Add(new Vector3()
                    {
                        X = br.ReadSingle(),
                        Y = br.ReadSingle(),
                        Z = br.ReadSingle()
                    });
                }

                // TEST
                StringBuilder vertexLis = new StringBuilder();
                StringBuilder faceList = new StringBuilder();

                Debug.Write(nVerts);
                Debug.Write(",");
                Debug.WriteLine(nFaces);
                foreach (Vector3 v in vertices)
                {
                    vertexLis.Append(String.Format("[{0},{1},{2}],", v.X, v.Y, v.Z));
                }
                Debug.WriteLine(vertexLis.ToString());

                foreach (Indices f in faces)
                {
                    faceList.Append(String.Format("[{0},{1},{2}],", f.a + 1, f.b + 1, f.c + 1));
                }
                Debug.WriteLine(faceList.ToString());


                br.Close();
            }

        }
    }
}

no uvw mapping yet.

T.
finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 307 times

Re: Kung Fu Strike: The Warriors Rise (*.a3d)

Post by finale00 »

Code: Select all

idxBuff = self.parse_faces(numIdx)
numSections = self.inFile.readUInt()
for i in range(numSections):
    chunkType, unk2 = self.inFile.read('2L')
    size = self.inFile.readUInt()

    if chunkType == 2:
        vertBuff = self.parse_vertices(numVerts)
    elif chunkType == 3:
        self.inFile.seek(size, 1)
    elif chunkType == 4:
        self.inFile.seek(size, 1)
    elif chunkType == 1:
        self.inFile.seek(size, 1)

self.inFile.readInt() # delimiter ?
After the faces you get a section count, followed by structs that look like

Code: Select all

struct Chunk {
   int32 ?
   int32 ?
   int32 size
   byte[size] data
}
User avatar
TaylorMouse
ultra-veteran
ultra-veteran
Posts: 348
Joined: Mon Sep 26, 2011 12:51 pm
Has thanked: 11 times
Been thanked: 89 times

Re: Kung Fu Strike: The Warriors Rise (*.a3d)

Post by TaylorMouse »

I haven't looked any further yet, but I think the next chunk will probably have the uv mappings, then it switches to the next submesh
or first vertex normals or something else..

I'll look at it later this evening.

T.
finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 307 times

Re: Kung Fu Strike: The Warriors Rise (*.a3d)

Post by finale00 »

I couldn't figure out how it handles multiple meshes. It just seemed like something completely different afterwards.
User avatar
TaylorMouse
ultra-veteran
ultra-veteran
Posts: 348
Joined: Mon Sep 26, 2011 12:51 pm
Has thanked: 11 times
Been thanked: 89 times

Re: Kung Fu Strike: The Warriors Rise (*.a3d)

Post by TaylorMouse »

Alright after some plumbing, I found the uv texture coordinates

still only works with one submesh

I needed to jump 2 chunks over... don't know what is in there, a lot of.... bull

here is the sample:

Image

lets see how to find multiple meshes....

T.
User avatar
TaylorMouse
ultra-veteran
ultra-veteran
Posts: 348
Joined: Mon Sep 26, 2011 12:51 pm
Has thanked: 11 times
Been thanked: 89 times

Re: Kung Fu Strike: The Warriors Rise (*.a3d)

Post by TaylorMouse »

still not found this piece of j(ch)unk...

anyone any idea ?

T.
finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 307 times

Re: Kung Fu Strike: The Warriors Rise (*.a3d)

Post by finale00 »

It's just a sequence of mesh structs.

After the section with the different chunks there are some more structs

Code: Select all

struct Mesh {
    int[2] nulls
    int numVerts
    int numIdx
    # index buffer
    
    int numSections
    # vertex, normal, uv buffers, other buffers

    int count1
    Unk1[count1] unks

    int count2
    Unk2[count2] ...
   
    int count3
    Unk3[count3]
}

Code: Select all

struct Unk1 {
   68 bytes
}

struct Unk2 {
   8 bytes
}

struct Unk3 {
   1 byte
}
User avatar
TaylorMouse
ultra-veteran
ultra-veteran
Posts: 348
Joined: Mon Sep 26, 2011 12:51 pm
Has thanked: 11 times
Been thanked: 89 times

Re: Kung Fu Strike: The Warriors Rise (*.a3d)

Post by TaylorMouse »

Did you (finale00) include in you py script?

T.
finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 307 times

Re: Kung Fu Strike: The Warriors Rise (*.a3d)

Post by finale00 »

I did now.
User avatar
TaylorMouse
ultra-veteran
ultra-veteran
Posts: 348
Joined: Mon Sep 26, 2011 12:51 pm
Has thanked: 11 times
Been thanked: 89 times

Re: Kung Fu Strike: The Warriors Rise (*.a3d)

Post by TaylorMouse »

Alright !!!

I check it out this evening :)

T.
Sir Kane
veteran
Posts: 104
Joined: Mon Aug 06, 2012 4:14 am
Been thanked: 96 times

Re: Kung Fu Strike: The Warriors Rise (*.a3d)

Post by Sir Kane »

The game is written in some .NET language. Use .NET reflector on it and you will find the complete spec for the model format.
Post Reply