I've always wanted this, so here goes. Just like $detail_box, but a sphere.
Index: model.h
===================================================================
--- model.h (revision 8255)
+++ model.h (working copy)
@@ -307,7 +307,9 @@
vec3d render_box_min;
vec3d render_box_max;
- int use_render_box; // 0==do nothing, 1==only render this object if you are inside the box, -1==only if your out
+ float render_sphere_radius;
+ int use_render_box; // 0==do nothing, 1==only render this object if you are inside the box, -1==only if you're outside
+ int use_render_sphere; // 0==do nothing, 1==only render this object if you are inside the sphere, -1==only if you're outside
bool gun_rotation; // for animated weapon models
bool no_collisions; // for $no_collisions property - kazan
bool nocollide_this_only; //SUSHI: Like no_collisions, but not recursive. For the "replacement" collision model scheme.
@@ -340,7 +342,9 @@
next_sibling = 0;
num_details = 0;
num_arcs = 0;
+ render_sphere_radius = 0;
use_render_box = 0;
+ use_render_sphere = 0;
gun_rotation = false;
no_collisions = false;
nocollide_this_only = false;
Index: modelinterp.cpp
===================================================================
--- modelinterp.cpp (revision 8255)
+++ modelinterp.cpp (working copy)
@@ -78,9 +78,10 @@
static vertex **Interp_list = NULL;
static int Num_interp_list_verts_allocated = 0;
-static float Interp_box_scale = 1.0f;
+static float Interp_box_scale = 1.0f; // this is used to scale both detail boxes and spheres
static vec3d Interp_render_box_min = ZERO_VECTOR;
static vec3d Interp_render_box_max = ZERO_VECTOR;
+static float Interp_render_sphere_radius = 0.0f;
// -------------------------------------------------------------------
// lighting save stuff
@@ -361,6 +362,7 @@
Interp_box_scale = 1.0f;
Interp_render_box_min = vmd_zero_vector;
Interp_render_box_max = vmd_zero_vector;
+ Interp_render_sphere_radius = 0.0f;
}
/**
@@ -4290,7 +4292,19 @@
return -1;
}
+inline int in_sphere(vec3d *center, float radius)
+{
+ vec3d point;
+ vm_vec_sub(&point, &View_position, center);
+
+ if ( vm_vec_dist(&point, center) <= radius )
+ return 1;
+ else
+ return -1;
+}
+
+
void model_render_children_buffers(polymodel *pm, int mn, int detail_level)
{
int i;
@@ -4318,7 +4332,7 @@
Interp_thrust_scale_subobj = 0;
}
- // if using detail boxes, check that we are valid for the range
+ // if using detail boxes or spheres, check that we are valid for the range
if ( !(Interp_flags & MR_FULL_DETAIL) && model->use_render_box ) {
vm_vec_copy_scale(&Interp_render_box_min, &model->render_box_min, Interp_box_scale);
vm_vec_copy_scale(&Interp_render_box_max, &model->render_box_max, Interp_box_scale);
@@ -4326,7 +4340,13 @@
if ( (-model->use_render_box + in_box(&Interp_render_box_min, &Interp_render_box_max, &model->offset)) )
return;
}
+ if ( !(Interp_flags & MR_FULL_DETAIL) && model->use_render_sphere ) {
+ Interp_render_sphere_radius = model->render_sphere_radius * Interp_box_scale;
+ if ( (-model->use_render_sphere + in_sphere(&model->offset, Interp_render_sphere_radius)) )
+ return;
+ }
+
// Get submodel rotation data and use submodel orientation matrix
// to put together a matrix describing the final orientation of
// the submodel relative to its parent
@@ -4408,7 +4428,7 @@
bsp_info *model = &pm->submodel[mn];
- // if using detail boxes, check that we are valid for the range
+ // if using detail boxes or spheres, check that we are valid for the range
if ( !is_child && !(Interp_flags & MR_FULL_DETAIL) && model->use_render_box ) {
vm_vec_copy_scale(&Interp_render_box_min, &model->render_box_min, Interp_box_scale);
vm_vec_copy_scale(&Interp_render_box_max, &model->render_box_max, Interp_box_scale);
@@ -4416,7 +4436,13 @@
if ( (-model->use_render_box + in_box(&Interp_render_box_min, &Interp_render_box_max, &model->offset)) )
return;
}
+ if ( !(Interp_flags & MR_FULL_DETAIL) && model->use_render_sphere ) {
+ Interp_render_sphere_radius = model->render_sphere_radius * Interp_box_scale;
+ if ( (-model->use_render_sphere + in_sphere(&model->offset, Interp_render_sphere_radius)) )
+ return;
+ }
+
vec3d scale;
if (Interp_thrust_scale_subobj) {
Index: modelread.cpp
===================================================================
--- modelread.cpp (revision 8255)
+++ modelread.cpp (working copy)
@@ -1352,6 +1352,20 @@
}
}
+ if ( (p = strstr(props, "$detail_sphere:")) != NULL ) {
+ p += 15;
+ while (*p == ' ') p++;
+ pm->submodel[n].use_render_sphere = atoi(p);
+
+ if ( (p = strstr(props, "$radius:")) != NULL ) {
+ p += 8;
+ while (*p == ' ') p++;
+ pm->submodel[n].render_sphere_radius = (float)strtod(p, (char **)NULL);
+ } else {
+ pm->submodel[n].render_sphere_radius = pm->submodel[n].rad;
+ }
+ }
+
// Added for new handling of turret orientation - KeldorKatarn
matrix *orient = &pm->submodel[n].orientation;
Example:
$detail_sphere: 1
$radius: 1200
Will commit sometime soon if no problems are found.