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

Import Tuner Challenge [XBOX360]

Post questions about game models here, or help out others!
Post Reply
User avatar
blackracer
advanced
Posts: 51
Joined: Sat Jun 27, 2015 1:20 pm
Has thanked: 30 times
Been thanked: 49 times

Import Tuner Challenge [XBOX360]

Post by blackracer »

Image


Hi guys, I got a little progress with the opening of Import Tuner Challenge, unfortunately I am not a programmer and can not are allowed to do all the questions fully.


- Archive opened from QuickBMS
I used this script: http://aluigi.altervista.org/bms/tokyo_xtreme_racer.bms
[Structure is not folders, all in one]

- Textures in archive from TGA and XPR format
Cars Livery in TGA format [please view Hex code and find in final file "TRUEVISION-XFILE" and rename this dat to * .tga]

Others main cars textures in XPR format [XPR2, Xbox Bundle Container] opened from Noesis script this: https://www.dropbox.com/s/yehlij6vwpaxd ... R.zip?dl=0
(Noesis XPR Script error from using big size textures files)
UPDATE: XPR2TGA Tool : https://www.dropbox.com/s/ecaid3jdks78h ... a.zip?dl=0

- Geometry is not converted yet. :?:
Finally what need help to create script to import geometry from this game ...

Geometry alleged in these files [Perhaps it *.XBM -Xbox360 Genki Model file format viewtopic.php?f=16&t=12373&p=102509&hilit=xbm#p102509 ]:
https://www.dropbox.com/s/bnvw5wm9m081z ... 8.dat?dl=0
https://www.dropbox.com/s/2ahiuw43bu1e5 ... a.dat?dl=0

Example extracted textures:

Image
Last edited by blackracer on Thu Jan 19, 2017 8:10 pm, edited 13 times in total.
User avatar
shakotay2
MEGAVETERAN
MEGAVETERAN
Posts: 4285
Joined: Fri Apr 20, 2012 9:24 am
Location: Nexus, searching for Jim Kirk
Has thanked: 1147 times
Been thanked: 2242 times

Re: Import Tuner Challenge [XBOX360]

Post by shakotay2 »

00000538_dat_.JPG
(unsure about uvs start address)
You do not have the required permissions to view the files attached to this post.
Tuts: a) Bigchillghost, viewtopic.php?f=29&t=17889
b) Extracting simple models: http://forum.xentax.com/viewtopic.php?f=29&t=10894
"Quoting the whole thing. Would u ever stop this nonsense?"
User avatar
REDZOEU
veteran
Posts: 151
Joined: Thu Mar 10, 2011 8:03 am
Location: Jakarta, Indonesia
Has thanked: 74 times
Been thanked: 50 times
Contact:

Re: Import Tuner Challenge [XBOX360]

Post by REDZOEU »

I am so bookmarking this topic. Finally! I'll help if i can though hehehe :D
User avatar
Takukun
advanced
Posts: 45
Joined: Sun Sep 06, 2015 1:40 am
Has thanked: 136 times
Been thanked: 24 times

Re: Import Tuner Challenge [XBOX360]

Post by Takukun »

Oh yes what better christmas should we get. I'm so happy I could cry.
lratafia
ultra-n00b
Posts: 7
Joined: Tue Oct 20, 2015 2:27 am
Has thanked: 1 time
Been thanked: 2 times

Re: Import Tuner Challenge [XBOX360]

Post by lratafia »

cool, I hope some good stuff comes out for Assetto Corsa :)
User avatar
blackracer
advanced
Posts: 51
Joined: Sat Jun 27, 2015 1:20 pm
Has thanked: 30 times
Been thanked: 49 times

Re: Import Tuner Challenge [XBOX360]

Post by blackracer »

We were able to extract all files from game archive, thanks Aluigy
Get access to all textures but with this there are some nuances.

In this moment I'm looking for a versatile way to extract 3d models from this game, very much hope to the aid of those who have an idea of Noesis and 3D Max Script

