From bcf3f2e3e3ad4506985e612cdd7432a60a41d59a Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Sun, 1 Oct 2017 12:39:15 -0600 Subject: [PATCH] qbsp: add _external_map_scale key for misc_external_map --- include/qbsp/map.hh | 2 +- man/qbsp.1 | 2 ++ qbsp/map.cc | 65 ++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/include/qbsp/map.hh b/include/qbsp/map.hh index ec8e51e5..a82a9025 100644 --- a/include/qbsp/map.hh +++ b/include/qbsp/map.hh @@ -157,7 +157,7 @@ int FindTexinfoEnt(mtexinfo_t *texinfo, mapentity_t *entity); //FIXME: Make this void PrintEntity(const mapentity_t *entity); const char *ValueForKey(const mapentity_t *entity, const char *key); void SetKeyValue(mapentity_t *entity, const char *key, const char *value); -void GetVectorForKey(const mapentity_t *entity, const char *szKey, vec3_t vec); +int GetVectorForKey(const mapentity_t *entity, const char *szKey, vec3_t vec); void WriteEntitiesToString(void); diff --git a/man/qbsp.1 b/man/qbsp.1 index f78bfaa0..4d8e7bc2 100644 --- a/man/qbsp.1 +++ b/man/qbsp.1 @@ -155,6 +155,8 @@ or a regular bmodel classname like "func_wall" or "func_door". Rotation for the prefab, "pitch yaw roll" format. Negative pitch is down. .IP "\fB_external_map_angle\fP" Short version of "_external_map_angles" for when you want to specify just a yaw rotation. +.IP "\fB_external_map_scale\fP" +Scale factor for the prefab, defaults to 1. Either specify a single value or three scales, "x y z". .SH "DETAIL BRUSH SUPPORT" .PP diff --git a/qbsp/map.cc b/qbsp/map.cc index 22711930..3772316c 100644 --- a/qbsp/map.cc +++ b/qbsp/map.cc @@ -1543,6 +1543,49 @@ ParseEntity(parser_t *parser, mapentity_t *entity) return true; } +static void ScaleMapFace(mapface_t *face, const vec3_t scale) +{ + const qmat3x3d scaleM { + // column-major... + static_cast(scale[0]), 0.0, 0.0, + 0.0, static_cast(scale[1]), 0.0, + 0.0, 0.0, static_cast(scale[2]) + }; + + vec3_t new_planepts[3]; + for (int i=0; i<3; i++) { + qvec3d oldpt = qvec3d_from_vec3(face->planepts[i]); + qvec3d newpt = scaleM * oldpt; + + glm_to_vec3_t(newpt, new_planepts[i]); + } + + face->set_planepts(new_planepts); + + // update texinfo + + const qmat3x3d inversescaleM { + // column-major... + static_cast(1/scale[0]), 0.0, 0.0, + 0.0, static_cast(1/scale[1]), 0.0, + 0.0, 0.0, static_cast(1/scale[2]) + }; + + const std::array texvecs = face->get_texvecs(); + std::array newtexvecs; + + for (int i=0; i<2; i++) { + const qvec4f in = texvecs.at(i); + const qvec3f in_first3(in); + + const qvec3f out_first3 = inversescaleM * in_first3; + const qvec4f out(out_first3[0], out_first3[1], out_first3[2], in[3]); + newtexvecs.at(i) = out; + } + + face->set_texvecs(newtexvecs); +} + static void RotateMapFace(mapface_t *face, const vec3_t angles) { const double pitch = DEG2RAD(angles[0]); @@ -1633,12 +1676,24 @@ ProcessExternalMapEntity(mapentity_t *entity) angles[1] = atof(ValueForKey(entity, "_external_map_angle")); } + vec3_t scale; + int ncomps = GetVectorForKey(entity, "_external_map_scale", scale); + if (ncomps < 3) { + if (scale[0] == 0.0) { + VectorSet(scale, 1, 1, 1); + } else { + scale[1] = scale[0]; + scale[2] = scale[0]; + } + } + for (int i=0; inummapbrushes; i++) { mapbrush_t *brush = const_cast(&entity->mapbrush(i)); for (int j=0; jnumfaces; j++) { mapface_t *face = const_cast(&brush->face(j)); + ScaleMapFace(face, scale); RotateMapFace(face, angles); TranslateMapFace(face, origin); } @@ -2020,8 +2075,10 @@ SetKeyValue(mapentity_t *entity, const char *key, const char *value) ep->value = copystring(value); } - -void +/** + * returnts number of vector components read + */ +int GetVectorForKey(const mapentity_t *entity, const char *szKey, vec3_t vec) { const char *value; @@ -2030,10 +2087,12 @@ GetVectorForKey(const mapentity_t *entity, const char *szKey, vec3_t vec) value = ValueForKey(entity, szKey); v1 = v2 = v3 = 0; // scanf into doubles, then assign, so it is vec_t size independent - sscanf(value, "%lf %lf %lf", &v1, &v2, &v3); + const int numComps = sscanf(value, "%lf %lf %lf", &v1, &v2, &v3); vec[0] = v1; vec[1] = v2; vec[2] = v3; + + return numComps; }