Author Topic: [CANCELED] Submodel prop to expand bbox to encompass children  (Read 2018 times)

0 Members and 1 Guest are viewing this topic.

Offline zookeeper

  • *knock knock* Who's there? Poe. Poe who?
  • 210
[CANCELED] Submodel prop to expand bbox to encompass children
EDIT: This hasn't been necessary ever since PCS2 got the bounding box override controls.

I've found that quite often the bounding box of my detail-0 doesn't cover the whole ship (because of submodel subsystems), which is annoying because it causes the targeting brackets to get drawn wrong, and there's not always a good workaround available. This patch enables an $expanded_bbox submodel prop, which causes the game to re-calculate the bounding box for the submodel so that it fully encompasses all the submodel's children as well.

And before anyone states the obvious: of course it'd be better to have the feature in PCS2.

Code: [Select]
Index: model.h
===================================================================
--- model.h (revision 8188)
+++ model.h (working copy)
@@ -316,6 +316,7 @@
  char lod_name[MAX_NAME_LEN]; //FUBAR:  Name to be used for LOD naming comparison to preserve compatibility with older tables.  Only used on LOD0
  bool attach_thrusters; //zookeeper: If set and this submodel or any of its parents rotates, also rotates associated thrusters.
  float dumb_turn_rate;
+ bool expanded_bbox; //zookeeper: Expand the bounding box of this submodel to also encompass any child submodels.
 
  /* If you've got a better way to do this, please implement it! */
  void Reset( )
@@ -351,6 +352,7 @@
  rad = 0.f;
  lod_name[ 0 ] = '\0';
  attach_thrusters = false;
+ expanded_bbox = false;
 
  /* Compound types */
  memset( live_debris, 0, sizeof( live_debris ) );
Index: modelread.cpp
===================================================================
--- modelread.cpp (revision 8188)
+++ modelread.cpp (working copy)
@@ -930,7 +930,58 @@
  box[7].xyz.x = big_mn->xyz.x; box[7].xyz.y = big_mx->xyz.y; box[7].xyz.z = big_mx->xyz.z;
 }
 
+/**
+ * Returns the min and max points of a bounding box which would be big enough to
+ * encompass not only the given submodel itself, but all its children as well.
+ *
+ * @param *mins Output point (min)
+ * @param *maxs Output point (max)
+ * @param *pm The model we're interested in
+ * @param submodel_num Which submodel's min and max we want
+ */
+void submodel_calc_expanded_bound_box( vec3d *mins, vec3d *maxs, polymodel *pm, int submodel_num )
+{
+ vec3d min, max;
 
+ vm_vec_add(&min, &pm->submodel[submodel_num].min, &pm->submodel[submodel_num].offset);
+ vm_vec_add(&max, &pm->submodel[submodel_num].max, &pm->submodel[submodel_num].offset);
+
+ int child_submodel_num = pm->submodel[submodel_num].first_child;
+
+ if ( child_submodel_num == -1) {
+ *mins = min;
+ *maxs = max;
+
+ return;
+ }
+
+ while ( child_submodel_num != -1 ) {
+ vec3d child_min;
+ vec3d child_max;
+
+ submodel_calc_expanded_bound_box(&child_min, &child_max, pm, child_submodel_num);
+
+ vm_vec_add2(&child_min, &pm->submodel[submodel_num].offset);
+ vm_vec_add2(&child_max, &pm->submodel[submodel_num].offset);
+
+ min.xyz.x = MIN(min.xyz.x, child_min.xyz.x);
+ min.xyz.y = MIN(min.xyz.y, child_min.xyz.y);
+ min.xyz.z = MIN(min.xyz.z, child_min.xyz.z);
+ max.xyz.x = MAX(max.xyz.x, child_max.xyz.x);
+ max.xyz.y = MAX(max.xyz.y, child_max.xyz.y);
+ max.xyz.z = MAX(max.xyz.z, child_max.xyz.z);
+
+ child_submodel_num = pm->submodel[child_submodel_num].next_sibling;
+ }
+
+ vm_vec_sub2(&min, &pm->submodel[submodel_num].offset);
+ vm_vec_sub2(&max, &pm->submodel[submodel_num].offset);
+
+ *mins = min;
+ *maxs = max;
+}
+
+
 void parse_triggers(int &n_trig, queued_animation **triggers, char *props);
 
 
@@ -1322,6 +1373,11 @@
  else
  pm->submodel[n].attach_thrusters = false;
 
