Skip to content
View in the app

A better way to browse. Learn more.

ResHax

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
Help us keep the site running.

Gran Turismo 4 (car models and tracks)

Featured Replies

Solved by Nenkai

  • Supporter

Found several chunks with varying length (17, 49 or 33 vertices for example) but too lazy to code a script or something (picture is a sum up of some of those chunks):

mazda.png

Edited by shak-otay

  • Supporter

There are no indices. Seems like they are autogenerated.

Anyway is there a way how to generate face indices based on vertices?

Edited by h3x3r

  • Supporter

What do you mean by "based on vertices"?

(As you may know it's rather simple to autogenerate face indices based on a vertex count. hex2obj can do this.)

 

btw, the bytes 40 C0 seem to be some signature. I'll look if that helps with the chunks.

Edited by shak-otay

  • Supporter

Do you know any good algo to not end up like this?

fckup.jpg

I am using something like this:

f1_0=1,
f1_1=1,
f1_2=1,

f2_0=2,
f2_1=2,
f2_2=2,

f3_0=3,
f3_1=3;
f3_2=3;

for (l=0; l < VtxCount; l++)
{
	Printf("f %u/%u %u/%u %u/%u\n",f1_0++,f1_1++,f2_0++,f2_1++,f3_0++,f3_1++);
}

 

  • Supporter

Looks like linear FIs to me.

You could try TriStrips:

void build_Strips (FILE * stream, DWORD VertexCount)
{
    int faceDir, startDir= -1 ;
    WORD a=0, b=1, cnt=0, f1,f2,f3 ;
    f1 = a + 1 ;
    f2 = b + 1 ;
    faceDir = startDir ;
    do {
        cnt++ ;    f3 = cnt ;
        faceDir *= -1 ;
        if ((f1!=f2)&&(f2!=f3)&&(f3!=f1)) {
            if (faceDir > 0) fprintf( stream, "f %d %d %d\n", f1, f2, f3 ) ;
            else fprintf( stream, "f %d %d %d\n", f1, f3, f2 ) ;
        }
        f1 = f2 ;
        f2 = f3 ;
    } while (cnt < VertexCount) ;
}
	

Edited by shak-otay

  • Supporter

Is that correct order for tristrips?

f 1/1 2/2 3/3
f 2/2 4/4 3/3
f 3/3 4/4 5/5
f 4/4 6/6 5/5
f 5/5 6/6 7/7
f 6/6 8/8 7/7
f 7/7 8/8 9/9
f 8/8 10/10 9/9
f 9/9 10/10 11/11
f 10/10 12/12 11/11
f 11/11 12/12 13/13
f 12/12 14/14 13/13
f 13/13 14/14 15/15

 

  • Supporter

Correct. But I remember slightly  different implementations also (just in case you come across a format with tristrips where these faces don't do).

  • Supporter

Thanks for info. One more thing, what code do you use to convert "vertices" short to float or hfloat?

  • Supporter

"short to float": see main.cpp of my Make_obj project (Tutorials section)

"short to hfloat"? Don't remember a case where I needed this. (There's a conversion from HF to float in main.cpp, float HFloat().)

  • Supporter

So it is this code right?

if (!bBigE) lPosXYZ= nValue[0] + nValue[1]*256 ;
else lPosXYZ= nValue[0]*256 + nValue[1] ;            // big endian
if (lPosXYZ>32767) lPosXYZ -= 65536;
fprintf( stream, "%f ", lPosXYZ/256.0) ;        // 32768.0?

Now let me understand.

First parse short and apply *256 on it and if result is bigger than 32767 then apply -65536 and lastly /256.0?

  • Supporter

OK. Can you please determine these? I am not sure if big or little endian. They are for sure short. But i am getting wierd results... It's just a part of the mesh.

Vertex count: 64.

Thank you!

Also i implemented your code to this one which is not much different...

typedef struct
{
    int16 X;
    int16 Y;
    int16 Z;

    local int16 Xtmp=X*256,Ytmp=Y*256,Ztmp=Z*256;
    if (Xtmp > 32767){
        Xtmp=Xtmp-65536;
    }
    else if (Ytmp > 32767){
        Ytmp=Ytmp-65536;
    }
    else if (Ztmp > 32767){
        Ztmp=Ztmp-65536;
    }
	Printf("v %f %f %f\n",Xtmp/256.0,Ytmp/256.0,Ztmp/256.0);
} Vec3PosInt16;

But i am getting big endian result although bytes are read as little endian... what a magic :). Also numbers are not same as in h2o or model researcher.

