Skip to content

Commit 975e108

Browse files
author
Goober5000
committed
further accommodation of the dumb-rotation movement type, including, finally, proper collision detection!
1 parent 6d60bb1 commit 975e108

File tree

1 file changed

+47
-41
lines changed

1 file changed

+47
-41
lines changed

code/model/modelread.cpp

Lines changed: 47 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#define MODEL_LIB
2121

22+
#include "asteroid/asteroid.h"
2223
#include "bmpman/bmpman.h"
2324
#include "cfile/cfile.h"
2425
#include "cmdline/cmdline.h"
@@ -34,6 +35,7 @@
3435
#include "parse/parselo.h"
3536
#include "render/3dinternal.h"
3637
#include "ship/ship.h"
38+
#include "weapon/weapon.h"
3739

3840
flag_def_list model_render_flags[] =
3941
{
@@ -3395,7 +3397,7 @@ void model_get_rotating_submodel_axis(vec3d *model_axis, vec3d *world_axis, int
33953397
polymodel *pm = model_get(modelnum);
33963398

33973399
bsp_info *sm = &pm->submodel[submodel_num];
3398-
Assert(sm->movement_type == MOVEMENT_TYPE_ROT);
3400+
Assert(sm->movement_type == MOVEMENT_TYPE_ROT || sm->movement_type == MOVEMENT_TYPE_DUMB_ROTATE);
33993401

34003402
if (sm->movement_axis == MOVEMENT_AXIS_X) {
34013403
vm_vec_make(model_axis, 1.0f, 0.0f, 0.0f);
@@ -4403,67 +4405,71 @@ int rotating_submodel_has_ship_subsys(int submodel, ship *shipp)
44034405
return found;
44044406
}
44054407

4408+
/*
4409+
* Get all submodel indexes that satisfy the following:
4410+
* 1) Have the rotating or dumb-rotating movement type
4411+
* 2) Are currently rotating (i.e. actually moving and not part of the superstructure due to being destroyed or replaced)
4412+
* 3) Are not rotating too far for collision detection (c.f. MAX_SUBMODEL_COLLISION_ROT_ANGLE)
4413+
*/
44064414
void model_get_rotating_submodel_list(SCP_vector<int> *submodel_vector, object *objp)
44074415
{
4408-
Assert(objp->type == OBJ_SHIP);
4409-
4410-
// Check if not currently rotating - then treat as part of superstructure.
4411-
int modelnum = Ship_info[Ships[objp->instance].ship_info_index].model_num;
4412-
polymodel *pm = model_get(modelnum);
4413-
bsp_info *child_submodel;
4416+
Assert(objp->type == OBJ_SHIP || objp->type == OBJ_WEAPON || objp->type == OBJ_ASTEROID);
44144417

4415-
child_submodel = &pm->submodel[pm->detail[0]];
4418+
int model_instance_num;
4419+
int model_num;
4420+
if (objp->type == OBJ_SHIP) {
4421+
model_instance_num = Ships[objp->instance].model_instance_num;
4422+
model_num = Ship_info[Ships[objp->instance].ship_info_index].model_num;
4423+
}
4424+
else if (objp->type == OBJ_WEAPON) {
4425+
model_instance_num = Weapons[objp->instance].model_instance_num;
4426+
if (model_instance_num < 0) {
4427+
return;
4428+
}
4429+
model_num = Weapon_info[Weapons[objp->instance].weapon_info_index].model_num;
4430+
}
4431+
else if (objp->type == OBJ_ASTEROID) {
4432+
model_instance_num = Asteroids[objp->instance].model_instance_num;
4433+
if (model_instance_num < 0) {
4434+
return;
4435+
}
4436+
model_num = Asteroid_info[Asteroids[objp->instance].asteroid_type].model_num[Asteroids[objp->instance].asteroid_subtype];
4437+
}
4438+
else {
4439+
return;
4440+
}
4441+
4442+
polymodel *pm = model_get(model_num);
4443+
bsp_info *child_submodel = &pm->submodel[pm->detail[0]];
44164444

44174445
if(child_submodel->no_collisions) { // if detail0 has $no_collision set dont check childs
44184446
return;
44194447
}
44204448

4449+
polymodel_instance *pmi = model_get_instance(model_instance_num);
4450+
44214451
int i = child_submodel->first_child;
44224452
while ( i >= 0 ) {
44234453
child_submodel = &pm->submodel[i];
44244454

44254455
// Don't check it or its children if it is destroyed or it is a replacement (non-moving)
44264456
if ( !child_submodel->blown_off && (child_submodel->i_replace == -1) && !child_submodel->no_collisions && !child_submodel->nocollide_this_only) {
44274457

4428-
// Only look for submodels that rotate
4429-
if (child_submodel->movement_type == MOVEMENT_TYPE_ROT) {
4458+
// Only look for submodels that rotate or dumb-rotate
4459+
if (child_submodel->movement_type == MOVEMENT_TYPE_ROT || child_submodel->movement_type == MOVEMENT_TYPE_DUMB_ROTATE) {
44304460

4431-
// find ship subsys and check submodel rotation is less than max allowed.
4432-
ship *pship = &Ships[objp->instance];
4433-
ship_subsys *subsys;
4461+
// check submodel rotation is less than max allowed.
4462+
submodel_instance_info *sii = pmi->submodel[i].sii;
44344463

4435-
for ( subsys = GET_FIRST(&pship->subsys_list); subsys !=END_OF_LIST(&pship->subsys_list); subsys = GET_NEXT(subsys) ) {
4436-
Assert(subsys->system_info->model_num == modelnum);
4437-
if (i == subsys->system_info->subobj_num) {
4438-
// found the correct subsystem - now check delta rotation angle not too large
4439-
float delta_angle = get_submodel_delta_angle(&subsys->submodel_info_1);
4440-
if (delta_angle < MAX_SUBMODEL_COLLISION_ROT_ANGLE) {
4441-
submodel_vector->push_back(i);
4442-
}
4443-
break;
4444-
}
4464+
// found the correct submodel instance - now check delta rotation angle not too large
4465+
float delta_angle = get_submodel_delta_angle(sii);
4466+
if (delta_angle < MAX_SUBMODEL_COLLISION_ROT_ANGLE) {
4467+
submodel_vector->push_back(i);
44454468
}
44464469
}
44474470
}
44484471
i = child_submodel->next_sibling;
44494472
}
4450-
4451-
// error checking
4452-
//#define MODEL_CHECK
4453-
#ifdef MODEL_CHECK
4454-
ship *pship = &Ships[objp->instance];
4455-
for (size_t idx=0; idx<submodel_vector->size(); idx++) {
4456-
int valid = rotating_submodel_has_ship_subsys(submodel_vector[idx], pship);
4457-
// Assert( valid );
4458-
if ( !valid ) {
4459-
4460-
Warning( LOCATION, "Ship %s has rotating submodel [%s] without ship subsystem\n", pship->ship_name, pm->submodel[submodel_vector[idx]].name );
4461-
pm->submodel[submodel_vector[idx]].movement_type &= ~MOVEMENT_TYPE_ROT;
4462-
submodel_vector->erase(submodel_vector->begin()+i);
4463-
}
4464-
}
4465-
#endif
4466-
44674473
}
44684474

44694475
void model_get_submodel_tree_list(SCP_vector<int> &submodel_vector, polymodel* pm, int mn)
@@ -4876,7 +4882,7 @@ void model_init_submodel_axis_pt(submodel_instance_info *sii, int model_num, int
48764882
vec3d p1, v1, p2, v2, int1;
48774883

48784884
polymodel *pm = model_get(model_num);
4879-
Assert(pm->submodel[submodel_num].movement_type == MOVEMENT_TYPE_ROT);
4885+
Assert(pm->submodel[submodel_num].movement_type == MOVEMENT_TYPE_ROT || pm->submodel[submodel_num].movement_type == MOVEMENT_TYPE_DUMB_ROTATE);
48804886
Assert(sii);
48814887

48824888
mpoint1 = NULL;

0 commit comments

Comments
 (0)