Skip to content

Commit aabc0df

Browse files
authored
Merge pull request scp-fs2open#6686 from Goober5000/enhance_look_at
enhance look_at
2 parents 56d8c48 + 3fb82e5 commit aabc0df

1 file changed

Lines changed: 42 additions & 39 deletions

File tree

code/model/modelread.cpp

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,16 +1370,24 @@ void determine_submodel_movement(bool is_rotation, const char *filename, bsp_inf
13701370
if (in(p, props, axis_string))
13711371
{
13721372
if (get_user_vec3d_value(p + 20, movement_axis, true, sm->name, filename))
1373-
vm_vec_normalize(movement_axis);
1373+
{
1374+
if (!fl_near_zero(vm_vec_mag(movement_axis)))
1375+
vm_vec_normalize(movement_axis);
1376+
else
1377+
{
1378+
Warning(LOCATION, "%s on submodel '%s' on ship %s has a magnitude near zero!", axis_string, sm->name, filename);
1379+
*movement_type = MOVEMENT_TYPE_NONE;
1380+
}
1381+
}
13741382
else
13751383
{
1376-
Warning(LOCATION, "Failed to parse %s on subsystem '%s' on ship %s!", axis_string, sm->name, filename);
1384+
Warning(LOCATION, "Failed to parse %s on submodel '%s' on ship %s!", axis_string, sm->name, filename);
13771385
*movement_type = MOVEMENT_TYPE_NONE;
13781386
}
13791387
}
13801388
else
13811389
{
1382-
Warning(LOCATION, "A %s was not specified for subsystem '%s' on ship %s!", axis_string, sm->name, filename);
1390+
Warning(LOCATION, "A %s was not specified for submodel '%s' on ship %s!", axis_string, sm->name, filename);
13831391
*movement_type = MOVEMENT_TYPE_NONE;
13841392
}
13851393
}
@@ -1483,8 +1491,9 @@ void do_movement_sanity_checks(bsp_info *sm, bsp_info *parent_sm, const char *fi
14831491

14841492
extract_movement_info(sm, is_rotation, movement_axis_id, movement_axis, movement_type);
14851493

1486-
// make sure this is a validly normalized axis
1487-
if (vm_vec_mag(movement_axis) < 0.999f || vm_vec_mag(movement_axis) > 1.001f)
1494+
// make sure this is a validly normalized axis - also catch axes that are unspecified or 0,0,0
1495+
// (it would be nice to warn here, but the signal to noise ratio is extremely poor)
1496+
if (!vm_vec_is_normalized(movement_axis))
14881497
*movement_type = MOVEMENT_TYPE_NONE;
14891498

14901499
// maybe use the FOR to manipulate the axes
@@ -2055,45 +2064,38 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename,
20552064
}
20562065

20572066
// KeldorKatarn, with modifications
2058-
if (in(p, props, "$uvec")) {
2059-
matrix submodel_orient;
2060-
2061-
if (get_user_vec3d_value(p + 5, &submodel_orient.vec.uvec, false, sm->name, pm->filename)) {
2062-
2063-
if (in(p, props, "$fvec")) {
2064-
2065-
if (get_user_vec3d_value(p + 5, &submodel_orient.vec.fvec, false, sm->name, pm->filename)) {
2066-
2067-
vm_vec_normalize(&submodel_orient.vec.uvec);
2068-
vm_vec_normalize(&submodel_orient.vec.fvec);
2069-
2070-
vm_vec_cross(&submodel_orient.vec.rvec, &submodel_orient.vec.uvec, &submodel_orient.vec.fvec);
2071-
vm_vec_cross(&submodel_orient.vec.fvec, &submodel_orient.vec.rvec, &submodel_orient.vec.uvec);
2067+
{
2068+
bool has_fvec = false, has_uvec = false, has_rvec = false;
2069+
vec3d fvec, uvec, rvec;
20722070

2073-
vm_vec_normalize(&submodel_orient.vec.fvec);
2074-
vm_vec_normalize(&submodel_orient.vec.rvec);
2071+
// default
2072+
sm->frame_of_reference = parent_sm ? parent_sm->frame_of_reference : vmd_identity_matrix;
20752073

2076-
vm_orthogonalize_matrix(&submodel_orient);
2074+
// parse what we can
2075+
auto vectors = { std::make_tuple("$fvec", &fvec, &has_fvec), std::make_tuple("$uvec", &uvec, &has_uvec), std::make_tuple("$rvec", &rvec, &has_rvec) };
2076+
for (auto &item : vectors)
2077+
{
2078+
if (in(p, props, std::get<0>(item)))
2079+
{
2080+
if (get_user_vec3d_value(p + 5, std::get<1>(item), false, sm->name, pm->filename))
2081+
*std::get<2>(item) = true;
2082+
else
2083+
Warning(LOCATION, "Submodel '%s' of model '%s' has an improperly formatted %s declaration in its properties.\n\n%s should be followed by 3 numbers separated with commas.", sm->name, filename, std::get<0>(item), std::get<0>(item));
2084+
}
2085+
}
20772086

2078-
sm->frame_of_reference = submodel_orient;
2087+
// make a matrix if we have at least the fvec
2088+
if (has_fvec)
2089+
{
2090+
vm_vector_2_matrix(&sm->frame_of_reference, &fvec, has_uvec ? &uvec : nullptr, has_rvec ? &rvec : nullptr);
20792091

2080-
} else {
2081-
Warning(LOCATION,
2082-
"Submodel '%s' of model '%s' has an improperly formatted $fvec declaration in its properties."
2083-
"\n\n$fvec should be followed by 3 numbers separated with commas.",
2084-
sm->name, filename);
2085-
}
2086-
} else {
2087-
Warning(LOCATION, "Improper custom orientation matrix for subsystem %s; you must define both an up vector and a forward vector", sm->name);
2088-
}
2089-
} else {
2090-
Warning(LOCATION,
2091-
"Submodel '%s' of model '%s' has an improperly formatted $uvec declaration in its properties."
2092-
"\n\n$uvec should be followed by 3 numbers separated with commas.",
2093-
sm->name, filename);
2092+
// if the look_at_offset is still the default value (hasn't been set by submodel properties), assume that
2093+
// by specifying the submodel orientation matrix we are also specifying the "looking" direction
2094+
if (sm->look_at_offset == -1.0f)
2095+
sm->look_at_offset = 0.0f;
20942096
}
2095-
} else {
2096-
sm->frame_of_reference = parent_sm ? parent_sm->frame_of_reference : vmd_identity_matrix;
2097+
else if (has_uvec || has_rvec)
2098+
Warning(LOCATION, "Improper custom orientation matrix for subsystem %s; you must define an $fvec", sm->name);
20972099
}
20982100

20992101
{
@@ -2939,6 +2941,7 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename,
29392941

29402942
// if we couldn't find it, we shouldn't move
29412943
if (sm->look_at_submodel < 0) {
2944+
Warning(LOCATION, "Could not find $look_at target for %s %s!", pm->filename, sm->name);
29422945
sm->rotation_type = MOVEMENT_TYPE_NONE;
29432946
}
29442947
// are we navel-gazing?

0 commit comments

Comments
 (0)