Here is compare.

h2o result

v 0.000000 0.000000 0.000000 
v 22.007813 -27.003906 78.011719 
v -67.972656 0.000000 126.960938 
v 24.007813 -24.003906 77.011719 
v -58.972656 -15.003906 125.960938 
v 26.007813 -12.003906 74.011719 
v -55.972656 -11.003906 126.960938 
v 25.007813 -24.003906 75.011719 
v -50.972656 -17.003906 121.960938 
v 24.007813 -22.003906 76.011719 
v -54.972656 1.000000 117.960938 
v 24.007813 -38.003906 76.011719 
v -65.972656 -11.003906 115.960938 
v 24.007813 -24.003906 76.011719 
v -69.972656 1.000000 119.960938 
v 23.007813 -36.003906 77.011719 
v -58.972656 -6.003906 121.960938 
v 22.007813 -34.003906 78.011719 
v -50.972656 0.000000 119.960938 
v 21.007813 -48.003906 78.011719 

Model Researcher result

v  0.0000 0.0000 0.0000
v  22.0078 -27.0039 78.0117
v  -67.9727 0.0000 126.9609
v  24.0078 -24.0039 77.0117
v  -58.9727 -15.0039 125.9609
v  26.0078 -12.0039 74.0117
v  -55.9727 -11.0039 126.9609
v  25.0078 -24.0039 75.0117
v  -50.9727 -17.0039 121.9609
v  24.0078 -22.0039 76.0117
v  -54.9727 1.0000 117.9609
v  24.0078 -38.0039 76.0117
v  -65.9727 -11.0039 115.9609
v  24.0078 -24.0039 76.0117
v  -69.9727 1.0000 119.9609
v  23.0078 -36.0039 77.0117
v  -58.9727 -6.0039 121.9609
v  22.0078 -34.0039 78.0117
v  -50.9727 0.0000 119.9609
v  21.0078 -48.0039 78.0117

And my template with that code

v 0.000000 0.000000 0.000000
v 22.000000 -28.000000 78.000000
v -68.000000 0.000000 126.000000
v 24.000000 -25.000000 77.000000
v -59.000000 -16.000000 125.000000
v 26.000000 -13.000000 74.000000
v -56.000000 -12.000000 126.000000
v 25.000000 -25.000000 75.000000
v -51.000000 -18.000000 121.000000
v 24.000000 -23.000000 76.000000
v -55.000000 1.000000 117.000000
v 24.000000 -39.000000 76.000000
v -66.000000 -12.000000 115.000000
v 24.000000 -25.000000 76.000000
v -70.000000 1.000000 119.000000
v 23.000000 -37.000000 77.000000
v -59.000000 -7.000000 121.000000
v 22.000000 -35.000000 78.000000
v -51.000000 0.000000 119.000000
v 21.000000 -49.000000 78.000000

Untitled1.7z

Edited by h3x3r

  • Supporter

The first non zero short value is 0x1602 as big endian, divided by 256= 22.0...

I'd print out x at the beginning to see what's happening.

 

well, I see the reason for the confusion. It's this line:

nValue[i] = (*pFBuf & 255) ;

I'm using an int16 value as BYTE (or CHAR) thus anding the higher byte to zero. Sorry for that.

