From 455c8b09aaba197476d420e4442f2a5313638259 Mon Sep 17 00:00:00 2001 From: Willian Henrique Date: Tue, 27 Aug 2024 16:53:27 +0100 Subject: Add basic server-side tracing functionality Restricted to L4D for now due to known ABI compatibility issues on other branches. This should be easy to fix later when needed elsewhere. Committer's note: I've counted myself as a joint author and added a copyright notice to the .c file since this code is reasonably modified from the code bill originally wrote last year. but June of this year and , so I've gone ahead and corrected his copyright notice too, with permission. --- src/trace.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 src/trace.c (limited to 'src/trace.c') diff --git a/src/trace.c b/src/trace.c new file mode 100644 index 0000000..0a301a7 --- /dev/null +++ b/src/trace.c @@ -0,0 +1,101 @@ +/* + * Copyright © 2023 Willian Henrique + * Copyright © 2024 Michael Smith + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "engineapi.h" +#include "errmsg.h" +#include "feature.h" +#include "gametype.h" +#include "intdefs.h" +#include "trace.h" + +FEATURE() + +struct ray { + // these have type VectorAligned in the engine, which occupies 16 bytes + struct vec3f _Alignas(16) start, delta, startoff, extents; + // align to 16 since "extents" is supposed to occupy 16 bytes. + // TODO(compat): this member isn't in every engine branch + const float _Alignas(16) (*worldaxistransform)[3][4]; + bool isray, isswept; +}; + +static void *srvtrace; + +DECL_VFUNC(void, TraceRay, 5, struct ray *, uint /*mask*/, void */*filter*/, + struct CGameTrace *) + +static inline bool nonzero(struct vec3f v) { + union { struct vec3f v; struct { unsigned int x, y, z; }; } u = {v}; + return (u.x | u.y | u.z) << 1 != 0; // ignore sign bit +} + +struct CGameTrace trace_line(struct vec3f start, struct vec3f end, uint mask, + void *filt) { + struct CGameTrace t; + struct vec3f delta = {end.x - start.x, end.y - start.y, end.z - start.z}; + struct ray r = { + .isray = true, + .isswept = nonzero(delta), + .start = start, + .delta = delta + }; + TraceRay(srvtrace, &r, mask, filt, &t); + return t; +} + +struct CGameTrace trace_hull(struct vec3f start, struct vec3f end, + struct vec3f mins, struct vec3f maxs, uint mask, void *filt) { + struct CGameTrace t; + struct vec3f delta = {end.x - start.x, end.y - start.y, end.z - start.z}; + struct vec3f extents = { + (maxs.x - mins.x) * 0.5f, + (maxs.y - mins.y) * 0.5f, + (maxs.z - mins.z) * 0.5f + }; + struct ray r = { + // NOTE: could maybe hardcode this to false, but we copy engine logic + // just on the off chance we're tracing some insanely thin hull + .isray = (extents.x * extents.x + r.extents.y * r.extents.y + + extents.z * extents.z) < 1e-6, + .isswept = nonzero(delta), + .start = start, + .delta = delta, + .extents = extents, + .startoff = { + (mins.x + maxs.x) * -0.5f, + (mins.y + maxs.y) * -0.5f, + (mins.z + maxs.z) * -0.5f + } + }; + TraceRay(srvtrace, &r, mask, filt, &t); + return t; +} + +PREINIT { + // TODO(compat): restricting this to tested branches for now + return GAMETYPE_MATCHES(L4D); +} + +INIT { + if (!(srvtrace = factory_engine("EngineTraceServer003", 0))) { + errmsg_errorx("couldn't get server-side tracing interface"); + return false; + } + return true; +} + +// vi: sw=4 ts=4 noet tw=80 cc=80 -- cgit v1.2.3