XeNTaX Forum Index
Forum MultiEx Commander Tools Tools Home
It is currently Thu Feb 22, 2018 9:33 pm

All times are UTC + 1 hour


Forum rules


Please click here to view the forum rules



Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Noesis / Maxscript scripting questions
PostPosted: Thu Jan 04, 2018 3:54 pm 
Offline
beginner

Joined: Tue Oct 13, 2015 10:25 am
Posts: 20
Has thanked: 3 times
Have thanks: 0 time

Hi all, i recently started getting my hands on Noesis and i wanted to give it a try to open some meshes and writing my own scripts to perform the task...
But i'm really new to it and i'm stuck at reading the binary file's vertices and faces i have an error message saying that the "vertex position list is empty" i tried looking at already existing scripts for other games assets but it's a bit confusing.
I mainly use Hex2obj and ModelResearcher to extract some meshes but having a script for doing it is faster and could help me for learning purposes...
Here is my script for now (i've made it with the exemple sample provided in Neosis) :
- http://www.mediafire.com/file/zh3diy5aj ... -Script.py

And this is the error message :
Image

Theses are the samples i'm using for making the script :
- http://www.mediafire.com/file/bddsn7szqrt8whs/%u7CD6%u679C%u821E%u53F0.rgm (STAGE file)
- http://www.mediafire.com/file/hiuk6edvh ... ancer1.rgm (AVATAR file)
- http://www.mediafire.com/file/nym1t18lt ... ove_01.rgm (ANIMATION file)

Note that my goal is mainly being able to read / import Avatars and Stages RGMs on Noesis (Animations aren't for me at all it's too difficult)
I've studied the format for a while now and i have collected many infos about it, i still have trouble saying what data types i'm seeing but i guess it will comes with time...

But after looking at many RGM samples i can give these informations (with help of other skilled peoples) :

Code:
File structure :
- little endian
- byte = 8 bit int
- short = 16 bit int
- long = 32 bit int
- float = 32 bit float


It's common to every RGMs i've "worked" with !
also it's a "dynamic file format" i don't know yet what it exactly means but i don't think it's really important for now...
Anyway thanks for reading, if someone can guide me with Noesis scripting i will really appreciate it.
I know that their is a tutorial made by "Chroxx" somewhere on xentax but it's missing the pictures (because links are dead) and it's still a bit confusing.
As usual sorry for my english.

Oh and Happy new year :]

You can make the ads go away by registering



Last edited by Loginoux on Wed Jan 10, 2018 1:45 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Noesis python script problem
PostPosted: Thu Jan 04, 2018 11:56 pm 
Offline
VIP member
VIP member

Joined: Wed Nov 05, 2008 12:16 pm
Posts: 1022
Has thanked: 2029 times
Have thanks: 542 times
Loginoux wrote:
i tried looking at already existing scripts for other games assets but it's a bit confusing.

indeed many are confusing, and some for no reason, i newbified your script to open the discoclub_dancer1.rgm :D
Code:
from inc_noesis import *

def registerNoesisTypes():
    handle = noesis.register("Audition online dance battle [PC]", ".RGM")
    noesis.setHandlerTypeCheck(handle, noepyCheckType)
    noesis.setHandlerLoadModel(handle, noepyLoadModel)
    #noesis.logPopup()
    return 1

#check if it's this type based on the data
def noepyCheckType(data):
    bs = NoeBitStream(data)
    magic = noeStrFromBytes(bs.readBytes(9))
    if magic != "Delight3D":
       return 0
    return 1

#load the model
def noepyLoadModel(data, mdlList):              #standard line
    ctx = rapi.rpgCreateContext()               #standard line
    bs = NoeBitStream(data)                     #standard line
    bs.seek(0x25a, NOESEEK_ABS)      #jump to position 0x25a from 0x0
    vCount = bs.readUInt()            #read vertex count
    bs.readByte()                      #skip this unknown byte
    vBuff = bs.readBytes(vCount * 32)   #read vertex buffer which is vertex count * vertex stride
    fCount = bs.readUInt() * 3           #read face count and multiply by 3
    fBuff = bs.readBytes(fCount * 2)      #read face buffer which is face count * 2
    rapi.rpgBindPositionBufferOfs(vBuff, noesis.RPGEODATA_FLOAT, 32, 0)   #pos of vertices (byte array, data type, stride, pos within stride)
    rapi.rpgBindUV1BufferOfs(vBuff, noesis.RPGEODATA_FLOAT, 32, 24)       #UV1  (byte array, data type, stride, pos within stride)
    if fCount % 3 == 0:                       #check if evenly divisible by 3 and do this
        rapi.rpgCommitTriangles(fBuff, noesis.RPGEODATA_SHORT, fCount, noesis.RPGEO_TRIANGLE, 1)
    else:                                        #if not evenly divisible by 3 do this instead
        rapi.rpgCommitTriangles(fBuff, noesis.RPGEODATA_SHORT, fCount, noesis.RPGEO_TRIANGLE_STRIP, 1)
    mdlList.append(rapi.rpgConstructModel())    #standard line
    rapi.rpgClearBufferBinds()                  #standard line
    return 1                                    #standard line

