From lordhavoc at icculus.org Thu May 4 19:09:55 2006
From: lordhavoc at icculus.org (lordhavoc at icculus.org)
Date: 4 May 2006 19:09:55 -0400
Subject: r702 - trunk
Message-ID: <20060504230955.23533.qmail@icculus.org>
Author: lordhavoc
Date: 2006-05-04 19:09:55 -0400 (Thu, 04 May 2006)
New Revision: 702
Modified:
trunk/material.c
Log:
added a hack to detect skybox at load and use texture clamping on it,
this hack will be removed when a material language is implemented someday
Modified: trunk/material.c
===================================================================
--- trunk/material.c 2006-04-18 11:01:00 UTC (rev 701)
+++ trunk/material.c 2006-05-04 23:09:55 UTC (rev 702)
@@ -9,53 +9,60 @@
char *filename;
r->data = material = Mem_Alloc(r->memzone, sizeof(Material));
filename = String_APrintf(r->memzone, "%s.tga", r->name);
- material->texture_color = Resource_IndexForName(filename, RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
- String_Free(&filename);
- filename = String_APrintf(r->memzone, "%s_norm.tga", r->name);
- material->texture_normal = Resource_IndexForName(filename, RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
- String_Free(&filename);
- if (!Resource_GetData(material->texture_normal))
+ // TODO: eventually add a material language, until then this skybox hack is needed
+ if (strstr(r->name, "sky"))
{
- filename = String_APrintf(r->memzone, "%s_bump.tga", r->name);
- material->texture_normal = Resource_IndexForName(filename, RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP | RESOURCEFLAG_BUMPMAPASNORMALMAP, 4);
+ material->texture_color = Resource_IndexForName(filename, RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP | RESOURCEFLAG_CLAMP, 0);
String_Free(&filename);
}
- filename = String_APrintf(r->memzone, "%s_gloss.tga", r->name);
- material->texture_gloss = Resource_IndexForName(filename, RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
- String_Free(&filename);
- filename = String_APrintf(r->memzone, "%s_glow.tga", r->name);
- material->texture_glow = Resource_IndexForName(filename, RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
- String_Free(&filename);
- filename = String_APrintf(r->memzone, "%s_back.tga", r->name);
- material->texture_background = Resource_IndexForName(filename, RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
- String_Free(&filename);
- material->specularpower = 8;
- // these can be used for High Dynamic Range (HDR), boosting a material's
- // specular intensity to allow a gloss texture to have the RGB range 0-4
- // instead of 0-1.
- // ambient can be used instead of diffuse and specular to make soft-shaded
- // materials like snow which react very little to light direction.
- material->ambientintensity = 1;
- material->diffuseintensity = 1;
- material->specularintensity = 1;
- // offset mapping is off by default,
- // example values: scale 0.04, bias -0.02
- material->offsetmapping_scale = 0;
- material->offsetmapping_bias = 0;
+ else
+ {
+ material->texture_color = Resource_IndexForName(filename, RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
+ String_Free(&filename);
+ filename = String_APrintf(r->memzone, "%s_norm.tga", r->name);
+ material->texture_normal = Resource_IndexForName(filename, RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
+ String_Free(&filename);
+ if (!Resource_GetData(material->texture_normal))
+ {
+ filename = String_APrintf(r->memzone, "%s_bump.tga", r->name);
+ material->texture_normal = Resource_IndexForName(filename, RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP | RESOURCEFLAG_BUMPMAPASNORMALMAP, 4);
+ String_Free(&filename);
+ }
+ filename = String_APrintf(r->memzone, "%s_gloss.tga", r->name);
+ material->texture_gloss = Resource_IndexForName(filename, RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
+ String_Free(&filename);
+ filename = String_APrintf(r->memzone, "%s_glow.tga", r->name);
+ material->texture_glow = Resource_IndexForName(filename, RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
+ String_Free(&filename);
+ filename = String_APrintf(r->memzone, "%s_back.tga", r->name);
+ material->texture_background = Resource_IndexForName(filename, RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
+ String_Free(&filename);
+ material->specularpower = 8;
+ // these can be used for High Dynamic Range (HDR), boosting a material's
+ // specular intensity to allow a gloss texture to have the RGB range 0-4
+ // instead of 0-1.
+ // ambient can be used instead of diffuse and specular to make soft-shaded
+ // materials like snow which react very little to light direction.
+ material->ambientintensity = 1;
+ material->diffuseintensity = 1;
+ material->specularintensity = 1;
+ // offset mapping is off by default,
+ // example values: scale 0.04, bias -0.02
+ material->offsetmapping_scale = 0;
+ material->offsetmapping_bias = 0;
- // if some textures are missing, load default
- if (!Resource_GetData(material->texture_color))
- material->texture_color = Resource_IndexForName("engine/default.tga", RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
- if (!Resource_GetData(material->texture_normal))
- material->texture_normal = Resource_IndexForName("engine/default_norm.tga", RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
- if (!Resource_GetData(material->texture_gloss))
- material->texture_gloss = 0;//Resource_IndexForName("engine/default_gloss.tga", RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
- if (!Resource_GetData(material->texture_glow))
- material->texture_glow = Resource_IndexForName("engine/default_glow.tga", RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
- if (!Resource_GetData(material->texture_background))
- material->texture_background = 0;//Resource_IndexForName("engine/default_back.tga", RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
-
- // TODO: eventually add a material language
+ // if some textures are missing, load default
+ if (!Resource_GetData(material->texture_color))
+ material->texture_color = Resource_IndexForName("engine/default.tga", RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
+ if (!Resource_GetData(material->texture_normal))
+ material->texture_normal = Resource_IndexForName("engine/default_norm.tga", RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
+ if (!Resource_GetData(material->texture_gloss))
+ material->texture_gloss = 0;//Resource_IndexForName("engine/default_gloss.tga", RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
+ if (!Resource_GetData(material->texture_glow))
+ material->texture_glow = Resource_IndexForName("engine/default_glow.tga", RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
+ if (!Resource_GetData(material->texture_background))
+ material->texture_background = 0;//Resource_IndexForName("engine/default_back.tga", RESOURCETYPE_TEXTURE, RESOURCEFLAG_MIPMAP, 0);
+ }
}
void Material_Unload(UNUSED ResourceEntry *r)
From lordhavoc at icculus.org Fri May 5 12:23:34 2006
From: lordhavoc at icculus.org (lordhavoc at icculus.org)
Date: 5 May 2006 12:23:34 -0400
Subject: r703 - trunk/game
Message-ID: <20060505162334.18844.qmail@icculus.org>
Author: lordhavoc
Date: 2006-05-05 12:23:34 -0400 (Fri, 05 May 2006)
New Revision: 703
Modified:
trunk/game/g_entity.c
trunk/game/g_main.h
Log:
thanks to painQuin for a patch to handle freed entity timeouts (to give
other entities a chance to notice that their reference is dead)
Modified: trunk/game/g_entity.c
===================================================================
--- trunk/game/g_entity.c 2006-05-04 23:09:55 UTC (rev 702)
+++ trunk/game/g_entity.c 2006-05-05 16:23:34 UTC (rev 703)
@@ -8,7 +8,9 @@
G_Entity *G_Entity_New(G_Entity *parent, const G_Entity_Class *eclass, const G_Entity_Position *position)
{
G_Entity *entity;
- NUint32 childindex = 0;
+ Nbool bestfound = false;
+ Nvec tbest = 0;
+ NUint32 childindex = 0, bestindex = 0;
if (!eclass)
return NULL;
if (!eclass->codeclass->name)
@@ -33,32 +35,56 @@
}
if (!position)
position = &GS.identityposition;
- // TODO: add a timeout after freeing an entity before it will be reused? (if so this will need to scan twice if it can't find one with the timeout)
+
for (entity = G.entities + G.allocentity;G.allocentity < G_MAX_ENTITIES;G.allocentity++, entity++)
{
if (!entity->eclass)
{
- G.allocentity++;
- G.numentities = Max(G.numentities, G.allocentity);
- memset(entity, 0, sizeof(G_Entity));
- entity->eclass = eclass;
- // mark this entity as not being a network related entity
- // (if it really is, the network code will change this)
- entity->networkindex = -1;
- if (parent)
+ if (G.time - entity->freetime >= FREETIMEOUT)
{
- entity->owner = parent;
- parent->children[childindex] = entity;
+ // this entity has not been used recently, so anything
+ // referencing it has probably cleared its references already,
+ // so it is probably safe to reuse it now
+ bestfound = true;
+ bestindex = G.allocentity++;
+ break;
}
- entity->position = *position;
- if (entity->eclass->modelname && entity->eclass->modelname[0])
- G_Entity_SetModel(entity, entity->eclass->modelname);
- entity->lifetime = entity->eclass->lifetime;
- return entity;
+ else if (!foundbest || (entity->freetime < tbest))
+ {
+ // found a free slot that hasn't timed out yet, keep track of
+ // which one is oldest incase we can't find one
+ // (this is a dangerous situation but it's even worse to fail)
+ foundbest = true;
+ bestindex = G.allocentity;
+ tbest = entity->freetime;
+ }
}
}
- Console_Printf("Ran out of entities (%i)\n", G_MAX_ENTITIES);
- return NULL;
+ if (!bestfound)
+ {
+ Console_Printf("Ran out of entities (%i)\n", G_MAX_ENTITIES);
+ return NULL;
+ }
+ entity = G.entities + bestindex;
+ // update entity range to include this newly allocated entity
+ // (the entity range is used to avoid processing the entire array each
+ // frame)
+ G.numentities = Max(G.numentities, bestindex);
+ memset(entity, 0, sizeof(G_Entity));
+ entity->eclass = eclass;
+ // mark this entity as not being a network related entity
+ // (if it really is, the network code will change this)
+ entity->networkindex = -1;
+ if (parent)
+ {
+ entity->owner = parent;
+ parent->children[childindex] = entity;
+ }
+ entity->position = *position;
+ if (entity->eclass->modelname && entity->eclass->modelname[0])
+ G_Entity_SetModel(entity, entity->eclass->modelname);
+ entity->lifetime = entity->eclass->lifetime;
+ return entity;
}
void G_Entity_Spawn(G_Entity *entity)
@@ -115,6 +141,7 @@
memset(entity, 0, sizeof(*entity));
// reset allocentity to a level that will find this freshly freed entity
G.allocentity = Min(G.allocentity, entitynum);
+ entity->freetime = G.time;
}
void G_Entity_RemoveChildren(G_Entity *entity)
Modified: trunk/game/g_main.h
===================================================================
--- trunk/game/g_main.h 2006-05-04 23:09:55 UTC (rev 702)
+++ trunk/game/g_main.h 2006-05-05 16:23:34 UTC (rev 703)
@@ -541,9 +541,14 @@
Nvec lifetime;
// weapons
Nvec attackdelay;
+
+ Nvec freetime;
}
G_Entity;
+// number of seconds before an entity slot will be reused (unless overloaded, in which case the least recently freed entity will be chosen)
+#define FREETIMEOUT 0.2
+
typedef struct G_Trace
{
G_Entity *moveentity;
From lordhavoc at icculus.org Fri May 5 15:08:10 2006
From: lordhavoc at icculus.org (lordhavoc at icculus.org)
Date: 5 May 2006 15:08:10 -0400
Subject: r704 - trunk/game
Message-ID: <20060505190810.15480.qmail@icculus.org>
Author: lordhavoc
Date: 2006-05-05 15:08:10 -0400 (Fri, 05 May 2006)
New Revision: 704
Modified:
trunk/game/g_entity.c
Log:
fix for previous patch (oops, I named a variable bestfound but forgot to
edit two foundbest references)
Modified: trunk/game/g_entity.c
===================================================================
--- trunk/game/g_entity.c 2006-05-05 16:23:34 UTC (rev 703)
+++ trunk/game/g_entity.c 2006-05-05 19:08:10 UTC (rev 704)
@@ -49,12 +49,12 @@
bestindex = G.allocentity++;
break;
}
- else if (!foundbest || (entity->freetime < tbest))
+ else if (!bestfound || (entity->freetime < tbest))
{
// found a free slot that hasn't timed out yet, keep track of
// which one is oldest incase we can't find one
// (this is a dangerous situation but it's even worse to fail)
- foundbest = true;
+ bestfound = true;
bestindex = G.allocentity;
tbest = entity->freetime;
}
From lordhavoc at icculus.org Fri May 5 15:09:19 2006
From: lordhavoc at icculus.org (lordhavoc at icculus.org)
Date: 5 May 2006 15:09:19 -0400
Subject: r705 - trunk
Message-ID: <20060505190919.15569.qmail@icculus.org>
Author: lordhavoc
Date: 2006-05-05 15:09:19 -0400 (Fri, 05 May 2006)
New Revision: 705
Modified:
trunk/r_main.c
trunk/resource.c
Log:
some warning prints done by painQuin
Modified: trunk/r_main.c
===================================================================
--- trunk/r_main.c 2006-05-05 19:08:10 UTC (rev 704)
+++ trunk/r_main.c 2006-05-05 19:09:19 UTC (rev 705)
@@ -1914,17 +1914,29 @@
return;
// TODO: verify the resource type is RESOURCETYPE_MODEL
model = Resource_GetData(R.entitymodelresource);
- if (!model)
- return; // TODO: warning
+ if (!model) {
+ Console_Printf("R_DrawMesh failed to find model\n");
+ return;
+ }
// TODO: verify the resource type is RESOURCETYPE_MATERIAL
material = Resource_GetData(materialresource);
- if (!material)
- return; // TODO: warning
- if (meshindex >= model->num_meshes)
- return; // TODO: warning
+ if (!material) {
+ Console_Printf("R_DrawMesh failed to find material\n");
+ return;
+ }
+ if (meshindex >= model->num_meshes) {
+ Console_Printf("R_DrawMesh meshindex out of bounds\n");
+ return;
+ }
mesh = model->data_meshes + meshindex;
- if (mesh->num_vertices < 1 || mesh->num_triangles < 1)
- return; // TODO: warning
+ if (mesh->num_vertices < 1) {
+ Console_Printf("R_DrawMesh num_vertices out of range\n");
+ return;
+ }
+ if (mesh->num_triangles < 1) {
+ Console_Printf("R_DrawMesh num_triangles out of range\n");
+ return;
+ }
R.speeds_data.numdrawmesh_vertices += mesh->num_vertices;
R.speeds_data.numdrawmesh_triangles += mesh->num_triangles;
switch (R.drawmode)
Modified: trunk/resource.c
===================================================================
--- trunk/resource.c 2006-05-05 19:08:10 UTC (rev 704)
+++ trunk/resource.c 2006-05-05 19:09:19 UTC (rev 705)
@@ -178,7 +178,8 @@
switch(r->type)
{
case RESOURCETYPE_INVALID:
- // TODO: error?
+ Console_Printf("Resource Load: Unknown Resource Type: %i\n",
+ r->type);
break;
case RESOURCETYPE_MODEL:
Model_Load(r);
@@ -220,7 +221,8 @@
switch(r->type)
{
case RESOURCETYPE_INVALID:
- // TODO: error?
+ Console_Printf("Resource Unload: Unknown Resource Type: %i\n",
+ r->type);
break;
case RESOURCETYPE_MODEL:
Model_Unload(r);
From lordhavoc at icculus.org Fri May 5 15:28:50 2006
From: lordhavoc at icculus.org (lordhavoc at icculus.org)
Date: 5 May 2006 15:28:50 -0400
Subject: r706 - trunk/game
Message-ID: <20060505192850.18116.qmail@icculus.org>
Author: lordhavoc
Date: 2006-05-05 15:28:49 -0400 (Fri, 05 May 2006)
New Revision: 706
Modified:
trunk/game/m_menucore.c
trunk/game/m_menucore.h
Log:
function pointer casts patch from painQuin to hush warnings
Modified: trunk/game/m_menucore.c
===================================================================
--- trunk/game/m_menucore.c 2006-05-05 19:09:19 UTC (rev 705)
+++ trunk/game/m_menucore.c 2006-05-05 19:28:49 UTC (rev 706)
@@ -196,10 +196,10 @@
item = Mem_Alloc(Menu.menu_zone, bytes);
- item->Frame = Menu_Generic_Frame;
+ item->Frame = (MenuItemFrame_t)Menu_Generic_Frame;
item->MouseMove = Menu_Generic_MouseMoveNonSelectable;
- item->KeyEvent = Menu_Generic_KeyPressIgnore;
- item->Destroy = Menu_Generic_Destroy;
+ item->KeyEvent = (MenuItemKeyEvent_t)Menu_Generic_KeyPressIgnore;
+ item->Destroy = (MenuItemDestroy_t)Menu_Generic_Destroy;
item->type = type;
@@ -247,11 +247,11 @@
Menu_TextItem *it;
it = (Menu_TextItem*)Menu_Generic_Create(parent, MENU_ITEMTYPE_TEXT, x, y, sizeof(Menu_TextItem));
- it->super.Draw = Menu_Text_Draw;
+ it->super.Draw = (MenuItemDraw_t)Menu_Text_Draw;
if (cookie != NULL)
{
- it->super.MouseMove = Menu_Generic_MouseMoveSelectable;
- it->super.KeyEvent = Menu_Text_KeyPress;
+ it->super.MouseMove = (MenuItemMouseMove_t)Menu_Generic_MouseMoveSelectable;
+ it->super.KeyEvent = (MenuItemKeyEvent_t)Menu_Text_KeyPress;
}
it->super.size[0] = 8*strlen(text);
it->super.size[1] = 8;
@@ -356,9 +356,9 @@
Menu_EditItem *it;
it = (Menu_EditItem*)Menu_Generic_Create(parent, MENU_ITEMTYPE_EDIT, x, y, sizeof(Menu_EditItem));
- it->super.Draw = Menu_Edit_Draw;
- it->super.MouseMove = Menu_Generic_MouseMoveSelectable;
- it->super.KeyEvent = Menu_Edit_KeyPress;
+ it->super.Draw = (MenuItemDraw_t)Menu_Edit_Draw;
+ it->super.MouseMove = (MenuItemMouseMove_t)Menu_Generic_MouseMoveSelectable;
+ it->super.KeyEvent = (MenuItemKeyEvent_t)Menu_Edit_KeyPress;
it->super.size[0] = 8*strlen(text);
it->super.size[1] = 8;
@@ -481,10 +481,10 @@
Menu_ComboItem *it;
it = (Menu_ComboItem*)Menu_Generic_Create(parent, MENU_ITEMTYPE_COMBO, x, y, sizeof(Menu_ComboItem));
- it->super.super.Draw = Menu_Combo_Draw;
- it->super.super.MouseMove = Menu_Generic_MouseMoveSelectable;
- it->super.super.KeyEvent = Menu_Combo_KeyPress;
- it->super.super.Destroy = Menu_Combo_Destroy;
+ it->super.super.Draw = (MenuItemDraw_t)Menu_Combo_Draw;
+ it->super.super.MouseMove = (MenuItemMouseMove_t)Menu_Generic_MouseMoveSelectable;
+ it->super.super.KeyEvent = (MenuItemKeyEvent_t)Menu_Combo_KeyPress;
+ it->super.super.Destroy = (MenuItemDestroy_t)Menu_Combo_Destroy;
it->super.super.size[0] = w;
it->super.super.size[1] = 8;
@@ -558,11 +558,11 @@
Menu_PictureItem *it;
it = (Menu_PictureItem*)Menu_Generic_Create(parent, MENU_ITEMTYPE_PICTURE, x, y, sizeof(Menu_PictureItem));
- it->super.Draw = Menu_Picture_Draw;
+ it->super.Draw = (MenuItemDraw_t)Menu_Picture_Draw;
if (command != NULL)
{
- it->super.MouseMove = Menu_Generic_MouseMoveSelectable;
- it->super.KeyEvent = Menu_Picture_KeyPress;
+ it->super.MouseMove = (MenuItemMouseMove_t)Menu_Generic_MouseMoveSelectable;
+ it->super.KeyEvent = (MenuItemKeyEvent_t)Menu_Picture_KeyPress;
}
it->super.size[0] = w;
it->super.size[1] = h;
@@ -671,9 +671,9 @@
Menu_SliderItem *it;
it = (Menu_SliderItem*)Menu_Generic_Create(parent, MENU_ITEMTYPE_SLIDER, x, y, sizeof(Menu_SliderItem));
- it->super.Draw = Menu_Slider_Draw;
- it->super.MouseMove = Menu_Generic_MouseMoveSelectable;
- it->super.KeyEvent = Menu_Slider_KeyPress;
+ it->super.Draw = (MenuItemDraw_t)Menu_Slider_Draw;
+ it->super.MouseMove = (MenuItemMouseMove_t)Menu_Generic_MouseMoveSelectable;
+ it->super.KeyEvent = (MenuItemKeyEvent_t)Menu_Slider_KeyPress;
it->super.size[0] = w;
it->super.size[1] = h;
@@ -877,11 +877,11 @@
Menu_SubMenu_AddAtFront(parent, &menu->super);
}
- menu->super.MouseMove = Menu_SubMenu_MouseMove;
- menu->super.Frame = Menu_SubMenu_Frame;
- menu->super.Draw = Menu_SubMenu_Draw;
- menu->super.KeyEvent = Menu_SubMenu_KeyEvent;
- menu->super.Destroy = Menu_SubMenu_Destroy;
+ menu->super.MouseMove = (MenuItemMouseMove_t)Menu_SubMenu_MouseMove;
+ menu->super.Frame = (MenuItemFrame_t)Menu_SubMenu_Frame;
+ menu->super.Draw = (MenuItemDraw_t)Menu_SubMenu_Draw;
+ menu->super.KeyEvent = (MenuItemKeyEvent_t)Menu_SubMenu_KeyEvent;
+ menu->super.Destroy = (MenuItemDestroy_t)Menu_SubMenu_Destroy;
menu->allowclose = true;
@@ -1185,8 +1185,8 @@
// init the root menu
// FIXME: create the rootmenu using the normal submenu creation function instead?
- Menu.rootmenu.super.Frame = Menu_SubMenu_Frame;
- Menu.rootmenu.super.MouseMove = Menu_SubMenu_MouseMove;
- Menu.rootmenu.super.Draw = Menu_SubMenu_Draw;
- Menu.rootmenu.super.KeyEvent = Menu_SubMenu_KeyEvent;
+ Menu.rootmenu.super.Frame = (MenuItemFrame_t)Menu_SubMenu_Frame;
+ Menu.rootmenu.super.MouseMove = (MenuItemMouseMove_t)Menu_SubMenu_MouseMove;
+ Menu.rootmenu.super.Draw = (MenuItemDraw_t)Menu_SubMenu_Draw;
+ Menu.rootmenu.super.KeyEvent = (MenuItemKeyEvent_t)Menu_SubMenu_KeyEvent;
}
Modified: trunk/game/m_menucore.h
===================================================================
--- trunk/game/m_menucore.h 2006-05-05 19:09:19 UTC (rev 705)
+++ trunk/game/m_menucore.h 2006-05-05 19:28:49 UTC (rev 706)
@@ -30,6 +30,12 @@
}
Menu_ItemType;
+typedef void (*MenuItemFrame_t)(void *, Menu_Inheritance *, Ndouble);
+typedef void (*MenuItemDraw_t)(void *, Menu_Inheritance *);
+typedef Nbool (*MenuItemKeyEvent_t)(void *, NUint, NUint, NUint, Nbool);
+typedef void (*MenuItemMouseMove_t)(void *, Menu_Inheritance *);
+typedef void (*MenuItemDestroy_t)(void *);
+
typedef struct Menu_Item
{
// pass an elapsedtime parameter to make animation-speed changes, etc. possible
From painquin at icculus.org Fri May 5 17:32:26 2006
From: painquin at icculus.org (painquin at icculus.org)
Date: 5 May 2006 17:32:26 -0400
Subject: r707 - trunk
Message-ID: <20060505213226.9503.qmail@icculus.org>
Author: painquin
Date: 2006-05-05 17:32:26 -0400 (Fri, 05 May 2006)
New Revision: 707
Modified:
trunk/cvar.c
Log:
added a check in Cvar_Find to ensure the Cvar Manager is running
Modified: trunk/cvar.c
===================================================================
--- trunk/cvar.c 2006-05-05 19:28:49 UTC (rev 706)
+++ trunk/cvar.c 2006-05-05 21:32:26 UTC (rev 707)
@@ -37,13 +37,16 @@
static Shell_SymbolDecl Cvar_Shell_Get_Decl;
-//TODO: add checks for .active!
static inline Cvar * Cvar_Find( const char *cvarName )
{
Cvar *cvar;
Hash_Data search;
+ if( !CvarManager.active ) {
+ Console_Warning( "The Cvar system has not been initialized!\n" );
+ return NULL;
+ }
search.name = cvarName;
search.name_len = String_Length (cvarName);
From lordhavoc at icculus.org Fri May 5 17:50:55 2006
From: lordhavoc at icculus.org (lordhavoc at icculus.org)
Date: 5 May 2006 17:50:55 -0400
Subject: r708 - trunk/game
Message-ID: <20060505215055.12561.qmail@icculus.org>
Author: lordhavoc
Date: 2006-05-05 17:50:55 -0400 (Fri, 05 May 2006)
New Revision: 708
Modified:
trunk/game/g_entity.c
Log:
reworked G_Entity_New some more to fix a horrible crash and added more
comments
Modified: trunk/game/g_entity.c
===================================================================
--- trunk/game/g_entity.c 2006-05-05 21:32:26 UTC (rev 707)
+++ trunk/game/g_entity.c 2006-05-05 21:50:55 UTC (rev 708)
@@ -8,9 +8,8 @@
G_Entity *G_Entity_New(G_Entity *parent, const G_Entity_Class *eclass, const G_Entity_Position *position)
{
G_Entity *entity;
- Nbool bestfound = false;
- Nvec tbest = 0;
- NUint32 childindex = 0, bestindex = 0;
+ Nvec tbest;
+ NUint32 childindex = 0, bestindex, index;
if (!eclass)
return NULL;
if (!eclass->codeclass->name)
@@ -36,35 +35,45 @@
if (!position)
position = &GS.identityposition;
- for (entity = G.entities + G.allocentity;G.allocentity < G_MAX_ENTITIES;G.allocentity++, entity++)
+ // search for the first available entity slot in an optimized manner.
+ // G.allocentity tracks the first known gap in the G.entities array, it is
+ // incremented until a gap is found, and reset when an entity is freed
+ while (G.allocentity < G_MAX_ENTITIES && G.entities[G.allocentity].eclass)
+ G.allocentity++;
+ // if we couldn't find any at all, return NULL
+ if (G.allocentity >= G_MAX_ENTITIES)
{
+ Console_Printf("Ran out of entities (%i)\n", G_MAX_ENTITIES);
+ return NULL;
+ }
+ // now we know we're sitting at a valid free slot, but we want to choose
+ // one that hasn't been freed recently as there may still be references
+ // pointing to it (usually they will be cleared a moment later)
+ bestindex = G.allocentity;
+ tbest = G.entities[bestindex].freetime;
+ for (index = G.allocentity + 1, entity = G.entities + index;index < G_MAX_ENTITIES;index++, entity++)
+ {
if (!entity->eclass)
{
- if (G.time - entity->freetime >= FREETIMEOUT)
+ if (entity->freetime == 0 || G.time - entity->freetime >= FREETIMEOUT)
{
// this entity has not been used recently, so anything
// referencing it has probably cleared its references already,
// so it is probably safe to reuse it now
- bestfound = true;
- bestindex = G.allocentity++;
+ bestindex = index;
+ tbest = entity->freetime;
break;
}
- else if (!bestfound || (entity->freetime < tbest))
+ else if (entity->freetime < tbest)
{
// found a free slot that hasn't timed out yet, keep track of
- // which one is oldest incase we can't find one
+ // which one is oldest incase we can't find any safe ones
// (this is a dangerous situation but it's even worse to fail)
- bestfound = true;
- bestindex = G.allocentity;
+ bestindex = index;
tbest = entity->freetime;
}
}
}
- if (!bestfound)
- {
- Console_Printf("Ran out of entities (%i)\n", G_MAX_ENTITIES);
- return NULL;
- }
entity = G.entities + bestindex;
// update entity range to include this newly allocated entity
// (the entity range is used to avoid processing the entire array each
From painquin at icculus.org Sun May 7 23:25:24 2006
From: painquin at icculus.org (painquin at icculus.org)
Date: 7 May 2006 23:25:24 -0400
Subject: r709 - trunk/game
Message-ID: <20060508032524.12773.qmail@icculus.org>
Author: painquin
Date: 2006-05-07 23:25:23 -0400 (Sun, 07 May 2006)
New Revision: 709
Modified:
trunk/game/m_menucore.c
trunk/game/m_menucore.h
Log:
menu revisions,
Reworked the main menu (not a placeholder anymore),
Added a BigText item for menu headings and such,
Added menu padding (defaults to 2, menu->padding[axis] = n to change)
Modified: trunk/game/m_menucore.c
===================================================================
--- trunk/game/m_menucore.c 2006-05-05 21:50:55 UTC (rev 708)
+++ trunk/game/m_menucore.c 2006-05-08 03:25:23 UTC (rev 709)
@@ -225,12 +225,18 @@
{
R_SetBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
R_SetTexture(R.resource_font);
- R_DrawString(item->text, 0, item->super.pos[0] + inh->origin[0], item->super.pos[1] + inh->origin[1], 8, 8, Console_DefaultColorTable, Console_DefaultColorTableSize, item->super.parent->selecteditem == &item->super);
+ R_DrawString(item->text, 0, item->super.pos[0] + inh->origin[0], item->super.pos[1] + inh->origin[1], item->super.size[1], item->super.size[1], Console_DefaultColorTable, Console_DefaultColorTableSize, item->super.parent->selecteditem == &item->super);
+ /* Notice: this uses the height of the text to determine the scale (for height and width)
+ * if this is not right, we need an alternative way to track the scaling factor and size.
+ */
}
+
+
void Menu_Text_DefaultUse (struct Menu_TextItem *item, void *cookie)
{
Shell_ExecuteScript("menu text use", cookie);
}
+
Nbool Menu_Text_KeyPress (Menu_TextItem *item, UNUSED NUint mod, NUint sym, UNUSED NUint character, Nbool downevent)
{
if (sym == SDLK_RETURN || sym == MOUSE1)
@@ -267,9 +273,40 @@
return it;
}
+Menu_TextItem *Menu_BigText_Create(Menu_SubMenu *parent, NSint x, NSint y, char *text, void *cookie, void (*UseItem) (struct Menu_TextItem *item, void *cookie))
+{
+ Menu_TextItem *it;
+ it = Menu_Text_Create(parent, x, y, text, cookie, UseItem);
+ it->super.size[0] *= 2;
+ it->super.size[1] *= 2;
+ /* Todo: Alternate scaling factors? */
+
+ return it;
+}
+
+
+/*
+ * Menu Padding
+ */
+void Menu_Pad_Draw(Menu_PadItem *item, Menu_Inheritance *inh)
+{
+ return;
+}
+
+Menu_PadItem *Menu_Pad_Create(Menu_SubMenu *parent, NSint padx, NSint pady)
+{
+ Menu_PadItem *it = (Menu_PadItem*)Menu_Generic_Create(parent, MENU_ITEMTYPE_PAD, 0, 0, sizeof(Menu_PadItem));
+
+ it->super.Draw = (MenuItemDraw_t)Menu_Pad_Draw;
+ it->super.size[0] = padx;
+ it->super.size[1] = pady;
+ return it;
+}
+
+
//text-edit fields
//fixme: only work with grabs?
void Menu_Edit_Draw(Menu_EditItem *item, Menu_Inheritance *inh)
@@ -884,6 +921,8 @@
menu->super.Destroy = (MenuItemDestroy_t)Menu_SubMenu_Destroy;
menu->allowclose = true;
+ menu->padding[1] = 2;
+ /* default spacing of 2 pixels - I think this helps readability significantly -quin */
return menu;
}
@@ -942,13 +981,13 @@
for (sitem = menu->subitems; sitem; sitem = sitem->next)
{
sitem->pos[axis] = maxval;
- maxval += sitem->size[axis] + pad;
+ maxval += sitem->size[axis] + pad + menu->padding[axis];
}
+ val = maxval;
- val = maxval;
for (sitem = menu->subitems; sitem; sitem = sitem->next)
{
- val -= sitem->size[axis] + pad;
+ val -= sitem->size[axis] + pad + menu->padding[axis];
sitem->pos[axis] = val;
switch(arrange)
@@ -1052,6 +1091,8 @@
Menu_SubMenu *menu = cookie;
it->value = menu->subwindow.pos[1];
}
+
+#if 0
void Menu_Menu_Test(void)
{
//fixme: we still need to figure out how to do the parent's frames, so the subwindow doesn't appear outside the parent
@@ -1090,30 +1131,39 @@
(Shell_Symbol_Callback) Menu_Menu_Test
};
+#endif
+/* Menu_Text_Create(menu, 0, 16, "Hello World", "echo Hello World\n", NULL);
+ Menu_Text_Create(menu, 0, 24, "Start up test map", "map test\n", NULL);
+ Menu_Text_Create(menu, 0, 32, "Go to the west!", "map west\n", NULL);*/
+ /*
+ Menu_Text_Create(menu, 0, 56+16, "test menu", "menu_test\n", NULL);
+ Menu_Edit_Create(menu, 0, 56, "EditItem");
+ Menu_Combo_Create(menu, 0, 56, 21*8, "ComboItem", "Option 1|Option 2|Option 3|Fuzzy Little Bunnies|Big Rocket Launcher|Children|Lightning Gun|Newborn Chicks|Grenade Launcher|Rodents|Nukes");
+*/
+#define IHEIGHT 160
+
void Menu_Main(void)
{
Menu_SubMenu *menu = Menu_SubMenu_Create(&Menu.rootmenu);
menu->dragable = true;
+
- Menu_Text_Create(menu, 0, 0, "Main menu", NULL, NULL);
+ Menu_BigText_Create(menu, 0, 0, "DarkWar", NULL, NULL); // TODO: replace this with a graphic -quin
+ Menu_Pad_Create(menu, 0, 8);
- Menu_Text_Create(menu, 0, 16, "Hello World", "echo Hello World\n", NULL);
- Menu_Text_Create(menu, 0, 24, "Start up test map", "map test\n", NULL);
- Menu_Text_Create(menu, 0, 32, "Go to the west!", "map west\n", NULL);
- Menu_Text_Create(menu, 0, 40, "quit", "menu_quit\n", NULL);
+ Menu_Text_Create(menu, 0, 0, "Singleplayer", NULL, NULL);
- Menu_Text_Create(menu, 0, 56, "Close menu", "menu_close\n", NULL);
+ Menu_Text_Create(menu, 0, 0, "Multiplayer", "menu_multiplayer", NULL);
- Menu_Text_Create(menu, 0, 56+16, "test menu", "menu_test\n", NULL);
-
- Menu_Edit_Create(menu, 0, 56, "EditItem");
- Menu_Combo_Create(menu, 0, 56, 21*8, "ComboItem", "Option 1|Option 2|Option 3|Fuzzy Little Bunnies|Big Rocket Launcher|Children|Lightning Gun|Newborn Chicks|Grenade Launcher|Rodents|Nukes");
-
+ Menu_Text_Create(menu, 0, 0, "Options", NULL, NULL);
+
+ Menu_Text_Create(menu, 0, 0, "Exit DarkWar", "quit", NULL);
+
Menu_SubMenu_Finish(menu);
Menu_SubMenu_Arrange(menu, false, 0, MENU_ARRANGESTYLE_CENTER);
Menu_SubMenu_Finish(menu);
@@ -1146,41 +1196,12 @@
(Shell_Symbol_Callback) Menu_CloseMenu
};
-
-
-//The simple quit menu
-void Menu_Menu_Quit(void)
-{
- Menu_SubMenu *menu = Menu_SubMenu_Create(&Menu.rootmenu);
- menu->dragable = true;
-
- Menu_Text_Create(menu, 0, 0, "Really Quit?", NULL, NULL);
-
- Menu_Text_Create(menu, 0, 16, "Yes, and wipe my harddrive too.", "quit\n", NULL);
- Menu_Text_Create(menu, 0, 24, "No. I want to keep playing this awesome game", "menu_close\n", NULL);
-
- Menu_SubMenu_Finish(menu);
-
- Menu_Picture_Create(menu, 0, 0, menu->super.size[0], menu->super.size[1], "maps/test/skybox_ny.tga", NULL, NULL);
-
- Menu_MoveToCenter(menu);
-}
-static Shell_SymbolDecl Menu_Menu_Quit_Decl = {
- "menu_quit",
- "asks the user if they want to quit, in a polite way.",
- "usage: menu_quit",
- "",
- (Shell_Symbol_Callback) Menu_Menu_Quit
-};
-
-
void Menu_Init(void)
{
Menu.menu_zone = Mem_AllocZone ("MenuZone", NULL, 0);
Shell_Register(&Menu_Menu_Main_Decl, NULL);
- Shell_Register(&Menu_Menu_Test_Decl, NULL);
- Shell_Register(&Menu_Menu_Quit_Decl, NULL);
+ //Shell_Register(&Menu_Menu_Test_Decl, NULL);
Shell_Register(&Menu_Menu_Close_Decl, NULL);
// init the root menu
Modified: trunk/game/m_menucore.h
===================================================================
--- trunk/game/m_menucore.h 2006-05-05 21:50:55 UTC (rev 708)
+++ trunk/game/m_menucore.h 2006-05-08 03:25:23 UTC (rev 709)
@@ -27,6 +27,7 @@
MENU_ITEMTYPE_COMBO,
MENU_ITEMTYPE_TEXT,
MENU_ITEMTYPE_PICTURE,
+ MENU_ITEMTYPE_PAD
}
Menu_ItemType;
@@ -68,6 +69,7 @@
struct Menu_Item *selecteditem;
struct Menu_Item *subitems;
+ NSint padding[2];
}
Menu_SubMenu;
@@ -85,6 +87,13 @@
}
Menu_TextItem;
+
+typedef struct Menu_PadItem
+{
+ Menu_Item super;
+}
+Menu_PadItem;
+
typedef struct Menu_EditItem
{
Menu_Item super;
From painquin at icculus.org Mon May 8 09:32:57 2006
From: painquin at icculus.org (painquin at icculus.org)
Date: 8 May 2006 09:32:57 -0400
Subject: r710 - trunk
Message-ID: <20060508133257.1630.qmail@icculus.org>
Author: painquin
Date: 2006-05-08 09:32:57 -0400 (Mon, 08 May 2006)
New Revision: 710
Modified:
trunk/darkwar-net2003.vcproj
Log:
Added modelanim.c/h to the vcproj file
Modified: trunk/darkwar-net2003.vcproj
===================================================================
--- trunk/darkwar-net2003.vcproj 2006-05-08 03:25:23 UTC (rev 709)
+++ trunk/darkwar-net2003.vcproj 2006-05-08 13:32:57 UTC (rev 710)
@@ -481,6 +481,12 @@
RelativePath=".\model.h">
+
+
+
+
Author: painquin
Date: 2006-05-08 13:47:12 -0400 (Mon, 08 May 2006)
New Revision: 711
Added:
trunk/base/menu/
trunk/base/menu/main_logo.tga
Log:
menu graphics - main logo
Added: trunk/base/menu/main_logo.tga
===================================================================
(Binary files differ)
Property changes on: trunk/base/menu/main_logo.tga
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
From painquin at icculus.org Mon May 8 19:19:48 2006
From: painquin at icculus.org (painquin at icculus.org)
Date: 8 May 2006 19:19:48 -0400
Subject: r712 - in trunk: . game
Message-ID: <20060508231948.29750.qmail@icculus.org>
Author: painquin
Date: 2006-05-08 19:19:48 -0400 (Mon, 08 May 2006)
New Revision: 712
Modified:
trunk/darkwar-net2003.vcproj
trunk/game/m_menucore.c
trunk/game/m_menucore.h
Log:
more work on the visual aspect of the menus, please give feedback
this update includes margins for padding menu size
this is useful mostly when creating background images
also m_menucore.h was missing from the vcproj
Modified: trunk/darkwar-net2003.vcproj
===================================================================
--- trunk/darkwar-net2003.vcproj 2006-05-08 17:47:12 UTC (rev 711)
+++ trunk/darkwar-net2003.vcproj 2006-05-08 23:19:48 UTC (rev 712)
@@ -286,6 +286,9 @@
RelativePath=".\game\m_menucore.c">
+
+
super.MouseMove = (MenuItemMouseMove_t)Menu_Generic_MouseMoveSelectable;
it->super.KeyEvent = (MenuItemKeyEvent_t)Menu_Text_KeyPress;
}
- it->super.size[0] = 8*strlen(text);
- it->super.size[1] = 8;
+ it->super.size[0] = 16*strlen(text);
+ it->super.size[1] = 16;
it->text = text;
it->cookie = cookie;
@@ -306,7 +306,14 @@
return it;
}
+void Menu_CloseOnUse(struct Menu_TextItem *item, void *cookie)
+{
+ Shell_ExecuteScript("menu text use", cookie);
+ Menu_Item_RemoveFromParent(&item->super.parent->super);
+ item->super.parent->super.Destroy(item->super.parent);
+}
+
//text-edit fields
//fixme: only work with grabs?
void Menu_Edit_Draw(Menu_EditItem *item, Menu_Inheritance *inh)
@@ -832,6 +839,8 @@
R_SetScissor(inh->window.pos[0], inh->window.pos[1], inh->window.size[0], inh->window.size[1]);
}
+
+
Nbool Menu_SubMenu_KeyEvent (Menu_SubMenu *item, NUint mod, NUint sym, NUint character, Nbool downevent)
{
Menu_Item *subitem;
@@ -923,6 +932,8 @@
menu->allowclose = true;
menu->padding[1] = 2;
/* default spacing of 2 pixels - I think this helps readability significantly -quin */
+ menu->margin[0] = 4;
+ menu->margin[1] = 4;
return menu;
}
@@ -954,11 +965,11 @@
minpos[1] = subitem->pos[1];
}
- menu->super.size[0] = maxpos[0];
- menu->super.size[1] = maxpos[1];
+ menu->super.size[0] = maxpos[0] + menu->margin[0];
+ menu->super.size[1] = maxpos[1] + menu->margin[1];
- menu->subwindow.size[0] = maxpos[0] - minpos[0];
- menu->subwindow.size[1] = maxpos[1] - minpos[1];
+ menu->subwindow.size[0] = maxpos[0] - minpos[0] + menu->margin[0] * 2;
+ menu->subwindow.size[1] = maxpos[1] - minpos[1] + menu->margin[1] * 2;
}
void Menu_SubMenu_Arrange(Menu_SubMenu *menu, Nbool horizontal, NSint pad, Menu_ArrangeStyle arrange)
@@ -966,18 +977,14 @@
Menu_Item *sitem;
NSint axis, otheraxis;
NSint val = 0;
- NSint maxval = 0;
+ NSint maxval = menu->margin[horizontal];
//axis is usually the 'vertical' axis, where each field is spaced with padding
//otheraxis is the axis on which we align stuff (rather than just space it)
- if (horizontal)
- axis = 0;
- else
- axis = 1;
+ otheraxis = horizontal;
+ axis = !otheraxis;
- otheraxis = !axis;
-
for (sitem = menu->subitems; sitem; sitem = sitem->next)
{
sitem->pos[axis] = maxval;
@@ -996,15 +1003,16 @@
break;
case MENU_ARRANGESTYLE_LEFT:
- sitem->pos[otheraxis] = 0;
+ sitem->pos[otheraxis] = menu->margin[otheraxis];
break;
case MENU_ARRANGESTYLE_CENTER:
- sitem->pos[otheraxis] = (menu->subwindow.size[otheraxis] - sitem->size[otheraxis])/2;
+ sitem->pos[otheraxis] = ((menu->subwindow.size[otheraxis] - menu->margin[otheraxis]*2)
+ - sitem->size[otheraxis])/2 + menu->margin[otheraxis];
break;
case MENU_ARRANGESTYLE_RIGHT:
- sitem->pos[otheraxis] = (menu->subwindow.size[otheraxis] - sitem->size[otheraxis]);
+ sitem->pos[otheraxis] = (menu->subwindow.size[otheraxis] - (sitem->size[otheraxis] + menu->margin[otheraxis]));
break;
case MENU_ARRANGESTYLE_RESIZE:
@@ -1055,17 +1063,6 @@
-
-
-
-
-
-
-
-
-
-
-
Nfloat sliderscale = 8;
Nfloat imagesize = 512;
Nfloat windowsize = 128;
@@ -1145,29 +1142,52 @@
Menu_Edit_Create(menu, 0, 56, "EditItem");
Menu_Combo_Create(menu, 0, 56, 21*8, "ComboItem", "Option 1|Option 2|Option 3|Fuzzy Little Bunnies|Big Rocket Launcher|Children|Lightning Gun|Newborn Chicks|Grenade Launcher|Rodents|Nukes");
*/
-#define IHEIGHT 160
+void Menu_Multiplayer(Menu_TextItem *item, void *cookie)
+{
+ Menu_SubMenu *menu = Menu_SubMenu_Create(&Menu.rootmenu);
+ Menu_SubMenu_Destroy(item->super.parent);
+ menu->padding[0] = menu->padding[1] = 4;
+ menu->margin[0] = menu->margin[1] = 15;
+ Menu_BigText_Create(menu, 0, 0, "Multiplayer", NULL, NULL);
+ Menu_Pad_Create(menu, 0, 6);
+
+ Menu_Text_Create(menu, 0, 0, "Join a Game", "map west", Menu_CloseOnUse); //Menu_ServerBrowser);
+ Menu_Text_Create(menu, 0, 0, "Start a Server", "map test", Menu_CloseOnUse);
+ Menu_Text_Create(menu, 0, 0, "Multiplayer Settings", NULL, NULL); //Menu_MPSettings);
+ Menu_Text_Create(menu, 0, 0, "Back", "menu_main", Menu_CloseOnUse);
+
+ Menu_SubMenu_Finish(menu);
+ Menu_SubMenu_Arrange(menu, false, 0, MENU_ARRANGESTYLE_CENTER);
+ Menu_SubMenu_Finish(menu);
+// Menu_Picture_Create(menu, 0, 0, menu->super.size[0], menu->super.size[1], "maps/test/skybox_ny.tga", NULL, NULL);
+
+ Menu_MoveToCenter(menu);
+
+}
+
void Menu_Main(void)
{
Menu_SubMenu *menu = Menu_SubMenu_Create(&Menu.rootmenu);
- menu->dragable = true;
-
+ menu->padding[0] = menu->padding[1] = 4;
+ menu->margin[0] = menu->margin[1] = 15;
- Menu_BigText_Create(menu, 0, 0, "DarkWar", NULL, NULL); // TODO: replace this with a graphic -quin
- Menu_Pad_Create(menu, 0, 8);
+ Menu_Picture_Create(menu, 0, 0, 138, 81, "menu/main_logo.tga", NULL, NULL);
+ Menu_Pad_Create(menu, 0, 6);
Menu_Text_Create(menu, 0, 0, "Singleplayer", NULL, NULL);
- Menu_Text_Create(menu, 0, 0, "Multiplayer", "menu_multiplayer", NULL);
+ Menu_Text_Create(menu, 0, 0, "Multiplayer", "", Menu_Multiplayer);
Menu_Text_Create(menu, 0, 0, "Options", NULL, NULL);
+ Menu_Pad_Create(menu, 0, 8);
Menu_Text_Create(menu, 0, 0, "Exit DarkWar", "quit", NULL);
Menu_SubMenu_Finish(menu);
Menu_SubMenu_Arrange(menu, false, 0, MENU_ARRANGESTYLE_CENTER);
Menu_SubMenu_Finish(menu);
- Menu_Picture_Create(menu, 0, 0, menu->super.size[0], menu->super.size[1], "maps/test/skybox_ny.tga", NULL, NULL);
+// Menu_Picture_Create(menu, 0, 0, menu->super.size[0], menu->super.size[1], "maps/test/skybox_ny.tga", NULL, NULL);
Menu_MoveToCenter(menu);
}
Modified: trunk/game/m_menucore.h
===================================================================
--- trunk/game/m_menucore.h 2006-05-08 17:47:12 UTC (rev 711)
+++ trunk/game/m_menucore.h 2006-05-08 23:19:48 UTC (rev 712)
@@ -70,6 +70,7 @@
struct Menu_Item *selecteditem;
struct Menu_Item *subitems;
NSint padding[2];
+ NSint margin[2];
}
Menu_SubMenu;
From painquin at icculus.org Tue May 9 16:05:18 2006
From: painquin at icculus.org (painquin at icculus.org)
Date: 9 May 2006 16:05:18 -0400
Subject: r713 - in trunk: base/menu game
Message-ID: <20060509200518.19524.qmail@icculus.org>
Author: painquin
Date: 2006-05-09 16:05:18 -0400 (Tue, 09 May 2006)
New Revision: 713
Added:
trunk/base/menu/ll.tga
trunk/base/menu/lr.tga
trunk/base/menu/ul.tga
trunk/base/menu/ur.tga
Modified:
trunk/game/m_menucore.c
Log:
more menu graphics - someone with art skills please replace
Added: trunk/base/menu/ll.tga
===================================================================
(Binary files differ)
Property changes on: trunk/base/menu/ll.tga
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/base/menu/lr.tga
===================================================================
(Binary files differ)
Property changes on: trunk/base/menu/lr.tga
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/base/menu/ul.tga
===================================================================
(Binary files differ)
Property changes on: trunk/base/menu/ul.tga
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/base/menu/ur.tga
===================================================================
(Binary files differ)
Property changes on: trunk/base/menu/ur.tga
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: trunk/game/m_menucore.c
===================================================================
--- trunk/game/m_menucore.c 2006-05-08 23:19:48 UTC (rev 712)
+++ trunk/game/m_menucore.c 2006-05-09 20:05:18 UTC (rev 713)
@@ -1142,6 +1142,10 @@
Menu_Edit_Create(menu, 0, 56, "EditItem");
Menu_Combo_Create(menu, 0, 56, 21*8, "ComboItem", "Option 1|Option 2|Option 3|Fuzzy Little Bunnies|Big Rocket Launcher|Children|Lightning Gun|Newborn Chicks|Grenade Launcher|Rodents|Nukes");
*/
+
+#define MSIZE 50
+
+
void Menu_Multiplayer(Menu_TextItem *item, void *cookie)
{
Menu_SubMenu *menu = Menu_SubMenu_Create(&Menu.rootmenu);
@@ -1155,12 +1159,17 @@
Menu_Text_Create(menu, 0, 0, "Join a Game", "map west", Menu_CloseOnUse); //Menu_ServerBrowser);
Menu_Text_Create(menu, 0, 0, "Start a Server", "map test", Menu_CloseOnUse);
Menu_Text_Create(menu, 0, 0, "Multiplayer Settings", NULL, NULL); //Menu_MPSettings);
+ Menu_Pad_Create(menu, 0, 6);
Menu_Text_Create(menu, 0, 0, "Back", "menu_main", Menu_CloseOnUse);
Menu_SubMenu_Finish(menu);
Menu_SubMenu_Arrange(menu, false, 0, MENU_ARRANGESTYLE_CENTER);
Menu_SubMenu_Finish(menu);
// Menu_Picture_Create(menu, 0, 0, menu->super.size[0], menu->super.size[1], "maps/test/skybox_ny.tga", NULL, NULL);
+ Menu_Picture_Create(menu, 0, 0, MSIZE, MSIZE, "menu/ul.tga", NULL, NULL);
+ Menu_Picture_Create(menu, menu->super.size[0] - MSIZE, 0, MSIZE, MSIZE, "menu/ur.tga", NULL, NULL);
+ Menu_Picture_Create(menu, menu->super.size[0] - MSIZE, menu->super.size[1] - MSIZE, MSIZE, MSIZE, "menu/lr.tga", NULL, NULL);
+ Menu_Picture_Create(menu, 0, menu->super.size[1] - MSIZE, MSIZE, MSIZE, "menu/ll.tga", NULL, NULL);
Menu_MoveToCenter(menu);
@@ -1170,7 +1179,7 @@
{
Menu_SubMenu *menu = Menu_SubMenu_Create(&Menu.rootmenu);
menu->padding[0] = menu->padding[1] = 4;
- menu->margin[0] = menu->margin[1] = 15;
+ menu->margin[0] = menu->margin[1] = 25;
Menu_Picture_Create(menu, 0, 0, 138, 81, "menu/main_logo.tga", NULL, NULL);
Menu_Pad_Create(menu, 0, 6);
@@ -1187,6 +1196,12 @@
Menu_SubMenu_Finish(menu);
Menu_SubMenu_Arrange(menu, false, 0, MENU_ARRANGESTYLE_CENTER);
Menu_SubMenu_Finish(menu);
+
+ Menu_Picture_Create(menu, 0, 0, MSIZE, MSIZE, "menu/ul.tga", NULL, NULL);
+ Menu_Picture_Create(menu, menu->super.size[0] - MSIZE, 0, MSIZE, MSIZE, "menu/ur.tga", NULL, NULL);
+ Menu_Picture_Create(menu, menu->super.size[0] - MSIZE, menu->super.size[1] - MSIZE, MSIZE, MSIZE, "menu/lr.tga", NULL, NULL);
+ Menu_Picture_Create(menu, 0, menu->super.size[1] - MSIZE, MSIZE, MSIZE, "menu/ll.tga", NULL, NULL);
+
// Menu_Picture_Create(menu, 0, 0, menu->super.size[0], menu->super.size[1], "maps/test/skybox_ny.tga", NULL, NULL);
Menu_MoveToCenter(menu);
From lordhavoc at icculus.org Fri May 12 04:36:48 2006
From: lordhavoc at icculus.org (lordhavoc at icculus.org)
Date: 12 May 2006 04:36:48 -0400
Subject: r714 - in trunk: . base/shaders
Message-ID: <20060512083648.5869.qmail@icculus.org>
Author: lordhavoc
Date: 2006-05-12 04:36:47 -0400 (Fri, 12 May 2006)
New Revision: 714
Modified:
trunk/base/shaders/light.vert
trunk/model.c
trunk/model.h
trunk/util.c
trunk/util.h
Log:
migrated Util_BuildModel code into Model_Build namespace and it now uses
the Model struct
Modified: trunk/base/shaders/light.vert
===================================================================
--- trunk/base/shaders/light.vert 2006-05-09 20:05:18 UTC (rev 713)
+++ trunk/base/shaders/light.vert 2006-05-12 08:36:47 UTC (rev 714)
@@ -30,14 +30,14 @@
vec3 lightminusvertex = LightPosition - gl_Vertex.xyz;
LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);
LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);
- LightVector.z = -dot(lightminusvertex, gl_MultiTexCoord3.xyz);
+ LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);
#if defined(USESPECULAR) || defined(USEFOG) || defined(USEOFFSETMAPPING)
// transform unnormalized eye direction into tangent space
vec3 eyeminusvertex = EyePosition - gl_Vertex.xyz;
EyeVector.x = dot(eyeminusvertex, gl_MultiTexCoord1.xyz);
EyeVector.y = dot(eyeminusvertex, gl_MultiTexCoord2.xyz);
- EyeVector.z = -dot(eyeminusvertex, gl_MultiTexCoord3.xyz);
+ EyeVector.z = dot(eyeminusvertex, gl_MultiTexCoord3.xyz);
#endif
// transform vertex to camera space, using ftransform to match non-VS
Modified: trunk/model.c
===================================================================
--- trunk/model.c 2006-05-09 20:05:18 UTC (rev 713)
+++ trunk/model.c 2006-05-12 08:36:47 UTC (rev 714)
@@ -22,21 +22,37 @@
}
}
-// build vectors (along S, T, and Normal) for a triangle
-static void Model_TriangleVectors(const float *v0, const float *v1, const float *v2, const float *tc0, const float *tc1, const float *tc2, float *svector3f, float *tvector3f, float *normal3f)
+// build smoothed normals for all vertices of a mesh
+static void Model_MeshNormals(NUint32 numtriangles, const NUint32 *element3i, NUint32 numvertices, const float *vertex3f, const float *texcoord2f, float *normal3f)
{
- float f, tangentcross[3], v10[3], v20[3], tc10[2], tc20[2];
- // 103 add/sub/negate/multiply (1 cycle), 3 divide (20 cycle), 3 sqrt (22 cycle), 4 compare (3 cycle?), total cycles not counting load/store/exchange roughly 241 cycles
- // 12 add, 28 subtract, 57 multiply, 3 divide, 3 sqrt, 4 compare, 50% chance of 6 negates
+ NUint32 i, j;
+ float normal[3];
+ // clear the output array
+ memset(normal3f, 0, numvertices * sizeof(float[3]));
+ // iterate the triangles
+ for (i = 0;i < numtriangles;i++)
+ {
+ TriangleNormal(vertex3f + element3i[i*3+0]*3, vertex3f + element3i[i*3+1]*3, vertex3f + element3i[i*3+2]*3, normal);
+ // accumulate normals
+ for (j = 0;j < 3;j++)
+ VectorAdd(normal3f + element3i[i*3+j]*3, normal, normal3f + element3i[i*3+j]*3);
+ }
+ // normalize the results
+ for (i = 0;i < numvertices;i++)
+ VectorNormalize(normal3f + i * 3);
+}
+// build tangent vectors (vectors along S, T texcoords) for a triangle
+static void Model_TangentVectors(const float *v0, const float *v1, const float *v2, const float *tc0, const float *tc1, const float *tc2, float *svector3f, float *tvector3f)
+{
+ float tangentcross[3], v10[3], v20[3], tc10[2], tc20[2], normal3f[3];
+
// 6 multiply, 9 subtract
VectorSubtract(v1, v0, v10);
VectorSubtract(v2, v0, v20);
normal3f[0] = v20[1] * v10[2] - v10[1] * v20[2];
normal3f[1] = v20[2] * v10[0] - v10[2] * v20[0];
normal3f[2] = v20[0] * v10[1] - v10[0] * v20[1];
- // 1 sqrt, 1 divide, 6 multiply, 2 add, 1 compare
- VectorNormalize(normal3f);
// 12 multiply, 10 subtract
tc10[1] = tc1[1] - tc0[1];
tc20[1] = tc2[1] - tc0[1];
@@ -48,18 +64,6 @@
tvector3f[0] = v20[0] * tc10[0] - v10[0] * tc20[0];
tvector3f[1] = v20[1] * tc10[0] - v10[1] * tc20[0];
tvector3f[2] = v20[2] * tc10[0] - v10[2] * tc20[0];
- // 12 multiply, 4 add, 6 subtract
- f = DotProduct(svector3f, normal3f);
- svector3f[0] -= f * normal3f[0];
- svector3f[1] -= f * normal3f[1];
- svector3f[2] -= f * normal3f[2];
- f = DotProduct(tvector3f, normal3f);
- tvector3f[0] -= f * normal3f[0];
- tvector3f[1] -= f * normal3f[1];
- tvector3f[2] -= f * normal3f[2];
- // 2 sqrt, 2 divide, 12 multiply, 4 add, 2 compare
- VectorNormalize(svector3f);
- VectorNormalize(tvector3f);
// if texture is mapped the wrong way (counterclockwise), the tangents
// have to be flipped, this is detected by calculating a normal from the
// two tangents, and seeing if it is opposite the surface normal
@@ -73,39 +77,48 @@
}
// build smoothed vectors (along S, T, and Normal) for all vertices of a mesh
-static void Model_MeshVectors(NUint32 numtriangles, const NUint32 *element3i, NUint32 numvertices, const float *vertex3f, const float *texcoord2f, float *svector3f, float *tvector3f, float *normal3f)
+static void Model_MeshTangents(NUint32 numtriangles, const NUint32 *element3i, NUint32 numvertices, const float *vertex3f, const float *texcoord2f, float *normal3f, float *svector3f, float *tvector3f)
{
NUint32 i, j;
- float svector[3], tvector[3], normal[3];
// this calculates a set of vectors per triangle and blends them onto the
// triangle's vertices, if triangle share vertices (continuous mesh) this
// smooths them, if they are not shared then this looks facetted.
//
- // a possibly more intelligent scheme would be to smooth vectors on all
- // vertices at the same position that share similar vectors, but that
- // takes longer and may still yield artifacts on texcoord seams
+ // a possibly more intelligent scheme would be to smooth normals on all
+ // vertices at the same position that share similar normals, but that
+ // takes longer and is difficult if they belong to different meshes
// clear the output arrays
memset(svector3f, 0, numvertices * sizeof(float[3]));
memset(tvector3f, 0, numvertices * sizeof(float[3]));
- memset(normal3f, 0, numvertices * sizeof(float[3]));
// iterate the triangles
for (i = 0;i < numtriangles;i++)
{
- Model_TriangleVectors(vertex3f + element3i[i*3+0] * 3, vertex3f + element3i[i*3+1] * 3, vertex3f + element3i[i*3+2] * 3, texcoord2f + element3i[i*3+0] * 2, texcoord2f + element3i[i*3+1] * 2, texcoord2f + element3i[i*3+2] * 2, svector, tvector, normal);
+ float svector[3], tvector[3];
+ Model_TangentVectors(vertex3f + element3i[i*3+0] * 3, vertex3f + element3i[i*3+1] * 3, vertex3f + element3i[i*3+2] * 3, texcoord2f + element3i[i*3+0] * 2, texcoord2f + element3i[i*3+1] * 2, texcoord2f + element3i[i*3+2] * 2, svector, tvector);
// accumulate vectors onto vertices
for (j = 0;j < 3;j++)
{
VectorAdd(svector3f + element3i[i*3+j]*3, svector, svector3f + element3i[i*3+j]*3);
VectorAdd(tvector3f + element3i[i*3+j]*3, tvector, tvector3f + element3i[i*3+j]*3);
- VectorAdd(normal3f + element3i[i*3+j]*3, normal, normal3f + element3i[i*3+j]*3);
}
}
- // normalize the results
- for (i = 0;i < numvertices;i++)
+ // project tangents onto planes and normalize the results
+ for (i = 0;i < numvertices;i++, svector3f += 3, tvector3f += 3, normal3f += 3)
{
- VectorNormalize(svector3f + i * 3);
- VectorNormalize(tvector3f + i * 3);
- VectorNormalize(normal3f + i * 3);
+ // project tangents onto plane defined by normal
+ // (makes sure they are perpendicular to the normal)
+ float f;
+ f = DotProduct(svector3f, normal3f);
+ svector3f[0] -= f * normal3f[0];
+ svector3f[1] -= f * normal3f[1];
+ svector3f[2] -= f * normal3f[2];
+ f = DotProduct(tvector3f, normal3f);
+ tvector3f[0] -= f * normal3f[0];
+ tvector3f[1] -= f * normal3f[1];
+ tvector3f[2] -= f * normal3f[2];
+ // normalize the tangents
+ VectorNormalize(svector3f);
+ VectorNormalize(tvector3f);
}
}
@@ -175,6 +188,563 @@
Mem_Free(&hashtable);
}
+void Model_Build_Begin(Model *b, Mem_Zone *memzone, Nbool isskeletal)
+{
+ memset(b, 0, sizeof(*b));
+ b->memzone = memzone;
+ b->isskeletal = isskeletal;
+}
+
+static void Model_Build_GenerateNeighbors(Model_Mesh *mesh)
+{
+ Model_MeshNeighbors(mesh->num_triangles, mesh->data_element3i, mesh->data_neighbor3i, mesh->num_vertices);
+}
+
+static void Model_Build_GeneratePlanes(Model_Mesh *mesh)
+{
+ Model_BuildTrianglePlanes(mesh->data_vertex3f, mesh->num_triangles, mesh->data_element3i, mesh->data_plane4f);
+}
+
+static void Model_Build_GenerateNormals(Model_Mesh *mesh)
+{
+ Model_MeshNormals(mesh->num_triangles, mesh->data_element3i, mesh->num_vertices, mesh->data_vertex3f, mesh->data_texcoord2f, mesh->data_normal3f);
+}
+
+static void Model_Build_GenerateTangents(Model_Mesh *mesh)
+{
+ Model_MeshTangents(mesh->num_triangles, mesh->data_element3i, mesh->num_vertices, mesh->data_vertex3f, mesh->data_texcoord2f, mesh->data_normal3f, mesh->data_svector3f, mesh->data_tvector3f);
+}
+
+static void Model_Build_GenerateLightmapTexCoords(Model_Mesh *mesh)
+{
+ // TODO
+ // this function should build non-overlapping triangle groups in a
+ // lightmap texture with some kind of assumed resolution based on the
+ // model bounding box (the resolution only matters when ensuring that
+ // some texture exists around each group to accomodate linear filtering,
+ // or perhaps a bit more if we decide to use mipmapped lightmaps)
+ //
+ // TODO: how do do this?
+}
+
+void Model_Build_Compile(Model *b, Nbool generateneighbors, Nbool generateplanes, Nbool generatenormals, Nbool generatetangents, Nbool generatelightmaptexcoords, Nbool generatecollisionbrushes)
+{
+ NUint32 i, j;
+ const float *v;
+ Model_Mesh *mesh;
+ Nbool initbox;
+ initbox = true;
+ VectorClear(b->basecullmins);
+ VectorClear(b->basecullmaxs);
+ for (i = 0, mesh = b->data_meshes;i < b->num_meshes;i++, mesh++)
+ {
+ if (mesh->max_triangles > mesh->num_triangles)
+ {
+ mesh->max_triangles = mesh->num_triangles;
+ if (mesh->data_element3i) Mem_ReAlloc(b->memzone, &mesh->data_element3i, mesh->max_triangles * 3 * sizeof(*mesh->data_element3i));
+ if (mesh->data_neighbor3i) Mem_ReAlloc(b->memzone, &mesh->data_neighbor3i, mesh->max_triangles * 3 * sizeof(*mesh->data_neighbor3i));
+ if (mesh->data_plane4f) Mem_ReAlloc(b->memzone, &mesh->data_plane4f, mesh->max_triangles * 4 * sizeof(*mesh->data_plane4f));
+ }
+
+ if (mesh->max_vertices > mesh->num_vertices)
+ {
+ mesh->max_vertices = mesh->num_vertices;
+ if (mesh->data_vertex3f) Mem_ReAlloc(b->memzone, &mesh->data_vertex3f, mesh->max_vertices * 3 * sizeof(*mesh->data_vertex3f));
+ if (mesh->data_svector3f) Mem_ReAlloc(b->memzone, &mesh->data_svector3f, mesh->max_vertices * 3 * sizeof(*mesh->data_svector3f));
+ if (mesh->data_tvector3f) Mem_ReAlloc(b->memzone, &mesh->data_tvector3f, mesh->max_vertices * 3 * sizeof(*mesh->data_tvector3f));
+ if (mesh->data_normal3f) Mem_ReAlloc(b->memzone, &mesh->data_normal3f, mesh->max_vertices * 3 * sizeof(*mesh->data_normal3f));
+ if (mesh->data_texcoord2f) Mem_ReAlloc(b->memzone, &mesh->data_texcoord2f, mesh->max_vertices * 2 * sizeof(*mesh->data_texcoord2f));
+ if (mesh->data_lightmaptexcoord2f) Mem_ReAlloc(b->memzone, &mesh->data_lightmaptexcoord2f, mesh->max_vertices * 2 * sizeof(*mesh->data_lightmaptexcoord2f));
+ if (mesh->data_weightindex4b) Mem_ReAlloc(b->memzone, &mesh->data_weightindex4b, mesh->max_vertices * 4 * sizeof(*mesh->data_weightindex4b));
+ if (mesh->data_weightvalue4b) Mem_ReAlloc(b->memzone, &mesh->data_weightvalue4b, mesh->max_vertices * 4 * sizeof(*mesh->data_weightvalue4b));
+ }
+
+ if (generateneighbors)
+ {
+ if (!mesh->data_neighbor3i) Mem_ReAlloc(b->memzone, &mesh->data_neighbor3i, mesh->max_triangles * 3 * sizeof(*mesh->data_neighbor3i));
+ Model_Build_GenerateNeighbors(mesh);
+ }
+
+ if (generateplanes)
+ {
+ if (!mesh->data_plane4f) Mem_ReAlloc(b->memzone, &mesh->data_plane4f, mesh->max_triangles * 4 * sizeof(*mesh->data_plane4f));
+ Model_Build_GeneratePlanes(mesh);
+ }
+
+ if (generatenormals)
+ {
+ if (!mesh->data_normal3f) Mem_ReAlloc(b->memzone, &mesh->data_normal3f, mesh->max_vertices * 3 * sizeof(*mesh->data_normal3f));
+ Model_Build_GenerateNormals(mesh);
+ }
+
+ if (generatetangents)
+ {
+ if (!mesh->data_svector3f) Mem_ReAlloc(b->memzone, &mesh->data_svector3f, mesh->max_vertices * 3 * sizeof(*mesh->data_svector3f));
+ if (!mesh->data_tvector3f) Mem_ReAlloc(b->memzone, &mesh->data_tvector3f, mesh->max_vertices * 3 * sizeof(*mesh->data_tvector3f));
+ Model_Build_GenerateTangents(mesh);
+ }
+
+ if (generatelightmaptexcoords)
+ {
+ if (!mesh->data_lightmaptexcoord2f) Mem_ReAlloc(b->memzone, &mesh->data_lightmaptexcoord2f, mesh->max_vertices * 2 * sizeof(*mesh->data_lightmaptexcoord2f));
+ Model_Build_GenerateLightmapTexCoords(mesh);
+ }
+
+ if (mesh->data_collisionbrushes)
+ {
+ Collision_Brush_FreeBrushesForTriangleMesh(mesh->data_collisionbrushes, mesh->max_collisionbrushes);
+ mesh->num_collisionbrushes = 0;
+ mesh->max_collisionbrushes = 0;
+ mesh->data_collisionbrushes = NULL;
+ }
+ if (generatecollisionbrushes)
+ {
+ mesh->num_collisionbrushes = mesh->num_triangles;
+ mesh->max_collisionbrushes = mesh->num_collisionbrushes;
+ mesh->data_collisionbrushes = Collision_Brush_AllocBrushesForTriangleMesh(b->memzone, mesh->max_collisionbrushes);
+ Collision_Brush_UpdateTriangleMeshBrushes(mesh->data_collisionbrushes, mesh->max_collisionbrushes, mesh->data_element3i, mesh->data_vertex3f);
+ }
+
+ for (j = 0, v = mesh->data_vertex3f;j < mesh->num_vertices;j++, v += 3)
+ {
+ if (initbox)
+ {
+ initbox = false;
+ VectorCopy(v, b->basecullmins);
+ VectorCopy(v, b->basecullmaxs);
+ }
+ else
+ {
+ b->basecullmins[0] = Min(b->basecullmins[0], v[0]);
+ b->basecullmins[1] = Min(b->basecullmins[1], v[1]);
+ b->basecullmins[2] = Min(b->basecullmins[2], v[2]);
+ b->basecullmaxs[0] = Max(b->basecullmaxs[0], v[0]);
+ b->basecullmaxs[1] = Max(b->basecullmaxs[1], v[1]);
+ b->basecullmaxs[2] = Max(b->basecullmaxs[2], v[2]);
+ }
+ }
+ }
+}
+
+void Model_Build_Free(Model *b)
+{
+ NUint32 i;
+ Model_Mesh *mesh;
+ for (i = 0, mesh = b->data_meshes;i < b->num_meshes;i++, mesh++)
+ {
+ if (mesh->materialname) String_Free(&mesh->materialname);
+ if (mesh->data_element3i) Mem_Free(&mesh->data_element3i);
+ if (mesh->data_neighbor3i) Mem_Free(&mesh->data_neighbor3i);
+ if (mesh->data_plane4f) Mem_Free(&mesh->data_plane4f);
+ if (mesh->data_vertex3f) Mem_Free(&mesh->data_vertex3f);
+ if (mesh->data_svector3f) Mem_Free(&mesh->data_svector3f);
+ if (mesh->data_tvector3f) Mem_Free(&mesh->data_tvector3f);
+ if (mesh->data_normal3f) Mem_Free(&mesh->data_normal3f);
+ if (mesh->data_texcoord2f) Mem_Free(&mesh->data_texcoord2f);
+ if (mesh->data_lightmaptexcoord2f) Mem_Free(&mesh->data_lightmaptexcoord2f);
+ if (mesh->data_weightindex4b) Mem_Free(&mesh->data_weightindex4b);
+ if (mesh->data_weightvalue4b) Mem_Free(&mesh->data_weightvalue4b);
+ if (mesh->data_collisionbrushes) Collision_Brush_FreeBrushesForTriangleMesh(mesh->data_collisionbrushes, mesh->max_collisionbrushes);
+ }
+ if (b->data_meshes)
+ Mem_Free(&b->data_meshes);
+ memset(b, 0, sizeof(*b));
+}
+
+NUint32 Model_Build_AddSurface(Model *b, Mem_Zone *zone, const char *materialname, NUint32 initialtriangles, NUint32 initialvertices)
+{
+ Model_Mesh *mesh;
+ if (b->num_meshes >= b->max_meshes)
+ {
+ b->max_meshes = Max(b->max_meshes * 2, 16);
+ Mem_ReAlloc(Global_Zone, &b->data_meshes, b->max_meshes * sizeof(*b->data_meshes));
+ }
+ mesh = b->data_meshes + b->num_meshes;
+ String_Set(&mesh->materialname, zone, materialname);
+ mesh->max_triangles = initialtriangles;
+ mesh->max_vertices = initialvertices;
+ b->num_meshes++;
+ return b->num_meshes - 1;
+}
+
+NUint32 Model_Build_AddVertex(Model *b, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t)
+{
+ float *v;
+ Model_Mesh *mesh = b->data_meshes + meshindex;
+ if (mesh->num_vertices >= mesh->max_vertices)
+ {
+ mesh->max_vertices = Max(mesh->max_vertices * 2, 1024);
+ Mem_ReAlloc(b->memzone, &mesh->data_vertex3f, mesh->max_vertices * 3 * sizeof(*mesh->data_vertex3f));
+ Mem_ReAlloc(b->memzone, &mesh->data_normal3f, mesh->max_vertices * 3 * sizeof(*mesh->data_normal3f));
+ Mem_ReAlloc(b->memzone, &mesh->data_texcoord2f, mesh->max_vertices * 2 * sizeof(*mesh->data_texcoord2f));
+ if (b->isskeletal)
+ {
+ Mem_ReAlloc(b->memzone, &mesh->data_weightindex4b, mesh->max_vertices * 4 * sizeof(*mesh->data_weightindex4b));
+ Mem_ReAlloc(b->memzone, &mesh->data_weightvalue4b, mesh->max_vertices * 4 * sizeof(*mesh->data_weightvalue4b));
+ }
+ }
+ v = mesh->data_vertex3f + mesh->num_vertices * 3;
+ v[0] = x;
+ v[1] = y;
+ v[2] = z;
+ v = mesh->data_normal3f + mesh->num_vertices * 3;
+ v[0] = nx;
+ v[1] = ny;
+ v[2] = nz;
+ v = mesh->data_texcoord2f + mesh->num_vertices * 2;
+ v[0] = s;
+ v[1] = t;
+ if (b->isskeletal)
+ {
+ NUint8 *wi = mesh->data_weightindex4b + mesh->num_vertices * 4;
+ NUint8 *wf = mesh->data_weightvalue4b + mesh->num_vertices * 4;
+ wi[0] = 0;
+ wi[1] = 0;
+ wi[2] = 0;
+ wi[3] = 0;
+ wf[0] = 255;
+ wf[1] = 0;
+ wf[2] = 0;
+ wf[3] = 0;
+ }
+ mesh->num_vertices++;
+ return mesh->num_vertices - 1;
+}
+
+NUint32 Model_Build_AddVertexSkeletal(Model *b, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t, NUint8 *wib, NUint8 *wfb)
+{
+ float *v;
+ Model_Mesh *mesh = b->data_meshes + meshindex;
+ if (mesh->num_vertices >= mesh->max_vertices)
+ {
+ mesh->max_vertices = Max(mesh->max_vertices * 2, 1024);
+ Mem_ReAlloc(b->memzone, &mesh->data_vertex3f, mesh->max_vertices * 3 * sizeof(*mesh->data_vertex3f));
+ Mem_ReAlloc(b->memzone, &mesh->data_normal3f, mesh->max_vertices * 3 * sizeof(*mesh->data_normal3f));
+ Mem_ReAlloc(b->memzone, &mesh->data_texcoord2f, mesh->max_vertices * 2 * sizeof(*mesh->data_texcoord2f));
+ if (b->isskeletal)
+ {
+ Mem_ReAlloc(b->memzone, &mesh->data_weightindex4b, mesh->max_vertices * 4 * sizeof(*mesh->data_weightindex4b));
+ Mem_ReAlloc(b->memzone, &mesh->data_weightvalue4b, mesh->max_vertices * 4 * sizeof(*mesh->data_weightvalue4b));
+ }
+ }
+ v = mesh->data_vertex3f + mesh->num_vertices * 3;
+ v[0] = x;
+ v[1] = y;
+ v[2] = z;
+ v = mesh->data_normal3f + mesh->num_vertices * 3;
+ v[0] = nx;
+ v[1] = ny;
+ v[2] = nz;
+ v = mesh->data_texcoord2f + mesh->num_vertices * 2;
+ v[0] = s;
+ v[1] = t;
+ if (b->isskeletal)
+ {
+ NUint8 *wi = mesh->data_weightindex4b + mesh->num_vertices * 4;
+ NUint8 *wf = mesh->data_weightvalue4b + mesh->num_vertices * 4;
+ Vector4Copy(wib, wi);
+ Vector4Copy(wfb, wf);
+ }
+ mesh->num_vertices++;
+ return mesh->num_vertices - 1;
+}
+
+NUint32 Model_Build_FindOrAddVertex(Model *b, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t)
+{
+ NUint32 i;
+ float *v, *n, *tc;
+ NUint8 *wi, *wf;
+ Model_Mesh *mesh = b->data_meshes + meshindex;
+ for (i = 0, v = mesh->data_vertex3f, n = mesh->data_normal3f, tc = mesh->data_texcoord2f, wi = mesh->data_weightindex4b, wf = mesh->data_weightvalue4b;i < mesh->num_vertices;i++, v += 3, n += 3, tc += 2, wi += 4, wf += 4)
+ if (fabs(v[0] - x) < 0.0001 && fabs(v[1] - y) < 0.0001 && fabs(v[2] - z) < 0.0001
+ && fabs(n[0] - nx) < 0.0001 && fabs(n[1] - ny) < 0.0001 && fabs(n[2] - nz) < 0.0001
+ && fabs(tc[0] - s) < 0.0001 && fabs(tc[1] - t) < 0.0001)
+ return i;
+ return Model_Build_AddVertex(b, meshindex, x, y, z, nx, ny, nz, s, t);
+}
+
+NUint32 Model_Build_FindOrAddVertexSkeletal(Model *b, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t, NUint8 *wib, NUint8 *wfb)
+{
+ NUint32 i;
+ float *v, *n, *tc;
+ NUint8 *wi, *wf;
+ Model_Mesh *mesh = b->data_meshes + meshindex;
+ for (i = 0, v = mesh->data_vertex3f, n = mesh->data_normal3f, tc = mesh->data_texcoord2f, wi = mesh->data_weightindex4b, wf = mesh->data_weightvalue4b;i < mesh->num_vertices;i++, v += 3, n += 3, tc += 2, wi += 4, wf += 4)
+ if (fabs(v[0] - x) < 0.0001 && fabs(v[1] - y) < 0.0001 && fabs(v[2] - z) < 0.0001
+ && fabs(n[0] - nx) < 0.0001 && fabs(n[1] - ny) < 0.0001 && fabs(n[2] - nz) < 0.0001
+ && fabs(tc[0] - s) < 0.0001 && fabs(tc[1] - t) < 0.0001
+ && wi[0] == wib[0] && wi[1] == wib[1] && wi[2] == wib[2] && wi[3] == wib[3]
+ && wf[0] == wfb[0] && wf[1] == wfb[1] && wf[2] == wfb[2] && wf[3] == wfb[3])
+ return i;
+ return Model_Build_AddVertexSkeletal(b, meshindex, x, y, z, nx, ny, nz, s, t, wib, wfb);
+}
+
+NUint32 Model_Build_AddTriangle(Model *b, NUint32 meshindex, int e0, int e1, int e2)
+{
+ Model_Mesh *mesh = b->data_meshes + meshindex;
+ NUint32 *e;
+ if (mesh->num_triangles >= mesh->max_triangles)
+ {
+ mesh->max_triangles = Max(mesh->max_triangles * 2, 1024);
+ Mem_ReAlloc(b->memzone, &mesh->data_element3i, mesh->max_triangles * 3 * sizeof(*mesh->data_element3i));
+ }
+ e = mesh->data_element3i + mesh->num_triangles * 3;
+ e[0] = e0;
+ e[1] = e1;
+ e[2] = e2;
+ mesh->num_triangles++;
+ return mesh->num_triangles - 1;
+}
+
+void Model_Build_Write(Model *b, const char *filename)
+{
+ // FIXME: this is very unlikely to overflow but it should be made buffer size safe at some point
+ NUint32 i, num;
+ Nsize textsize, textmaxsize;
+ char *text;
+ Model_Mesh *mesh;
+ textmaxsize = 0x100000;
+ for (i = 0, mesh = b->data_meshes;i < b->num_meshes;i++, mesh++)
+ textmaxsize += mesh->num_vertices * 60 + mesh->num_triangles * 40;
+ textsize = 0;
+ text = Mem_Alloc(Global_Zone, textmaxsize);
+ textsize += snprintf(text + textsize, textmaxsize - textsize, "MD5Version 10\ncommandline \"\"\n\nnumJoints 1\nnumMeshes %u\n\njoints {\n\t\"ROOT\"\t-1 ( 0.000000 0.000000 0.000000 ) ( 0.000000 0.000000 0.000000 ) // \n}\n", b->num_meshes);
+ for (i = 0, mesh = b->data_meshes;i < b->num_meshes;i++, mesh++)
+ {
+ if (textmaxsize < textsize + mesh->num_vertices * 100 + mesh->num_triangles * 100 + mesh->num_vertices * 100 + 1000)
+ {
+ textmaxsize = textsize + mesh->num_vertices * 200 + mesh->num_triangles * 200 + mesh->num_vertices * 200 + 2000;
+ Mem_ReAlloc(Global_Zone, &text, textmaxsize);
+ }
+ textsize += snprintf(text + textsize, textmaxsize - textsize, "\nmesh {\n\tshader \"%s\"\n\n\tnumverts %u\n", mesh->materialname, mesh->num_vertices);
+ for (num = 0;num < mesh->num_vertices;num++)
+ textsize += snprintf(text + textsize, textmaxsize - textsize, "\tvert %u ( %.6f %.6f ) %u 1\n", num, mesh->data_texcoord2f[num*2+0], mesh->data_texcoord2f[num*2+1], num);
+ textsize += snprintf(text + textsize, textmaxsize - textsize, "\n\tnumtris %u\n", mesh->num_triangles);
+ for (num = 0;num < mesh->num_triangles;num++)
+ textsize += snprintf(text + textsize, textmaxsize - textsize, "\ttri %u %u %u %u\n", num, mesh->data_element3i[num*3+0], mesh->data_element3i[num*3+1], mesh->data_element3i[num*3+2]);
+ textsize += snprintf(text + textsize, textmaxsize - textsize, "\n\tnumweights %u\n", mesh->num_vertices);
+ for (num = 0;num < mesh->num_vertices;num++)
+ textsize += snprintf(text + textsize, textmaxsize - textsize, "\tweight %u 0 1.000000 ( %.6f %.6f %.6f )\n", num, mesh->data_vertex3f[num*3+0], mesh->data_vertex3f[num*3+1], mesh->data_vertex3f[num*3+2]);
+ textsize += snprintf(text + textsize, textmaxsize - textsize, "}\n");
+ }
+ File_WriteFile(filename, text, textsize);
+ Mem_Free(&text);
+}
+
+void Model_Build_ImportOBJ(Model *b, const char *inputname, const char *text, const char *textend)
+{
+ NUint32 linenumber = 0;
+ NSint32 meshindex = -1;
+ NUint32 num_vertices = 0, max_vertices = 0;
+ NUint32 num_normals = 0, max_normals = 0;
+ NUint32 num_texcoords = 0, max_texcoords = 0;
+ float *data_vertex3f = NULL;
+ float *data_normal3f = NULL;
+ float *data_texcoord2f = NULL;
+ while (text < textend)
+ {
+ Nbool comment = false;
+ NUint32 argc = 0;
+ char argv[64][256];
+ // parse the line
+ linenumber++;
+ while (text < textend && *text != '\r' && *text != '\n')
+ {
+ if (comment || *text <= ' ')
+ text++;
+ else if (*text == '#')
+ comment = true;
+ else
+ {
+ NUint32 charnum;
+ for (charnum = 0;text < textend && *text > ' ';text++)
+ if (charnum < sizeof(argv[0]) - 1)
+ argv[argc][charnum++] = *text;
+ argv[argc++][charnum] = 0;
+ }
+ }
+ if (*text == '\r' && text[1] == '\n')
+ text++;
+ if (*text == '\n')
+ text++;
+ // now we have a command
+ if (argc < 1)
+ continue;
+ if (!String_Compare(argv[0], "v"))
+ {
+ // v -4.99960e-2 0.250000 -1.00000
+ if (argc == 4)
+ {
+ if (num_vertices >= max_vertices)
+ {
+ max_vertices = Max(max_vertices * 2, 1024);
+ Mem_ReAlloc(Global_Zone, &data_vertex3f, max_vertices * sizeof(float[3]));
+ }
+ data_vertex3f[num_vertices*3+0] = atof(argv[1]);
+ data_vertex3f[num_vertices*3+2] = atof(argv[2]);
+ data_vertex3f[num_vertices*3+1] = atof(argv[3]);
+ num_vertices++;
+ }
+ else
+ Console_Printf("Model_Build_ImportOBJ: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 3);
+ }
+ else if (!String_Compare(argv[0], "vn"))
+ {
+ // vn 1.99019e-6 2.65359e-5 -1.000000
+ if (argc == 4)
+ {
+ if (num_normals >= max_normals)
+ {
+ max_normals = Max(max_normals * 2, 1024);
+ Mem_ReAlloc(Global_Zone, &data_normal3f, max_normals * sizeof(float[3]));
+ }
+ data_normal3f[num_normals*3+0] = atof(argv[1]);
+ data_normal3f[num_normals*3+2] = atof(argv[2]);
+ data_normal3f[num_normals*3+1] = atof(argv[3]);
+ num_normals++;
+ }
+ else
+ Console_Printf("Model_Build_ImportOBJ: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 3);
+ }
+ else if (!String_Compare(argv[0], "vt"))
+ {
+ // vt 0.00000e+0 1.99019e-6
+ if (argc == 3)
+ {
+ if (num_texcoords >= max_texcoords)
+ {
+ max_texcoords = Max(max_texcoords * 2, 1024);
+ Mem_ReAlloc(Global_Zone, &data_texcoord2f, max_texcoords * sizeof(float[2]));
+ }
+ data_texcoord2f[num_texcoords*2+0] = atof(argv[1]);
+ data_texcoord2f[num_texcoords*2+1] = -atof(argv[2]);
+ num_texcoords++;
+ }
+ else
+ Console_Printf("Model_Build_ImportOBJ: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 2);
+ }
+ else if (!String_Compare(argv[0], "usemtl"))
+ {
+ // usemtl mtrl/chrome
+ if (argc == 2)
+ meshindex = Model_Build_AddSurface(b, Global_Zone, argv[1], 0, 0);
+ else
+ Console_Printf("Model_Build_ImportOBJ: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 1);
+ }
+ else if (!String_Compare(argv[0], "f"))
+ {
+ // f 1/11/5 18/56/71 17/58/67
+ NUint32 i;
+ NUint32 indices[64];
+ if (argc >= 4)
+ {
+ if (meshindex == -1)
+ meshindex = Model_Build_AddSurface(b, Global_Zone, "default", 0, 0);
+ for (i = 0;i < argc - 1;i++)
+ {
+ NUint32 j;
+ const char *s = argv[i+1];
+ float v[3];
+ float vn[3];
+ float tc[2];
+ // if there are 3 indices, they are vertex, texcoord, normal
+ // if there are 2 indices, they are vertex, texcoord
+ // if there is only one index, it is vertex
+ // so we just initialize the values to defaults,
+ // and update them as indices are read
+ VectorClear(v);
+ VectorClear(vn);
+ Vector2Clear(tc);
+ for (j = 0;j < 3;j++)
+ {
+ if (*s)
+ {
+ NSint32 k = atoi(s);
+ switch (j)
+ {
+ case 0:
+ if (k < 0)
+ k += num_vertices;
+ else
+ k--;
+ if (k >= 0 && k < num_vertices)
+ VectorCopy(data_vertex3f + k * 3, v);
+ else
+ Console_Printf("Model_Build_ImportOBJ: %s:%i: invalid face vertex index (parameter #%i)\n", inputname, linenumber, i + 1);
+ break;
+ case 1:
+ if (k < 0)
+ k += num_texcoords;
+ else
+ k--;
+ if (k >= 0 && k < num_texcoords)
+ Vector2Copy(data_texcoord2f + k * 2, tc);
+ else
+ Console_Printf("Model_Build_ImportOBJ: %s:%i: invalid face texcoord index (parameter #%i)\n", inputname, linenumber, i + 1);
+ break;
+ case 2:
+ if (k < 0)
+ k += num_normals;
+ else
+ k--;
+ if (k >= 0 && k < num_normals)
+ VectorCopy(data_normal3f + k * 3, vn);
+ else
+ Console_Printf("Model_Build_ImportOBJ: %s:%i: invalid face vertexnormal index (parameter #%i)\n", inputname, linenumber, i + 1);
+ break;
+ }
+ }
+ // this weird code construct exits at NUL, or if the
+ // character is /, and then leaves s at the character
+ // after the NUL or /
+ while (*s)
+ {
+ if (*s == '/')
+ {
+ s++;
+ break;
+ }
+ s++;
+ }
+ }
+ indices[i] = Model_Build_FindOrAddVertex(b, meshindex, v[0], v[1], v[2], vn[0], vn[1], vn[2], tc[0], tc[1]);
+ // make a triangle fan if we have enough vertices
+ if (i >= 2)
+ Model_Build_AddTriangle(b, meshindex, indices[0], indices[i-1], indices[i]);
+ }
+ }
+ else
+ Console_Printf("Model_Build_ImportOBJ: %s:%i: command %s takes %i or more parameters\n", inputname, linenumber, argv[0], 3);
+ }
+ else if (!String_Compare(argv[0], "o"))
+ {
+ // o cylinder1
+ if (argc != 2)
+ Console_Printf("Model_Build_ImportOBJ: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 1);
+ }
+ else if (!String_Compare(argv[0], "mtllib"))
+ {
+ // mtllib zrail2.mtl
+ if (argc != 2)
+ Console_Printf("Model_Build_ImportOBJ: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 1);
+ }
+ else if (!String_Compare(argv[0], "g"))
+ {
+ // g cylinder1_mtrl/invisible
+ if (argc != 2)
+ Console_Printf("Model_Build_ImportOBJ: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 1);
+ }
+ else
+ Console_Printf("Model_Build_ImportOBJ: %s:%i: unknown obj command %s\n", inputname, linenumber, argv[0]);
+ }
+ if (data_vertex3f)
+ Mem_Free(&data_vertex3f);
+ if (data_normal3f)
+ Mem_Free(&data_normal3f);
+ if (data_texcoord2f)
+ Mem_Free(&data_texcoord2f);
+}
+
/* example clips of an MD5 model
MD5Version 10
commandline ""
@@ -578,7 +1148,8 @@
VectorCopy(md5weights[md5weightrange[i*2+0]].vertex, mesh->data_vertex3f + i*3);
}
// compile the base frame of the mesh for static uses
- Model_MeshVectors(mesh->num_triangles, mesh->data_element3i, mesh->num_vertices, mesh->data_vertex3f, mesh->data_texcoord2f, mesh->data_svector3f, mesh->data_tvector3f, mesh->data_normal3f);
+ Model_MeshNormals(mesh->num_triangles, mesh->data_element3i, mesh->num_vertices, mesh->data_vertex3f, mesh->data_texcoord2f, mesh->data_normal3f);
+ Model_MeshTangents(mesh->num_triangles, mesh->data_element3i, mesh->num_vertices, mesh->data_vertex3f, mesh->data_texcoord2f, mesh->data_normal3f, mesh->data_svector3f, mesh->data_tvector3f);
Model_MeshNeighbors(mesh->num_triangles, mesh->data_element3i, mesh->data_neighbor3i, mesh->num_vertices);
Model_BuildTrianglePlanes(mesh->data_vertex3f, mesh->num_triangles, mesh->data_element3i, mesh->data_plane4f);
// collision brushes are for the static frame
Modified: trunk/model.h
===================================================================
--- trunk/model.h 2006-05-09 20:05:18 UTC (rev 713)
+++ trunk/model.h 2006-05-12 08:36:47 UTC (rev 714)
@@ -80,6 +80,11 @@
typedef struct Model
{
+ // set at the creation of the Model
+ Mem_Zone *memzone;
+
+ Nbool isskeletal;
+
NUint32 num_meshes;
NUint32 max_meshes;
Model_Mesh *data_meshes;
@@ -97,6 +102,18 @@
void Model_Load(ResourceEntry *r);
void Model_Unload(ResourceEntry *r);
+void Model_Build_Begin(Model *b, Mem_Zone *memzone, Nbool isskeletal);
+void Model_Build_Compile(Model *b, Nbool generateneighbors, Nbool generateplanes, Nbool generatenormals, Nbool generatetangents, Nbool generatelightmaptexcoords, Nbool generatecollisionbrushes);
+void Model_Build_Free(Model *b);
+NUint32 Model_Build_AddSurface(Model *b, Mem_Zone *zone, const char *materialname, NUint32 initialtriangles, NUint32 initialvertices);
+NUint32 Model_Build_AddVertex(Model *b, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t);
+NUint32 Model_Build_AddVertexSkeletal(Model *b, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t, NUint8 *wib, NUint8 *wfb);
+NUint32 Model_Build_FindOrAddVertex(Model *b, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t);
+NUint32 Model_Build_FindOrAddVertexSkeletal(Model *b, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t, NUint8 *wib, NUint8 *wfb);
+NUint32 Model_Build_AddTriangle(Model *b, NUint32 meshindex, int e0, int e1, int e2);
+void Model_Build_Write(Model *b, const char *filename);
+void Model_Build_ImportOBJ(Model *b, const char *inputname, const char *text, const char *textend);
+
// this function decodes skeletal vertex information to your supplied arrays
// NOTE: outplane4f requires outvertex3f
void Model_GetVertices(NUint32 resourceindex, NUint32 meshindex, const matrix4x4_t *transforms, float *outvertex3f, float *outsvector3f, float *outtvector3f, float *outnormal3f, float *outplane4f);
Modified: trunk/util.c
===================================================================
--- trunk/util.c 2006-05-09 20:05:18 UTC (rev 713)
+++ trunk/util.c 2006-05-12 08:36:47 UTC (rev 714)
@@ -2,6 +2,7 @@
#include "ncommon.h"
#include "util.h"
#include "texture.h"
+#include "model.h"
static Shell_SymbolDecl Util_Shell_MakeSkyBox_Decl;
static Shell_SymbolDecl Util_Shell_MakeTerrain_Decl;
@@ -240,337 +241,6 @@
#undef ReadNext
}
-void Util_BuildModel_Begin(Util_BuildModel *b)
-{
- memset(b, 0, sizeof(*b));
-}
-
-void Util_BuildModel_End(Util_BuildModel *b)
-{
- NUint32 i;
- Util_BuildModel_Surface *surface;
- for (i = 0, surface = b->data_surfaces;i < b->num_surfaces;i++, surface++)
- {
- Mem_Free(&surface->data_element3i);
- Mem_Free(&surface->data_vertex8f);
- }
- Mem_Free(&b->data_surfaces);
- memset(b, 0, sizeof(*b));
-}
-
-NUint32 Util_BuildModel_AddSurface(Util_BuildModel *b, const char *materialname)
-{
- Util_BuildModel_Surface *surface;
- if (b->num_surfaces >= b->max_surfaces)
- {
- b->max_surfaces = Max(b->max_surfaces * 2, 16);
- Mem_ReAlloc(Global_Zone, &b->data_surfaces, b->max_surfaces * sizeof(Util_BuildModel_Surface));
- }
- surface = b->data_surfaces + b->num_surfaces;
- strncpy(surface->materialname, materialname, sizeof(surface->materialname) - 1);
- b->num_surfaces++;
- return b->num_surfaces - 1;
-}
-
-NUint32 Util_BuildModel_AddVertex(Util_BuildModel *b, NUint32 surfaceindex, float x, float y, float z, float nx, float ny, float nz, float s, float t)
-{
- float *v;
- Util_BuildModel_Surface *surface = b->data_surfaces + surfaceindex;
- if (surface->num_vertices >= surface->max_vertices)
- {
- surface->max_vertices = Max(surface->max_vertices * 2, 1024);
- Mem_ReAlloc(Global_Zone, &surface->data_vertex8f, surface->max_vertices * sizeof(float[8]));
- }
- v = surface->data_vertex8f + surface->num_vertices * 8;
- v[0] = x;
- v[1] = y;
- v[2] = z;
- v[3] = nx;
- v[4] = ny;
- v[5] = nz;
- v[6] = s;
- v[7] = t;
- surface->num_vertices++;
- return surface->num_vertices - 1;
-}
-
-NUint32 Util_BuildModel_FindOrAddVertex(Util_BuildModel *b, NUint32 surfaceindex, float x, float y, float z, float nx, float ny, float nz, float s, float t)
-{
- NUint32 i;
- float *v;
- Util_BuildModel_Surface *surface = b->data_surfaces + surfaceindex;
- for (i = 0, v = surface->data_vertex8f;i < surface->num_vertices;i++, v += 8)
- if (fabs(v[0] - x) < 0.0001 && fabs(v[1] - y) < 0.0001 && fabs(v[2] - z) < 0.0001 && fabs(v[3] - nx) < 0.0001 && fabs(v[4] - ny) < 0.0001 && fabs(v[5] - nz) < 0.0001 && fabs(v[6] - s) < 0.0001 && fabs(v[7] - t) < 0.0001)
- return i;
- return Util_BuildModel_AddVertex(b, surfaceindex, x, y, z, nx, ny, nz, s, t);
-}
-
-NUint32 Util_BuildModel_AddTriangle(Util_BuildModel *b, NUint32 surfaceindex, int e0, int e1, int e2)
-{
- Util_BuildModel_Surface *surface = b->data_surfaces + surfaceindex;
- NUint32 *e;
- if (surface->num_triangles >= surface->max_triangles)
- {
- surface->max_triangles = Max(surface->max_triangles * 2, 1024);
- Mem_ReAlloc(Global_Zone, &surface->data_element3i, surface->max_triangles * sizeof(NUint32[3]));
- }
- e = surface->data_element3i + surface->num_triangles * 3;
- e[0] = e0;
- e[1] = e1;
- e[2] = e2;
- surface->num_triangles++;
- return surface->num_triangles - 1;
-}
-
-void Util_BuildModel_Write(Util_BuildModel *b, const char *filename)
-{
- // FIXME: this is very unlikely to overflow but it should be made buffer size safe at some point
- NUint32 i, num;
- Nsize textsize, textmaxsize;
- char *text;
- Util_BuildModel_Surface *surface;
- textmaxsize = 0x100000;
- for (i = 0, surface = b->data_surfaces;i < b->num_surfaces;i++, surface++)
- textmaxsize += surface->num_vertices * 60 + surface->num_triangles * 40;
- textsize = 0;
- text = Mem_Alloc(Global_Zone, textmaxsize);
- textsize += snprintf(text + textsize, textmaxsize - textsize, "MD5Version 10\ncommandline \"\"\n\nnumJoints 1\nnumMeshes %u\n\njoints {\n\t\"ROOT\"\t-1 ( 0.000000 0.000000 0.000000 ) ( 0.000000 0.000000 0.000000 ) // \n}\n", b->num_surfaces);
- for (i = 0, surface = b->data_surfaces;i < b->num_surfaces;i++, surface++)
- {
- if (textmaxsize < textsize + surface->num_vertices * 100 + surface->num_triangles * 100 + surface->num_vertices * 100 + 1000)
- {
- textmaxsize = textsize + surface->num_vertices * 200 + surface->num_triangles * 200 + surface->num_vertices * 200 + 2000;
- Mem_ReAlloc(Global_Zone, &text, textmaxsize);
- }
- textsize += snprintf(text + textsize, textmaxsize - textsize, "\nmesh {\n\tshader \"%s\"\n\n\tnumverts %u\n", surface->materialname, surface->num_vertices);
- for (num = 0;num < surface->num_vertices;num++)
- textsize += snprintf(text + textsize, textmaxsize - textsize, "\tvert %u ( %.6f %.6f ) %u 1\n", num, surface->data_vertex8f[num*8+6], surface->data_vertex8f[num*8+7], num);
- textsize += snprintf(text + textsize, textmaxsize - textsize, "\n\tnumtris %u\n", surface->num_triangles);
- for (num = 0;num < surface->num_triangles;num++)
- textsize += snprintf(text + textsize, textmaxsize - textsize, "\ttri %u %u %u %u\n", num, surface->data_element3i[num*3+0], surface->data_element3i[num*3+1], surface->data_element3i[num*3+2]);
- textsize += snprintf(text + textsize, textmaxsize - textsize, "\n\tnumweights %u\n", surface->num_vertices);
- for (num = 0;num < surface->num_vertices;num++)
- textsize += snprintf(text + textsize, textmaxsize - textsize, "\tweight %u 0 1.000000 ( %.6f %.6f %.6f )\n", num, surface->data_vertex8f[num*8+0], surface->data_vertex8f[num*8+1], surface->data_vertex8f[num*8+2]);
- textsize += snprintf(text + textsize, textmaxsize - textsize, "}\n");
- }
- File_WriteFile(filename, text, textsize);
- Mem_Free(&text);
-}
-
-void Util_BuildModel_ImportOBJ(Util_BuildModel *b, const char *inputname, const char *text, const char *textend)
-{
- NUint32 linenumber = 0;
- NSint32 surfaceindex = -1;
- NUint32 num_vertices = 0, max_vertices = 0;
- NUint32 num_normals = 0, max_normals = 0;
- NUint32 num_texcoords = 0, max_texcoords = 0;
- float *data_vertex3f = NULL;
- float *data_normal3f = NULL;
- float *data_texcoord2f = NULL;
- while (text < textend)
- {
- Nbool comment = false;
- NUint32 argc = 0;
- char argv[64][256];
- // parse the line
- linenumber++;
- while (text < textend && *text != '\r' && *text != '\n')
- {
- if (comment || *text <= ' ')
- text++;
- else if (*text == '#')
- comment = true;
- else
- {
- NUint32 charnum;
- for (charnum = 0;text < textend && *text > ' ';text++)
- if (charnum < sizeof(argv[0]) - 1)
- argv[argc][charnum++] = *text;
- argv[argc++][charnum] = 0;
- }
- }
- if (*text == '\r' && text[1] == '\n')
- text++;
- if (*text == '\n')
- text++;
- // now we have a command
- if (argc < 1)
- continue;
- if (!String_Compare(argv[0], "v"))
- {
- // v -4.99960e-2 0.250000 -1.00000
- if (argc == 4)
- {
- if (num_vertices >= max_vertices)
- {
- max_vertices = Max(max_vertices * 2, 1024);
- Mem_ReAlloc(Global_Zone, &data_vertex3f, max_vertices * sizeof(float[3]));
- }
- data_vertex3f[num_vertices*3+0] = atof(argv[1]);
- data_vertex3f[num_vertices*3+2] = atof(argv[2]);
- data_vertex3f[num_vertices*3+1] = atof(argv[3]);
- num_vertices++;
- }
- else
- Console_Printf("util_convertobj: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 3);
- }
- else if (!String_Compare(argv[0], "vn"))
- {
- // vn 1.99019e-6 2.65359e-5 -1.000000
- if (argc == 4)
- {
- if (num_normals >= max_normals)
- {
- max_normals = Max(max_normals * 2, 1024);
- Mem_ReAlloc(Global_Zone, &data_normal3f, max_normals * sizeof(float[3]));
- }
- data_normal3f[num_normals*3+0] = atof(argv[1]);
- data_normal3f[num_normals*3+2] = atof(argv[2]);
- data_normal3f[num_normals*3+1] = atof(argv[3]);
- num_normals++;
- }
- else
- Console_Printf("util_convertobj: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 3);
- }
- else if (!String_Compare(argv[0], "vt"))
- {
- // vt 0.00000e+0 1.99019e-6
- if (argc == 3)
- {
- if (num_texcoords >= max_texcoords)
- {
- max_texcoords = Max(max_texcoords * 2, 1024);
- Mem_ReAlloc(Global_Zone, &data_texcoord2f, max_texcoords * sizeof(float[2]));
- }
- data_texcoord2f[num_texcoords*2+0] = atof(argv[1]);
- data_texcoord2f[num_texcoords*2+1] = -atof(argv[2]);
- num_texcoords++;
- }
- else
- Console_Printf("util_convertobj: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 2);
- }
- else if (!String_Compare(argv[0], "usemtl"))
- {
- // usemtl mtrl/chrome
- if (argc == 2)
- surfaceindex = Util_BuildModel_AddSurface(b, argv[1]);
- else
- Console_Printf("util_convertobj: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 1);
- }
- else if (!String_Compare(argv[0], "f"))
- {
- // f 1/11/5 18/56/71 17/58/67
- NUint32 i;
- NUint32 indices[64];
- if (argc >= 4)
- {
- if (surfaceindex == -1)
- surfaceindex = Util_BuildModel_AddSurface(b, "default");
- for (i = 0;i < argc - 1;i++)
- {
- NUint32 j;
- const char *s = argv[i+1];
- float v[3];
- float vn[3];
- float tc[2];
- // if there are 3 indices, they are vertex, texcoord, normal
- // if there are 2 indices, they are vertex, texcoord
- // if there is only one index, it is vertex
- // so we just initialize the values to defaults,
- // and update them as indices are read
- VectorClear(v);
- VectorClear(vn);
- Vector2Clear(tc);
- for (j = 0;j < 3;j++)
- {
- if (*s)
- {
- NSint32 k = atoi(s);
- switch (j)
- {
- case 0:
- if (k < 0)
- k += num_vertices;
- else
- k--;
- if (k >= 0 && k < num_vertices)
- VectorCopy(data_vertex3f + k * 3, v);
- else
- Console_Printf("util_convertobj: %s:%i: invalid face vertex index (parameter #%i)\n", inputname, linenumber, i + 1);
- break;
- case 1:
- if (k < 0)
- k += num_texcoords;
- else
- k--;
- if (k >= 0 && k < num_texcoords)
- Vector2Copy(data_texcoord2f + k * 2, tc);
- else
- Console_Printf("util_convertobj: %s:%i: invalid face texcoord index (parameter #%i)\n", inputname, linenumber, i + 1);
- break;
- case 2:
- if (k < 0)
- k += num_normals;
- else
- k--;
- if (k >= 0 && k < num_normals)
- VectorCopy(data_normal3f + k * 3, vn);
- else
- Console_Printf("util_convertobj: %s:%i: invalid face vertexnormal index (parameter #%i)\n", inputname, linenumber, i + 1);
- break;
- }
- }
- // this weird code construct exits at NUL, or if the
- // character is /, and then leaves s at the character
- // after the NUL or /
- while (*s)
- {
- if (*s == '/')
- {
- s++;
- break;
- }
- s++;
- }
- }
- indices[i] = Util_BuildModel_FindOrAddVertex(b, surfaceindex, v[0], v[1], v[2], vn[0], vn[1], vn[2], tc[0], tc[1]);
- // make a triangle fan if we have enough vertices
- if (i >= 2)
- Util_BuildModel_AddTriangle(b, surfaceindex, indices[0], indices[i-1], indices[i]);
- }
- }
- else
- Console_Printf("util_convertobj: %s:%i: command %s takes %i or more parameters\n", inputname, linenumber, argv[0], 3);
- }
- else if (!String_Compare(argv[0], "o"))
- {
- // o cylinder1
- if (argc != 2)
- Console_Printf("util_convertobj: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 1);
- }
- else if (!String_Compare(argv[0], "mtllib"))
- {
- // mtllib zrail2.mtl
- if (argc != 2)
- Console_Printf("util_convertobj: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 1);
- }
- else if (!String_Compare(argv[0], "g"))
- {
- // g cylinder1_mtrl/invisible
- if (argc != 2)
- Console_Printf("util_convertobj: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 1);
- }
- else
- Console_Printf("util_convertobj: %s:%i: unknown obj command %s\n", inputname, linenumber, argv[0]);
- }
- if (data_vertex3f)
- Mem_Free(&data_vertex3f);
- if (data_normal3f)
- Mem_Free(&data_normal3f);
- if (data_texcoord2f)
- Mem_Free(&data_texcoord2f);
-}
-
static void Util_Shell_MakeTerrain(void)
{
NUint32 tilesize, width, height, bx, by, tx, ty, tilewidth, tileheight, num, tileswidth, tilesheight;
@@ -578,7 +248,7 @@
const char *basename, *imagename, *materialname;
char *tilename;
Nvec terrainsize[3], texturesize[2], terrainscale[3], terrainorigin[3], texturescale[2];
- Util_BuildModel b;
+ Model b;
basename = Shell_Callback_GetArg(1);
imagename = Shell_Callback_GetArg(2);
tilesize = (int) Shell_Callback_GetArgValue(3);
@@ -610,12 +280,12 @@
terrainorigin[2] = terrainsize[2] * -0.5;
tileswidth = width / tilesize;
tilesheight = height / tilesize;
- Util_BuildModel_Begin(&b);
+ Model_Build_Begin(&b, Global_Zone, false);
for (by = 0;by < height;by += tilesize)
{
for (bx = 0;bx < width;bx += tilesize)
{
- NUint32 surfaceindex = Util_BuildModel_AddSurface(&b, materialname);
+ NUint32 meshindex = Model_Build_AddSurface(&b, Global_Zone, materialname, 0, 0);
tilewidth = Bound(0, width - bx, tilesize+2);
tileheight = Bound(0, height - by, tilesize+2);
for (ty = 0, num = 0;ty < tileheight;ty++)
@@ -634,8 +304,8 @@
pyf = py - pyi;
p = pixels + (pyi * width + pxi) * 4;
pz = ((p[0]+p[1]+p[2])*(1.0-pxf)+(p[4]+p[5]+p[6])*(pxf))*(1.0-pyf)+((p[w+0]+p[w+1]+p[w+2])*(1.0-pxf)+(p[w+4]+p[w+5]+p[w+6])*(pxf))*(pyf);
- // FIXME: this SHOULD calculate a valid surface normal!!
- Util_BuildModel_AddVertex(&b, surfaceindex, px * terrainscale[0] + terrainorigin[0], py * terrainscale[1] + terrainorigin[1], pz * terrainscale[2] + terrainorigin[2], 0, 0, 1, (px * terrainscale[0] + terrainorigin[0]) * texturescale[0], (py * terrainscale[1] + terrainorigin[1]) * texturescale[1]);
+ // FIXME: this SHOULD calculate a valid mesh normal!!
+ Model_Build_AddVertex(&b, meshindex, px * terrainscale[0] + terrainorigin[0], py * terrainscale[1] + terrainorigin[1], pz * terrainscale[2] + terrainorigin[2], 0, 0, 1, (px * terrainscale[0] + terrainorigin[0]) * texturescale[0], (py * terrainscale[1] + terrainorigin[1]) * texturescale[1]);
}
}
for (ty = 0, num = 0;ty < tileheight-1;ty++)
@@ -643,17 +313,17 @@
for (tx = 0;tx < tilewidth-1;tx++, num += 6)
{
NUint32 i = ty*tilewidth+tx;
- Util_BuildModel_AddTriangle(&b, surfaceindex, i, i+1, i+1+tilewidth);
- Util_BuildModel_AddTriangle(&b, surfaceindex, i, i+1+tilewidth, i+tilewidth);
+ Model_Build_AddTriangle(&b, meshindex, i, i+1, i+1+tilewidth);
+ Model_Build_AddTriangle(&b, meshindex, i, i+1+tilewidth, i+tilewidth);
}
}
}
}
Mem_Free(&pixels);
tilename = String_APrintf(Global_Zone, "%s.md5mesh", basename);
- Util_BuildModel_Write(&b, tilename);
+ Model_Build_Write(&b, tilename);
String_Free(&tilename);
- Util_BuildModel_End(&b);
+ Model_Build_Free(&b);
}
static Shell_SymbolDecl Util_Shell_MakeTerrain_Decl = {
@@ -669,7 +339,7 @@
static void Util_Shell_ConvertOBJ(void)
{
Nsize objtextsize;
- Util_BuildModel b;
+ Model b;
const char *inputname = Shell_Callback_GetArg(1);
const char *outputname = Shell_Callback_GetArg(2);
char *objtext = File_LoadFile(inputname, &objtextsize);
@@ -679,10 +349,10 @@
// SHELLTODO
return;
}
- Util_BuildModel_Begin(&b);
- Util_BuildModel_ImportOBJ(&b, inputname, objtext, objtext + objtextsize);
- Util_BuildModel_Write(&b, outputname);
- Util_BuildModel_End(&b);
+ Model_Build_Begin(&b, Global_Zone, false);
+ Model_Build_ImportOBJ(&b, inputname, objtext, objtext + objtextsize);
+ Model_Build_Write(&b, outputname);
+ Model_Build_Free(&b);
Mem_Free(&objtext);
}
@@ -702,7 +372,7 @@
#define UTIL_SHELL_CONVERTLWO_FACE_MAXVERTS 4
typedef struct Util_Shell_ConvertLWO_Face
{
- NUint32 surfaceindex;
+ NUint32 meshindex;
NUint32 numpoints;
float point[UTIL_SHELL_CONVERTLWO_FACE_MAXVERTS][3];
}
@@ -823,7 +493,7 @@
// polygon attributes
if (!memcmp(chunk, "SURF", 4))
{
- // list of polygons and their corresponding surfaces
+ // list of polygons and their corresponding meshes
chunk_ptag_surf = chunk;
}
continue;
@@ -846,7 +516,7 @@
if (!memcmp(chunk, "SURF", 4))
{
materialindex++;
- // surface name, often Default
+ // mesh name, often Default
while (*content)
content++;
// skip to 4 byte boundary in file
@@ -965,27 +635,27 @@
double boxsize;
const char *basefilename, *baseimagename;
char *filename;
- Util_BuildModel b;
+ Model b;
basefilename = Shell_Callback_GetArg(1);
baseimagename = Shell_Callback_GetArg(2);
boxsize = atof(Shell_Callback_GetArg(3));
- Util_BuildModel_Begin(&b);
+ Model_Build_Begin(&b, 0, 0);
for (i = 0;i < 6;i++)
{
NUint32 j;
NUint32 indices[4];
char *materialname = String_APrintf(Global_Zone, "%s_%s", baseimagename, skyboxsuffix[i]);
- NUint32 surfaceindex = Util_BuildModel_AddSurface(&b, materialname);
+ NUint32 meshindex = Model_Build_AddSurface(&b, Global_Zone, materialname, 2, 4);
String_Free(&materialname);
for (j = 0;j < 4;j++)
- indices[j] = Util_BuildModel_FindOrAddVertex(&b, surfaceindex, skyboxvertex[i][j][0], skyboxvertex[i][j][1], skyboxvertex[i][j][2], skyboxvertex[i][j][3], skyboxvertex[i][j][4], skyboxvertex[i][j][5], skyboxvertex[i][j][6], skyboxvertex[i][j][7]);
- Util_BuildModel_AddTriangle(&b, surfaceindex, indices[0], indices[2], indices[1]);
- Util_BuildModel_AddTriangle(&b, surfaceindex, indices[0], indices[3], indices[2]);
+ indices[j] = Model_Build_FindOrAddVertex(&b, meshindex, skyboxvertex[i][j][0], skyboxvertex[i][j][1], skyboxvertex[i][j][2], skyboxvertex[i][j][3], skyboxvertex[i][j][4], skyboxvertex[i][j][5], skyboxvertex[i][j][6], skyboxvertex[i][j][7]);
+ Model_Build_AddTriangle(&b, meshindex, indices[0], indices[2], indices[1]);
+ Model_Build_AddTriangle(&b, meshindex, indices[0], indices[3], indices[2]);
}
filename = String_APrintf(Global_Zone, "%s.md5mesh", basefilename);
- Util_BuildModel_Write(&b, filename);
+ Model_Build_Write(&b, filename);
String_Free(&filename);
- Util_BuildModel_End(&b);
+ Model_Build_Free(&b);
}
static Shell_SymbolDecl Util_Shell_MakeSkyBox_Decl = {
Modified: trunk/util.h
===================================================================
--- trunk/util.h 2006-05-09 20:05:18 UTC (rev 713)
+++ trunk/util.h 2006-05-12 08:36:47 UTC (rev 714)
@@ -40,35 +40,6 @@
// lex the next token
void Util_ParseC_Lex(Util_ParseC_Thread *thread);
-typedef struct Util_BuildModel_Surface
-{
- // no support for skeletal weighting since this is only used by utilities building simple models
- char materialname[64];
- NUint32 num_triangles, max_triangles;
- NUint32 *data_element3i;
- NUint32 num_vertices, max_vertices;
- float *data_vertex8f;
-}
-Util_BuildModel_Surface;
-
-typedef struct Util_BuildModel
-{
- NUint32 num_surfaces, max_surfaces;
- Util_BuildModel_Surface *data_surfaces;
- // no support for skeleton since this is only used by utilities building simple models
-}
-Util_BuildModel;
-
-// a small system for easily building md5mesh files
-void Util_BuildModel_Begin(Util_BuildModel *b);
-void Util_BuildModel_End(Util_BuildModel *b);
-NUint32 Util_BuildModel_AddSurface(Util_BuildModel *b, const char *materialname);
-NUint32 Util_BuildModel_AddVertex(Util_BuildModel *b, NUint32 surfaceindex, float x, float y, float z, float nx, float ny, float nz, float s, float t);
-NUint32 Util_BuildModel_FindOrAddVertex(Util_BuildModel *b, NUint32 surfaceindex, float x, float y, float z, float nx, float ny, float nz, float s, float t);
-NUint32 Util_BuildModel_AddTriangle(Util_BuildModel *b, NUint32 surfaceindex, int e0, int e1, int e2);
-void Util_BuildModel_Write(Util_BuildModel *b, const char *filename);
-void Util_BuildModel_ImportOBJ(Util_BuildModel *b, const char *inputname, const char *text, const char *textend);
-
void Util_Init(void);
void Util_Quit(void);
From lordhavoc at icculus.org Fri May 12 07:03:18 2006
From: lordhavoc at icculus.org (lordhavoc at icculus.org)
Date: 12 May 2006 07:03:18 -0400
Subject: r715 - trunk
Message-ID: <20060512110318.31208.qmail@icculus.org>
Author: lordhavoc
Date: 2006-05-12 07:03:18 -0400 (Fri, 12 May 2006)
New Revision: 715
Modified:
trunk/console.c
Log:
avoid an assertion failure when cursoring up/down if command history is empty
Modified: trunk/console.c
===================================================================
--- trunk/console.c 2006-05-12 08:36:47 UTC (rev 714)
+++ trunk/console.c 2006-05-12 11:03:18 UTC (rev 715)
@@ -156,7 +156,7 @@
(Shell_Symbol_Callback) Console_Toggle
};
-static void Console_Shell_Echo(void)
+static void Console_Shell_Echo(void)
{
NUint i;
Console_Printf( "%s", Shell_Callback_GetArg( 1 ) );
@@ -174,7 +174,7 @@
(Shell_Symbol_Callback) Console_Shell_Echo
};
-static void Console_Shell_Print(void)
+static void Console_Shell_Print(void)
{
NUint i;
Console_Printf( "%s", Shell_Callback_GetArg( 1 ) );
@@ -493,6 +493,8 @@
void Console_Cursor_Up(void)
{
+ if (!Console.numcommandhistorymessages)
+ return;
if (Console.commandindex == 0)
return;
Console.commandindex--;
@@ -502,6 +504,8 @@
void Console_Cursor_Down(void)
{
+ if (!Console.numcommandhistorymessages)
+ return;
if (Console.commandindex < Console.numcommandhistorymessages - 1) {
Console.commandindex++;
String_Set(&Console.command, Console.zone, Console_GetCommandHistoryLine(Console.commandindex));
From lordhavoc at icculus.org Fri May 12 07:04:49 2006
From: lordhavoc at icculus.org (lordhavoc at icculus.org)
Date: 12 May 2006 07:04:49 -0400
Subject: r716 - in trunk: . base/maps
Message-ID: <20060512110449.31288.qmail@icculus.org>
Author: lordhavoc
Date: 2006-05-12 07:04:48 -0400 (Fri, 12 May 2006)
New Revision: 716
Modified:
trunk/base/maps/test.ent
trunk/model.c
trunk/model.h
trunk/nstring.c
trunk/nstring.h
trunk/util.c
Log:
reworked model system to use Import functions for loading each model
format and also Write now identifies file extension, this means that
util_convertobj has become util_convertmodel (able to convert any
supported format to any other supported format), and obj models now work
in the game without conversion.
Modified: trunk/base/maps/test.ent
===================================================================
--- trunk/base/maps/test.ent 2006-05-12 11:03:18 UTC (rev 715)
+++ trunk/base/maps/test.ent 2006-05-12 11:04:48 UTC (rev 716)
@@ -19,7 +19,7 @@
"classname" "vehicle_tank"
}
{
- "origin" "0 -23 8"
+ "origin" "0 -35 6"
"classname" "model"
"model" "models/players/generic/player_generic.md5mesh"
}
Modified: trunk/model.c
===================================================================
--- trunk/model.c 2006-05-12 11:03:18 UTC (rev 715)
+++ trunk/model.c 2006-05-12 11:04:48 UTC (rev 716)
@@ -188,11 +188,12 @@
Mem_Free(&hashtable);
}
-void Model_Build_Begin(Model *b, Mem_Zone *memzone, Nbool isskeletal)
+void Model_Build_Begin(Model *model, const char *filename, Mem_Zone *memzone, Nbool isskeletal)
{
- memset(b, 0, sizeof(*b));
- b->memzone = memzone;
- b->isskeletal = isskeletal;
+ memset(model, 0, sizeof(*model));
+ strncpy(model->filename, filename, sizeof(model->filename) - 1);
+ model->memzone = memzone;
+ model->isskeletal = isskeletal;
}
static void Model_Build_GenerateNeighbors(Model_Mesh *mesh)
@@ -227,69 +228,85 @@
// TODO: how do do this?
}
-void Model_Build_Compile(Model *b, Nbool generateneighbors, Nbool generateplanes, Nbool generatenormals, Nbool generatetangents, Nbool generatelightmaptexcoords, Nbool generatecollisionbrushes)
+void Model_Build_Compile(Model *model, Nbool generateneighbors, Nbool generateplanes, Nbool generatenormals, Nbool generatetangents, Nbool generatelightmaptexcoords, Nbool generatecollisionbrushes)
{
- NUint32 i, j;
+ NUint32 meshindex, vertexindex, weightindex, transformindex;
const float *v;
Model_Mesh *mesh;
Nbool initbox;
initbox = true;
- VectorClear(b->basecullmins);
- VectorClear(b->basecullmaxs);
- for (i = 0, mesh = b->data_meshes;i < b->num_meshes;i++, mesh++)
+ VectorClear(model->basecullmins);
+ VectorClear(model->basecullmaxs);
+ // clear the culling radius value in each transform as it will be regenerated
+ if (model->num_transforms)
+ for (transformindex = 0;transformindex < model->num_transforms;transformindex++)
+ model->data_transforminfo[transformindex].radius = 0;
+ // process each mesh
+ for (meshindex = 0, mesh = model->data_meshes;meshindex < model->num_meshes;meshindex++, mesh++)
{
+ // load the material
+ mesh->resource_material = Resource_IndexForName(mesh->materialname, RESOURCETYPE_MATERIAL, 0, 0);
+
+ // resize triangle arrays if there is some wasted space
if (mesh->max_triangles > mesh->num_triangles)
{
mesh->max_triangles = mesh->num_triangles;
- if (mesh->data_element3i) Mem_ReAlloc(b->memzone, &mesh->data_element3i, mesh->max_triangles * 3 * sizeof(*mesh->data_element3i));
- if (mesh->data_neighbor3i) Mem_ReAlloc(b->memzone, &mesh->data_neighbor3i, mesh->max_triangles * 3 * sizeof(*mesh->data_neighbor3i));
- if (mesh->data_plane4f) Mem_ReAlloc(b->memzone, &mesh->data_plane4f, mesh->max_triangles * 4 * sizeof(*mesh->data_plane4f));
+ if (mesh->data_element3i) Mem_ReAlloc(model->memzone, &mesh->data_element3i, mesh->max_triangles * 3 * sizeof(*mesh->data_element3i));
+ if (mesh->data_neighbor3i) Mem_ReAlloc(model->memzone, &mesh->data_neighbor3i, mesh->max_triangles * 3 * sizeof(*mesh->data_neighbor3i));
+ if (mesh->data_plane4f) Mem_ReAlloc(model->memzone, &mesh->data_plane4f, mesh->max_triangles * 4 * sizeof(*mesh->data_plane4f));
}
+ // resize vertex arrays if there is some wasted space
if (mesh->max_vertices > mesh->num_vertices)
{
mesh->max_vertices = mesh->num_vertices;
- if (mesh->data_vertex3f) Mem_ReAlloc(b->memzone, &mesh->data_vertex3f, mesh->max_vertices * 3 * sizeof(*mesh->data_vertex3f));
- if (mesh->data_svector3f) Mem_ReAlloc(b->memzone, &mesh->data_svector3f, mesh->max_vertices * 3 * sizeof(*mesh->data_svector3f));
- if (mesh->data_tvector3f) Mem_ReAlloc(b->memzone, &mesh->data_tvector3f, mesh->max_vertices * 3 * sizeof(*mesh->data_tvector3f));
- if (mesh->data_normal3f) Mem_ReAlloc(b->memzone, &mesh->data_normal3f, mesh->max_vertices * 3 * sizeof(*mesh->data_normal3f));
- if (mesh->data_texcoord2f) Mem_ReAlloc(b->memzone, &mesh->data_texcoord2f, mesh->max_vertices * 2 * sizeof(*mesh->data_texcoord2f));
- if (mesh->data_lightmaptexcoord2f) Mem_ReAlloc(b->memzone, &mesh->data_lightmaptexcoord2f, mesh->max_vertices * 2 * sizeof(*mesh->data_lightmaptexcoord2f));
- if (mesh->data_weightindex4b) Mem_ReAlloc(b->memzone, &mesh->data_weightindex4b, mesh->max_vertices * 4 * sizeof(*mesh->data_weightindex4b));
- if (mesh->data_weightvalue4b) Mem_ReAlloc(b->memzone, &mesh->data_weightvalue4b, mesh->max_vertices * 4 * sizeof(*mesh->data_weightvalue4b));
+ if (mesh->data_vertex3f) Mem_ReAlloc(model->memzone, &mesh->data_vertex3f, mesh->max_vertices * 3 * sizeof(*mesh->data_vertex3f));
+ if (mesh->data_svector3f) Mem_ReAlloc(model->memzone, &mesh->data_svector3f, mesh->max_vertices * 3 * sizeof(*mesh->data_svector3f));
+ if (mesh->data_tvector3f) Mem_ReAlloc(model->memzone, &mesh->data_tvector3f, mesh->max_vertices * 3 * sizeof(*mesh->data_tvector3f));
+ if (mesh->data_normal3f) Mem_ReAlloc(model->memzone, &mesh->data_normal3f, mesh->max_vertices * 3 * sizeof(*mesh->data_normal3f));
+ if (mesh->data_texcoord2f) Mem_ReAlloc(model->memzone, &mesh->data_texcoord2f, mesh->max_vertices * 2 * sizeof(*mesh->data_texcoord2f));
+ if (mesh->data_lightmaptexcoord2f) Mem_ReAlloc(model->memzone, &mesh->data_lightmaptexcoord2f, mesh->max_vertices * 2 * sizeof(*mesh->data_lightmaptexcoord2f));
+ if (mesh->data_weightindex4b) Mem_ReAlloc(model->memzone, &mesh->data_weightindex4b, mesh->max_vertices * 4 * sizeof(*mesh->data_weightindex4b));
+ if (mesh->data_weightvalue4b) Mem_ReAlloc(model->memzone, &mesh->data_weightvalue4b, mesh->max_vertices * 4 * sizeof(*mesh->data_weightvalue4b));
}
+ // generate triangle neighbors if requested
if (generateneighbors)
{
- if (!mesh->data_neighbor3i) Mem_ReAlloc(b->memzone, &mesh->data_neighbor3i, mesh->max_triangles * 3 * sizeof(*mesh->data_neighbor3i));
+ if (!mesh->data_neighbor3i) Mem_ReAlloc(model->memzone, &mesh->data_neighbor3i, mesh->max_triangles * 3 * sizeof(*mesh->data_neighbor3i));
Model_Build_GenerateNeighbors(mesh);
}
+ // generate triangle planes if requested
if (generateplanes)
{
- if (!mesh->data_plane4f) Mem_ReAlloc(b->memzone, &mesh->data_plane4f, mesh->max_triangles * 4 * sizeof(*mesh->data_plane4f));
+ if (!mesh->data_plane4f) Mem_ReAlloc(model->memzone, &mesh->data_plane4f, mesh->max_triangles * 4 * sizeof(*mesh->data_plane4f));
Model_Build_GeneratePlanes(mesh);
}
+ // generate vertex normals if requested
if (generatenormals)
{
- if (!mesh->data_normal3f) Mem_ReAlloc(b->memzone, &mesh->data_normal3f, mesh->max_vertices * 3 * sizeof(*mesh->data_normal3f));
+ if (!mesh->data_normal3f) Mem_ReAlloc(model->memzone, &mesh->data_normal3f, mesh->max_vertices * 3 * sizeof(*mesh->data_normal3f));
Model_Build_GenerateNormals(mesh);
}
+ // generate vertex tangent vectors if requested
if (generatetangents)
{
- if (!mesh->data_svector3f) Mem_ReAlloc(b->memzone, &mesh->data_svector3f, mesh->max_vertices * 3 * sizeof(*mesh->data_svector3f));
- if (!mesh->data_tvector3f) Mem_ReAlloc(b->memzone, &mesh->data_tvector3f, mesh->max_vertices * 3 * sizeof(*mesh->data_tvector3f));
+ if (!mesh->data_svector3f) Mem_ReAlloc(model->memzone, &mesh->data_svector3f, mesh->max_vertices * 3 * sizeof(*mesh->data_svector3f));
+ if (!mesh->data_tvector3f) Mem_ReAlloc(model->memzone, &mesh->data_tvector3f, mesh->max_vertices * 3 * sizeof(*mesh->data_tvector3f));
Model_Build_GenerateTangents(mesh);
}
+ // generate lightmap texcoords if requested
if (generatelightmaptexcoords)
{
- if (!mesh->data_lightmaptexcoord2f) Mem_ReAlloc(b->memzone, &mesh->data_lightmaptexcoord2f, mesh->max_vertices * 2 * sizeof(*mesh->data_lightmaptexcoord2f));
+ if (!mesh->data_lightmaptexcoord2f) Mem_ReAlloc(model->memzone, &mesh->data_lightmaptexcoord2f, mesh->max_vertices * 2 * sizeof(*mesh->data_lightmaptexcoord2f));
Model_Build_GenerateLightmapTexCoords(mesh);
}
+ // free old triangle collision brushes
if (mesh->data_collisionbrushes)
{
Collision_Brush_FreeBrushesForTriangleMesh(mesh->data_collisionbrushes, mesh->max_collisionbrushes);
@@ -297,40 +314,63 @@
mesh->max_collisionbrushes = 0;
mesh->data_collisionbrushes = NULL;
}
+ // generate triangle collision brushes if requested
if (generatecollisionbrushes)
{
mesh->num_collisionbrushes = mesh->num_triangles;
mesh->max_collisionbrushes = mesh->num_collisionbrushes;
- mesh->data_collisionbrushes = Collision_Brush_AllocBrushesForTriangleMesh(b->memzone, mesh->max_collisionbrushes);
+ mesh->data_collisionbrushes = Collision_Brush_AllocBrushesForTriangleMesh(model->memzone, mesh->max_collisionbrushes);
Collision_Brush_UpdateTriangleMeshBrushes(mesh->data_collisionbrushes, mesh->max_collisionbrushes, mesh->data_element3i, mesh->data_vertex3f);
}
- for (j = 0, v = mesh->data_vertex3f;j < mesh->num_vertices;j++, v += 3)
+ // compute culling box for this mesh and update model box
+ // also compute culling spheres for transforms
+ VectorCopy(mesh->data_vertex3f, mesh->basecullmins);
+ VectorCopy(mesh->data_vertex3f, mesh->basecullmaxs);
+ for (vertexindex = 0, v = mesh->data_vertex3f;vertexindex < mesh->num_vertices;vertexindex++, v += 3)
{
- if (initbox)
+ mesh->basecullmins[0] = Min(mesh->basecullmins[0], v[0]);
+ mesh->basecullmins[1] = Min(mesh->basecullmins[1], v[1]);
+ mesh->basecullmins[2] = Min(mesh->basecullmins[2], v[2]);
+ mesh->basecullmaxs[0] = Max(mesh->basecullmaxs[0], v[0]);
+ mesh->basecullmaxs[1] = Max(mesh->basecullmaxs[1], v[1]);
+ mesh->basecullmaxs[2] = Max(mesh->basecullmaxs[2], v[2]);
+ if (mesh->data_weightindex4b)
{
- initbox = false;
- VectorCopy(v, b->basecullmins);
- VectorCopy(v, b->basecullmaxs);
+ for (weightindex = 0;weightindex < 4 && mesh->data_weightvalue4b[vertexindex*4+weightindex] > 0;weightindex++)
+ {
+ NUint32 index = mesh->data_weightindex4b[vertexindex*4+weightindex];
+ Nvec3 v1, v;
+ Nvec r;
+ VectorCopy(mesh->data_vertex3f + vertexindex * 3, v1);
+ Matrix4x4_Transform(&model->data_transforminfo[index].baseinversematrix, v1, v);
+ r = VectorLength(v);
+ model->data_transforminfo[index].radius = Max(model->data_transforminfo[index].radius, r);
+ }
}
- else
- {
- b->basecullmins[0] = Min(b->basecullmins[0], v[0]);
- b->basecullmins[1] = Min(b->basecullmins[1], v[1]);
- b->basecullmins[2] = Min(b->basecullmins[2], v[2]);
- b->basecullmaxs[0] = Max(b->basecullmaxs[0], v[0]);
- b->basecullmaxs[1] = Max(b->basecullmaxs[1], v[1]);
- b->basecullmaxs[2] = Max(b->basecullmaxs[2], v[2]);
- }
}
+ if (!meshindex)
+ {
+ VectorCopy(mesh->basecullmins, model->basecullmins);
+ VectorCopy(mesh->basecullmaxs, model->basecullmaxs);
+ }
+ else
+ {
+ model->basecullmins[0] = Min(model->basecullmins[0], mesh->basecullmins[0]);
+ model->basecullmins[1] = Min(model->basecullmins[1], mesh->basecullmins[1]);
+ model->basecullmins[2] = Min(model->basecullmins[2], mesh->basecullmins[2]);
+ model->basecullmaxs[0] = Max(model->basecullmaxs[0], mesh->basecullmaxs[0]);
+ model->basecullmaxs[1] = Max(model->basecullmaxs[1], mesh->basecullmaxs[1]);
+ model->basecullmaxs[2] = Max(model->basecullmaxs[2], mesh->basecullmaxs[2]);
+ }
}
}
-void Model_Build_Free(Model *b)
+void Model_Build_Free(Model *model)
{
NUint32 i;
Model_Mesh *mesh;
- for (i = 0, mesh = b->data_meshes;i < b->num_meshes;i++, mesh++)
+ for (i = 0, mesh = model->data_meshes;i < model->num_meshes;i++, mesh++)
{
if (mesh->materialname) String_Free(&mesh->materialname);
if (mesh->data_element3i) Mem_Free(&mesh->data_element3i);
@@ -346,41 +386,41 @@
if (mesh->data_weightvalue4b) Mem_Free(&mesh->data_weightvalue4b);
if (mesh->data_collisionbrushes) Collision_Brush_FreeBrushesForTriangleMesh(mesh->data_collisionbrushes, mesh->max_collisionbrushes);
}
- if (b->data_meshes)
- Mem_Free(&b->data_meshes);
- memset(b, 0, sizeof(*b));
+ if (model->data_meshes)
+ Mem_Free(&model->data_meshes);
+ memset(model, 0, sizeof(*model));
}
-NUint32 Model_Build_AddSurface(Model *b, Mem_Zone *zone, const char *materialname, NUint32 initialtriangles, NUint32 initialvertices)
+NUint32 Model_Build_AddSurface(Model *model, const char *materialname, NUint32 initialtriangles, NUint32 initialvertices)
{
Model_Mesh *mesh;
- if (b->num_meshes >= b->max_meshes)
+ if (model->num_meshes >= model->max_meshes)
{
- b->max_meshes = Max(b->max_meshes * 2, 16);
- Mem_ReAlloc(Global_Zone, &b->data_meshes, b->max_meshes * sizeof(*b->data_meshes));
+ model->max_meshes = Max(model->max_meshes * 2, 16);
+ Mem_ReAlloc(model->memzone, &model->data_meshes, model->max_meshes * sizeof(*model->data_meshes));
}
- mesh = b->data_meshes + b->num_meshes;
- String_Set(&mesh->materialname, zone, materialname);
+ mesh = model->data_meshes + model->num_meshes;
+ String_Set(&mesh->materialname, model->memzone, materialname);
mesh->max_triangles = initialtriangles;
mesh->max_vertices = initialvertices;
- b->num_meshes++;
- return b->num_meshes - 1;
+ model->num_meshes++;
+ return model->num_meshes - 1;
}
-NUint32 Model_Build_AddVertex(Model *b, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t)
+NUint32 Model_Build_AddVertex(Model *model, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t)
{
float *v;
- Model_Mesh *mesh = b->data_meshes + meshindex;
+ Model_Mesh *mesh = model->data_meshes + meshindex;
if (mesh->num_vertices >= mesh->max_vertices)
{
mesh->max_vertices = Max(mesh->max_vertices * 2, 1024);
- Mem_ReAlloc(b->memzone, &mesh->data_vertex3f, mesh->max_vertices * 3 * sizeof(*mesh->data_vertex3f));
- Mem_ReAlloc(b->memzone, &mesh->data_normal3f, mesh->max_vertices * 3 * sizeof(*mesh->data_normal3f));
- Mem_ReAlloc(b->memzone, &mesh->data_texcoord2f, mesh->max_vertices * 2 * sizeof(*mesh->data_texcoord2f));
- if (b->isskeletal)
+ Mem_ReAlloc(model->memzone, &mesh->data_vertex3f, mesh->max_vertices * 3 * sizeof(*mesh->data_vertex3f));
+ Mem_ReAlloc(model->memzone, &mesh->data_normal3f, mesh->max_vertices * 3 * sizeof(*mesh->data_normal3f));
+ Mem_ReAlloc(model->memzone, &mesh->data_texcoord2f, mesh->max_vertices * 2 * sizeof(*mesh->data_texcoord2f));
+ if (model->isskeletal)
{
- Mem_ReAlloc(b->memzone, &mesh->data_weightindex4b, mesh->max_vertices * 4 * sizeof(*mesh->data_weightindex4b));
- Mem_ReAlloc(b->memzone, &mesh->data_weightvalue4b, mesh->max_vertices * 4 * sizeof(*mesh->data_weightvalue4b));
+ Mem_ReAlloc(model->memzone, &mesh->data_weightindex4b, mesh->max_vertices * 4 * sizeof(*mesh->data_weightindex4b));
+ Mem_ReAlloc(model->memzone, &mesh->data_weightvalue4b, mesh->max_vertices * 4 * sizeof(*mesh->data_weightvalue4b));
}
}
v = mesh->data_vertex3f + mesh->num_vertices * 3;
@@ -394,7 +434,7 @@
v = mesh->data_texcoord2f + mesh->num_vertices * 2;
v[0] = s;
v[1] = t;
- if (b->isskeletal)
+ if (model->isskeletal)
{
NUint8 *wi = mesh->data_weightindex4b + mesh->num_vertices * 4;
NUint8 *wf = mesh->data_weightvalue4b + mesh->num_vertices * 4;
@@ -411,20 +451,20 @@
return mesh->num_vertices - 1;
}
-NUint32 Model_Build_AddVertexSkeletal(Model *b, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t, NUint8 *wib, NUint8 *wfb)
+NUint32 Model_Build_AddVertexSkeletal(Model *model, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t, NUint8 *wib, NUint8 *wfb)
{
float *v;
- Model_Mesh *mesh = b->data_meshes + meshindex;
+ Model_Mesh *mesh = model->data_meshes + meshindex;
if (mesh->num_vertices >= mesh->max_vertices)
{
mesh->max_vertices = Max(mesh->max_vertices * 2, 1024);
- Mem_ReAlloc(b->memzone, &mesh->data_vertex3f, mesh->max_vertices * 3 * sizeof(*mesh->data_vertex3f));
- Mem_ReAlloc(b->memzone, &mesh->data_normal3f, mesh->max_vertices * 3 * sizeof(*mesh->data_normal3f));
- Mem_ReAlloc(b->memzone, &mesh->data_texcoord2f, mesh->max_vertices * 2 * sizeof(*mesh->data_texcoord2f));
- if (b->isskeletal)
+ Mem_ReAlloc(model->memzone, &mesh->data_vertex3f, mesh->max_vertices * 3 * sizeof(*mesh->data_vertex3f));
+ Mem_ReAlloc(model->memzone, &mesh->data_normal3f, mesh->max_vertices * 3 * sizeof(*mesh->data_normal3f));
+ Mem_ReAlloc(model->memzone, &mesh->data_texcoord2f, mesh->max_vertices * 2 * sizeof(*mesh->data_texcoord2f));
+ if (model->isskeletal)
{
- Mem_ReAlloc(b->memzone, &mesh->data_weightindex4b, mesh->max_vertices * 4 * sizeof(*mesh->data_weightindex4b));
- Mem_ReAlloc(b->memzone, &mesh->data_weightvalue4b, mesh->max_vertices * 4 * sizeof(*mesh->data_weightvalue4b));
+ Mem_ReAlloc(model->memzone, &mesh->data_weightindex4b, mesh->max_vertices * 4 * sizeof(*mesh->data_weightindex4b));
+ Mem_ReAlloc(model->memzone, &mesh->data_weightvalue4b, mesh->max_vertices * 4 * sizeof(*mesh->data_weightvalue4b));
}
}
v = mesh->data_vertex3f + mesh->num_vertices * 3;
@@ -438,7 +478,7 @@
v = mesh->data_texcoord2f + mesh->num_vertices * 2;
v[0] = s;
v[1] = t;
- if (b->isskeletal)
+ if (model->isskeletal)
{
NUint8 *wi = mesh->data_weightindex4b + mesh->num_vertices * 4;
NUint8 *wf = mesh->data_weightvalue4b + mesh->num_vertices * 4;
@@ -449,26 +489,26 @@
return mesh->num_vertices - 1;
}
-NUint32 Model_Build_FindOrAddVertex(Model *b, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t)
+NUint32 Model_Build_FindOrAddVertex(Model *model, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t)
{
NUint32 i;
float *v, *n, *tc;
NUint8 *wi, *wf;
- Model_Mesh *mesh = b->data_meshes + meshindex;
+ Model_Mesh *mesh = model->data_meshes + meshindex;
for (i = 0, v = mesh->data_vertex3f, n = mesh->data_normal3f, tc = mesh->data_texcoord2f, wi = mesh->data_weightindex4b, wf = mesh->data_weightvalue4b;i < mesh->num_vertices;i++, v += 3, n += 3, tc += 2, wi += 4, wf += 4)
if (fabs(v[0] - x) < 0.0001 && fabs(v[1] - y) < 0.0001 && fabs(v[2] - z) < 0.0001
&& fabs(n[0] - nx) < 0.0001 && fabs(n[1] - ny) < 0.0001 && fabs(n[2] - nz) < 0.0001
&& fabs(tc[0] - s) < 0.0001 && fabs(tc[1] - t) < 0.0001)
return i;
- return Model_Build_AddVertex(b, meshindex, x, y, z, nx, ny, nz, s, t);
+ return Model_Build_AddVertex(model, meshindex, x, y, z, nx, ny, nz, s, t);
}
-NUint32 Model_Build_FindOrAddVertexSkeletal(Model *b, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t, NUint8 *wib, NUint8 *wfb)
+NUint32 Model_Build_FindOrAddVertexSkeletal(Model *model, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t, NUint8 *wib, NUint8 *wfb)
{
NUint32 i;
float *v, *n, *tc;
NUint8 *wi, *wf;
- Model_Mesh *mesh = b->data_meshes + meshindex;
+ Model_Mesh *mesh = model->data_meshes + meshindex;
for (i = 0, v = mesh->data_vertex3f, n = mesh->data_normal3f, tc = mesh->data_texcoord2f, wi = mesh->data_weightindex4b, wf = mesh->data_weightvalue4b;i < mesh->num_vertices;i++, v += 3, n += 3, tc += 2, wi += 4, wf += 4)
if (fabs(v[0] - x) < 0.0001 && fabs(v[1] - y) < 0.0001 && fabs(v[2] - z) < 0.0001
&& fabs(n[0] - nx) < 0.0001 && fabs(n[1] - ny) < 0.0001 && fabs(n[2] - nz) < 0.0001
@@ -476,17 +516,17 @@
&& wi[0] == wib[0] && wi[1] == wib[1] && wi[2] == wib[2] && wi[3] == wib[3]
&& wf[0] == wfb[0] && wf[1] == wfb[1] && wf[2] == wfb[2] && wf[3] == wfb[3])
return i;
- return Model_Build_AddVertexSkeletal(b, meshindex, x, y, z, nx, ny, nz, s, t, wib, wfb);
+ return Model_Build_AddVertexSkeletal(model, meshindex, x, y, z, nx, ny, nz, s, t, wib, wfb);
}
-NUint32 Model_Build_AddTriangle(Model *b, NUint32 meshindex, int e0, int e1, int e2)
+NUint32 Model_Build_AddTriangle(Model *model, NUint32 meshindex, int e0, int e1, int e2)
{
- Model_Mesh *mesh = b->data_meshes + meshindex;
+ Model_Mesh *mesh = model->data_meshes + meshindex;
NUint32 *e;
if (mesh->num_triangles >= mesh->max_triangles)
{
mesh->max_triangles = Max(mesh->max_triangles * 2, 1024);
- Mem_ReAlloc(b->memzone, &mesh->data_element3i, mesh->max_triangles * 3 * sizeof(*mesh->data_element3i));
+ Mem_ReAlloc(model->memzone, &mesh->data_element3i, mesh->max_triangles * 3 * sizeof(*mesh->data_element3i));
}
e = mesh->data_element3i + mesh->num_triangles * 3;
e[0] = e0;
@@ -496,7 +536,7 @@
return mesh->num_triangles - 1;
}
-void Model_Build_Write(Model *b, const char *filename)
+static void Model_Build_WriteMD5(Model *model, const char *filename)
{
// FIXME: this is very unlikely to overflow but it should be made buffer size safe at some point
NUint32 i, num;
@@ -504,12 +544,12 @@
char *text;
Model_Mesh *mesh;
textmaxsize = 0x100000;
- for (i = 0, mesh = b->data_meshes;i < b->num_meshes;i++, mesh++)
+ for (i = 0, mesh = model->data_meshes;i < model->num_meshes;i++, mesh++)
textmaxsize += mesh->num_vertices * 60 + mesh->num_triangles * 40;
textsize = 0;
text = Mem_Alloc(Global_Zone, textmaxsize);
- textsize += snprintf(text + textsize, textmaxsize - textsize, "MD5Version 10\ncommandline \"\"\n\nnumJoints 1\nnumMeshes %u\n\njoints {\n\t\"ROOT\"\t-1 ( 0.000000 0.000000 0.000000 ) ( 0.000000 0.000000 0.000000 ) // \n}\n", b->num_meshes);
- for (i = 0, mesh = b->data_meshes;i < b->num_meshes;i++, mesh++)
+ textsize += snprintf(text + textsize, textmaxsize - textsize, "MD5Version 10\ncommandline \"\"\n\nnumJoints 1\nnumMeshes %u\n\njoints {\n\t\"ROOT\"\t-1 ( 0.000000 0.000000 0.000000 ) ( 0.000000 0.000000 0.000000 ) // \n}\n", model->num_meshes);
+ for (i = 0, mesh = model->data_meshes;i < model->num_meshes;i++, mesh++)
{
if (textmaxsize < textsize + mesh->num_vertices * 100 + mesh->num_triangles * 100 + mesh->num_vertices * 100 + 1000)
{
@@ -531,8 +571,16 @@
Mem_Free(&text);
}
-void Model_Build_ImportOBJ(Model *b, const char *inputname, const char *text, const char *textend)
+void Model_Build_Write(Model *model, const char *filename)
{
+ if (String_EndsWith(filename, ".md5mesh"))
+ Model_Build_WriteMD5(model, filename);
+ else
+ Console_Printf("Model_Build_Write: %s extension not recognized\n", filename);
+}
+
+static Nbool Model_Build_Import_OBJ(Model *model, Nsize filesize, const char *filedata)
+{
NUint32 linenumber = 0;
NSint32 meshindex = -1;
NUint32 num_vertices = 0, max_vertices = 0;
@@ -541,6 +589,8 @@
float *data_vertex3f = NULL;
float *data_normal3f = NULL;
float *data_texcoord2f = NULL;
+ const char *text = filedata;
+ const char *textend = filedata + filesize;
while (text < textend)
{
Nbool comment = false;
@@ -586,7 +636,7 @@
num_vertices++;
}
else
- Console_Printf("Model_Build_ImportOBJ: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 3);
+ Console_Printf("Model_Build_Import_OBJ: %s:%i: command %s takes %i parameters\n", model->filename, linenumber, argv[0], 3);
}
else if (!String_Compare(argv[0], "vn"))
{
@@ -604,7 +654,7 @@
num_normals++;
}
else
- Console_Printf("Model_Build_ImportOBJ: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 3);
+ Console_Printf("Model_Build_Import_OBJ: %s:%i: command %s takes %i parameters\n", model->filename, linenumber, argv[0], 3);
}
else if (!String_Compare(argv[0], "vt"))
{
@@ -621,15 +671,15 @@
num_texcoords++;
}
else
- Console_Printf("Model_Build_ImportOBJ: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 2);
+ Console_Printf("Model_Build_Import_OBJ: %s:%i: command %s takes %i parameters\n", model->filename, linenumber, argv[0], 2);
}
else if (!String_Compare(argv[0], "usemtl"))
{
// usemtl mtrl/chrome
if (argc == 2)
- meshindex = Model_Build_AddSurface(b, Global_Zone, argv[1], 0, 0);
+ meshindex = Model_Build_AddSurface(model, argv[1], 0, 0);
else
- Console_Printf("Model_Build_ImportOBJ: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 1);
+ Console_Printf("Model_Build_Import_OBJ: %s:%i: command %s takes %i parameters\n", model->filename, linenumber, argv[0], 1);
}
else if (!String_Compare(argv[0], "f"))
{
@@ -639,7 +689,7 @@
if (argc >= 4)
{
if (meshindex == -1)
- meshindex = Model_Build_AddSurface(b, Global_Zone, "default", 0, 0);
+ meshindex = Model_Build_AddSurface(model, "default", 0, 0);
for (i = 0;i < argc - 1;i++)
{
NUint32 j;
@@ -670,7 +720,7 @@
if (k >= 0 && k < num_vertices)
VectorCopy(data_vertex3f + k * 3, v);
else
- Console_Printf("Model_Build_ImportOBJ: %s:%i: invalid face vertex index (parameter #%i)\n", inputname, linenumber, i + 1);
+ Console_Printf("Model_Build_Import_OBJ: %s:%i: invalid face vertex index (parameter #%i)\n", model->filename, linenumber, i + 1);
break;
case 1:
if (k < 0)
@@ -680,7 +730,7 @@
if (k >= 0 && k < num_texcoords)
Vector2Copy(data_texcoord2f + k * 2, tc);
else
- Console_Printf("Model_Build_ImportOBJ: %s:%i: invalid face texcoord index (parameter #%i)\n", inputname, linenumber, i + 1);
+ Console_Printf("Model_Build_Import_OBJ: %s:%i: invalid face texcoord index (parameter #%i)\n", model->filename, linenumber, i + 1);
break;
case 2:
if (k < 0)
@@ -690,7 +740,7 @@
if (k >= 0 && k < num_normals)
VectorCopy(data_normal3f + k * 3, vn);
else
- Console_Printf("Model_Build_ImportOBJ: %s:%i: invalid face vertexnormal index (parameter #%i)\n", inputname, linenumber, i + 1);
+ Console_Printf("Model_Build_Import_OBJ: %s:%i: invalid face vertexnormal index (parameter #%i)\n", model->filename, linenumber, i + 1);
break;
}
}
@@ -707,35 +757,35 @@
s++;
}
}
- indices[i] = Model_Build_FindOrAddVertex(b, meshindex, v[0], v[1], v[2], vn[0], vn[1], vn[2], tc[0], tc[1]);
+ indices[i] = Model_Build_FindOrAddVertex(model, meshindex, v[0], v[1], v[2], vn[0], vn[1], vn[2], tc[0], tc[1]);
// make a triangle fan if we have enough vertices
if (i >= 2)
- Model_Build_AddTriangle(b, meshindex, indices[0], indices[i-1], indices[i]);
+ Model_Build_AddTriangle(model, meshindex, indices[0], indices[i], indices[i-1]);
}
}
else
- Console_Printf("Model_Build_ImportOBJ: %s:%i: command %s takes %i or more parameters\n", inputname, linenumber, argv[0], 3);
+ Console_Printf("Model_Build_Import_OBJ: %s:%i: command %s takes %i or more parameters\n", model->filename, linenumber, argv[0], 3);
}
else if (!String_Compare(argv[0], "o"))
{
// o cylinder1
if (argc != 2)
- Console_Printf("Model_Build_ImportOBJ: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 1);
+ Console_Printf("Model_Build_Import_OBJ: %s:%i: command %s takes %i parameters\n", model->filename, linenumber, argv[0], 1);
}
else if (!String_Compare(argv[0], "mtllib"))
{
// mtllib zrail2.mtl
if (argc != 2)
- Console_Printf("Model_Build_ImportOBJ: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 1);
+ Console_Printf("Model_Build_Import_OBJ: %s:%i: command %s takes %i parameters\n", model->filename, linenumber, argv[0], 1);
}
else if (!String_Compare(argv[0], "g"))
{
// g cylinder1_mtrl/invisible
if (argc != 2)
- Console_Printf("Model_Build_ImportOBJ: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 1);
+ Console_Printf("Model_Build_Import_OBJ: %s:%i: command %s takes %i parameters\n", model->filename, linenumber, argv[0], 1);
}
else
- Console_Printf("Model_Build_ImportOBJ: %s:%i: unknown obj command %s\n", inputname, linenumber, argv[0]);
+ Console_Printf("Model_Build_Import_OBJ: %s:%i: unknown obj command %s\n", model->filename, linenumber, argv[0]);
}
if (data_vertex3f)
Mem_Free(&data_vertex3f);
@@ -743,6 +793,7 @@
Mem_Free(&data_normal3f);
if (data_texcoord2f)
Mem_Free(&data_texcoord2f);
+ return false;
}
/* example clips of an MD5 model
@@ -782,50 +833,41 @@
}
Model_MD5_Weight;
-void Model_Load(ResourceEntry *r)
+static Nbool Model_Build_Import_MD5(Model *model, Nsize filesize, const char *filedata)
{
Util_ParseC_Thread thread;
NUint32 meshnum, version, numjoints = 0;
Nbool error;
- Nsize filesize;
- Model *model;
- char *filedata;
Nbool isskeletal = false;
- model = Mem_Alloc(r->memzone, sizeof(Model));
-
- filedata = File_LoadFile(r->name, &filesize);
- if (!filedata)
- return;
-
Util_ParseC_SetUpThread(&thread, filedata, filesize);
#define Abort() { error = true; break; }
#define LoadValue(var, errstr) if (thread.type != UTIL_PARSEC_TOKENTYPE_VALUE) { \
- Console_Printf("Model_Load: Expected value " errstr "\n"); Abort(); \
+ Console_Printf("Model_Build_Import_MD5: Expected value " errstr "\n"); Abort(); \
} else \
(var) = thread.value, Util_ParseC_Lex(&thread)
#define LoadInt(var, errstr) if (thread.type != UTIL_PARSEC_TOKENTYPE_VALUE) { \
- Console_Printf("Model_Load: Expected integer " errstr "\n"); Abort(); \
+ Console_Printf("Model_Build_Import_MD5: Expected integer " errstr "\n"); Abort(); \
} else \
(var) = thread.value, Util_ParseC_Lex(&thread)
#define LoadString(var, errstr) if (thread.type != UTIL_PARSEC_TOKENTYPE_STRING) { \
- Console_Printf("Model_Load: Expected string " errstr "\n"); Abort(); \
+ Console_Printf("Model_Build_Import_MD5: Expected string " errstr "\n"); Abort(); \
} else \
- String_Set( &(var), r->memzone, thread.token), Util_ParseC_Lex(&thread)
+ String_Set( &(var), model->memzone, thread.token), Util_ParseC_Lex(&thread)
#define ExpectKeyword(str, errstr) if (!Util_ParseC_MatchName(&thread, (str))) { \
- Console_Printf("Model_Load: Expected '" str "' " errstr "\n"); Abort(); }
+ Console_Printf("Model_Build_Import_MD5: Expected '" str "' " errstr "\n"); Abort(); }
version = 0;
meshnum = 0;
error = false;
- VectorClear(model->basecullmins);
- VectorClear(model->basecullmaxs);
-
+ // FIXME: this code should probably use more of the Model_Build_ functions
+ // where possible, to allow importing additional geometry into an existing
+ // model structure
while (!error && thread.type != UTIL_PARSEC_TOKENTYPE_EOF)
{
//MD5Version 10
@@ -834,7 +876,7 @@
LoadInt(version, "after 'MD5Version'");
if (version != 10)
{
- Console_Printf("Model_Load: MD5Version %i not supported\n", version);
+ Console_Printf("Model_Build_Import_MD5: MD5Version %i not supported\n", version);
Abort();
}
}
@@ -849,7 +891,7 @@
LoadInt(numjoints, "after 'numJoints'");
if (numjoints < 1)
{
- Console_Printf("Model_Load: numJoints %i < 1\n", numjoints);
+ Console_Printf("Model_Build_Import_MD5: numJoints %i < 1\n", numjoints);
Abort();
}
if (numjoints > 1)
@@ -857,7 +899,7 @@
isskeletal = true;
model->num_transforms = numjoints;
model->max_transforms = model->num_transforms;
- model->data_transforminfo = Mem_Alloc(r->memzone, model->max_transforms * sizeof(*model->data_transforminfo));
+ model->data_transforminfo = Mem_Alloc(model->memzone, model->max_transforms * sizeof(*model->data_transforminfo));
}
}
//numMeshes 1
@@ -866,11 +908,11 @@
LoadInt(model->num_meshes, "after 'numMeshes'");
if (model->num_meshes < 1)
{
- Console_Printf("Model_Load: numMeshes %i < 1\n", model->num_meshes);
+ Console_Printf("Model_Build_Import_MD5: numMeshes %i < 1\n", model->num_meshes);
Abort();
}
model->max_meshes = model->num_meshes;
- model->data_meshes = Mem_Alloc(r->memzone, model->max_meshes * sizeof(Model_Mesh));
+ model->data_meshes = Mem_Alloc(model->memzone, model->max_meshes * sizeof(Model_Mesh));
}
//joints {
// "root" -1 ( 0.000000 0.000000 0.000000 ) ( -0.707107 -0.000000 -0.000000 ) //
@@ -902,7 +944,7 @@
if (parent >= (NSint32)jointnum)
{
String_Free(&name);
- Console_Printf("Model_Load: joint.parent (%i) >= joint (%i)\n", parent, jointnum);
+ Console_Printf("Model_Build_Import_MD5: joint.parent (%i) >= joint (%i)\n", parent, jointnum);
Abort();
}
if (isskeletal)
@@ -916,7 +958,7 @@
String_Free(&name);
if (jointnum != numjoints)
{
- Console_Printf("Model_Load: final jointnum (%i) != numJoints (%i)\n", jointnum, numjoints);
+ Console_Printf("Model_Build_Import_MD5: final jointnum (%i) != numJoints (%i)\n", jointnum, numjoints);
Abort();
}
}
@@ -933,7 +975,7 @@
ExpectKeyword("{", "after 'mesh'");
if (meshnum >= model->num_meshes)
{
- Console_Printf("Model_Load: meshnum (%i) >= nummeshes (%i)\n", meshnum, model->num_meshes);
+ Console_Printf("Model_Build_Import_MD5: meshnum (%i) >= nummeshes (%i)\n", meshnum, model->num_meshes);
Abort();
}
mesh = model->data_meshes + meshnum;
@@ -952,22 +994,22 @@
LoadInt(mesh->num_vertices, "after 'numverts'");
if (mesh->num_vertices < 3)
{
- Console_Printf("Model_Load: numverts (%i) < 3\n", mesh->num_vertices);
+ Console_Printf("Model_Build_Import_MD5: numverts (%i) < 3\n", mesh->num_vertices);
Abort();
}
mesh->max_vertices = mesh->num_vertices;
- mesh->data_vertex3f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[3]));
- mesh->data_svector3f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[3]));
- mesh->data_tvector3f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[3]));
- mesh->data_normal3f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[3]));
- mesh->data_texcoord2f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[2]));
- mesh->data_lightmaptexcoord2f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[2]));
+ mesh->data_vertex3f = Mem_Alloc(model->memzone, mesh->max_vertices * sizeof(float[3]));
+ mesh->data_svector3f = Mem_Alloc(model->memzone, mesh->max_vertices * sizeof(float[3]));
+ mesh->data_tvector3f = Mem_Alloc(model->memzone, mesh->max_vertices * sizeof(float[3]));
+ mesh->data_normal3f = Mem_Alloc(model->memzone, mesh->max_vertices * sizeof(float[3]));
+ mesh->data_texcoord2f = Mem_Alloc(model->memzone, mesh->max_vertices * sizeof(float[2]));
+ mesh->data_lightmaptexcoord2f = Mem_Alloc(model->memzone, mesh->max_vertices * sizeof(float[2]));
if (isskeletal)
{
- mesh->data_weightindex4b = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(NUint8[4]));
- mesh->data_weightvalue4b = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(NUint8[4]));
+ mesh->data_weightindex4b = Mem_Alloc(model->memzone, mesh->max_vertices * sizeof(NUint8[4]));
+ mesh->data_weightvalue4b = Mem_Alloc(model->memzone, mesh->max_vertices * sizeof(NUint8[4]));
}
- md5weightrange = Mem_Alloc(Global_Zone, mesh->max_vertices * sizeof(NUint32[2]));
+ md5weightrange = Mem_Alloc(model->memzone, mesh->max_vertices * sizeof(NUint32[2]));
}
// vert 0 ( 0.142532 0.983877 ) 0 1
// vert 1 ( 0.155314 0.987100 ) 1 1
@@ -979,7 +1021,7 @@
LoadInt(vertexnum, "after 'vert'");
if (vertexnum >= mesh->num_vertices)
{
- Console_Printf("Model_Load: vert (%i) >= numverts (%i)\n", vertexnum, mesh->num_vertices);
+ Console_Printf("Model_Build_Import_MD5: vert (%i) >= numverts (%i)\n", vertexnum, mesh->num_vertices);
Abort();
}
// (
@@ -1002,13 +1044,13 @@
LoadInt(mesh->num_triangles, "after 'numtris'");
if (mesh->num_triangles < 1)
{
- Console_Printf("Model_Load: numtris (%i) < 1\n", mesh->num_triangles);
+ Console_Printf("Model_Build_Import_MD5: numtris (%i) < 1\n", mesh->num_triangles);
Abort();
}
mesh->max_triangles = mesh->num_triangles;
- mesh->data_element3i = Mem_Alloc(r->memzone, mesh->max_triangles * sizeof(NUint32[3]));
- mesh->data_neighbor3i = Mem_Alloc(r->memzone, mesh->max_triangles * sizeof(NSint32[3]));
- mesh->data_plane4f = Mem_Alloc(r->memzone, mesh->max_triangles * sizeof(float[4]));
+ mesh->data_element3i = Mem_Alloc(model->memzone, mesh->max_triangles * sizeof(NUint32[3]));
+ mesh->data_neighbor3i = Mem_Alloc(model->memzone, mesh->max_triangles * sizeof(NSint32[3]));
+ mesh->data_plane4f = Mem_Alloc(model->memzone, mesh->max_triangles * sizeof(float[4]));
}
// tri 0 29 30 31
// tri 1 32 29 76
@@ -1019,7 +1061,7 @@
LoadInt(trianglenum, "after 'tri'");
if (trianglenum >= mesh->num_triangles)
{
- Console_Printf("Model_Load: tri (%i) >= numtris (%i)\n", trianglenum, mesh->num_triangles);
+ Console_Printf("Model_Build_Import_MD5: tri (%i) >= numtris (%i)\n", trianglenum, mesh->num_triangles);
Abort();
}
// TODO: boundscheck elements
@@ -1035,7 +1077,7 @@
LoadInt(md5numweights, "after 'numweights'");
if (md5numweights < 1)
{
- Console_Printf("Model_Load: numweights (%i) < 1\n", md5numweights);
+ Console_Printf("Model_Build_Import_MD5: numweights (%i) < 1\n", md5numweights);
Abort();
}
md5weights = Mem_Alloc(Global_Zone, md5numweights * sizeof(Model_MD5_Weight));
@@ -1051,7 +1093,7 @@
LoadInt(weightnum, "after 'weight'");
if (weightnum >= md5numweights)
{
- Console_Printf("Model_Load: weight (%i) >= numweights (%i)\n", weightnum, md5numweights);
+ Console_Printf("Model_Build_Import_MD5: weight (%i) >= numweights (%i)\n", weightnum, md5numweights);
Abort();
}
md5weight = md5weights + weightnum;
@@ -1059,7 +1101,7 @@
LoadInt(md5weight->jointnum, "(weight jointnum)");
if (md5weight->jointnum >= numjoints)
{
- Console_Printf("Model_Load: joint (%i) >= numjoints (%i)\n", md5weight->jointnum, numjoints);
+ Console_Printf("Model_Build_Import_MD5: joint (%i) >= numjoints (%i)\n", md5weight->jointnum, numjoints);
Abort();
}
// 1.000000
@@ -1147,63 +1189,6 @@
for (i = 0;i < mesh->num_vertices;i++)
VectorCopy(md5weights[md5weightrange[i*2+0]].vertex, mesh->data_vertex3f + i*3);
}
- // compile the base frame of the mesh for static uses
- Model_MeshNormals(mesh->num_triangles, mesh->data_element3i, mesh->num_vertices, mesh->data_vertex3f, mesh->data_texcoord2f, mesh->data_normal3f);
- Model_MeshTangents(mesh->num_triangles, mesh->data_element3i, mesh->num_vertices, mesh->data_vertex3f, mesh->data_texcoord2f, mesh->data_normal3f, mesh->data_svector3f, mesh->data_tvector3f);
- Model_MeshNeighbors(mesh->num_triangles, mesh->data_element3i, mesh->data_neighbor3i, mesh->num_vertices);
- Model_BuildTrianglePlanes(mesh->data_vertex3f, mesh->num_triangles, mesh->data_element3i, mesh->data_plane4f);
- // collision brushes are for the static frame
- // TODO: load separate collision brush file for faster collisions?
- mesh->num_collisionbrushes = mesh->num_triangles;
- mesh->max_collisionbrushes = mesh->num_collisionbrushes;
- mesh->data_collisionbrushes = Collision_Brush_AllocBrushesForTriangleMesh(r->memzone, mesh->max_triangles);
- Collision_Brush_UpdateTriangleMeshBrushes(mesh->data_collisionbrushes, mesh->num_triangles, mesh->data_element3i, mesh->data_vertex3f);
- // calculate culling shapes
- for (i = 0;i < mesh->num_vertices;i++)
- {
- NUint32 k;
- if (!i && !meshnum)
- {
- VectorCopy(mesh->data_vertex3f, model->basecullmins);
- VectorCopy(mesh->data_vertex3f, model->basecullmaxs);
- }
- else
- {
- model->basecullmins[0] = Min(model->basecullmins[0], mesh->data_vertex3f[i * 3 + 0]);
- model->basecullmins[1] = Min(model->basecullmins[1], mesh->data_vertex3f[i * 3 + 1]);
- model->basecullmins[2] = Min(model->basecullmins[2], mesh->data_vertex3f[i * 3 + 2]);
- model->basecullmaxs[0] = Max(model->basecullmaxs[0], mesh->data_vertex3f[i * 3 + 0]);
- model->basecullmaxs[1] = Max(model->basecullmaxs[1], mesh->data_vertex3f[i * 3 + 1]);
- model->basecullmaxs[2] = Max(model->basecullmaxs[2], mesh->data_vertex3f[i * 3 + 2]);
- }
- if (!i)
- {
- VectorCopy(mesh->data_vertex3f, mesh->basecullmins);
- VectorCopy(mesh->data_vertex3f, mesh->basecullmaxs);
- }
- else
- {
- mesh->basecullmins[0] = Min(mesh->basecullmins[0], mesh->data_vertex3f[i * 3 + 0]);
- mesh->basecullmins[1] = Min(mesh->basecullmins[1], mesh->data_vertex3f[i * 3 + 1]);
- mesh->basecullmins[2] = Min(mesh->basecullmins[2], mesh->data_vertex3f[i * 3 + 2]);
- mesh->basecullmaxs[0] = Max(mesh->basecullmaxs[0], mesh->data_vertex3f[i * 3 + 0]);
- mesh->basecullmaxs[1] = Max(mesh->basecullmaxs[1], mesh->data_vertex3f[i * 3 + 1]);
- mesh->basecullmaxs[2] = Max(mesh->basecullmaxs[2], mesh->data_vertex3f[i * 3 + 2]);
- }
- if (isskeletal)
- {
- for (k = 0;k < 4 && mesh->data_weightvalue4b[i*4+k] > 0;k++)
- {
- NUint32 index = mesh->data_weightindex4b[i*4+k];
- Nvec3 v1, v;
- Nvec r;
- VectorCopy(mesh->data_vertex3f + i * 3, v1);
- Matrix4x4_Transform(&model->data_transforminfo[index].baseinversematrix, v1, v);
- r = VectorLength(v);
- model->data_transforminfo[index].radius = Max(model->data_transforminfo[index].radius, r);
- }
- }
- }
Mem_Free(&md5weights);
Mem_Free(&md5weightrange);
meshnum++;
@@ -1212,17 +1197,55 @@
}
Util_ParseC_CleanUpThread(&thread);
Mem_Free(&filedata);
- // if there was a load error, don't point to the Model so nothing will try
- // to use the incomplete data
- if (!error)
- r->data = model;
#undef Abort
#undef LoadInt
#undef LoadValue
#undef LoadString
#undef ExpectKeyword
+ return error;
}
+Nbool Model_Build_Import(Model *model, Nsize filesize, const char *filedata)
+{
+ Nbool error = false;
+ if (String_EndsWith(model->filename, ".obj"))
+ error = Model_Build_Import_OBJ(model, filesize, filedata);
+ else if (String_EndsWith(model->filename, ".md5mesh"))
+ error = Model_Build_Import_MD5(model, filesize, filedata);
+ else
+ {
+ Console_Printf("Model_Build_Import_MD5: %s extension not recognized\n", model->filename);
+ error = true;
+ }
+ return error;
+}
+
+void Model_Load(ResourceEntry *r)
+{
+ Nsize filesize;
+ Model *model;
+ Nbool error;
+ char *filedata;
+
+ filedata = File_LoadFile(r->name, &filesize);
+ if (!filedata)
+ return;
+
+ model = Mem_Alloc(r->memzone, sizeof(Model));
+ Model_Build_Begin(model, r->name, r->memzone, false);
+
+ error = Model_Build_Import(model, filesize, filedata);
+
+ // if there was a load error, don't point to the Model so nothing will try
+ // to use the incomplete data
+ if (!error)
+ {
+ Model_Build_Compile(model, true, true, true, true, true, true);
+ r->data = model;
+ }
+}
+
+
void Model_Unload(UNUSED ResourceEntry *r)
{
// freeing of the memzone will get rid of the model
Modified: trunk/model.h
===================================================================
--- trunk/model.h 2006-05-12 11:03:18 UTC (rev 715)
+++ trunk/model.h 2006-05-12 11:04:48 UTC (rev 716)
@@ -81,6 +81,7 @@
typedef struct Model
{
// set at the creation of the Model
+ char filename[64];
Mem_Zone *memzone;
Nbool isskeletal;
@@ -99,20 +100,20 @@
}
Model;
+Nbool Model_Build_Import(Model *model, Nsize filesize, const char *filedata);
void Model_Load(ResourceEntry *r);
void Model_Unload(ResourceEntry *r);
-void Model_Build_Begin(Model *b, Mem_Zone *memzone, Nbool isskeletal);
-void Model_Build_Compile(Model *b, Nbool generateneighbors, Nbool generateplanes, Nbool generatenormals, Nbool generatetangents, Nbool generatelightmaptexcoords, Nbool generatecollisionbrushes);
-void Model_Build_Free(Model *b);
-NUint32 Model_Build_AddSurface(Model *b, Mem_Zone *zone, const char *materialname, NUint32 initialtriangles, NUint32 initialvertices);
-NUint32 Model_Build_AddVertex(Model *b, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t);
-NUint32 Model_Build_AddVertexSkeletal(Model *b, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t, NUint8 *wib, NUint8 *wfb);
-NUint32 Model_Build_FindOrAddVertex(Model *b, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t);
-NUint32 Model_Build_FindOrAddVertexSkeletal(Model *b, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t, NUint8 *wib, NUint8 *wfb);
-NUint32 Model_Build_AddTriangle(Model *b, NUint32 meshindex, int e0, int e1, int e2);
-void Model_Build_Write(Model *b, const char *filename);
-void Model_Build_ImportOBJ(Model *b, const char *inputname, const char *text, const char *textend);
+void Model_Build_Begin(Model *model, const char *filename, Mem_Zone *memzone, Nbool isskeletal);
+void Model_Build_Compile(Model *model, Nbool generateneighbors, Nbool generateplanes, Nbool generatenormals, Nbool generatetangents, Nbool generatelightmaptexcoords, Nbool generatecollisionbrushes);
+void Model_Build_Free(Model *model);
+NUint32 Model_Build_AddSurface(Model *model, const char *materialname, NUint32 initialtriangles, NUint32 initialvertices);
+NUint32 Model_Build_AddVertex(Model *model, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t);
+NUint32 Model_Build_AddVertexSkeletal(Model *model, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t, NUint8 *wib, NUint8 *wfb);
+NUint32 Model_Build_FindOrAddVertex(Model *model, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t);
+NUint32 Model_Build_FindOrAddVertexSkeletal(Model *model, NUint32 meshindex, float x, float y, float z, float nx, float ny, float nz, float s, float t, NUint8 *wib, NUint8 *wfb);
+NUint32 Model_Build_AddTriangle(Model *model, NUint32 meshindex, int e0, int e1, int e2);
+void Model_Build_Write(Model *model, const char *filename);
// this function decodes skeletal vertex information to your supplied arrays
// NOTE: outplane4f requires outvertex3f
Modified: trunk/nstring.c
===================================================================
--- trunk/nstring.c 2006-05-12 11:03:18 UTC (rev 715)
+++ trunk/nstring.c 2006-05-12 11:04:48 UTC (rev 716)
@@ -269,6 +269,18 @@
return strncasecmp(s ? s : "", t ? t : "", n);
}
+Nbool String_EndsWith(const char *s, const char *t)
+{
+ Nsize i;
+ Nsize slen = String_Length(s);
+ Nsize tlen = String_Length(t);
+ if (tlen && slen >= tlen)
+ for (i = 0;i <= slen - tlen;i++)
+ if (!String_Compare(s + i, t))
+ return true;
+ return false;
+}
+
void String_ToLower(char *s)
{
if( !s )
Modified: trunk/nstring.h
===================================================================
--- trunk/nstring.h 2006-05-12 11:03:18 UTC (rev 715)
+++ trunk/nstring.h 2006-05-12 11:04:48 UTC (rev 716)
@@ -29,6 +29,7 @@
NSint String_ICompare(const char *s, const char *t);
NSint String_NCompare(const char *s, const char *t, Nsize n);
NSint String_NICompare(const char *s, const char *t, Nsize n);
+Nbool String_EndsWith(const char *s, const char *t);
Nsize String_Length(const char *s);
Modified: trunk/util.c
===================================================================
--- trunk/util.c 2006-05-12 11:03:18 UTC (rev 715)
+++ trunk/util.c 2006-05-12 11:04:48 UTC (rev 716)
@@ -248,7 +248,7 @@
const char *basename, *imagename, *materialname;
char *tilename;
Nvec terrainsize[3], texturesize[2], terrainscale[3], terrainorigin[3], texturescale[2];
- Model b;
+ Model model;
basename = Shell_Callback_GetArg(1);
imagename = Shell_Callback_GetArg(2);
tilesize = (int) Shell_Callback_GetArgValue(3);
@@ -280,12 +280,14 @@
terrainorigin[2] = terrainsize[2] * -0.5;
tileswidth = width / tilesize;
tilesheight = height / tilesize;
- Model_Build_Begin(&b, Global_Zone, false);
+ tilename = String_APrintf(Global_Zone, "%s.md5mesh", basename);
+ Model_Build_Begin(&model, tilename, Global_Zone, false);
+ String_Free(&tilename);
for (by = 0;by < height;by += tilesize)
{
for (bx = 0;bx < width;bx += tilesize)
{
- NUint32 meshindex = Model_Build_AddSurface(&b, Global_Zone, materialname, 0, 0);
+ NUint32 meshindex = Model_Build_AddSurface(&model, materialname, 0, 0);
tilewidth = Bound(0, width - bx, tilesize+2);
tileheight = Bound(0, height - by, tilesize+2);
for (ty = 0, num = 0;ty < tileheight;ty++)
@@ -305,7 +307,7 @@
p = pixels + (pyi * width + pxi) * 4;
pz = ((p[0]+p[1]+p[2])*(1.0-pxf)+(p[4]+p[5]+p[6])*(pxf))*(1.0-pyf)+((p[w+0]+p[w+1]+p[w+2])*(1.0-pxf)+(p[w+4]+p[w+5]+p[w+6])*(pxf))*(pyf);
// FIXME: this SHOULD calculate a valid mesh normal!!
- Model_Build_AddVertex(&b, meshindex, px * terrainscale[0] + terrainorigin[0], py * terrainscale[1] + terrainorigin[1], pz * terrainscale[2] + terrainorigin[2], 0, 0, 1, (px * terrainscale[0] + terrainorigin[0]) * texturescale[0], (py * terrainscale[1] + terrainorigin[1]) * texturescale[1]);
+ Model_Build_AddVertex(&model, meshindex, px * terrainscale[0] + terrainorigin[0], py * terrainscale[1] + terrainorigin[1], pz * terrainscale[2] + terrainorigin[2], 0, 0, 1, (px * terrainscale[0] + terrainorigin[0]) * texturescale[0], (py * terrainscale[1] + terrainorigin[1]) * texturescale[1]);
}
}
for (ty = 0, num = 0;ty < tileheight-1;ty++)
@@ -313,17 +315,15 @@
for (tx = 0;tx < tilewidth-1;tx++, num += 6)
{
NUint32 i = ty*tilewidth+tx;
- Model_Build_AddTriangle(&b, meshindex, i, i+1, i+1+tilewidth);
- Model_Build_AddTriangle(&b, meshindex, i, i+1+tilewidth, i+tilewidth);
+ Model_Build_AddTriangle(&model, meshindex, i, i+1, i+1+tilewidth);
+ Model_Build_AddTriangle(&model, meshindex, i, i+1+tilewidth, i+tilewidth);
}
}
}
}
Mem_Free(&pixels);
- tilename = String_APrintf(Global_Zone, "%s.md5mesh", basename);
- Model_Build_Write(&b, tilename);
- String_Free(&tilename);
- Model_Build_Free(&b);
+ Model_Build_Write(&model, model.filename);
+ Model_Build_Free(&model);
}
static Shell_SymbolDecl Util_Shell_MakeTerrain_Decl = {
@@ -336,33 +336,33 @@
(Shell_Symbol_Callback) Util_Shell_MakeTerrain
};
-static void Util_Shell_ConvertOBJ(void)
+static void Util_Shell_ConvertModel(void)
{
- Nsize objtextsize;
- Model b;
+ Nsize filesize;
+ Model model;
const char *inputname = Shell_Callback_GetArg(1);
const char *outputname = Shell_Callback_GetArg(2);
- char *objtext = File_LoadFile(inputname, &objtextsize);
- if (!objtext)
+ char *filedata = File_LoadFile(inputname, &filesize);
+ if (!filedata)
{
- Shell_Callback_ThrowError("Could not open OBJ file\n");
+ Shell_Callback_ThrowError("Could not open model file\n");
// SHELLTODO
return;
}
- Model_Build_Begin(&b, Global_Zone, false);
- Model_Build_ImportOBJ(&b, inputname, objtext, objtext + objtextsize);
- Model_Build_Write(&b, outputname);
- Model_Build_Free(&b);
- Mem_Free(&objtext);
+ Model_Build_Begin(&model, inputname, Global_Zone, false);
+ if (!Model_Build_Import(&model, filesize, filedata))
+ Model_Build_Write(&model, outputname);
+ Model_Build_Free(&model);
+ Mem_Free(&filedata);
}
-static Shell_SymbolDecl Util_Shell_ConvertOBJ_Decl = {
- "util_convertobj",
- "Turn a .obj model into a .md5mesh model file.",
- "Usage: util_convertobj \n"
- "Example: util_convertobj maps/mymap/mymodel.obj maps/mymap/mymodel.md5mesh",
+static Shell_SymbolDecl Util_Shell_ConvertModel_Decl = {
+ "util_convertmodel",
+ "Convert a model from any supported format to any other.",
+ "Usage: util_convertmodel \n"
+ "Example: util_convertmodel maps/mymap/mymodel.obj maps/mymap/mymodel.md5mesh",
"ss",
- (Shell_Symbol_Callback) Util_Shell_ConvertOBJ
+ (Shell_Symbol_Callback) Util_Shell_ConvertModel
};
@@ -635,32 +635,32 @@
double boxsize;
const char *basefilename, *baseimagename;
char *filename;
- Model b;
+ Model model;
basefilename = Shell_Callback_GetArg(1);
baseimagename = Shell_Callback_GetArg(2);
boxsize = atof(Shell_Callback_GetArg(3));
- Model_Build_Begin(&b, 0, 0);
+ filename = String_APrintf(Global_Zone, "%s.md5mesh", basefilename);
+ Model_Build_Begin(&model, filename, Global_Zone, false);
+ String_Free(&filename);
for (i = 0;i < 6;i++)
{
NUint32 j;
NUint32 indices[4];
char *materialname = String_APrintf(Global_Zone, "%s_%s", baseimagename, skyboxsuffix[i]);
- NUint32 meshindex = Model_Build_AddSurface(&b, Global_Zone, materialname, 2, 4);
+ NUint32 meshindex = Model_Build_AddSurface(&model, materialname, 2, 4);
String_Free(&materialname);
for (j = 0;j < 4;j++)
- indices[j] = Model_Build_FindOrAddVertex(&b, meshindex, skyboxvertex[i][j][0], skyboxvertex[i][j][1], skyboxvertex[i][j][2], skyboxvertex[i][j][3], skyboxvertex[i][j][4], skyboxvertex[i][j][5], skyboxvertex[i][j][6], skyboxvertex[i][j][7]);
- Model_Build_AddTriangle(&b, meshindex, indices[0], indices[2], indices[1]);
- Model_Build_AddTriangle(&b, meshindex, indices[0], indices[3], indices[2]);
+ indices[j] = Model_Build_FindOrAddVertex(&model, meshindex, skyboxvertex[i][j][0], skyboxvertex[i][j][1], skyboxvertex[i][j][2], skyboxvertex[i][j][3], skyboxvertex[i][j][4], skyboxvertex[i][j][5], skyboxvertex[i][j][6], skyboxvertex[i][j][7]);
+ Model_Build_AddTriangle(&model, meshindex, indices[0], indices[2], indices[1]);
+ Model_Build_AddTriangle(&model, meshindex, indices[0], indices[3], indices[2]);
}
- filename = String_APrintf(Global_Zone, "%s.md5mesh", basefilename);
- Model_Build_Write(&b, filename);
- String_Free(&filename);
- Model_Build_Free(&b);
+ Model_Build_Write(&model, model.filename);
+ Model_Build_Free(&model);
}
static Shell_SymbolDecl Util_Shell_MakeSkyBox_Decl = {
"util_makeskybox",
- "Make an skybox md5mesh file.",
+ "Make a skybox md5mesh file.",
"Usage: util_makeskybox \n"
"Example: util_makeskybox maps/mymap/sunnyday maps/mymap/sunnyday 30000\n"
"would produce a file named maps/mymap/sunnyday.md5mesh containing 6 meshes for maps/mymap/sunnyday_px.tga and _nx, _py, _ny, _pz, _nz, forming a box +-100000m in each direction",
@@ -672,7 +672,7 @@
{
Shell_RegisterFunction(&Util_Shell_MakeTerrain_Decl);
Shell_RegisterFunction(&Util_Shell_MakeSkyBox_Decl);
- Shell_RegisterFunction(&Util_Shell_ConvertOBJ_Decl);
+ Shell_RegisterFunction(&Util_Shell_ConvertModel_Decl);
}
void Util_Quit(void)
From lordhavoc at icculus.org Fri May 12 07:19:17 2006
From: lordhavoc at icculus.org (lordhavoc at icculus.org)
Date: 12 May 2006 07:19:17 -0400
Subject: r717 - trunk
Message-ID: <20060512111917.962.qmail@icculus.org>
Author: lordhavoc
Date: 2006-05-12 07:19:17 -0400 (Fri, 12 May 2006)
New Revision: 717
Modified:
trunk/model.c
Log:
now preserves smooth shading across texture seams in obj models that
contain vertex normals
Modified: trunk/model.c
===================================================================
--- trunk/model.c 2006-05-12 11:04:48 UTC (rev 716)
+++ trunk/model.c 2006-05-12 11:19:17 UTC (rev 717)
@@ -1240,7 +1240,12 @@
// to use the incomplete data
if (!error)
{
- Model_Build_Compile(model, true, true, true, true, true, true);
+ // generate new vertex normals if the loaded model does not have any
+ // (we detect this by checking if the first vertex's normal is
+ // zero-length or if the array is missing entirely)
+ Nbool generatenormals = !model->data_meshes || !model->data_meshes[0].data_normal3f || !VectorLength2(model->data_meshes[0].data_normal3f);
+ Nbool generatetangents = !model->data_meshes || !model->data_meshes[0].data_svector3f || !VectorLength2(model->data_meshes[0].data_svector3f);
+ Model_Build_Compile(model, true, true, generatenormals, generatetangents, true, true);
r->data = model;
}
}
From lordhavoc at icculus.org Fri May 12 08:34:10 2006
From: lordhavoc at icculus.org (lordhavoc at icculus.org)
Date: 12 May 2006 08:34:10 -0400
Subject: r718 - in trunk: . game
Message-ID: <20060512123410.11844.qmail@icculus.org>
Author: lordhavoc
Date: 2006-05-12 08:34:09 -0400 (Fri, 12 May 2006)
New Revision: 718
Modified:
trunk/game/g_entity.c
trunk/game/g_entityclass.c
trunk/mathlib.h
Log:
turned IsNAN into a macro in mathlib.h and moved the NAN velocity checks
to G_Entity_PlayerPhysics
Modified: trunk/game/g_entity.c
===================================================================
--- trunk/game/g_entity.c 2006-05-12 11:19:17 UTC (rev 717)
+++ trunk/game/g_entity.c 2006-05-12 12:34:09 UTC (rev 718)
@@ -506,8 +506,12 @@
void G_Entity_PlayerPhysics(G_Entity *self, Nvec3 wishvel, Nvec groundfriction, Nvec groundaccel, Nvec groundstopspeed, Nvec airfriction, Nvec airaccel, Nvec airstopspeed, Nvec jumpspeed, Nvec gravityscale, Nvec3 thrustvel)
{
+ NUint32 j;
Nvec f;
Nvec3 gravityimpulse, countergravityimpulse;
+ for (j = 0; j < 3; j++)
+ if (IS_NAN(self->position.velocity[j]))
+ self->position.velocity[j] = 0;
VectorScale(G.globalgravity, G.frametime * gravityscale, gravityimpulse);
if (self->groundentity)
{
@@ -575,6 +579,9 @@
}
if (thrustvel)
VectorMA(self->position.velocity, G.frametime, thrustvel, self->position.velocity);
+ for (j = 0; j < 3; j++)
+ if (IS_NAN(self->position.velocity[j]))
+ self->position.velocity[j] = 0;
}
static Collision_Brush boxbrush;
Modified: trunk/game/g_entityclass.c
===================================================================
--- trunk/game/g_entityclass.c 2006-05-12 11:19:17 UTC (rev 717)
+++ trunk/game/g_entityclass.c 2006-05-12 12:34:09 UTC (rev 718)
@@ -100,15 +100,6 @@
{
}
-Nbool IsNAN(float f)
-{
- return (*((int*)&f)&0x7fc00000) == 0x7fc00000;
-}
-//Nbool IsNAN(double f)
-//{
-// return (*((int*)&f)&0x7fe00000) == 0x7fe00000;
-//}
-
static void G_Object_Infantry_Frame(G_Entity *self)
{
NUint32 buttonbits;
@@ -163,15 +154,6 @@
else
G_Entity_PlayerPhysics(self, rotatedmovement, self->eclass->friction, self->eclass->acceleration, self->eclass->stopspeed, self->eclass->airfriction, self->eclass->airacceleration, self->eclass->airstopspeed, (buttonbits & G_BUTTON_MOVEUP) ? self->eclass->jumpvelocity : 0, 1, NULL);
- {
- int j;
- for (j = 0; j < 3; j++)
- {
- if (IsNAN(self->position.velocity[j]))
- self->position.velocity[j] = 0;
- }
- }
-
G_Entity_Move(self, user->noclipmode ? 0 : G_SCOPE_BLOCK_PLAYER, self->eclass->stepheight, 0);
//Matrix4x4_ConcatQuakeEntity(&self->position.m, movement[0], movement[1], movement[2], turn[0], turn[1], turn[2], 1);
Modified: trunk/mathlib.h
===================================================================
--- trunk/mathlib.h 2006-05-12 11:19:17 UTC (rev 717)
+++ trunk/mathlib.h 2006-05-12 12:34:09 UTC (rev 718)
@@ -2,6 +2,7 @@
#ifndef MATHLIB_H
#define MATHLIB_H
+#define IS_NAN(x) (((*(int *)&x)&0x7fc00000) == 0x7fc00000)
#define Min( a, b ) ( ((a) < (b)) ? (a) : (b) )
#define Max( a, b ) ( ((a) > (b)) ? (a) : (b) )
From sajt at icculus.org Sun May 14 22:07:33 2006
From: sajt at icculus.org (sajt at icculus.org)
Date: 14 May 2006 22:07:33 -0400
Subject: r719 - trunk
Message-ID: <20060515020733.21786.qmail@icculus.org>
Author: sajt
Date: 2006-05-14 22:07:33 -0400 (Sun, 14 May 2006)
New Revision: 719
Modified:
trunk/darkwar.dsp
Log:
Added modelanim.[ch] to VC6 project file
Modified: trunk/darkwar.dsp
===================================================================
(Binary files differ)
From kazashi at icculus.org Sun May 14 22:14:50 2006
From: kazashi at icculus.org (kazashi at icculus.org)
Date: 14 May 2006 22:14:50 -0400
Subject: r720 - trunk
Message-ID: <20060515021450.22899.qmail@icculus.org>
Author: kazashi
Date: 2006-05-14 22:14:50 -0400 (Sun, 14 May 2006)
New Revision: 720
Modified:
trunk/darkwar.dev
Log:
Added modelanim.[ch], m_menucore.h to Dev-C++ project file
Modified: trunk/darkwar.dev
===================================================================
--- trunk/darkwar.dev 2006-05-15 02:07:33 UTC (rev 719)
+++ trunk/darkwar.dev 2006-05-15 02:14:50 UTC (rev 720)
@@ -1,7 +1,7 @@
[Project]
FileName=darkwar.dev
Name=DarkWar
-UnitCount=99
+UnitCount=102
Type=0
Ver=1
ObjFiles=
@@ -1020,7 +1020,7 @@
[Unit98]
FileName=systemfallbacks.c
CompileCpp=0
-Folder=DarkWar
+Folder=
Compile=1
Link=1
Priority=1000
@@ -1037,3 +1037,33 @@
OverrideBuildCmd=0
BuildCmd=
+[Unit100]
+FileName=..\darkwar\game\m_menucore.h
+CompileCpp=0
+Folder=Headers
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit101]
+FileName=..\darkwar\modelanim.c
+CompileCpp=0
+Folder=
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit102]
+FileName=..\darkwar\modelanim.h
+CompileCpp=0
+Folder=Headers
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
From black at icculus.org Tue May 23 15:42:08 2006
From: black at icculus.org (black at icculus.org)
Date: 23 May 2006 15:42:08 -0400
Subject: r721 - trunk
Message-ID: <20060523194208.1397.qmail@icculus.org>
Author: black
Date: 2006-05-23 15:42:08 -0400 (Tue, 23 May 2006)
New Revision: 721
Modified:
trunk/shell.c
Log:
Change the shell parser to not split up tokens into one value and one string token but
treat it as one token (as it should) - this is necessary for IP addresses to work correctly.
Modified: trunk/shell.c
===================================================================
--- trunk/shell.c 2006-05-15 02:14:50 UTC (rev 720)
+++ trunk/shell.c 2006-05-23 19:42:08 UTC (rev 721)
@@ -374,7 +374,11 @@
if( Shell_Parser_MatchChar( parser, '.' ) ) {
while( Shell_Parser_MatchDigit( parser ) );
}
- return true;
+ // do not match e.g. 192.168.0.1 as 192.168|.0.1 but as one string
+ // TODO: maybe add an IP/DNS type to the console? This needs to be discussed.
+ if( IsWhitespace( *parser->currentChar ) ) {
+ return true;
+ }
}
return false;
}
From kazashi at icculus.org Wed May 31 23:57:24 2006
From: kazashi at icculus.org (kazashi at icculus.org)
Date: 31 May 2006 23:57:24 -0400
Subject: r722 - in trunk/base/maps: . west
Message-ID: <20060601035724.16651.qmail@icculus.org>
Author: kazashi
Date: 2006-05-31 23:51:15 -0400 (Wed, 31 May 2006)
New Revision: 722
Added:
trunk/base/maps/west/
trunk/base/maps/west/roofing_01.tga
trunk/base/maps/west/roofing_01_gloss.tga
trunk/base/maps/west/roofing_01_norm.tga
Log:
Added: trunk/base/maps/west/roofing_01.tga
===================================================================
(Binary files differ)
Property changes on: trunk/base/maps/west/roofing_01.tga
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/base/maps/west/roofing_01_gloss.tga
===================================================================
(Binary files differ)
Property changes on: trunk/base/maps/west/roofing_01_gloss.tga
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/base/maps/west/roofing_01_norm.tga
===================================================================
(Binary files differ)
Property changes on: trunk/base/maps/west/roofing_01_norm.tga
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream