Author Topic: SubObject Vert Limits (and canteloupe)  (Read 3646 times)

0 Members and 1 Guest are viewing this topic.

Offline Rga_Noris

  • 29
  • What?
SubObject Vert Limits (and canteloupe)
So I had a discussion with Zacam regarding the vert limitations in FSO. Here is my concern:

Currently, FSO eats polies/verts for breakfast. The problem is that there is a 64K vert limit per subobject. The issue is that this limit applies to ALL objects, detail0 included. With models becoming more and more complicated, this vert limit is easy to hit, meaning that in order to have complex and detailed detail0 meshes, we must only make a portion the mesh the 'actual' detail0, and the rest is actually subobjects attached to detail0 (the Sath is this way.... detail0 is just from the 'neck' back... the head and arms are actually just a subobject).

This is an issue because while FSO can eat polygon flavored Doritos all day, it slows down when more subobjects are introduced... the current vert limit requires we introduce more subobjects the more complicated the model gets. We could get more performance milage if we were able to make detail0 one single object as opposed to multiple.

Oh, and as promised:



EDIT: More reasonable melon image.
« Last Edit: February 20, 2014, 11:50:39 pm by Rga_Noris »
I think I'll call REAL Mahjong 'Chinese Dominoes', just to make people think I'm an ignorant asshat.

 

Offline The E

  • He's Ebeneezer Goode
  • Moderator
  • 213
  • Nothing personal, just tech support.
    • Steam
    • Twitter
Re: SubObject Vert Limits (and canteloupe)
The problem lies not only with fso, but also with the pof format. In order to allow submeshes that large, we would also need to make changes there.
If I'm just aching this can't go on
I came from chasing dreams to feel alone
There must be changes, miss to feel strong
I really need lifе to touch me
--Evergrey, Where August Mourns

 

Offline Rga_Noris

  • 29
  • What?
Re: SubObject Vert Limits (and canteloupe)
I'm going to guess that updating that format would be a sticky wicket. As in FSO would need to use a new format, thus making old POF's broked.

What if we used honey dew melon instead? I think the problem lies in melon choice.
I think I'll call REAL Mahjong 'Chinese Dominoes', just to make people think I'm an ignorant asshat.

 

Offline Fury

  • The Curmudgeon
  • 213
Re: SubObject Vert Limits (and canteloupe)
The problem lies not only with fso, but also with the pof format. In order to allow submeshes that large, we would also need to make changes there.
At some point some serious consideration should be made to support Collada...

 

Offline m!m

  • 211
Re: SubObject Vert Limits (and canteloupe)
We could use an external library like assimp to handle to actual loading. We would need some way to load the exta data which is currently stored inside the POF file like gunpoints or dockingpoints.

 

Offline Rga_Noris

  • 29
  • What?
Re: SubObject Vert Limits (and canteloupe)
Would such a library require another item to install, ala OpenAL?
I think I'll call REAL Mahjong 'Chinese Dominoes', just to make people think I'm an ignorant asshat.

 

Offline The E

  • He's Ebeneezer Goode
  • Moderator
  • 213
  • Nothing personal, just tech support.
    • Steam
    • Twitter
