Jump to content

MM 3D - Model Format discussion


Twili
 Share

Recommended Posts

Sorry for double posting.

 

Most of the CTXB files can be extracted with Texture Ripper 1.1.7, although a whole folder with around 110 or so CTXB files is the exception. The scene folder's CTXB files cannot be ripped using Texture Ripper 1.1.7, so if anyone else can get some information on this, that'd be awesome! I can say this much: What Texture Ripper does is makes completely blank text files for specifically those ctxbs, and doesn't rip anything from them, even if I attempt to do each file individually.

Link to comment
Share on other sites

I wrote a tool to convert Majora's Mask 3D models to Ocarina of Time 3D models: http://www.mediafire.com/download/je1vzk9e36zpx61/mm2oot.exe

 

And here's the MM3D files all extracted and decompressed: https://mega.co.nz/#!88NWmYJA!IZ9i_k4D14qO4KZy0XzPVm3_oJNtQVcaxxAnA14AmxM

 

Usage: mm2oot.exe model_in model_out

 

Example .bat file to run it (goes in the folder with it):

 

@echo off

mm2oot.exe E:\Users\nick\MyStuff\3ds\extracted_mm3d_rom\actors\zelda2_link_boy_new.gar.lzs\link_demon.cmb E:\Users\nick\MyStuff\3ds\converted\link_demon.cmb

 

PSWfLA8.png

 

OrrbiuG.png

 

xdaniel is going to hate me for using the old ETC1.dll, viewer, etc.  :lol:

 

If it doesn't close on its own, you must close it yourself ASAP. This means that it's stuck in a file that doesn't have all of the needed chunks and will keep eating disk space with the output file.

  • Like 3
Link to comment
Share on other sites

What language is this written in?

 

If its c#.net, you can have the execution stop after a certain amount of time to avoid this issue.

 

Here is a sample code snippet

using System.Timers;


Timer _timer = new Timer();

_timer.Interval = 7000; // Time in milliseconds, so this would be 7 seconds
_timer.Tick += Timer_Tick;
_timer.Start();
convertModels("path1", "path2");

private void convertModels(string fileIn, string fileOut)
{
    converter logic here
}

void Timer_Tick(object sender, EventArgs e)
{
    _timer.Stop();
    MessageBox.Show("There is an issue with the converter. \nPress Enter to stop the process", "Too much space taken", MessageBoxButtons.OK, MessageBoxIcon.Error);
    System.Environment.Exit(0);
}

This would kill the converter if it takes more than 7 seconds. I didnt test it, but it *should* work.

 

A better way is to check the file before processing to ensure it has all the needed chunks.

  • Like 1
Link to comment
Share on other sites

What language is this written in?

 

If its c#.net, you can have the execution stop after a certain amount of time to avoid this issue.

 

Here is a sample code snippet

using System.Timers;


Timer _timer = new Timer();

_timer.Interval = 7000; // Time in milliseconds, so this would be 7 seconds
_timer.Tick += Timer_Tick;
_timer.Start();
convertModels("path1", "path2");

private void convertModels(string fileIn, string fileOut)
{
    converter logic here
}

void Timer_Tick(object sender, EventArgs e)
{
    _timer.Stop();
    MessageBox.Show("There is an issue with the converter. \nPress Enter to stop the process", "Too much space taken", MessageBoxButtons.OK, MessageBoxIcon.Error);
    System.Environment.Exit(0);
}

This would kill the converter if it takes more than 7 seconds. I didnt test it, but it *should* work.

 

A better way is to check the file before processing to ensure it has all the needed chunks.

'tis a false alarm. The issue happens if you try to batch-run it too many times in a row. Works fine in small doses. Also, C. The code is very ugly!

 

http://pointblank.bz/pb/Nontondo_64/mm2oot.c

Link to comment
Share on other sites

Is there a specific number of times it must run before the issue happens?

 

It may be prudent to simply spawn a thread for each run, one at a time until completion of the job (foreach loop passing a backGroundWorker for each run). That should prevent such issues. Although without the code there is no way to know for sure.

 

Edit: I just realized I may be speaking out of turn because you never asked for my help and here I am throwing it out there. Sorry :)

Link to comment
Share on other sites

xdaniel is going to hate me for using the old ETC1.dll, viewer, etc.  :lol:

Not "hate", no. Just "strongly dislike"? ;)

 

Nah, just joking. Seriously tho, I guess this is useful for anyone not able to run newer builds of the viewer, for whatever reason. Anyone else:

 

MLekUvd.png

 

