|
19 | 19 |
|
20 | 20 | #define MODEL_LIB |
21 | 21 |
|
| 22 | +#include "asteroid/asteroid.h" |
22 | 23 | #include "bmpman/bmpman.h" |
23 | 24 | #include "cfile/cfile.h" |
24 | 25 | #include "cmdline/cmdline.h" |
|
34 | 35 | #include "parse/parselo.h" |
35 | 36 | #include "render/3dinternal.h" |
36 | 37 | #include "ship/ship.h" |
| 38 | +#include "weapon/weapon.h" |
37 | 39 |
|
38 | 40 | flag_def_list model_render_flags[] = |
39 | 41 | { |
@@ -3395,7 +3397,7 @@ void model_get_rotating_submodel_axis(vec3d *model_axis, vec3d *world_axis, int |
3395 | 3397 | polymodel *pm = model_get(modelnum); |
3396 | 3398 |
|
3397 | 3399 | 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); |
3399 | 3401 |
|
3400 | 3402 | if (sm->movement_axis == MOVEMENT_AXIS_X) { |
3401 | 3403 | 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) |
4403 | 4405 | return found; |
4404 | 4406 | } |
4405 | 4407 |
|
| 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 | + */ |
4406 | 4414 | void model_get_rotating_submodel_list(SCP_vector<int> *submodel_vector, object *objp) |
4407 | 4415 | { |
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); |
4414 | 4417 |
|
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]]; |
4416 | 4444 |
|
4417 | 4445 | if(child_submodel->no_collisions) { // if detail0 has $no_collision set dont check childs |
4418 | 4446 | return; |
4419 | 4447 | } |
4420 | 4448 |
|
| 4449 | + polymodel_instance *pmi = model_get_instance(model_instance_num); |
| 4450 | + |
4421 | 4451 | int i = child_submodel->first_child; |
4422 | 4452 | while ( i >= 0 ) { |
4423 | 4453 | child_submodel = &pm->submodel[i]; |
4424 | 4454 |
|
4425 | 4455 | // Don't check it or its children if it is destroyed or it is a replacement (non-moving) |
4426 | 4456 | if ( !child_submodel->blown_off && (child_submodel->i_replace == -1) && !child_submodel->no_collisions && !child_submodel->nocollide_this_only) { |
4427 | 4457 |
|
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) { |
4430 | 4460 |
|
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; |
4434 | 4463 |
|
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); |
4445 | 4468 | } |
4446 | 4469 | } |
4447 | 4470 | } |
4448 | 4471 | i = child_submodel->next_sibling; |
4449 | 4472 | } |
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 | | - |
4467 | 4473 | } |
4468 | 4474 |
|
4469 | 4475 | 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 |
4876 | 4882 | vec3d p1, v1, p2, v2, int1; |
4877 | 4883 |
|
4878 | 4884 | 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); |
4880 | 4886 | Assert(sii); |
4881 | 4887 |
|
4882 | 4888 | mpoint1 = NULL; |
|
0 commit comments