Re: SubObject Vert Limits (and canteloupe)
No, assimp is a single DLL that can be shipped with the executables (maybe there are static link options available, I don't know). It would definitely not require additional installers to run.
If I'm just aching this can't go on
I came from chasing dreams to feel alone
There must be changes, miss to feel strong
I really need lifе to touch me
--Evergrey, Where August Mourns

 

Offline FUBAR-BDHR

  • Self-Propelled Trouble Magnet
  • 212
  • Master Drunk
    • 165th Beer Drinking Hell Raisers
Re: SubObject Vert Limits (and canteloupe)
Are there any facts behind the use of multiple subobjects slowing down things or is it just old rumors?  We heard the same things back when Diaspora R1 was in development and did some extensive testing only to find no difference and I believe in some cases performance slowdowns when models made up of multiple small subobjects were combined into a single large detail0.
No-one ever listens to Zathras. Quite mad, they say. It is good that Zathras does not mind. He's even grown to like it. Oh yes. -Zathras

 

Offline zookeeper

  • *knock knock* Who's there? Poe. Poe who?
  • 210
Re: SubObject Vert Limits (and canteloupe)
Well if you have to split a large submodel into 3 smaller ones then I doubt there's any measurable performance loss unless you have obscene amounts of those models on-screen. I believe it's more a case of rendering of for example capships with lots of turrets spending most of the time switching context from one submodel to another.

I'd think that practically any ship detailed enough to require splitting submodels would have a whole lot more turrets or other modelled subsystems to make the rendering performance loss caused by the splitting effectively meaningless.

Collision detection might be a slightly different story though; if the bounding boxes of your submodels don't overlap much, then I'd think it possible that splitting could even improve performance if some of those submodels get culled immediately with cheap bounding box checks. In any case, when hundreds of weapons are flying around, the performance drop from complicated models seems to mostly come from collision detection, not rendering. Especially when the collision detection needs to be done even when you're looking the other way.

 

Offline Bobboau

  • Just a MODern kinda guy
    Just MODerately cool
    And MODest too
  • 213
Re: SubObject Vert Limits (and canteloupe)
Where exactly is the problem? I remember back in the day implementing 32bit index buffers, there was a time when that was working I thought.
are we sure this is not simply a PCS2 bug?
Bobboau, bringing you products that work... in theory
learn to use PCS
creator of the ProXimus Procedural Texture and Effect Generator
My latest build of PCS2, get it while it's hot!
PCS 2.0.3


DEUTERONOMY 22:11
Thou shalt not wear a garment of diverse sorts, [as] of woollen and linen together

 

Offline Zacam

  • Magnificent Bastard
  • Administrator
  • 211
  • I go Sledge-O-Matic on Spammers
    • Minecraft
    • Steam
    • Twitter
    • ModDB Feature
Re: SubObject Vert Limits (and canteloupe)
The index buffer may very well be 32 bit, which will be nice. But the value declaration being stored there is still in ushort.
Report MediaVP issues, now on the MediaVP Mantis! Read all about it Here!
Talk with the community on Discord
"If you can keep a level head in all this confusion, you just don't understand the situation"

¤[D+¬>

[08/01 16:53:11] <sigtau> EveningTea: I have decided that I am a 32-bit registerkin.  Pronouns are eax, ebx, ecx, edx.
[08/01 16:53:31] <EveningTea> dhauidahh
[08/01 16:53:32] <EveningTea> sak
[08/01 16:53:40] * EveningTea froths at the mouth
[08/01 16:53:40] <sigtau> i broke him, boys

 

Offline The E

  • He's Ebeneezer Goode
  • Moderator
  • 213
  • Nothing personal, just tech support.
    • Steam
    • Twitter
Re: SubObject Vert Limits (and canteloupe)
Okay, so here's a quick patch for the FSO side of things. Be aware I haven't been able to test it yet due to a lack of matching PCS2:

Code: [Select]
Index: code/model/model.h
===================================================================
--- code/model/model.h (revision 10471)
+++ code/model/model.h (working copy)
@@ -265,6 +265,13 @@
  float u,v;
 } model_tmap_vert;
 
+// The E: This struct is used by POF models version 2118 and up, for models with subobjects that have >2^16 vertices
+typedef struct model_tmap_vert_large {
+ uint vertnum;
+ uint normnum;
+ float u, v;
+} model_tmap_vert_large;
+
 struct bsp_collision_node {
  vec3d min;
  vec3d max;
Index: code/model/modelinterp.cpp
===================================================================
--- code/model/modelinterp.cpp (revision 10471)
+++ code/model/modelinterp.cpp (working copy)
@@ -68,7 +68,7 @@
 // Local variables
 //
 
-static int Num_interp_verts_allocated = 0;
+static uint Num_interp_verts_allocated = 0;
 vec3d **Interp_verts = NULL;
 static vertex *Interp_points = NULL;
 static vertex *Interp_splode_points = NULL;
@@ -97,7 +97,7 @@
 // -------------------------------------------------------------------
 
 
-static int Num_interp_norms_allocated = 0;
+static uint Num_interp_norms_allocated = 0;
 static vec3d **Interp_norms = NULL;
 static ubyte *Interp_light_applied = NULL;
 static int Interp_num_norms = 0;
@@ -217,7 +217,7 @@
 extern void model_collide_allocate_point_list(int n_points);
 extern void model_collide_free_point_list();
 
-void model_allocate_interp_data(int n_verts = 0, int n_norms = 0, int n_list_verts = 0)
+void model_allocate_interp_data(uint n_verts = 0, uint n_norms = 0, int n_list_verts = 0)
 {
  static ubyte dealloc = 0;
 
@@ -746,11 +746,17 @@
 ubyte Interp_subspace_g = 255;
 ubyte Interp_subspace_b = 255;
 
+#define GET_VERT_NUM(i) verts != NULL ? verts[i].vertnum : vert_large[i].vertnum
+#define GET_NORM_NUM(i) verts != NULL ? verts[i].normnum : vert_large[i].normnum
+#define GET_TEXCO_U(i) verts != NULL ? verts[i].u : vert_large[i].u
+#define GET_TEXCO_V(i) verts != NULL ? verts[i].v : vert_large[i].v
+
 void model_interp_tmappoly(ubyte * p,polymodel * pm)
 {
  int i;
  int nv;
  model_tmap_vert *verts;
+ model_tmap_vert_large *vert_large;
  int cull = 0;
 
  // Goober5000
@@ -793,14 +799,23 @@
  if ( nv < 0 )
  return;
 
- verts = (model_tmap_vert *)(p+44);
+ if (pm->version < 2118) {
+ verts = (model_tmap_vert *) (p + 44);
+ vert_large = NULL;
+ }
+ else {
+ vert_large = (model_tmap_vert_large *) (p + 44);
+ verts = NULL;
+ }
 
- int max_n_verts = 0;
- int max_n_norms = 0;
+ Assertion(verts != NULL || vert_large != NULL, "No valid vertex data found in pof file!\n");
 
+ uint max_n_verts = 0;
+ uint max_n_norms = 0;
+
  for (i = 0; i < nv; i++) {
- max_n_verts = MAX(verts[i].vertnum + 1, max_n_verts);
- max_n_norms = MAX(verts[i].normnum + 1, max_n_norms);
+ max_n_verts = MAX(GET_VERT_NUM(i) + 1, max_n_verts);
+ max_n_norms = MAX(GET_NORM_NUM(i) + 1, max_n_norms);
  }
 
  model_allocate_interp_data(max_n_verts, max_n_norms, nv);
@@ -814,14 +829,14 @@
 
  if(splodeing){
  float salpha = 1.0f - splode_level;
- for (i=0;i<nv;i++){
+ for (i = 0; i < nv; i++){
  Interp_list[i] = &Interp_splode_points[verts[i].vertnum];
- Interp_list[i]->texture_position.u = verts[i].u*2;
- Interp_list[i]->texture_position.v = verts[i].v*2;
- Interp_list[i]->r = (unsigned char)(255*salpha);
- Interp_list[i]->g = (unsigned char)(250*salpha);
- Interp_list[i]->b = (unsigned char)(200*salpha);
- model_interp_edge_alpha(&Interp_list[i]->r, &Interp_list[i]->g, &Interp_list[i]->b, Interp_verts[verts[i].vertnum], Interp_norms[verts[i].normnum], salpha, false);
+ Interp_list[i]->texture_position.u = verts[i].u * 2;
+ Interp_list[i]->texture_position.v = verts[i].v * 2;
+ Interp_list[i]->r = (unsigned char) (255 * salpha);
+ Interp_list[i]->g = (unsigned char) (250 * salpha);
+ Interp_list[i]->b = (unsigned char) (200 * salpha);
+ model_interp_edge_alpha(&Interp_list[i]->r, &Interp_list[i]->g, &Interp_list[i]->b, Interp_verts[GET_VERT_NUM(i)], Interp_norms[GET_NORM_NUM(i)], salpha, false);
  }
  cull = gr_set_cull(0);
  gr_set_bitmap( splodeingtexture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, salpha );
@@ -832,11 +847,13 @@
  }
 
  for (i=0;i<nv;i++) {
- Interp_list[i] = &Interp_points[verts[i].vertnum];
+
+ Interp_list[i] = &Interp_points[GET_VERT_NUM(i)];
 
- Interp_list[i]->texture_position.u = verts[i].u;
- Interp_list[i]->texture_position.v = verts[i].v;
+ Interp_list[i]->texture_position.u = GET_TEXCO_U(i);
+ Interp_list[i]->texture_position.v = GET_TEXCO_V(i);
 
+
  if ( Interp_subspace ) {
  Interp_list[i]->texture_position.v += Interp_subspace_offset_u;
  Interp_list[i]->texture_position.u += Interp_subspace_offset_v;
@@ -854,11 +871,11 @@
  Interp_list[i]->spec_b = 0;
 
  if (Interp_flags & MR_EDGE_ALPHA) {
- model_interp_edge_alpha(&Interp_list[i]->r, &Interp_list[i]->g, &Interp_list[i]->b, Interp_verts[verts[i].vertnum], Interp_norms[verts[i].normnum], Interp_warp_alpha, false);
+ model_interp_edge_alpha(&Interp_list[i]->r, &Interp_list[i]->g, &Interp_list[i]->b, Interp_verts[GET_VERT_NUM(i)], Interp_norms[GET_NORM_NUM(i)], Interp_warp_alpha, false);
  }
 
  if (Interp_flags & MR_CENTER_ALPHA) {
- model_interp_edge_alpha(&Interp_list[i]->r, &Interp_list[i]->g, &Interp_list[i]->b, Interp_verts[verts[i].vertnum], Interp_norms[verts[i].normnum], Interp_warp_alpha, true);
+ model_interp_edge_alpha(&Interp_list[i]->r, &Interp_list[i]->g, &Interp_list[i]->b, Interp_verts[GET_VERT_NUM(i)], Interp_norms[GET_NORM_NUM(i)], Interp_warp_alpha, true);
  }
 
  SPECMAP = -1;
@@ -867,8 +884,8 @@
  MISCMAP = -1;
  } else {
 
- int vertnum = verts[i].vertnum;
- int norm = verts[i].normnum;
+ uint vertnum = GET_VERT_NUM(i);
+ uint norm = GET_NORM_NUM(i);
 
  if ( Interp_flags & MR_NO_SMOOTHING ) {
  light_apply_rgb( &Interp_list[i]->r, &Interp_list[i]->g, &Interp_list[i]->b, Interp_verts[vertnum], vp(p+8), Interp_light );
Index: code/model/modeloctant.cpp
===================================================================
--- code/model/modeloctant.cpp (revision 10471)
+++ code/model/modeloctant.cpp (working copy)
@@ -19,7 +19,7 @@
 #include "model/modelsinc.h"
 #include "cmdline/cmdline.h"
 
-extern void model_allocate_interp_data(int n_verts, int n_norms, int n_list_verts = 0);
+extern void model_allocate_interp_data(uint n_verts, uint n_norms, int n_list_verts = 0);
 
 
 // returns 1 if a point is in an octant.
Index: code/model/modelread.cpp
===================================================================
--- code/model/modelread.cpp (revision 10471)
+++ code/model/modelread.cpp (working copy)
@@ -5076,7 +5076,7 @@
 }
 
 #if BYTE_ORDER == BIG_ENDIAN
-extern void model_allocate_interp_data(int, int, int);
+extern void model_allocate_interp_data(uint, uint, int);
 
 // tigital -
 void swap_bsp_defpoints(ubyte * p)

Now, here's the changes that still need to be made on the PCS2 side of things:

1. Introduce a corresponding vert_large structure in PCS2's BSP writer
2. Switch to using it when necessary (by default would be kinda bad, I think)

This, however, requires setting up to build PCS2, which as I am discovering right now is not exactly trivial :P But that should not be an insurmountable hurdle, I think.
« Last Edit: February 22, 2014, 04:26:34 am by The E »
If I'm just aching this can't go on
I came from chasing dreams to feel alone
There must be changes, miss to feel strong
I really need lifе to touch me
--Evergrey, Where August Mourns

 

Offline Bryan See

  • Has anyone really been far as decided to use even go want to do look more like?
  • 210
  • Trying to redeem, but under Tiger Parents
    • Skype
    • Steam
    • Twitter
Re: SubObject Vert Limits (and canteloupe)
I've got a suggestion: How about changing the "unsigned short" declaration to "unsigned long"? That would increase the 64k limit further. I know this may require some work and changes involved, but you have to do it, because I, like many modellers, wanted to do more hi-poly models.
Bryan See - My FreeSpace Wiki User Page (Talk, Contributions)

Full Projects:
Shattered Stars

Campaigns:
Lost in the Mist - Cyrene vs. Psamtik
FreeSpace: Reunited

Ships:
GTS Hygeia, GTT Argo, SC Raguel

Tools:
FSO TC/Game template

I've been under attack by Tiger Parents like Jennifer Pan...

 

Offline The E

  • He's Ebeneezer Goode
  • Moderator
  • 213
  • Nothing personal, just tech support.
    • Steam
    • Twitter
Re: SubObject Vert Limits (and canteloupe)
No, we actually do not "have" to do anything. Way I see it, this is not a critical feature, since you can already do very complex models without issues; they just won't be as efficient as possible.

Also, this "some work" you're speaking of? It's actually more like "a lot of work".

A small tip for you: Never, ever assume that just because something sounds simple, it actually will be. There's nothing more frustrating than having to read replies that spell out the easy solution without knowledge of the ramifications of said easy solutions.
If I'm just aching this can't go on
I came from chasing dreams to feel alone
There must be changes, miss to feel strong
I really need lifе to touch me
--Evergrey, Where August Mourns