see how simple it can be? this script reads only the mesh and UVs but still, its simple. :D
i put comments in there so you can see what is happening.

edit
adding link to original research thread because it has much info about basic rgm reversal already (:
viewtopic.php?f=16&t=14885

_________________
Noesis
Hex2obj
QuickBMS
TextureFinder
Unity Assets Bundle Extractor


Last edited by AceWell on Tue Jan 09, 2018 8:23 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Noesis python script problem
PostPosted: Fri Jan 05, 2018 1:37 am 
Offline
beginner

Joined: Tue Oct 13, 2015 10:25 am
Posts: 20
Has thanked: 3 times
Have thanks: 0 time
AceWell wrote:
Loginoux wrote:
i tried looking at already existing scripts for other games assets but it's a bit confusing.

indeed many are confusing, and some for no reason, i newbified your script to open the discoclub_dancer1.rgm :D
Code:
from inc_noesis import *

def registerNoesisTypes():
    handle = noesis.register("Audition online dance battle [PC]", ".RGM")
    noesis.setHandlerTypeCheck(handle, noepyCheckType)
    noesis.setHandlerLoadModel(handle, noepyLoadModel)
    #noesis.logPopup()
    return 1

#check if it's this type based on the data
def noepyCheckType(data):
    bs = NoeBitStream(data)
    magic = noeStrFromBytes(bs.readBytes(9))
    if magic != "Delight3D":
       return 0
    return 1

#load the model
def noepyLoadModel(data, mdlList):              #standard line
    ctx = rapi.rpgCreateContext()               #standard line
    bs = NoeBitStream(data)                     #standard line
    bs.seek(0x25a, NOESEEK_ABS)      #jump to position 0x25a from 0x0
    vCount = bs.readUInt()            #read vertex count
    bs.readByte()                      #skip this unknown byte
    vBuff = bs.readBytes(vCount * 32)   #read vertex buffer which is vertex count * vertex stride
    fCount = bs.readUInt() * 3           #read face count and multiply by 3
    fBuff = bs.readBytes(fCount * 2)      #read face buffer which is face count * 2
    rapi.rpgBindPositionBufferOfs(vBuff, noesis.RPGEODATA_FLOAT, 32, 0)   #pos of vertices (byte array, data type, stride, pos within stride)
    rapi.rpgBindUV1BufferOfs(vBuff, noesis.RPGEODATA_FLOAT, 32, 24)       #UV1  (byte array, data type, stride, pos within stride)
    if fCount % 3 == 0:                       #check if evenly divisible by 3 and do this
        rapi.rpgCommitTriangles(fBuff, noesis.RPGEODATA_SHORT, fCount, noesis.RPGEO_TRIANGLE, 1)
    else:                                        #if not evenly divisible by 3 do this instead
        rapi.rpgCommitTriangles(fBuff, noesis.RPGEODATA_SHORT, fCount, noesis.RPGEO_TRIANGLE_STRIP, 1)
    mdlList.append(rapi.rpgConstructModel())    #standard line
    rapi.rpgClearBufferBinds()                  #standard line
    return 1                                    #standard line

see how simple it can be? this script reads only the mesh and UVs but still, its simple. :D
i put comments in there so you can see what is happening.


Hi thank you for replying !
It's super clear now it makes more sense to me, i will try to read other RGM files and use this script as a base, i might need to change just some lines i guess !
I will update my progress here so far.
Thank you very much !


Top
 Profile  
 
 Post subject: Re: Noesis python script problem
PostPosted: Tue Jan 09, 2018 4:51 pm 
Offline
beginner

Joined: Tue Oct 13, 2015 10:25 am
Posts: 20
Has thanked: 3 times
Have thanks: 0 time
Hello guys, i tried to continue with Noesis scripting and i'm fine with it i can read some models now !
recently i tried to import the stage's RGM to 3ds max, so i started writing a script for it :
Code:
-- Clear listener
clearListener()
-- Open a "*.RGM" file
fRGM = getOpenFileName \
caption:"Open an RGM file:" \
filename:"C:\Users\RGM\Acv tool -CN\*.rgm" \
types:"RGM(*.rgm)|*.rgm"
-- Read binaries from "*.RGM"
if fRGM != undefined then
(
   f = fopen fRGM "rb"
   clearlistener()
   
   Vert_array=#()
   Face_array=#()
   UV_array=#()

   fseek f 762 #seek_set
   
   -- Vertex data
   
      vertexCount = readbyte f #unsigned
    print ("VertexCount: " + vertexCount as string)
   for x = 1 to vertexCount do
   (
      vx = readfloat f
      print ("VectorX: " + vx as string)
      vy = readfloat f
      vz = readfloat f
      append Vert_array[vx,vy,vz]
   )

      Print ("Last Read @ 0x"+((bit.intAsHex(ftell f))as string))
         
-- Close the RGM file
fclose f
      )


But i have a problem with vertex count... i think i have found the spot where it is stored in the file (i mean the address) but i have trouble actually reading the data...
i tried doing readlong, readfloats, readshort to get the right value (because i was confused and still having trouble telling if the data is a long short etc) but it's still not correct ! my script is stopping waaaay before the end of the vertex buffer...
Anyone have an idea ?

thanks.

PS : the vertex count address is right before the vertex buffer one in every file i saw (including avatars)
And also the file is a chinese one it's the same structure between all of the them just different another language...


Top
 Profile  
 
 Post subject: Re: Noesis / Maxscript scripting questions
PostPosted: Sun Feb 11, 2018 11:16 pm 
Offline
beginner

Joined: Tue Oct 13, 2015 10:25 am
Posts: 20
Has thanked: 3 times
Have thanks: 0 time
Hi guys !
After a few weeks i updated my script but i didn't managed to extract the stage mesh yet...
I have mainly collected infos about the format and updated my kind of "data structure" a little bit...
Here is what i have for now :
Quote:
structure of the FILE :

string file_id;
short file_type (01 02 = 2.1 | 00 02 = 2.0)
dummy data (DE DE FF FF)
unknown - scene object name count ?
unknown4
unknown5
list of strings(3D objects names in the file) + whitespaces (00 00)
unknown6;
short count1 (vertex count);
*vertex buffer*
short count2 (face count)
*face buffer array of short values*

struct RGM_Vertex { float x, float y, float z, char padding[20] }



Note that this is not a real structure like in C++ or whatever just me messing around ! some things might be missing...
I discovered that 1 single vertex is stored as 32 bytes and that the 12 first bytes are basically x,y and z value the 20 others are still unknown to this date :/
So i tried skipping these "20" bytes left in my maxscript but it doesn't work i don't know how i could do it "manually"

Code:
-- Clear listener
clearListener()
-- Open a "*.RGM" file
fRGM = getOpenFileName \
caption:"Open an RGM file:" \
filename:"C:\Users\Videos\Acv tool -CN\*.rgm" \
types:"RGM(*.rgm)|*.rgm"

-- Read binaries from "*.RGM"
if fRGM != undefined then
(
   f = fopen fRGM "rb"
   clearlistener()
   
   Vert_array=#()
   Face_array=#()
   UV_array=#()

   --Header
   /*fseek f 0 #seek_set
   ID = readstring f
   print("ID: " + ID)
   fseek f 30 #seek_set
   unk01 = readbyte f
   print("unk01 = " + unk01 as string)
   fseek f 31 #seek_set
   unk02 = readbyte f
   print("unk02 = " + unk02 as string)
   fseek f 38 #seek_set
   unk03 = readbyte f
   print("unk03 = " + unk03 as string)
   fseek f 41 #seek_set
   unk04 = readstring f
   print("unk04 = " + unk04)
   fseek f 47 #seek_set
   unk05 = readshort f
   print("unk05 = " + unk05 as string)*/
   
   /*for x = 1 to 20 do(
      strings =readstring f
      whitespace = readshort f
      print("String:" + strings)
      print("Whitespace:" + whitespace as string)
   )*/
   
   -- Vertex data
   fseek f 0x2FA #seek_set
   vertexCount = readshort f #seet_set
   print ("VertexCount: " + vertexCount as string)
   for x = 1 to vertexCount do
   (
      vx = readfloat f
      vy = readfloat f
      vz = readfloat f
      -- Unknowns values
      --unk000 = readfloat f
      --unk001 = readfloat f
      --unk002 = readfloat f
     --unk003 = readfloat f
     --unk004 = readfloat f
    
      append Vert_array[vx,vy,vz]
   )
   
   -- face data
   /*fseek f 0x1EB83  #seek_set
   FacesCount = readshort f #unsigned
   print ("FacesCount: " + FacesCount as string)

   for i = 1 to FacesCount do
   (
      fa = readshort f #unsigned
      fb = readshort f #unsigned
      fc = readshort f #unsigned
      append Face_array[fa+1,fb+1,fc+1]
   )*/
   
   -- UV data (not any info in the file....)
   /*count = readlong f #unsigned
   for i = 1 to count do
   {
      tu = readfloat f
      tv = readfloat f
      append UV_array[tu,1-tv,0]
   )*/
   
   -- Build the mesh
   msh = mesh vertices:Vert_array faces:Face_array name:(getFilenameFile fRGM)
   --msh.numTVerts = UV_array.count
   --buildTVFaces msh
   --for j = 1 to UV_array.count do setTVert msh j UV_array[j]
   --for j = 1 to Face_array.count do setTVFace msh j Face_array[j]
   
   --Printing
   Print ("Last Read @ 0x"+((bit.intAsHex(ftell f))as string))
      
   free Face_array
   free Vert_array
   --free UV_array      
      
-- Close the RGM file
fclose f
      )


It's possible that i'm doing huge mistakes because i'm still beginner in this...
Thanks for reading if someone have any suggestion or tips feel free to let me know i will appreciate the help.



Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: akderebur, Google [Bot] and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group