Go Back   EQEmulator Home > EQEmulator Forums > Archives > Archive::Development > Archive::Tools

Archive::Tools Archive area for Tools's posts that were moved here after an inactivity period of 90 days.

Reply
 
Thread Tools Display Modes
  #1  
Old 09-15-2004, 03:47 AM
daeken_bb
Discordant
 
Join Date: Mar 2003
Location: Chambersburg, PA
Posts: 469
Default Omens Of War .TER File Format

I've started reverse-engineering the .TER file format that's used in OoW zones and what follows is my progress thus far.

The header is as follows:

Code:
struct Header {
  char magic[4]; // Constant at EQGT
  uint32 unk1; // Seems constant at 2... version?
  uint32 list_length; // This is the size of the object/property list that follows
  uint32 object_count; // This is the number of objects in the list (NOT the number of elements total)
  uint32 vertex_count; // This seems to be the count of vertices in the mesh.
  uint32 poly_count; // Seems to be the count of polygons in the mesh.
};
After the header comes a list of objects and their properties.
Each element is a null-terminated name followed by a null-terminated value.
If the name starts with 'e_' it is a property of the previous object named, otherwise it's naming a new object and its associated base texture.

For example, the list for wall of slaughter is:

colmap01 colmap01.dds
e_TextureDiffuse0 palmap01a.bmp
e_TexturePalette0 HW_rd01_c.dds
e_TextureDetail0 e_fScale0
e_fGrassDensity0 FT_RD2_c.dds
e_TextureDetail1 e_fScale1
e_fGrassDensity1 FT_path01.dds
e_TextureDetail2 e_fScale2
e_fGrassDensity2 FT_plateau01.dds
e_TextureDetail3 e_fScale3
e_fGrassDensity3 FT_grass01.dds
e_TextureDetail4 e_fScale4
e_fGrassDensity4 FT_plateau02.dds
e_TextureDetail5 e_fScale5
e_fGrassDensity5 None
e_TextureDetail6 e_fScale6
e_fGrassDensity6 None
e_TextureDetail7 e_fScale7
e_fGrassDensity7 None
e_TextureDetail8 e_fScale8
e_fGrassDensity8 None
e_TextureDetail9 e_fScale9
e_fGrassDensity9 Opaque_MaxC1DTP.fx
colmap02 colmap02.dds
e_TextureDiffuse0 palmap02a.bmp
e_TexturePalette0 HW_rd01_c.dds
e_TextureDetail0 e_fScale0
e_fGrassDensity0 FT_RD2_c.dds
e_TextureDetail1 e_fScale1
e_fGrassDensity1 FT_path01.dds
e_TextureDetail2 e_fScale2
e_fGrassDensity2 FT_plateau01.dds
e_TextureDetail3 e_fScale3
e_fGrassDensity3 FT_grass01.dds
e_TextureDetail4 e_fScale4
e_fGrassDensity4 FT_plateau02.dds
e_TextureDetail5 e_fScale5
e_fGrassDensity5 None
e_TextureDetail6 e_fScale6
e_fGrassDensity6 None
e_TextureDetail7 e_fScale7
e_fGrassDensity7 None
e_TextureDetail8 e_fScale8
e_fGrassDensity8 None
e_TextureDetail9 e_fScale9
e_fGrassDensity9 Opaque_MaxC1DTP.fx
colmap03 colmap03.dds
e_TextureDiffuse0 palmap03a.bmp
e_TexturePalette0 HW_rd01_c.dds
e_TextureDetail0 e_fScale0
e_fGrassDensity0 FT_RD2_c.dds
e_TextureDetail1 e_fScale1
e_fGrassDensity1 FT_path01.dds
e_TextureDetail2 e_fScale2
e_fGrassDensity2 FT_plateau01.dds
e_TextureDetail3 e_fScale3
e_fGrassDensity3 FT_DRD2_c.dds
e_TextureDetail4 e_fScale4
e_fGrassDensity4 FT_plateau02.dds
e_TextureDetail5 e_fScale5
e_fGrassDensity5 None
e_TextureDetail6 e_fScale6
e_fGrassDensity6 None
e_TextureDetail7 e_fScale7
e_fGrassDensity7 None
e_TextureDetail8 e_fScale8
e_fGrassDensity8 None
e_TextureDetail9 e_fScale9
e_fGrassDensity9 Opaque_MaxC1DTP.fx
colmap04 colmap04.dds
e_TextureDiffuse0 palmap04a.bmp
e_TexturePalette0 HW_rd01_c.dds
e_TextureDetail0 e_fScale0
e_fGrassDensity0 FT_RD2_c.dds
e_TextureDetail1 e_fScale1
e_fGrassDensity1 FT_path01.dds
e_TextureDetail2 e_fScale2
e_fGrassDensity2 FT_plateau01.dds
e_TextureDetail3 e_fScale3
e_fGrassDensity3 FT_DRD2_c.dds
e_TextureDetail4 e_fScale4
e_fGrassDensity4 FT_plateau02.dds
e_TextureDetail5 e_fScale5
e_fGrassDensity5 None
e_TextureDetail6 e_fScale6
e_fGrassDensity6 None
e_TextureDetail7 e_fScale7
e_fGrassDensity7 None
e_TextureDetail8 e_fScale8
e_fGrassDensity8 None
e_TextureDetail9 e_fScale9
e_fGrassDensity9 Opaque_MaxC1DTP.fx
tunn04 sp_tunn04.dds
e_TextureDiffuse0 sp_tunn04_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
tunn05 sp_tunn05.dds
e_TextureDiffuse0 sp_tunn05_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
tunn06 sp_tunn06.dds
e_TextureDiffuse0 sp_tunn06_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
tunn07 tunn07.dds
e_TextureDiffuse0 tunn07_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
ab_wall_T01 sp_ft_wall_high.dds
e_TextureDiffuse0 Di_ent_cinderblock01_mid_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
ab_wall_M01 sp_ft_wall_mid.dds
e_TextureDiffuse0 Di_ent_cinderblock01_mid_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
ab_wall_B01 sp_ft_wall_low.dds
e_TextureDiffuse0 Di_ent_cinderblock01_low_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
ab_arch_T01 ab_arch_T01.dds
e_TextureDiffuse0 Di_ent_metal02_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
ab_arch_M01 ab_arch_M01.dds
e_TextureDiffuse0 Di_ent_metal02_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
ab_arch_B01 ab_arch_B01.dds
e_TextureDiffuse0 Di_ent_metal02_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
ab_floor_01 ab_floor_01.dds
e_TextureDiffuse0 sp_ft_floor_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
rock18 av_rock18_c.dds
e_TextureDiffuse0 av_rock18_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
rock10 av_rock10_c.dds
e_TextureDiffuse0 av_rock10_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
rock16 av_rock16_c.dds
e_TextureDiffuse0 Di_ent_wall_crumble01_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
maze01 av_rock12_c.dds
e_TextureDiffuse0 av_rock12_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
maze02 Di_rune_plain_bkg_c.dds
e_TextureDiffuse0 Di_rune_plain_bkg_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
maze03 ab_maze01_c.dds
e_TextureDiffuse0 ab_maze01_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
maze04 Di_floor01_c.dds
e_TextureDiffuse0 Di_floor01_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
maze05 Di_Maze01_Power_c.dds
e_TextureDiffuse0 Di_Maze01_Main_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
ra_pris19 ra_prison19_c.dds
e_TextureDiffuse0 ra_prison19_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
av_pris14high av_prison14_c.dds
e_TextureDiffuse0 av_prison13a_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
av_pris22mid av_prison22_c.dds
e_TextureDiffuse0 av_prison22_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
av_pris15low av_prison15_c.dds
e_TextureDiffuse0 av_prison15_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
av_pris18flr av_prison18_c.dds
e_TextureDiffuse0 av_prison18a_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx
dn_path HW_rd01_c.dds
e_TextureDiffuse0 HW_rd01_n.dds
e_TextureNormal0 Opaque_MaxCB1.fx