UPDATE
It was possible to find a way to extract all textures from * .XPR with no errors
You do not have the required permissions to view the files attached to this post.
JohnHudeski
mega-veteran
mega-veteran
Posts: 177
Joined: Wed Mar 02, 2011 10:38 pm
Has thanked: 10 times
Been thanked: 58 times

Re: Import Tuner Challenge [XBOX360]

Post by JohnHudeski »

Send me the files. If it is anything like their other games then i can help you with the uv
The only problem is knowing what textures go where
User avatar
blackracer
advanced
Posts: 51
Joined: Sat Jun 27, 2015 1:20 pm
Has thanked: 30 times
Been thanked: 49 times

Re: Import Tuner Challenge [XBOX360]

Post by blackracer »

JohnHudeski wrote:Send me the files. If it is anything like their other games then i can help you with the uv
The only problem is knowing what textures go where
I sent you files in PM :)
JohnHudeski
mega-veteran
mega-veteran
Posts: 177
Joined: Wed Mar 02, 2011 10:38 pm
Has thanked: 10 times
Been thanked: 58 times

Re: Import Tuner Challenge [XBOX360]

Post by JohnHudeski »

shakotay2 wrote:
00000538_dat_.JPG
(unsure about uvs start address)
Quick question. Does it use triangles (list) or triangle strips?
User avatar
blackracer
advanced
Posts: 51
Joined: Sat Jun 27, 2015 1:20 pm
Has thanked: 30 times
Been thanked: 49 times

Re: Import Tuner Challenge [XBOX360]

Post by blackracer »

JohnHudeski wrote:
Quick question. Does it use triangles (list) or triangle strips?
As far as I know it uses a Strips
JohnHudeski
mega-veteran
mega-veteran
Posts: 177
Joined: Wed Mar 02, 2011 10:38 pm
Has thanked: 10 times
Been thanked: 58 times

Re: Import Tuner Challenge [XBOX360]

Post by JohnHudeski »

I tested the sample files you sent with my 010 template and it worked perfectly.
The only problem is that it's been almost 2 years since i touched this so I have forgotten what some of the data types mean but i got your UVs

Here is the c# version of the data structures (using unity3d)

Code: Select all

using UnityEngine;
using System;
using System.Collections.Generic;

namespace XBM
{
    //Helper Classes
    
    public struct XBMHeader
    {
        public uint ID;  //00 20 00 00 - Package type (in your game it is different)
        public uint lightCount;
        public uint otherCount; //mesh? group?
        public uint shapeCount;
//------------Line 2---------------
        public uint other2Count;
        public uint[] addrs; //12
        public uint triangleSize;
        public uint shdAddr; //ShaderAddress
        public uint unkn3;
    }

    
    public struct KengoLight
    {
        public char[] name; //[32];
        public float []f0; //[20]
        public char[] data; //[144];
    }

    
    public struct Other //Bone?
    {
        public char[] name; //[32];
        public int[] unkn; //[8];
        public char[] data; //[128];
    } //other[header.otherCount]

    
    public struct Other2 //Bone?
    {
        public char[] data;
    }

    public struct Shape
    {
        public char[] name; //[32];
        public float[] matrix1; //[16];
        //public Vector3[] bbox; //[8]; 
        public Bounds bBox;
        public float[] chnk1; //[4];

        public struct Header
        {
            public int vertCount; //or id
            public int dataType; //0,5,7
            public int unitSize; //Has to do with read size
            public int totalSize; //floatCount or datatsize(float size* 3 or 4)
        } //header0[3]
        public Header hUVs;
        public Header hVerts;
        public Header hNorms;

        public struct UnknStruct00
        {
            public int i0;
            public int i1;
            public int i2;
            public int i3;
            public int i4;
            public int i5; //Constant -65536
            public int i6;
            public int i7; //268435554, 268435746, 268435458
        }
        public UnknStruct00[] sChnk; //[3]; 