Also figured out and fixed some more material-related stuff, like texture wrap modes (mirroring, etc. now works correctly) and source/destination blending factors. Like a lot of the format, this is shared with OoT3D.

  • Like 4
Link to comment
Share on other sites

Would it be possible to get an executable of the build for those who aren't able to compile it? I'm not much of a programmer and only have compiled things on the very rare occasion and its rare they turned out working lol.

I'll post an "unstable" one over the next couple of days. There's still some relatively serious problems, ex. it feeding invalid data to OpenGL on occasion, which I'd still like to fix, even for an unstable build.

 

I know that PwnzLPs posted a build based on the first commit to the repository over on Zelda64.net, but that's a bit outdated by now and not supported by me. Well, as far as I can try to support things anyway... you know what I mean? Anyway, as I said, I'll post one soon-ish.

 

Edit, actually: https://github.com/xdanieldzd/N3DSCmbViewer/releases/tag/v025-unstable - Unstable!

 

Edit 2: Make sure "Options" -> "Enable Skeletal Rendering" is checked for meshes in scenes to be positioned correctly. That'll break actor rendering because it's incomplete, tho.

Link to comment
Share on other sites

any where I can get the texture rips 

There are no texture rips yet. For now, you'll have to do them yourself. I am working on ripping the textures from every model in the game, but that is going to take some time, because I have to export every model, and then grab their textures.

 

/PwnzLPs

Link to comment
Share on other sites

There are no texture rips yet. For now, you'll have to do them yourself. I am working on ripping the textures from every model in the game, but that is going to take some time, because I have to export every model, and then grab their textures.

 

/PwnzLPs

The reason I want to do texture rips and model rips is because I think the game looks really good, and being the 3d modeler that I am, I like to look at game textures and models to see how their constructed, but yeah I guess I'll try to rip them my self  :)

Link to comment
Share on other sites

  • 3 weeks later...

I converted the LZSS decompressor that's part of N3DSCmbViewer to a standalone C program.

#include <stdio.h>

int main(int argc, char **argv)
{
    FILE *arc, *out;
    unsigned int tag,length,decompressedSize,compressedSize;
    unsigned short writeidx=0xFEE,readidx,y;
    unsigned char data[4096],flags,byte,x;
    arc=fopen(argv[1],"rb");
    out=fopen(argv[2],"wb");
    tag=(unsigned int)((fgetc(arc)<<24)|(fgetc(arc)<<16)|(fgetc(arc)<<8)|fgetc(arc));
    if(tag!=0x4C7A5301){printf("This isn't compressed!\n");return -1;}
    fseek(arc,4,SEEK_CUR);
    decompressedSize=(unsigned int)(fgetc(arc)|(fgetc(arc)<<8)|(fgetc(arc)<<16)|(fgetc(arc)<<24));
    compressedSize=(unsigned int)(fgetc(arc)|(fgetc(arc)<<8)|(fgetc(arc)<<16)|(fgetc(arc)<<24));
    fseek(arc,0,SEEK_END);
    length=ftell(arc);
    fseek(arc,0x10,SEEK_SET);
    if(length!=compressedSize+0x10){printf("Size mismatch.\n");return -1;}
    for(y=0;y<4096;y+=1){data[y]=0;}
    while(ftell(arc)<length)
    {
        flags=fgetc(arc);
        for(x=0;x<8;x+=1)
        {
            if((flags&1)!=0)
            {
                byte=fgetc(arc);
                fputc(byte,out);
                data[writeidx]=byte;
                writeidx+=1;writeidx%=4096;
            }
            else
            {
                readidx=fgetc(arc);
                byte=fgetc(arc);
                readidx|=(unsigned short)((byte&0xF0)<<4);
                for(y=0;y<(byte&0xF)+3;y+=1)
                {
                    fputc(data[readidx],out);
                    data[writeidx]=data[readidx];
                    readidx+=1;readidx%=4096;
                    writeidx+=1;writeidx%=4096;
                }
            }
            flags>>=1;
            if(ftell(arc)>=length){break;}
        }
    }
    return 0;
}

  • Like 1
Link to comment
Share on other sites

Here's the original C++ LZSS code by ShimmerFairy (lue) that I based my C# version on: https://github.com/lue/MM3D/blob/master/src/lzs.cpp

I knew of that. I couldn't compile it, which is why I rewrote it in C. Thanks anyway. It used at least one Linux gcc header, which annoyed me since it wasn't all set to compile without more work on my end. I looked at your C# version because it was easier to understand.

Link to comment
Share on other sites

 Share

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.