I'll post more as I figure it out.

Happy Hacking,
Lord Daeken M. BlackBlade
(Cody Brocious)


Edit #1: Added the object_count element to the struct.
Edit #2: Replaced uint32 unk[2]; with the vertex_count and poly_count fields. Put the struct in code brackets.
__________________
Keep me unemployed and working on OpenEQ, PM me about donating

Check out my deviantART page at http://daeken.deviantart.com/
Reply With Quote
  #2  
Old 09-15-2004, 04:02 AM
daeken_bb
Discordant
 
Join Date: Mar 2003
Location: Chambersburg, PA
Posts: 469
Default

You can also get a proper view of it at http://home.archshadow.com/~daeken/t...tress_objs.txt

This is the debug output of my python script for decoding these files, so it's a bit messy still hehe.
__________________
Keep me unemployed and working on OpenEQ, PM me about donating

Check out my deviantART page at http://daeken.deviantart.com/
Reply With Quote
  #3  
Old 09-15-2004, 06:53 AM
daeken_bb
Discordant
 
Join Date: Mar 2003
Location: Chambersburg, PA
Posts: 469
Default

Ok... figured out more.

After the list comes the vertices.

The struct for each vertex is as follows:

Code:
struct Vertex {
  float unk1, unk2;
  float x;
  float unk3;
  float y;
  float unk4;
  float z;
  float unk5;
};
I'm working on figuring out triangles now, and then I'll work on figuring out the unknown values. My guess is that 3 of them are normals, 2 are tex coords.
__________________
Keep me unemployed and working on OpenEQ, PM me about donating

Check out my deviantART page at http://daeken.deviantart.com/
Reply With Quote
  #4  
Old 09-15-2004, 03:28 PM
daeken_bb
Discordant
 
Join Date: Mar 2003
Location: Chambersburg, PA
Posts: 469
Default

Well, I just got zone geometry rendering perfectly, albiet without textures (it's figured out, just not coded as of yet)

It was very, very simple.

Code:
struct Header {
  char magic[4]; // Constant at EQGT
  uint32 version; // Constant at 2.
  uint32 list_length; // This is the total length of the material list that follows
  uint32 object_count; // This is the number of materials in the list (NOT the number of elements)
  uint32 vertex_count; // Number of vertices
  uint32 poly_count; // Polygon count
};
After the header comes a list of materials and their properties.
Each element is a null-terminated name followed by a null-terminated value.
If the name starts with 'e_' it is a property of the previous material named, otherwise it's naming a new material and its associated base texture. If the base texture named starts with e_, leave the base texture empty and treat this name as its own variable. In the case of having no base texture, simply use the first e_ entry value as the texture, but make sure you also set the e_ entry in your material data.

Now comes the one portion of the file that I have yet to figure out. My theory is that it is a BSP or octree, but I have yet to test it. To skip it, seek to 3 + (vertex_count * 32) + (poly_count * 20) bytes before the end of the file. I'll work on figuring this out when I get a chance, but my knowledge of BSPs and octrees is so limited its not even funny.

Next comes the vertices. You should decode these and store them in a zero-indexed array.

Code:
struct Vertex {
  float x, y, z; // Vertex location
  float i, j, k; // Normals?
  float u, v; // Tex coords, clamped to [0,1]
};
After that comes the triangles. The v0, v1, and v2 fields index the vertex array. The group field indexes the object type list if greater than or equal to zero, else it means the object is invisible I _think_.

Code:
struct Triangle {
  unsigned long v0, v1, v2; // These are vertex indices
  signed long group; // Texture/material group id.
  unsigned long flags; // This seems to flag if you can walk through the polygon or not.
};
Then after that is simply 3 null bytes, then the end of the file.


Enjoy
__________________
Keep me unemployed and working on OpenEQ, PM me about donating

Check out my deviantART page at http://daeken.deviantart.com/
Reply With Quote
  #5  
Old 09-15-2004, 04:03 PM
daeken_bb
Discordant
 
Join Date: Mar 2003
Location: Chambersburg, PA
Posts: 469
Default

God anguish looks beautiful running in the python version of my ter decoder with full textures

I got it working in about 10 minutes without having to change the file loader... everything was right on the first try

I would take screenshots, but unfortunately GLUT doesn't want to let me go windowed... Whatever. I'll have the C version rendering .ter soon anyhow

I will post screenshots ASAP.
__________________
Keep me unemployed and working on OpenEQ, PM me about donating

Check out my deviantART page at http://daeken.deviantart.com/
Reply With Quote
  #6  
Old 09-21-2004, 10:18 AM
jbb
Hill Giant
 
Join Date: Mar 2003
Location: UK
Posts: 242
Default

Anguish works great in my renderer but I can't display "riftseekers" at all. I have a problem loading the texture names from the strings at the start. The names seem to get out of step. Does it work for you?

And if so could you try to explain how to get the names decoded properly if you have the time

Thanks
Reply With Quote
  #7  
Old 09-21-2004, 12:16 PM
daeken_bb
Discordant
 
Join Date: Mar 2003
Location: Chambersburg, PA
Posts: 469
Default

I updated the guide (not the parent post, but one of the comments) to fix the material loading... basically, all you have to do is make sure that the base texture given isn't an e_ entry
__________________
Keep me unemployed and working on OpenEQ, PM me about donating

Check out my deviantART page at http://daeken.deviantart.com/
Reply With Quote
  #8  
Old 09-21-2004, 07:15 PM
jbb
Hill Giant
 
Join Date: Mar 2003
Location: UK
Posts: 242
Default

Thanks - I'm still having trouble with this though. I think I'll do what you appeared to have done based on your post and write a decoder in python as it's so much easier to prototype stuff and then when it works recode it in c++.
Reply With Quote
  #9  
Old 09-21-2004, 11:22 PM
jbb
Hill Giant
 
Join Date: Mar 2003
Location: UK
Posts: 242
Default

I've had a closer look at the materials information and believe it should be formatted like this (just an extract from the riftseekers zone)

Code:
cieling
	e_fShininess0		
	Di_ct_pyrilen_ceiling_c.dds	e_TextureDiffuse0
 	Di_ct_pyrilen_ceiling_8_n.dds	e_TextureNormal0
	Opaque_MaxCBSG1.fx

wall high
	e_fShininess0
	Di_ct_pyrilen_wall_high_c.dds	e_TextureDiffuse0
	Di_ct_pyrilen_wall_8_n.dds	e_TextureNormal0
	Opaque_MaxCBSG1.fx


red potion
	ra_crystowlava01_e.dds		e_TextureDiffuse0
	ra_crystow_water_n.dds		e_TextureNormal0
	ra_crystow_water_e.dds		e_TextureEnvironment0
	e_fFresnelBias
	e_fFresnelPower
	e_fWaterColor1
	e_fWaterColor2
	e_fReflectionAmount
	e_fReflectionColor
	Opaque_MaxWater.fx

silver
	e_fShininess0
	Di_ct_gelidran_silvermetal.dds		e_TextureDiffuse0
	Di_ct_gelidran_silvermetal_spec_8_n.dds	e_TextureNormal0
	Opaque_MaxCBS1.fx
It seems to start with a name and end with an effect and contain a number of effect parameters start with e_ which may or may not have a parameter before them in the file. Pretty much what you had except that there seems to be an e_TextureDiffuse0 texture for all of them which I guess will do as a base texture for the material for simple rendereing.

The effects exist as files in the RenderEffects directory on disk. I would guess that they might be encoded directx effects files and the material information in the TER file describes the parameters to them.
Reply With Quote
  #10  
Old 09-21-2004, 11:28 PM
daeken_bb
Discordant
 
Join Date: Mar 2003
Location: Chambersburg, PA
Posts: 469
Default

Quote:
Originally Posted by jbb
I've had a closer look at the materials information and believe it should be formatted like this (just an extract from the riftseekers zone)

Code:
cieling
	e_fShininess0		
	Di_ct_pyrilen_ceiling_c.dds	e_TextureDiffuse0
 	Di_ct_pyrilen_ceiling_8_n.dds	e_TextureNormal0
	Opaque_MaxCBSG1.fx

wall high
	e_fShininess0
	Di_ct_pyrilen_wall_high_c.dds	e_TextureDiffuse0
	Di_ct_pyrilen_wall_8_n.dds	e_TextureNormal0
	Opaque_MaxCBSG1.fx


red potion
	ra_crystowlava01_e.dds		e_TextureDiffuse0
	ra_crystow_water_n.dds		e_TextureNormal0
	ra_crystow_water_e.dds		e_TextureEnvironment0
	e_fFresnelBias
	e_fFresnelPower
	e_fWaterColor1
	e_fWaterColor2
	e_fReflectionAmount
	e_fReflectionColor
	Opaque_MaxWater.fx

silver
	e_fShininess0
	Di_ct_gelidran_silvermetal.dds		e_TextureDiffuse0
	Di_ct_gelidran_silvermetal_spec_8_n.dds	e_TextureNormal0
	Opaque_MaxCBS1.fx
It seems to start with a name and end with an effect and contain a number of effect parameters start with e_ which may or may not have a parameter before them in the file. Pretty much what you had except that there seems to be an e_TextureDiffuse0 texture for all of them which I guess will do as a base texture for the material for simple rendereing.

The effects exist as files in the RenderEffects directory on disk. I would guess that they might be encoded directx effects files and the material information in the TER file describes the parameters to them.
*blinks* Um... you're right... congrats... lol

Damn man... I can't believe I didn't see that before. Nice work
__________________
Keep me unemployed and working on OpenEQ, PM me about donating

Check out my deviantART page at http://daeken.deviantart.com/
Reply With Quote
  #11  
Old 09-21-2004, 11:39 PM
jbb
Hill Giant
 
Join Date: Mar 2003
Location: UK
Posts: 242
Default

Now I can get riftseekers to load properly.

Just using the diffuse textures it comes out all blue and orange. I wonder if it really looks like that.
Reply With Quote
  #12  
Old 09-21-2004, 11:46 PM
jbb
Hill Giant
 
Join Date: Mar 2003
Location: UK
Posts: 242
Default

Dranik zone looks like this with my renderer


Still some work to go on the textures I think. They almost look scaled wrong although it could just be that simply rendering the diffuse texture isn't enough to get a reasonable output.
Reply With Quote
  #13  
Old 09-22-2004, 08:54 AM
daeken_bb
Discordant
 
Join Date: Mar 2003
Location: Chambersburg, PA
Posts: 469
Default

Looks like you may be using the wrong mipmapping level perhaps? I dunno... m'be the bump mapping is neccesary to make it look good...
__________________
Keep me unemployed and working on OpenEQ, PM me about donating

Check out my deviantART page at http://daeken.deviantart.com/
Reply With Quote
  #14  
Old 09-22-2004, 09:12 AM
jbb
Hill Giant
 
Join Date: Mar 2003
Location: UK
Posts: 242
Default

Ah, good guess
Setting anisotropic mipmapping mode made it look far better
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 10:26 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3