(It's for historical reasons. Based on very old code.)

Edited by shak-otay

  • 3 weeks later...
  • Supporter

Hi Nenkai. When i used your tool on ac__0014 it hrows this error. Anyway how did you figure out face indices direction? Is it writen somewhere in car or track file? 

Also do you know where are coordinates for wheel size a positions?

Thanks!

E:\PROJEKTY\GT\GT4\Tools\GTPS2ModelTool.exe>GTPS2ModelTool dump -i ac__0014.dat
Info|-----------------------------------------
Info|- GTPS2ModelTool 1.0.2 by Nenkai
Info|-----------------------------------------
Info|- https://github.com/Nenkai
Info|- https://nenkai.github.io/gt-modding-hub/
Info|-----------------------------------------
Info|
Unhandled exception. System.Exception: Unexpected opcode pglCullFace_1
   at PDTools.Files.Models.PS2.Commands.ModelSetupPS2Command.GetByOpcode(ModelSetupPS2Opcode opcode) in C:\Safe\Develop\repos\GTPS2ModelTool\PDTools\PDTools.Files\Models\PS2\RenderCommands\ModelSetupCommand.cs:line 86
   at PDTools.Files.Models.PS2.Commands.Cmd_CallModelCallback.Read(BinaryStream bs, Int32 commandsBaseOffset) in C:\Safe\Develop\repos\GTPS2ModelTool\PDTools\PDTools.Files\Models\PS2\RenderCommands\Cmd_CallModelCallback.cs:line 98
   at PDTools.Files.Models.PS2.ModelSet.ModelSet2Model.FromStream(BinaryStream bs, Int64 mdlBasePos) in C:\Safe\Develop\repos\GTPS2ModelTool\PDTools\PDTools.Files\Models\PS2\ModelSet\ModelSet2Model.cs:line 103
   at PDTools.Files.Models.PS2.ModelSet.ModelSet2.ReadModels(BinaryStream bs, Int64 baseMdlPos, UInt32 offset, UInt32 count) in C:\Safe\Develop\repos\GTPS2ModelTool\PDTools\PDTools.Files\Models\PS2\ModelSet\ModelSet2.cs:line 172
   at PDTools.Files.Models.PS2.ModelSet.ModelSet2.FromStream(Stream stream) in C:\Safe\Develop\repos\GTPS2ModelTool\PDTools\PDTools.Files\Models\PS2\ModelSet\ModelSet2.cs:line 108
   at GTPS2ModelTool.Program.DumpFile(String path) in C:\Safe\Develop\repos\GTPS2ModelTool\GTPS2ModelTool\Program.cs:line 350
   at CommandLine.ParserResultExtensions.WithParsed[T](ParserResult`1 result, Action`1 action)
   at GTPS2ModelTool.Program.Main(String[] args) in C:\Safe\Develop\repos\GTPS2ModelTool\GTPS2ModelTool\Program.cs:line 34

And this one appear when i try to convert track file which i slightly edited to be dumped since your tool look for MDLS sign.

E:\PROJEKTY\GT\GT4\Tools\GTPS2ModelTool.exe>GTPS2ModelTool dump -i nurburgring.dat
Info|-----------------------------------------
Info|- GTPS2ModelTool 1.0.2 by Nenkai
Info|-----------------------------------------
Info|- https://github.com/Nenkai
Info|- https://nenkai.github.io/gt-modding-hub/
Info|-----------------------------------------
Info|
Unhandled exception. System.Exception: Unexpected opcode pgluCallShape_UShort
   at PDTools.Files.Models.PS2.Commands.ModelSetupPS2Command.GetByOpcode(ModelSetupPS2Opcode opcode) in C:\Safe\Develop\repos\GTPS2ModelTool\PDTools\PDTools.Files\Models\PS2\RenderCommands\ModelSetupCommand.cs:line 86
   at PDTools.Files.Models.PS2.ModelSet.ModelSet2Model.FromStream(BinaryStream bs, Int64 mdlBasePos) in C:\Safe\Develop\repos\GTPS2ModelTool\PDTools\PDTools.Files\Models\PS2\ModelSet\ModelSet2Model.cs:line 101
   at PDTools.Files.Models.PS2.ModelSet.ModelSet2.ReadModels(BinaryStream bs, Int64 baseMdlPos, UInt32 offset, UInt32 count) in C:\Safe\Develop\repos\GTPS2ModelTool\PDTools\PDTools.Files\Models\PS2\ModelSet\ModelSet2.cs:line 172
   at PDTools.Files.Models.PS2.ModelSet.ModelSet2.FromStream(Stream stream) in C:\Safe\Develop\repos\GTPS2ModelTool\PDTools\PDTools.Files\Models\PS2\ModelSet\ModelSet2.cs:line 108
   at GTPS2ModelTool.Program.DumpFile(String path) in C:\Safe\Develop\repos\GTPS2ModelTool\GTPS2ModelTool\Program.cs:line 362
   at CommandLine.ParserResultExtensions.WithParsed[T](ParserResult`1 result, Action`1 action)
   at GTPS2ModelTool.Program.Main(String[] args) in C:\Safe\Develop\repos\GTPS2ModelTool\GTPS2ModelTool\Program.cs:line 34

 

Edited by h3x3r

  • Supporter

Some GT4 models will require some work to get to export.

The whole rendering system works on a command system run on every game loop to know which shapes to render (which in a way, tells apart the lods, reflective shapes & other mechanical/scripted shapes). If some commands are not supported/unexpected, it'll throw these sorts of errors for now.

There are no face indices. Rather the number of vertices per strip (multiplied by 3 i believe) is included in a VIF code component. This is already handled by my code and can be seen in the source 

Edited by Nenkai

Create an account or sign in to comment

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.