+ if (strstr(props, "$expanded_bbox") != NULL )
+ pm->submodel[n].expanded_bbox = true;
+ else
+ pm->submodel[n].expanded_bbox = false;
+
  if ( (p = strstr(props, "$detail_box:")) != NULL ) {
  p += 12;
  while (*p == ' ') p++;
@@ -2448,6 +2504,16 @@
 
  create_family_tree(pm);
 
+ // Give an expanded bounding box to any submodel which wants one
+ for (int i=0; i<pm->n_models; i++ ) {
+ if ( pm->submodel[i].expanded_bbox ) {
+ vec3d min, max;
+
+ submodel_calc_expanded_bound_box(&min, &max, pm, i);
+ model_calc_bound_box(pm->submodel[i].bounding_box, &min, &max);
+ }
+ }
+
  // maybe generate vertex buffers
  create_vertex_buffer(pm);
 

EDIT: Note that this does not even try to account for rotating subsystems.
« Last Edit: December 27, 2013, 02:06:39 pm by zookeeper »

 

Offline zookeeper

  • *knock knock* Who's there? Poe. Poe who?
  • 210
Re: [patch] Submodel prop to expand bbox to encompass children
Oops, submodels which weren't at 0,0,0 weren't handled right. Updated the patch.

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
Re: [patch] Submodel prop to expand bbox to encompass children
does this let you specify the size of the bbox just tells the game to recompute? i know sometimes i want to set the bounding box a little bit bigger so that collision detection is handled better for animated objects.
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline zookeeper

  • *knock knock* Who's there? Poe. Poe who?
  • 210
Re: [patch] Submodel prop to expand bbox to encompass children
does this let you specify the size of the bbox just tells the game to recompute? i know sometimes i want to set the bounding box a little bit bigger so that collision detection is handled better for animated objects.
Nope, it just recomputes the box.

However, before I wrote this I also implemented a submodel prop with which you could override the bbox dimensions, but that seemed so unwieldy that I didn't even save it. It would be trivial to rewrite it though, so if it's really really needed I can do that.

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
Re: [patch] Submodel prop to expand bbox to encompass children
there are other ways to get around problems like that, the obvious way is with a big invisible box and no collide invisible. manually editing the bbox is a somewhat confusing operation, and an unnecessarily large bbox will be a bigger target for collisions (requiring additional collision testing), i think id rather have the box resized by the engine. just need a slightly different algorithm to determine the box size. perhaps a property for animated subobjects.

i figure there's probably a way to compute the bbox for an object that rotates about any number of axes. for a 2d example, find the bbox corner that is furthest from the submodel's center on any given plane and get its distance. then if you were to draw a circle about the center at of the model at that radius. then create a new bbox that can encompass that circle (the box would be square for the most part), then any possible rotation about the planes normal will result in the rotated submodel fitting into that box. the bounding box dimensions parallel to the plane axis could just be left as is. this is probably adequate for most flat rotations (anything about a single orthogonal axis). if necessary, the resulting box would be expanded to encompass children.

rotations on arbitrary axes or multiple orthogonal axes would only be slightly more complex. just figure out the bbox for each plane and use the largest dimentions for each axis from the 3 results. this results in a cube shaped box that should encompass all possible rotations. again expand to include children. also when processing the bounding boxes, it helps to expand children first, and then make sure the bounding boxes for the parents can contain them. this also allows for chains of animated objects to have proper collision detection.

you could probably also include some information about possible rotation ranges and use that to come up with the smallest box possible, but i dont know an algorithm for that.
« Last Edit: January 12, 2012, 04:20:06 pm by Nuke »
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 

Offline zookeeper

  • *knock knock* Who's there? Poe. Poe who?
  • 210
Re: [patch] Submodel prop to expand bbox to encompass children
there are other ways to get around problems like that, the obvious way is with a big invisible box and no collide invisible. manually editing the bbox is a somewhat confusing operation, and an unnecessarily large bbox will be a bigger target for collisions (requiring additional collision testing), i think id rather have the box resized by the engine.

Invisible non-collideable boxes are all nice and good as long as you don't use for example the wireframe targeting view, or care for the new ship tech animations in the loadout screen; the box is going to show up at those places (I'm not sure if there are any others) and look a bit silly.

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
Re: [patch] Submodel prop to expand bbox to encompass children
yea its somewhat of a dirty hack to use an invisible box in that way. something id rather like to avoid.
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN