Could anyone tell me or link me to a tutorial on how to make tags on models. I’ve been searching around for hours and I couldn’t find anything. I could find alot of information about tags but not how to make them. I read somewhere that they are simple one faced triangles, so I tried this but it didn’t work.
I’m using 3DSMax 7 and I’m using the Pop 'n Fresh md3 exporter to export the models.
Do I have to give these triangles a specific name, do I have make these triangles on some special way, do I need to give it a specific texture, do I have to set some options in the exporter dialog window, do I need another file (I’ve seen a .tag file somewhere)?
Any help is much appreciated.
Thanks.
tags
It all depends on the exporter.
I believe you need to prefix tags’ names with tag_ to show the Pop 'n fresh exporter that it should treat them as tags, though I never tried it for sure.
Thank you so much, that tutorial helped me alot. It’s actually very easy with max.
If someone else wants to know:
I created my tag like this (I’m not very good with max so there might be an easier way)
make a box, convert it to an editable mesh, delete 5 sides with the polygon selection tool and then, with the face selection tool, delete one half of the last side that you didn’t delete. You should now have a triangle. Place it like explained in the tutorial above (like this). Now give it a name that starts with tag_ ie. tag_box. Just export it with the md3 exporter, you don’t have to click anything, just make sure you put in the right frames.
That’s all you have to do in Max.
do I need another file (I’ve seen a .tag file somewhere
If you plan to attach an entity to a tag on your md3 model you need to include a tag-file.
The program “md3totag” will do this for you: Just place the md3totag.exe in the same directory where your md3 model is (model must contain at least one tag) and execute the program
link= www.planetquake.com/simland/files/md3totag.zip
Are you sure? I tested it by making a simple box model with a tag and I attached a target_smoke to it and it worked without a tag file.
Sorry, I should have mentioned in my post that you only need a tag-file for moving md3 models (like a truck,tank or tram). Static models don’t need this as far as I know…
If someone wants to create an MD3 with some tags in it, the easy way, here’s a way to do it very quickly:
I use Chrukers “MD3 Tag The Dummy” to create me a .TAG file with the tags i want (names and positions).
http://games.chruker.dk/enemy_territory/md3ttd.php
Then i use my own little tool to insert these tags into an existing MD3.
http://members.home.nl/core/ETpro/MD3_tagger.zip
Instructions:
Load an .MD3 file… load a .TAG file…
and Your tagged model has been saved as: <YourModelName>_tagged.MD3
Here 1 tutorial from wolfproject web http://www.wolfproject.net/modules.php?name=Tutorials&tut=model_with_tags
I coded something along MD3 the dummy myself. I compile my maps straight into PK3’s to prevent that I forget anything early on.
Let’s see if it fits into a post 
This I downloaded somewhere, call it md3struct.h
#define MAX_APATH 64
#define MAX_OSPATH 128
#define MD3_IDENT (('3'<<24) + ('P'<<16) + ('D'<<8) + 'I')
#define MD3_VERSION 15
#define MAX_MD3_MESHES 16
#define MAX_SKINS MAX_MODELS << 2
typedef unsigned char byte;
typedef float vec_t;
typedef vec_t vec2_t[2];
typedef vec_t vec3_t[3];
typedef vec_t vec4_t[4];
typedef vec_t vec5_t[5];
typedef unsigned int uint_t;
typedef uint_t uint3_t[3];
typedef struct orientation_s {
vec3_t origin;
vec3_t axis[3];
} orientation_t;
typedef struct
{
int id;
int version;
char filename[MAX_APATH];
int flags;
int numboneframes;
int numtags;
int nummeshes;
int numskins;
int bone_offs;
int tag_offs;
int mesh_offs;
int filesize;
} md3header_t;
typedef struct
{
char name[MAX_APATH];
int flags;
int shader; // Shader reference
int numverts;
int numskins;
int numtris;
int numframes;
vec3_t **points;
vec3_t *normals;
vec2_t *tex_st; // Texture coords
vec3_t **norms; // Used for environment mapping?
int numelems;
uint_t *elems;
int *skins;
} md3mesh_t;
typedef struct
{
vec3_t mins;
vec3_t maxs;
int nummeshes;
md3mesh_t *meshes;
} md3model_t;
typedef struct
{
vec3_t mins;
vec3_t maxs;
vec3_t pos;
float scale;
char creator[16];
} md3boneframe_t;
typedef struct
{
char name[MAX_APATH]; // tag name
orientation_t orient;
} md3tag_t;
typedef struct
{
int id;
char name[MAX_APATH];
int flags;
int numframes;
int numskins;
int numverts;
int numtris;
int elem_offs;
int skin_offs;
int tc_offs;
int vert_offs;
int meshsize;
} md3mesh_file_t;
typedef struct
{
char name[MAX_OSPATH];
vec3_t mins, maxs;
int nummeshes;
int numframes;
int numtags;
int numskins;
int *ids;
md3tag_t **tags;
md3mesh_t *meshes;
md3boneframe_t *frames;
} md3model2_t;
typedef struct
{
signed short vec[3];
byte tc[2];
} md3vert_t;
typedef struct
{
char mesh_name[MAX_APATH];
int shaderref;
} mesh_skin_t;
typedef struct {
char name[MAX_APATH];
mesh_skin_t skins[MAX_MD3_MESHES];
int num_mesh_skins;
} skin_t;
This I wrote myself, call it anything you like, like md3make.cpp
#include <afx.h>
#include <stdio.h>
#include <stdlib.h>
#include "md3struct.h"
int main( int argc, char *argv[ ], char *envp[ ] )
{
char szOutput[_MAX_PATH];
if (argc!=2) return 1;
CString strFileName(argv[1]);
strFileName.TrimLeft();
strFileName.TrimRight();
printf("Processing '%s'
",argv[1]);
GetPrivateProfileString("MD3","Output","",szOutput,_MAX_PATH,strFileName);
printf("Creating '%s'
",szOutput);
FILE* pfile=fopen(szOutput,"wb");
if (pfile)
{
md3header_t header={MD3_IDENT,MD3_VERSION,0};
CString strMD3Name(szOutput);
strMD3Name.Replace("PK3\\","");
strMD3Name.Replace("\\","/");
strncpy(header.filename,strMD3Name,sizeof(header.filename));
//----
fwrite(&header,sizeof(md3header_t),1,pfile);
header.bone_offs=ftell(pfile);
//----
header.numboneframes=1;
//----
md3boneframe_t* pframes=new md3boneframe_t[header.numboneframes];
memset(pframes,0,sizeof(md3boneframe_t)*header.numboneframes);
//----
strncpy(pframes[0].creator,"<HH> Lethal",sizeof(pframes[0].creator));
pframes[0].mins[0]=-1;
pframes[0].mins[1]=-1;
pframes[0].mins[2]=-1;
pframes[0].maxs[0]=1;
pframes[0].maxs[1]=1;
pframes[0].maxs[2]=1;
pframes[0].pos[0]=0;
pframes[0].pos[1]=0;
pframes[0].pos[2]=0;
pframes[0].scale=1;
//----
fwrite(pframes,sizeof(md3boneframe_t),header.numboneframes,pfile);
delete[] pframes;
header.tag_offs=ftell(pfile);
//----
UINT iTags=GetPrivateProfileInt("MD3","Tags",0,strFileName);
printf("Containing '%ld' tags.
",iTags);
header.numtags=iTags;
//----
md3tag_t* ptags=new md3tag_t[header.numtags];
memset(ptags,0,sizeof(md3tag_t)*header.numtags);
//----
for(UINT iTag=0;iTag<iTags;iTag++)
{
CString strTagName;
strTagName.Format("TAG%d",iTag+1);
GetPrivateProfileString(strTagName,"Name","",ptags[iTag].name,sizeof(ptags[iTag].name),strFileName);
ptags[iTag].orient.axis[0][0]=1;
ptags[iTag].orient.axis[1][1]=1;
ptags[iTag].orient.axis[2][2]=1;
ptags[iTag].orient.origin[0]=(float)int(GetPrivateProfileInt(strTagName,"X",0,strFileName));
ptags[iTag].orient.origin[1]=(float)int(GetPrivateProfileInt(strTagName,"Y",0,strFileName));
ptags[iTag].orient.origin[2]=(float)int(GetPrivateProfileInt(strTagName,"Z",0,strFileName));
}
//----
fwrite(ptags,sizeof(md3tag_t),header.numtags,pfile);
delete[] ptags;
header.mesh_offs=ftell(pfile);
//----
header.nummeshes=1;
//----
md3mesh_file_t* pmesh=new md3mesh_file_t[header.nummeshes];
memset(pmesh,0,sizeof(md3mesh_file_t)*header.nummeshes);
//----
pmesh[0].id=MD3_IDENT;
strncpy(pmesh[0].name,"model",sizeof(pmesh[0].name));
//----
pmesh[0].numframes=1;
pmesh[0].numskins=0;
pmesh[0].numverts=1;
pmesh[0].numtris=1;
//----
pmesh[0].skin_offs=sizeof(md3mesh_file_t);
pmesh[0].elem_offs=pmesh[0].skin_offs+sizeof(uint3_t)*pmesh[0].numskins;
pmesh[0].tc_offs=pmesh[0].skin_offs+sizeof(mesh_skin_t)*pmesh[0].numtris;
pmesh[0].vert_offs=pmesh[0].tc_offs+sizeof(vec2_t)*pmesh[0].numverts;
pmesh[0].meshsize=pmesh[0].vert_offs+sizeof(md3vert_t)*pmesh[0].numverts;
uint3_t* ptris=new uint3_t[pmesh[0].numtris];
memset(ptris,0,sizeof(uint3_t)*pmesh[0].numtris);
mesh_skin_t* pskin=new mesh_skin_t[pmesh[0].numskins];
memset(pskin,0,sizeof(mesh_skin_t)*pmesh[0].numskins);
vec2_t* pvec=new vec2_t[pmesh[0].numverts];
memset(pvec,0,sizeof(vec2_t)*pmesh[0].numverts);
md3vert_t* pvert=new md3vert_t[pmesh[0].numverts];
memset(pvert,0,sizeof(md3vert_t)*pmesh[0].numverts);
//----
ptris[0][0]=0;
ptris[0][1]=0;
ptris[0][2]=0;
//----
fwrite(pmesh,sizeof(md3mesh_file_t),header.nummeshes,pfile);
fwrite(ptris,sizeof(uint3_t),pmesh[0].numtris,pfile);
fwrite(pskin,sizeof(mesh_skin_t),pmesh[0].numskins,pfile);
fwrite(pvec,sizeof(vec2_t),pmesh[0].numverts,pfile);
fwrite(pvert,sizeof(md3vert_t),pmesh[0].numverts,pfile);
delete[] pvert;
delete[] pvec;
delete[] pskin;
delete[] ptris;
delete[] pmesh;
header.filesize=ftell(pfile);
rewind(pfile);
fwrite(&header,sizeof(header),1,pfile);
fclose(pfile);
}
else return 1;
return 0;
}
Store into a visual studio console project and compile 
Make one of these funky .ini style files and give the path to the file as input to the program you just compiled:
[MD3]
Output="PK3\models\mapobjects\hm713\smokerig.md3"
Tags=2
[TAG1]
Name=left
X=-96
Y=48
Z=16
[TAG2]
Name=right
X=-96
Y=-48
Z=16
The .exe file will do the rest like creating the .MD3 file in the directory pointed to by output. The directory must exist prior to running the .exe
If it is not straight forward:
- [MD3] : each input file must have this section.
- Output= : is where the .md3 gets written.
- Tags= : is the number of tags you made.
- [TAGx] : make one for each tag declared in Tags=, start at 1.
- Name= : is the name of your tag you’ll use in attachtotag’s last parameter.
- X= : The X Position of your tagpoint
- Y= : The Y position of your tagpoint
- Z= : The Z position of your tagpoint
Pay attention to the PK3\ on the path, I didn’t exactly wrote this for others to use so I ‘collect’ all my stuff into a subdirectory PK3 so I can easily zip the contents of that directory into a .pk3
I remove that PK3 prefix to create the path to the model in the .md3, you might want to change that code if you know what you’re doing and decided to store your model in your etmain directory instead. You might want to change:
strMD3Name.Replace("PK3\\","");
into
strMD3Name.Replace("C:\\Program Files\\Wolfenstein - Enemy Territory\\etmain\\","");
and use something like
Output="C:\Program Files\Wolfenstein - Enemy Territory\etmain\models\mapobjects\hm713\smokerig.md3"
instead of
Output="PK3\models\mapobjects\hm713\smokerig.md3"
in your input file.
Sorry if this is too complicated for most of you. Feel free to make it easier/more general if you’re up to it.
im stuck.
i made a model of an elevator. i want to make an elevator with buttons attached. i have an entity(scriptname:elevator) of script_mover made of clipbrushes. and it has key model2 set to my model. the buttons have a scriptname. at spawn i give wait 300 and attachtotag elevator tag_buttons. but in-game they are nowhere. any help?
if u want help whit elevator, u need to ask to C
he builded a map named UJE_flat and there is a elevator whit buttons
Murka 10
here you can find tutorial + map file on elevator basic + advanced with buttons - Simland http://simland.planetquake.gamespy.com//pages/articles.htm
f u want help whit elevator, u need to ask to C
he builded a map named UJE_flat and there is a elevator whit buttons
That map is not made by me… i’m helping my clanmate Niek a bit with it. I did make the elevator working though. However, it is not a model, just a script_mover with fixed buttons. The buttons can not be pushed in/out. On every floor there are some func_invisible_user entities covering the “buttons”.
I have made a fancy elevator-model, with real buttons, but is was never put into the any map… yet
murka10 says:
but in-game they are nowhere
If You would check Your elevator in-game (/noclip 1), maybe the buttons are at the origin of Your model, possibly inside the elevator brushwork. Could this be the case?..
nah i already checked with noclip. they werent inside the elevator brushwork. not even in the center of the map.
but can buttons actually be attachtotagged?
ill try making animation in the elevator model. maybe just make func_invisible_users attachtotagged.
trying to master this thing but maybe iv made the tag wrong. does it have to be made in the angles that the tut said. xD
maybe ill try the md3 tag the dummy.
checking coords in gmax and then using that. tho iv seen so many elevators with buttons on each floor, i just want to make an elevator like in real life, with stop buttons or sth.
edit:just saw tha map. eh it has no attachtotags. instead it has a lever and lift with same place of origin. both go down and seems like they are attached. clever thing. well thats good enough. now ill make 3 levers and make them faceangles xD. why didnt i think of that. ah nevermind, im a noob
