View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0002351 | FSSCP | tables | public | 2010-12-14 01:47 | 2010-12-27 08:04 |
Reporter | FUBAR-BDHR | Assigned To | Echelon9 | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Product Version | 3.6.13 | ||||
Fixed in Version | 3.6.13 | ||||
Summary | 0002351: Animated subsystems not counted as rotating allowing max to be exceeded | ||||
Description | It appears that subsystems with animation triggered count toward MAX_ROTATING_SUBMODELS but there is absolutely no checking for this. Strange things happen when rotating subsystems + animated ones exceed the max. In my testing turrets some multi-part turrets started firing 90 degrees off their normals. No idea how to test this one with retail data. | ||||
Tags | No tags attached. | ||||
|
FUBAR, can you test with the proposed patch attached. Thanks. This converts submodel_list to an STL vector (and also renames it to submodel_vector to be accurate). No need to bump the limit in future. |
2010-12-27 05:48
|
mantis-2351_proposed_patch_3.patch (15,843 bytes)
Index: code/asteroid/asteroid.cpp =================================================================== --- code/asteroid/asteroid.cpp (revision 6889) +++ code/asteroid/asteroid.cpp (working copy) @@ -976,8 +976,7 @@ // first test against the sphere - if this fails then don't do any submodel tests mc.flags = MC_ONLY_SPHERE | MC_CHECK_SPHERELINE; - int submodel_list[MAX_ROTATING_SUBMODELS]; - int num_rotating_submodels = 0; + SCP_vector<int> submodel_vector; polymodel *pm; polymodel_instance *pmi; @@ -989,7 +988,7 @@ // Do collision the cool new way if ( asteroid_hit_info->collide_rotate ) { // We collide with the sphere, find the list of rotating submodels and test one at a time - model_get_rotating_submodel_list(submodel_list, &num_rotating_submodels, heavy_obj); + model_get_rotating_submodel_list(&submodel_vector, heavy_obj); // Get polymodel and turn off all rotating submodels, collide against only 1 at a time. pm = model_get(Ship_info[Ships[heavy_obj->instance].ship_info_index].model_num); @@ -997,8 +996,8 @@ // turn off all rotating submodels and test for collision int i; - for (i=0; i<num_rotating_submodels; i++) { - pmi->submodel[submodel_list[i]].collision_checked = true; + for (i=0; i<submodel_vector.size(); i++) { + pmi->submodel[submodel_vector[i]].collision_checked = true; } // reset flags to check MC_CHECK_MODEL | MC_CHECK_SPHERELINE and maybe MC_CHECK_INVISIBLE_FACES and MC_SUBMODEL_INSTANCE @@ -1006,26 +1005,26 @@ // check each submodel in turn - for (i=0; i<num_rotating_submodels; i++) { + for (i=0; i<submodel_vector.size(); i++) { // turn on submodel for collision test - pmi->submodel[submodel_list[i]].collision_checked = false; + pmi->submodel[submodel_vector[i]].collision_checked = false; // set angles for last frame (need to set to prev to get p0) - angles copy_angles = pmi->submodel[submodel_list[i]].angs; + angles copy_angles = pmi->submodel[submodel_vector[i]].angs; // find the start and end positions of the sphere in submodel RF - pmi->submodel[submodel_list[i]].angs = pmi->submodel[submodel_list[i]].prev_angs; - world_find_model_instance_point(&p0, &light_obj->last_pos, pm, pmi, submodel_list[i], &heavy_obj->last_orient, &heavy_obj->last_pos); + pmi->submodel[submodel_vector[i]].angs = pmi->submodel[submodel_vector[i]].prev_angs; + world_find_model_instance_point(&p0, &light_obj->last_pos, pm, pmi, submodel_vector[i], &heavy_obj->last_orient, &heavy_obj->last_pos); - pmi->submodel[submodel_list[i]].angs = copy_angles; - world_find_model_instance_point(&p1, &light_obj->pos, pm, pmi, submodel_list[i], &heavy_obj->orient, &heavy_obj->pos); + pmi->submodel[submodel_vector[i]].angs = copy_angles; + world_find_model_instance_point(&p1, &light_obj->pos, pm, pmi, submodel_vector[i], &heavy_obj->orient, &heavy_obj->pos); mc.p0 = &p0; mc.p1 = &p1; // mc.pos = zero // in submodel RF mc.orient = &vmd_identity_matrix; - mc.submodel_num = submodel_list[i]; + mc.submodel_num = submodel_vector[i]; if ( model_collide(&mc) ) { if ( mc.hit_dist < asteroid_hit_info->hit_time ) { @@ -1047,7 +1046,7 @@ } } // Don't look at this submodel again - pmi->submodel[submodel_list[i]].collision_checked = true; + pmi->submodel[submodel_vector[i]].collision_checked = true; } } Index: code/object/collideshipship.cpp =================================================================== --- code/object/collideshipship.cpp (revision 6889) +++ code/object/collideshipship.cpp (working copy) @@ -247,8 +247,7 @@ // first test against the sphere - if this fails then don't do any submodel tests mc.flags = MC_ONLY_SPHERE | MC_CHECK_SPHERELINE; - int submodel_list[MAX_ROTATING_SUBMODELS]; - int num_rotating_submodels = 0; + SCP_vector<int> submodel_vector; int valid_hit_occured = 0; polymodel *pm; polymodel_instance *pmi; @@ -261,41 +260,41 @@ // Do collision the cool new way if ( ship_ship_hit_info->collide_rotate ) { - model_get_rotating_submodel_list(submodel_list, &num_rotating_submodels, heavy_obj); + model_get_rotating_submodel_list(&submodel_vector, heavy_obj); pm = model_get(Ship_info[heavy_shipp->ship_info_index].model_num); pmi = model_get_instance(heavy_shipp->model_instance_num); // turn off all rotating submodels and test for collision int i; - for (i=0; i<num_rotating_submodels; i++) { - pmi->submodel[submodel_list[i]].collision_checked = true; + for (i=0; i<submodel_vector.size(); i++) { + pmi->submodel[submodel_vector[i]].collision_checked = true; } // reset flags to check MC_CHECK_MODEL | MC_CHECK_SPHERELINE and maybe MC_CHECK_INVISIBLE_FACES and MC_SUBMODEL_INSTANCE mc.flags = copy_flags | MC_SUBMODEL_INSTANCE; // check each submodel in turn - for (i=0; i<num_rotating_submodels; i++) { + for (i=0; i<submodel_vector.size(); i++) { // turn on submodel for collision test - pmi->submodel[submodel_list[i]].collision_checked = false; + pmi->submodel[submodel_vector[i]].collision_checked = false; // set angles for last frame - angles copy_angles = pmi->submodel[submodel_list[i]].angs; + angles copy_angles = pmi->submodel[submodel_vector[i]].angs; // find the start and end positions of the sphere in submodel RF - pmi->submodel[submodel_list[i]].angs = pmi->submodel[submodel_list[i]].prev_angs; - world_find_model_instance_point(&p0, &light_obj->last_pos, pm, pmi, submodel_list[i], &heavy_obj->last_orient, &heavy_obj->last_pos); + pmi->submodel[submodel_vector[i]].angs = pmi->submodel[submodel_vector[i]].prev_angs; + world_find_model_instance_point(&p0, &light_obj->last_pos, pm, pmi, submodel_vector[i], &heavy_obj->last_orient, &heavy_obj->last_pos); - pmi->submodel[submodel_list[i]].angs = copy_angles; - world_find_model_instance_point(&p1, &light_obj->pos, pm, pmi, submodel_list[i], &heavy_obj->orient, &heavy_obj->pos); + pmi->submodel[submodel_vector[i]].angs = copy_angles; + world_find_model_instance_point(&p1, &light_obj->pos, pm, pmi, submodel_vector[i], &heavy_obj->orient, &heavy_obj->pos); mc.p0 = &p0; mc.p1 = &p1; // mc.pos = zero // in submodel RF mc.orient = &vmd_identity_matrix; - mc.submodel_num = submodel_list[i]; + mc.submodel_num = submodel_vector[i]; if ( model_collide(&mc) ) { if (mc.hit_dist < ship_ship_hit_info->hit_time ) { @@ -339,17 +338,17 @@ // set submodel angle at time of collision // TODO: generalize... what happens when angle passes 0 or 2PI angles temp_angs; - vm_vec_sub(&diff, (vec3d*)&pm->submodel[submodel_list[i]].angs, (vec3d*)&pm->submodel[submodel_list[i]].sii->prev_angs); - vm_vec_scale_add((vec3d*)&temp_angs, (vec3d *)&pm->submodel[submodel_list[i]].sii->prev_angs, &diff, mc.hit_dist); - pm->submodel[submodel_list[i]].angs = temp_angs; + vm_vec_sub(&diff, (vec3d*)&pm->submodel[submodel_vector[i]].angs, (vec3d*)&pm->submodel[submodel_vector[i]].sii->prev_angs); + vm_vec_scale_add((vec3d*)&temp_angs, (vec3d *)&pm->submodel[submodel_vector[i]].sii->prev_angs, &diff, mc.hit_dist); + pm->submodel[submodel_vector[i]].angs = temp_angs; // find intersection point in submodel RF - THEN advance to end of frametime. vec3d temp = int_light_pos; - world_find_model_point(&int_submodel_pos, &int_light_pos, pm, submodel_list[i], &int_heavy_orient, &int_heavy_pos); + world_find_model_point(&int_submodel_pos, &int_light_pos, pm, submodel_vector[i], &int_heavy_orient, &int_heavy_pos); vec3d temp2; // Advance to end of frametime - pm->submodel[submodel_list[i]].angs = copy_angles; + pm->submodel[submodel_vector[i]].angs = copy_angles; model_find_world_point(&ship_ship_hit_info->light_collision_cm_pos, &int_submodel_pos, mc.model_num, mc.hit_submodel, mc.orient, &zero); vm_vec_sub(&temp2, &ship_ship_hit_info->light_collision_cm_pos, &ship_ship_hit_info->hit_pos); */ @@ -359,7 +358,7 @@ } } // Don't look at this submodel again - pmi->submodel[submodel_list[i]].collision_checked = true; + pmi->submodel[submodel_vector[i]].collision_checked = true; } } Index: code/model/model.h =================================================================== --- code/model/model.h (revision 6889) +++ code/model/model.h (working copy) @@ -41,8 +41,6 @@ #define MOVEMENT_AXIS_Y 2 #define MOVEMENT_AXIS_Z 1 -#define MAX_ROTATING_SUBMODELS 50 - // defines for special objects like gun and missile points, docking point, etc // Hoffoss: Please make sure that subsystem NONE is always index 0, and UNKNOWN is // always the last subsystem in the list. Also, make sure that MAX is correct. @@ -130,6 +128,7 @@ #define MSS_FLAG_NO_LIVE_DEBRIS (1 << 25) // sets the subsys not to release live debris #define MSS_FLAG_IGNORE_IF_DEAD (1 << 26) // tells homing missiles to ignore the subsys if its dead and home on to hull instead of earlier subsys pos #define MSS_FLAG_ALLOW_VANISHING (1 << 27) // allows subsystem to vanish (prevents explosions & sounds effects from being played) +#define MSS_FLAG_DAMAGE_AS_HULL (1 << 28) // applys armor damage to subsystem instead of subsystem damage - FUBAR // definition of stepped rotation struct typedef struct stepped_rotation { @@ -863,7 +862,7 @@ void world_find_model_instance_point(vec3d *out, vec3d *world_pt, polymodel *pm, polymodel_instance *pmi, int submodel_num, matrix *orient, vec3d *pos); // Given a polygon model index, find a list of rotating submodels to be used for collision -void model_get_rotating_submodel_list(int *submodel_list, int *num_rotating_submodesl, object *objp); +void model_get_rotating_submodel_list(SCP_vector<int> *submodel_vector, object *objp); // For a rotating submodel, find a point on the axis void model_init_submodel_axis_pt(submodel_instance_info *sii, int model_num, int submodel_num); Index: code/model/modelread.cpp =================================================================== --- code/model/modelread.cpp (revision 6889) +++ code/model/modelread.cpp (working copy) @@ -3866,16 +3866,15 @@ return found; } -void model_get_rotating_submodel_list(int *submodel_list, int *num_rotating_submodels, object *objp) +void model_get_rotating_submodel_list(SCP_vector<int> *submodel_vector, object *objp) { Assert(objp->type == OBJ_SHIP); - + // Check if not currently rotating - then treat as part of superstructure. int modelnum = Ship_info[Ships[objp->instance].ship_info_index].model_num; polymodel *pm = model_get(modelnum); bsp_info *child_submodel; - - *num_rotating_submodels = 0; + child_submodel = &pm->submodel[pm->detail[0]]; int i = child_submodel->first_child; @@ -3898,8 +3897,7 @@ // found the correct subsystem - now check delta rotation angle not too large float delta_angle = get_submodel_delta_angle(&subsys->submodel_info_1); if (delta_angle < MAX_SUBMODEL_COLLISION_ROT_ANGLE) { - Assert(*num_rotating_submodels < MAX_ROTATING_SUBMODELS-1); - submodel_list[(*num_rotating_submodels)++] = i; + submodel_vector->push_back(i); } break; } @@ -3913,14 +3911,14 @@ //#define MODEL_CHECK #ifdef MODEL_CHECK ship *pship = &Ships[objp->instance]; - for (int idx=0; idx<*num_rotating_submodels; idx++) { - int valid = rotating_submodel_has_ship_subsys(submodel_list[idx], pship); + for (int idx=0; idx<submodel_vector->size(); idx++) { + int valid = rotating_submodel_has_ship_subsys(submodel_vector[idx], pship); // Assert( valid ); if ( !valid ) { - Warning( LOCATION, "Ship %s has rotating submodel [%s] without ship subsystem\n", pship->ship_name, pm->submodel[submodel_list[idx]].name ); - pm->submodel[submodel_list[idx]].movement_type &= ~MOVEMENT_TYPE_ROT; - *num_rotating_submodels = 0; + Warning( LOCATION, "Ship %s has rotating submodel [%s] without ship subsystem\n", pship->ship_name, pm->submodel[submodel_vector[idx]].name ); + pm->submodel[submodel_vector[idx]].movement_type &= ~MOVEMENT_TYPE_ROT; + submodel_vector->erase(submodel_vector->begin()+i); } } #endif Index: code/debris/debris.cpp =================================================================== --- code/debris/debris.cpp (revision 6889) +++ code/debris/debris.cpp (working copy) @@ -920,8 +920,7 @@ // first test against the sphere - if this fails then don't do any submodel tests mc.flags = MC_ONLY_SPHERE | MC_CHECK_SPHERELINE; - int submodel_list[MAX_ROTATING_SUBMODELS]; - int num_rotating_submodels = 0; + SCP_vector<int> submodel_vector; polymodel *pm; polymodel_instance *pmi; @@ -935,7 +934,7 @@ // Do collision the cool new way if ( debris_hit_info->collide_rotate ) { // We collide with the sphere, find the list of rotating submodels and test one at a time - model_get_rotating_submodel_list(submodel_list, &num_rotating_submodels, heavy_obj); + model_get_rotating_submodel_list(&submodel_vector, heavy_obj); // Get polymodel and turn off all rotating submodels, collide against only 1 at a time. pm = model_get(Ship_info[Ships[heavy_obj->instance].ship_info_index].model_num); @@ -943,34 +942,34 @@ // turn off all rotating submodels and test for collision int i; - for (i=0; i<num_rotating_submodels; i++) { - pmi->submodel[submodel_list[i]].collision_checked = true; + for (i=0; i<submodel_vector.size(); i++) { + pmi->submodel[submodel_vector[i]].collision_checked = true; } // reset flags to check MC_CHECK_MODEL | MC_CHECK_SPHERELINE and maybe MC_CHECK_INVISIBLE_FACES and MC_SUBMODEL_INSTANCE mc.flags = copy_flags | MC_SUBMODEL_INSTANCE; // check each submodel in turn - for (i=0; i<num_rotating_submodels; i++) { + for (i=0; i<submodel_vector.size(); i++) { // turn on submodel for collision test - pmi->submodel[submodel_list[i]].collision_checked = false; + pmi->submodel[submodel_vector[i]].collision_checked = false; // set angles for last frame (need to set to prev to get p0) - angles copy_angles = pmi->submodel[submodel_list[i]].angs; + angles copy_angles = pmi->submodel[submodel_vector[i]].angs; // find the start and end positions of the sphere in submodel RF - pmi->submodel[submodel_list[i]].angs = pmi->submodel[submodel_list[i]].prev_angs; - world_find_model_instance_point(&p0, &light_obj->last_pos, pm, pmi, submodel_list[i], &heavy_obj->last_orient, &heavy_obj->last_pos); + pmi->submodel[submodel_vector[i]].angs = pmi->submodel[submodel_vector[i]].prev_angs; + world_find_model_instance_point(&p0, &light_obj->last_pos, pm, pmi, submodel_vector[i], &heavy_obj->last_orient, &heavy_obj->last_pos); - pmi->submodel[submodel_list[i]].angs = copy_angles; - world_find_model_instance_point(&p1, &light_obj->pos, pm, pmi, submodel_list[i], &heavy_obj->orient, &heavy_obj->pos); + pmi->submodel[submodel_vector[i]].angs = copy_angles; + world_find_model_instance_point(&p1, &light_obj->pos, pm, pmi, submodel_vector[i], &heavy_obj->orient, &heavy_obj->pos); mc.p0 = &p0; mc.p1 = &p1; // mc.pos = zero // in submodel RF mc.orient = &vmd_identity_matrix; - mc.submodel_num = submodel_list[i]; + mc.submodel_num = submodel_vector[i]; if ( model_collide(&mc) ) { if ( mc.hit_dist < debris_hit_info->hit_time ) { @@ -993,7 +992,7 @@ } } // Don't look at this submodel again - pmi->submodel[submodel_list[i]].collision_checked = true; + pmi->submodel[submodel_vector[i]].collision_checked = true; } } |
2010-12-27 07:32
|
mantis-2351_proposed_patch_4.patch (16,005 bytes)
Index: code/asteroid/asteroid.cpp =================================================================== --- code/asteroid/asteroid.cpp (revision 6892) +++ code/asteroid/asteroid.cpp (working copy) @@ -976,8 +976,7 @@ // first test against the sphere - if this fails then don't do any submodel tests mc.flags = MC_ONLY_SPHERE | MC_CHECK_SPHERELINE; - int submodel_list[MAX_ROTATING_SUBMODELS]; - int num_rotating_submodels = 0; + SCP_vector<int> submodel_vector; polymodel *pm; polymodel_instance *pmi; @@ -989,16 +988,15 @@ // Do collision the cool new way if ( asteroid_hit_info->collide_rotate ) { // We collide with the sphere, find the list of rotating submodels and test one at a time - model_get_rotating_submodel_list(submodel_list, &num_rotating_submodels, heavy_obj); + model_get_rotating_submodel_list(&submodel_vector, heavy_obj); // Get polymodel and turn off all rotating submodels, collide against only 1 at a time. pm = model_get(Ship_info[Ships[heavy_obj->instance].ship_info_index].model_num); pmi = model_get_instance(Ships[ship_obj->instance].model_instance_num); // turn off all rotating submodels and test for collision - int i; - for (i=0; i<num_rotating_submodels; i++) { - pmi->submodel[submodel_list[i]].collision_checked = true; + for (size_t i=0; i<submodel_vector.size(); i++) { + pmi->submodel[submodel_vector[i]].collision_checked = true; } // reset flags to check MC_CHECK_MODEL | MC_CHECK_SPHERELINE and maybe MC_CHECK_INVISIBLE_FACES and MC_SUBMODEL_INSTANCE @@ -1006,26 +1004,26 @@ // check each submodel in turn - for (i=0; i<num_rotating_submodels; i++) { + for (size_t i=0; i<submodel_vector.size(); i++) { // turn on submodel for collision test - pmi->submodel[submodel_list[i]].collision_checked = false; + pmi->submodel[submodel_vector[i]].collision_checked = false; // set angles for last frame (need to set to prev to get p0) - angles copy_angles = pmi->submodel[submodel_list[i]].angs; + angles copy_angles = pmi->submodel[submodel_vector[i]].angs; // find the start and end positions of the sphere in submodel RF - pmi->submodel[submodel_list[i]].angs = pmi->submodel[submodel_list[i]].prev_angs; - world_find_model_instance_point(&p0, &light_obj->last_pos, pm, pmi, submodel_list[i], &heavy_obj->last_orient, &heavy_obj->last_pos); + pmi->submodel[submodel_vector[i]].angs = pmi->submodel[submodel_vector[i]].prev_angs; + world_find_model_instance_point(&p0, &light_obj->last_pos, pm, pmi, submodel_vector[i], &heavy_obj->last_orient, &heavy_obj->last_pos); - pmi->submodel[submodel_list[i]].angs = copy_angles; - world_find_model_instance_point(&p1, &light_obj->pos, pm, pmi, submodel_list[i], &heavy_obj->orient, &heavy_obj->pos); + pmi->submodel[submodel_vector[i]].angs = copy_angles; + world_find_model_instance_point(&p1, &light_obj->pos, pm, pmi, submodel_vector[i], &heavy_obj->orient, &heavy_obj->pos); mc.p0 = &p0; mc.p1 = &p1; // mc.pos = zero // in submodel RF mc.orient = &vmd_identity_matrix; - mc.submodel_num = submodel_list[i]; + mc.submodel_num = submodel_vector[i]; if ( model_collide(&mc) ) { if ( mc.hit_dist < asteroid_hit_info->hit_time ) { @@ -1047,7 +1045,7 @@ } } // Don't look at this submodel again - pmi->submodel[submodel_list[i]].collision_checked = true; + pmi->submodel[submodel_vector[i]].collision_checked = true; } } Index: code/object/collideshipship.cpp =================================================================== --- code/object/collideshipship.cpp (revision 6892) +++ code/object/collideshipship.cpp (working copy) @@ -247,8 +247,7 @@ // first test against the sphere - if this fails then don't do any submodel tests mc.flags = MC_ONLY_SPHERE | MC_CHECK_SPHERELINE; - int submodel_list[MAX_ROTATING_SUBMODELS]; - int num_rotating_submodels = 0; + SCP_vector<int> submodel_vector; int valid_hit_occured = 0; polymodel *pm; polymodel_instance *pmi; @@ -261,41 +260,40 @@ // Do collision the cool new way if ( ship_ship_hit_info->collide_rotate ) { - model_get_rotating_submodel_list(submodel_list, &num_rotating_submodels, heavy_obj); + model_get_rotating_submodel_list(&submodel_vector, heavy_obj); pm = model_get(Ship_info[heavy_shipp->ship_info_index].model_num); pmi = model_get_instance(heavy_shipp->model_instance_num); // turn off all rotating submodels and test for collision - int i; - for (i=0; i<num_rotating_submodels; i++) { - pmi->submodel[submodel_list[i]].collision_checked = true; + for (size_t i=0; i<submodel_vector.size(); i++) { + pmi->submodel[submodel_vector[i]].collision_checked = true; } // reset flags to check MC_CHECK_MODEL | MC_CHECK_SPHERELINE and maybe MC_CHECK_INVISIBLE_FACES and MC_SUBMODEL_INSTANCE mc.flags = copy_flags | MC_SUBMODEL_INSTANCE; // check each submodel in turn - for (i=0; i<num_rotating_submodels; i++) { + for (size_t i=0; i<submodel_vector.size(); i++) { // turn on submodel for collision test - pmi->submodel[submodel_list[i]].collision_checked = false; + pmi->submodel[submodel_vector[i]].collision_checked = false; // set angles for last frame - angles copy_angles = pmi->submodel[submodel_list[i]].angs; + angles copy_angles = pmi->submodel[submodel_vector[i]].angs; // find the start and end positions of the sphere in submodel RF - pmi->submodel[submodel_list[i]].angs = pmi->submodel[submodel_list[i]].prev_angs; - world_find_model_instance_point(&p0, &light_obj->last_pos, pm, pmi, submodel_list[i], &heavy_obj->last_orient, &heavy_obj->last_pos); + pmi->submodel[submodel_vector[i]].angs = pmi->submodel[submodel_vector[i]].prev_angs; + world_find_model_instance_point(&p0, &light_obj->last_pos, pm, pmi, submodel_vector[i], &heavy_obj->last_orient, &heavy_obj->last_pos); - pmi->submodel[submodel_list[i]].angs = copy_angles; - world_find_model_instance_point(&p1, &light_obj->pos, pm, pmi, submodel_list[i], &heavy_obj->orient, &heavy_obj->pos); + pmi->submodel[submodel_vector[i]].angs = copy_angles; + world_find_model_instance_point(&p1, &light_obj->pos, pm, pmi, submodel_vector[i], &heavy_obj->orient, &heavy_obj->pos); mc.p0 = &p0; mc.p1 = &p1; // mc.pos = zero // in submodel RF mc.orient = &vmd_identity_matrix; - mc.submodel_num = submodel_list[i]; + mc.submodel_num = submodel_vector[i]; if ( model_collide(&mc) ) { if (mc.hit_dist < ship_ship_hit_info->hit_time ) { @@ -339,17 +337,17 @@ // set submodel angle at time of collision // TODO: generalize... what happens when angle passes 0 or 2PI angles temp_angs; - vm_vec_sub(&diff, (vec3d*)&pm->submodel[submodel_list[i]].angs, (vec3d*)&pm->submodel[submodel_list[i]].sii->prev_angs); - vm_vec_scale_add((vec3d*)&temp_angs, (vec3d *)&pm->submodel[submodel_list[i]].sii->prev_angs, &diff, mc.hit_dist); - pm->submodel[submodel_list[i]].angs = temp_angs; + vm_vec_sub(&diff, (vec3d*)&pm->submodel[submodel_vector[i]].angs, (vec3d*)&pm->submodel[submodel_vector[i]].sii->prev_angs); + vm_vec_scale_add((vec3d*)&temp_angs, (vec3d *)&pm->submodel[submodel_vector[i]].sii->prev_angs, &diff, mc.hit_dist); + pm->submodel[submodel_vector[i]].angs = temp_angs; // find intersection point in submodel RF - THEN advance to end of frametime. vec3d temp = int_light_pos; - world_find_model_point(&int_submodel_pos, &int_light_pos, pm, submodel_list[i], &int_heavy_orient, &int_heavy_pos); + world_find_model_point(&int_submodel_pos, &int_light_pos, pm, submodel_vector[i], &int_heavy_orient, &int_heavy_pos); vec3d temp2; // Advance to end of frametime - pm->submodel[submodel_list[i]].angs = copy_angles; + pm->submodel[submodel_vector[i]].angs = copy_angles; model_find_world_point(&ship_ship_hit_info->light_collision_cm_pos, &int_submodel_pos, mc.model_num, mc.hit_submodel, mc.orient, &zero); vm_vec_sub(&temp2, &ship_ship_hit_info->light_collision_cm_pos, &ship_ship_hit_info->hit_pos); */ @@ -359,7 +357,7 @@ } } // Don't look at this submodel again - pmi->submodel[submodel_list[i]].collision_checked = true; + pmi->submodel[submodel_vector[i]].collision_checked = true; } } Index: code/model/model.h =================================================================== --- code/model/model.h (revision 6892) +++ code/model/model.h (working copy) @@ -41,8 +41,6 @@ #define MOVEMENT_AXIS_Y 2 #define MOVEMENT_AXIS_Z 1 -#define MAX_ROTATING_SUBMODELS 50 - // defines for special objects like gun and missile points, docking point, etc // Hoffoss: Please make sure that subsystem NONE is always index 0, and UNKNOWN is // always the last subsystem in the list. Also, make sure that MAX is correct. @@ -130,6 +128,7 @@ #define MSS_FLAG_NO_LIVE_DEBRIS (1 << 25) // sets the subsys not to release live debris #define MSS_FLAG_IGNORE_IF_DEAD (1 << 26) // tells homing missiles to ignore the subsys if its dead and home on to hull instead of earlier subsys pos #define MSS_FLAG_ALLOW_VANISHING (1 << 27) // allows subsystem to vanish (prevents explosions & sounds effects from being played) +#define MSS_FLAG_DAMAGE_AS_HULL (1 << 28) // applys armor damage to subsystem instead of subsystem damage - FUBAR // definition of stepped rotation struct typedef struct stepped_rotation { @@ -863,7 +862,7 @@ void world_find_model_instance_point(vec3d *out, vec3d *world_pt, polymodel *pm, polymodel_instance *pmi, int submodel_num, matrix *orient, vec3d *pos); // Given a polygon model index, find a list of rotating submodels to be used for collision -void model_get_rotating_submodel_list(int *submodel_list, int *num_rotating_submodesl, object *objp); +void model_get_rotating_submodel_list(SCP_vector<int> *submodel_vector, object *objp); // For a rotating submodel, find a point on the axis void model_init_submodel_axis_pt(submodel_instance_info *sii, int model_num, int submodel_num); Index: code/model/modelread.cpp =================================================================== --- code/model/modelread.cpp (revision 6892) +++ code/model/modelread.cpp (working copy) @@ -3866,16 +3866,15 @@ return found; } -void model_get_rotating_submodel_list(int *submodel_list, int *num_rotating_submodels, object *objp) +void model_get_rotating_submodel_list(SCP_vector<int> *submodel_vector, object *objp) { Assert(objp->type == OBJ_SHIP); - + // Check if not currently rotating - then treat as part of superstructure. int modelnum = Ship_info[Ships[objp->instance].ship_info_index].model_num; polymodel *pm = model_get(modelnum); bsp_info *child_submodel; - - *num_rotating_submodels = 0; + child_submodel = &pm->submodel[pm->detail[0]]; int i = child_submodel->first_child; @@ -3898,8 +3897,7 @@ // found the correct subsystem - now check delta rotation angle not too large float delta_angle = get_submodel_delta_angle(&subsys->submodel_info_1); if (delta_angle < MAX_SUBMODEL_COLLISION_ROT_ANGLE) { - Assert(*num_rotating_submodels < MAX_ROTATING_SUBMODELS-1); - submodel_list[(*num_rotating_submodels)++] = i; + submodel_vector->push_back(i); } break; } @@ -3913,14 +3911,14 @@ //#define MODEL_CHECK #ifdef MODEL_CHECK ship *pship = &Ships[objp->instance]; - for (int idx=0; idx<*num_rotating_submodels; idx++) { - int valid = rotating_submodel_has_ship_subsys(submodel_list[idx], pship); + for (size_t idx=0; idx<submodel_vector->size(); idx++) { + int valid = rotating_submodel_has_ship_subsys(submodel_vector[idx], pship); // Assert( valid ); if ( !valid ) { - Warning( LOCATION, "Ship %s has rotating submodel [%s] without ship subsystem\n", pship->ship_name, pm->submodel[submodel_list[idx]].name ); - pm->submodel[submodel_list[idx]].movement_type &= ~MOVEMENT_TYPE_ROT; - *num_rotating_submodels = 0; + Warning( LOCATION, "Ship %s has rotating submodel [%s] without ship subsystem\n", pship->ship_name, pm->submodel[submodel_vector[idx]].name ); + pm->submodel[submodel_vector[idx]].movement_type &= ~MOVEMENT_TYPE_ROT; + submodel_vector->erase(submodel_vector->begin()+i); } } #endif Index: code/debris/debris.cpp =================================================================== --- code/debris/debris.cpp (revision 6892) +++ code/debris/debris.cpp (working copy) @@ -920,8 +920,7 @@ // first test against the sphere - if this fails then don't do any submodel tests mc.flags = MC_ONLY_SPHERE | MC_CHECK_SPHERELINE; - int submodel_list[MAX_ROTATING_SUBMODELS]; - int num_rotating_submodels = 0; + SCP_vector<int> submodel_vector; polymodel *pm; polymodel_instance *pmi; @@ -935,42 +934,41 @@ // Do collision the cool new way if ( debris_hit_info->collide_rotate ) { // We collide with the sphere, find the list of rotating submodels and test one at a time - model_get_rotating_submodel_list(submodel_list, &num_rotating_submodels, heavy_obj); + model_get_rotating_submodel_list(&submodel_vector, heavy_obj); // Get polymodel and turn off all rotating submodels, collide against only 1 at a time. pm = model_get(Ship_info[Ships[heavy_obj->instance].ship_info_index].model_num); pmi = model_get_instance(Ships[heavy_obj->instance].model_instance_num); // turn off all rotating submodels and test for collision - int i; - for (i=0; i<num_rotating_submodels; i++) { - pmi->submodel[submodel_list[i]].collision_checked = true; + for (size_t i=0; i<submodel_vector.size(); i++) { + pmi->submodel[submodel_vector[i]].collision_checked = true; } // reset flags to check MC_CHECK_MODEL | MC_CHECK_SPHERELINE and maybe MC_CHECK_INVISIBLE_FACES and MC_SUBMODEL_INSTANCE mc.flags = copy_flags | MC_SUBMODEL_INSTANCE; // check each submodel in turn - for (i=0; i<num_rotating_submodels; i++) { + for (size_t i=0; i<submodel_vector.size(); i++) { // turn on submodel for collision test - pmi->submodel[submodel_list[i]].collision_checked = false; + pmi->submodel[submodel_vector[i]].collision_checked = false; // set angles for last frame (need to set to prev to get p0) - angles copy_angles = pmi->submodel[submodel_list[i]].angs; + angles copy_angles = pmi->submodel[submodel_vector[i]].angs; // find the start and end positions of the sphere in submodel RF - pmi->submodel[submodel_list[i]].angs = pmi->submodel[submodel_list[i]].prev_angs; - world_find_model_instance_point(&p0, &light_obj->last_pos, pm, pmi, submodel_list[i], &heavy_obj->last_orient, &heavy_obj->last_pos); + pmi->submodel[submodel_vector[i]].angs = pmi->submodel[submodel_vector[i]].prev_angs; + world_find_model_instance_point(&p0, &light_obj->last_pos, pm, pmi, submodel_vector[i], &heavy_obj->last_orient, &heavy_obj->last_pos); - pmi->submodel[submodel_list[i]].angs = copy_angles; - world_find_model_instance_point(&p1, &light_obj->pos, pm, pmi, submodel_list[i], &heavy_obj->orient, &heavy_obj->pos); + pmi->submodel[submodel_vector[i]].angs = copy_angles; + world_find_model_instance_point(&p1, &light_obj->pos, pm, pmi, submodel_vector[i], &heavy_obj->orient, &heavy_obj->pos); mc.p0 = &p0; mc.p1 = &p1; // mc.pos = zero // in submodel RF mc.orient = &vmd_identity_matrix; - mc.submodel_num = submodel_list[i]; + mc.submodel_num = submodel_vector[i]; if ( model_collide(&mc) ) { if ( mc.hit_dist < debris_hit_info->hit_time ) { @@ -993,7 +991,7 @@ } } // Don't look at this submodel again - pmi->submodel[submodel_list[i]].collision_checked = true; + pmi->submodel[submodel_vector[i]].collision_checked = true; } } |
|
New 4th version of patch, includes switch to size_t on for loops to address signedness. |
|
Resolved in r6895. Assistance from FUBAR. |
Date Modified | Username | Field | Change |
---|---|---|---|
2010-12-14 01:47 | FUBAR-BDHR | New Issue | |
2010-12-26 10:43 | Echelon9 | File Added: mantis-2351_proposed_patch_2.patch | |
2010-12-26 10:43 | Echelon9 | Status | new => assigned |
2010-12-26 10:43 | Echelon9 | Assigned To | => Echelon9 |
2010-12-26 10:44 | Echelon9 | Note Added: 0012575 | |
2010-12-27 05:48 | Echelon9 | File Deleted: mantis-2351_proposed_patch_2.patch | |
2010-12-27 05:48 | Echelon9 | File Added: mantis-2351_proposed_patch_3.patch | |
2010-12-27 07:32 | Echelon9 | File Added: mantis-2351_proposed_patch_4.patch | |
2010-12-27 07:34 | Echelon9 | Note Added: 0012577 | |
2010-12-27 08:04 | Echelon9 | Note Added: 0012578 | |
2010-12-27 08:04 | Echelon9 | Status | assigned => resolved |
2010-12-27 08:04 | Echelon9 | Fixed in Version | => 3.6.13 |
2010-12-27 08:04 | Echelon9 | Resolution | open => fixed |