        public int addrUV;    //0 = -1s
        public int addrVerts;  //1 = vertices floats
        public int addrTriStr; //2 = faces? shorts?
        public int addr0;      //3 = addr in un02 hdr(size,size,0,size)?
        //------------below are weird ints at the bottom of un03
        public int addrSkVertices;// Verts for skinned mesh
        public int addrSkNormals; // norms for skinned mesh or bone weights
        public int addrSkWeights;
        public int[] chunk3; //[33];
    }

    public struct Addr0
    {
        public uint count;
        public uint size;
        public int unkn0;
        public int unkn1;
        
        public struct Data
        {
            public Vector3 pos;
            public Vector3 rot;
            public Vector3 scale;
            //skip 332
            public const int SKIP0 = 332;

            public uint size;
            public uint addr;

            public const int SKIP1 = 124;
        }

        public Data[] data;
        //float[] f; //[(hdr.size-64)/4];
    }

    
    public struct Addr1 //Skin Verts
    {
        public struct Header
        {
            public uint id;
            public uint fileSize;
            //convert to size
            public uint offset0; //ints
            public uint offset1; //float[4]s
            public uint offset2; //ints
            public uint[] pad; //Pad to next line
        }
        public Header hdr;

        public int[] i0; //[(hdr.addr1-hdr.addr0)/4]; 
        public Vector4[] vec4; //[(hdr.addr2-hdr.addr1)/16]; 
        public int[] i1; //[(hdr.fileSize - hdr.addr2 + hdr.addr0 -32 )/4]; 
    }

    
    public struct Addr1_2 //Skin Verts and normal (addr1 and addr2
    {
        public struct Header
        {
            public uint id;
            public uint unkn0;
            public uint unkn1;
            public uint size;
        }   //hdr <bgcolor=cLtGray>; 
        public Header hdr;

        public Vector4[] vec4; //[hdr.size/16] <bgcolor=cLtBlue>; 
        //float f[hdr.size/4];
    }

    
    public struct XBM_UN03
    {
        public struct UN03_Header
        {
            public uint id;
            public uint count0;
            public uint zero;
            public uint count1;
            //Chunk0
            public uint addr;

            //TRS
            public uint[] transforms; //[3]; Addresses
            //Matrices
            public uint[] matrices; //[3]; Addresses

            public uint[] unkn; //[5];
        }
        public UN03_Header un03_Hdr;

        public struct Item
        {
            //160
            public char[] name; //[32];
            public char[] data; //[128];
        }
        public Item[] item; //[un03_Hdr.count0];
    

        public Vector4[] pos; //[un03_Hdr.count0];
        public Vector4[] rot; //[un03_Hdr.count0];
        public Vector4[] scale; //[un03_Hdr.count0];
    
        public struct Mat4x4
        {
            public Vector4 v0, v1, v2, v3;
        }
        public Mat4x4[] matrix0; //[un03_Hdr.count0];
        public Mat4x4[] matrix1; //[un03_Hdr.count0];
        public Mat4x4[] matrix2; //[un03_Hdr.count0];
    }

    
    public struct Un04_09 //packs of 32
    {
        /*
        
        public struct Pack
        {
            uint id;
            float []data; //7
        }
        */
        //shape related
        // 0 - might be an id/int or 2 shorts
        public float[] un04; //[(header.addrs[5]-header.addrs[4])/4];
        public float[] un05; //[(header.addrs[6]-header.addrs[5])/4];
        public float[] un06; //[(header.addrs[7]-header.addrs[6])/4];   //shape related
        public float[] un07; //[(header.addrs[8]-header.addrs[7])/4];   //shape related
        public float[] un08; //[(header.addrs[9]-header.addrs[8])/4];   //shape related
        public float[] un09; //[(header.addrs[10]-header.addrs[9])/4];   //shape related
    }

    
    public class KengoXBM 
    {
        public XBMHeader xbmHeader;
        public Other[] other; //other[header.otherCount]
        public Shape[] shape; //[header.shapeCount]

        //public Un02 un02; // if((header.addrs[3]-header.addrs[2]) > 0)
        public XBM_UN03 un03; //if((header.addrs[4]-header.addrs[3]) > 0)
        public Un04_09 un04_09;

        //un10 is best not read as it is just a data dump
        //un11 is padding
        //un12 is shaders
    }
}

(You can find the UV address in the ShapeHeader struct)
There are 3 types of uv and they have a mixture of float32 float16 or random -1 separators
You will need to use the "Header hUVs;" to decipher its format

Code: Select all

//From my XBM reader
    public struct UVContainer
    {
        public List<Vector2> UVs0;
        public List<Vector2> UVs1;
        public List<Vector2> UVs2;

        public Vector2[] GetUVs()
        {
            return UVs0 != null? UVs0.ToArray() :  null;
        }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="reader"></param>
    /// <param name="hUV"></param>
    /// <param name="uvC"></param>
    /// <param name="flipVertical"></param>
    void ReadUVChunk(BinaryReader reader, Shape.Header hUV, out UVContainer uvC, bool flipVertical = true)
    {
        List<Vector2> UVs0 = new List<Vector2>();
        List<Vector2> UVs1 = new List<Vector2>();
        List<Vector2> UVs2 = new List<Vector2>();
        
        Byte[] bytes;
        uvC = new UVContainer();
        switch (hUV.dataType)
        {
        case 0:
            for (int i = 0; i < hUV.vertCount; ++i)
            {
                UVs0.Add(Vector2.zero);
            }
            break;
        case 14:
            for (int i = 0; i < hUV.vertCount; ++i)
            {
                //bytes = reader.ReadBytes(4); //White? 0xFFFF
                reader.BaseStream.Position += 4;
                bytes = reader.ReadBytes(2);
                Array.Reverse(bytes);
                float x = BitConverter.ToInt16(bytes, 0).HalfFloat();
                bytes = reader.ReadBytes(2);
                Array.Reverse(bytes);
                float y = BitConverter.ToInt16(bytes, 0).HalfFloat() * (flipVertical? -1:1);
                UVs0.Add(new Vector2(x, y));
            }
            break;
        case 15:
            for (int i = 0; i < hUV.vertCount; ++i)
            {
                //bytes = reader.ReadBytes(4); //White? 0xFFFF
                reader.BaseStream.Position += 4;
                bytes = reader.ReadBytes(2);
                Array.Reverse(bytes);
                float x = BitConverter.ToInt16(bytes, 0).HalfFloat();
                bytes = reader.ReadBytes(2);
                Array.Reverse(bytes);
                float y = BitConverter.ToInt16(bytes, 0).HalfFloat() * (flipVertical ? -1 : 1);
                UVs0.Add(new Vector2(x, y));

                bytes = reader.ReadBytes(2);
                Array.Reverse(bytes);
                x = BitConverter.ToInt16(bytes, 0).HalfFloat();
                bytes = reader.ReadBytes(2);
                Array.Reverse(bytes);
                y = BitConverter.ToInt16(bytes, 0).HalfFloat() * (flipVertical ? -1 : 1);
                UVs1.Add(new Vector2(x, y));
            }
            break;
        case 16:
            for (int i = 0; i < hUV.vertCount; ++i)
            {
                //bytes = reader.ReadBytes(4); //White? 0xFFFF
                reader.BaseStream.Position += 4;
                bytes = reader.ReadBytes(2);
                Array.Reverse(bytes);
                float x = BitConverter.ToInt16(bytes, 0).HalfFloat();
                bytes = reader.ReadBytes(2);
                Array.Reverse(bytes);
                float y = BitConverter.ToInt16(bytes, 0).HalfFloat() * (flipVertical ? -1 : 1);
                UVs0.Add(new Vector2(x, y));

                bytes = reader.ReadBytes(2);
                Array.Reverse(bytes);
                x = BitConverter.ToInt16(bytes, 0).HalfFloat();
                bytes = reader.ReadBytes(2);
                Array.Reverse(bytes);
                y = BitConverter.ToInt16(bytes, 0).HalfFloat() * (flipVertical ? -1 : 1);
                UVs1.Add(new Vector2(x, y));

                bytes = reader.ReadBytes(2);
                Array.Reverse(bytes);
                x = BitConverter.ToInt16(bytes, 0).HalfFloat();
                bytes = reader.ReadBytes(2);
                Array.Reverse(bytes);
                y = BitConverter.ToInt16(bytes, 0).HalfFloat() * (flipVertical ? -1 : 1);
                UVs2.Add(new Vector2(x, y));
            }
            break;
        default:
                if(enableLoging) log += "Unknown UV data type" + hUV.dataType;
            Debug.LogError("Unknown UV data type" + hUV.dataType);
            return;
        }

        uvC.UVs0 = UVs0;
        uvC.UVs1 = UVs1;
        uvC.UVs2 = UVs2;
    }

        //Half float converter
        public static float HalfFloat(this short hbits)
        {
            int mant = hbits & 0x03ff;            // 10 bits mantissa
            int exp = hbits & 0x7c00;            // 5 bits exponent
            if (exp == 0x7c00)                   // NaN/Inf
                exp = 0x3fc00;                    // -> NaN/Inf
            else if (exp != 0)                   // normalized value
            {
                exp += 0x1c000;                   // exp - 15 + 127
                if (mant == 0 && exp > 0x1c400)  // smooth transition
                    return BitConverter.ToSingle(BitConverter.GetBytes((hbits & 0x8000) << 16
                                                    | exp << 13 | 0x3ff), 0);
            }
            else if (mant != 0)                  // && exp==0 -> subnormal
            {
                exp = 0x1c400;                    // make it normal
                do
                {
                    mant <<= 1;                   // mantissa * 2
                    exp -= 0x400;                 // decrease exp by 1
                } while ((mant & 0x400) == 0); // while not normal
                mant &= 0x3ff;                    // discard subnormal bit
            }                                     // else +/-0 -> +/-0
            return BitConverter.ToSingle(
                BitConverter.GetBytes(          // combine all parts
                (hbits & 0x8000) << 16          // sign  << ( 31 - 15 )
                | (exp | mant) << 13), 0);         // value << ( 23 - 10 )
        }
JohnHudeski
mega-veteran
mega-veteran
Posts: 177
Joined: Wed Mar 02, 2011 10:38 pm
Has thanked: 10 times
Been thanked: 58 times

Re: Import Tuner Challenge [XBOX360]

Post by JohnHudeski »

I am slightly surprised by the level of intrest in this game.
I am doing a 12-hour shift at work tonight when I get back I will give y'all some proper TLC
lmao
JohnHudeski
mega-veteran
mega-veteran
Posts: 177
Joined: Wed Mar 02, 2011 10:38 pm
Has thanked: 10 times
Been thanked: 58 times

Re: Import Tuner Challenge [XBOX360]

Post by JohnHudeski »

I am having some problems extracting the triangle list for these models.
I previously only focused on skinned meshes for this format and the skinned mes triangles are kept separately from the regular ones


Guys the moral of the story is to always comment your code
User avatar
blackracer
advanced
Posts: 51
Joined: Sat Jun 27, 2015 1:20 pm
Has thanked: 30 times
Been thanked: 49 times

Re: Import Tuner Challenge [XBOX360]

Post by blackracer »

This is bad :( , there is a chance of success?
I, too, is unable to get any progress...
JohnHudeski
mega-veteran
mega-veteran
Posts: 177
Joined: Wed Mar 02, 2011 10:38 pm
Has thanked: 10 times
Been thanked: 58 times

Re: Import Tuner Challenge [XBOX360]

Post by JohnHudeski »

I did get the UV's I just cant get the triangle indices
Post Reply