diff options
author | Willian Henrique <wsimanbrazil@yahoo.com.br> | 2024-08-27 16:53:27 +0100 |
---|---|---|
committer | Michael Smith <mikesmiffy128@gmail.com> | 2024-08-29 23:08:03 +0100 |
commit | 455c8b09aaba197476d420e4442f2a5313638259 (patch) | |
tree | 261f98b71e8ef899760e27f6943c0c516dc5b6bc /src | |
parent | 98d046645644ff59718a46e2d2bbc6b5f4620b28 (diff) |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/trace.c | 101 | ||||
-rw-r--r-- | src/trace.h | 60 |
2 files changed, 161 insertions, 0 deletions
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 <wsimanbrazil@yahoo.com.br> + * Copyright © 2024 Michael Smith <mikesmiffy128@gmail.com> + * + * 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 diff --git a/src/trace.h b/src/trace.h new file mode 100644 index 0000000..82d2dac --- /dev/null +++ b/src/trace.h @@ -0,0 +1,60 @@ +/* + * Copyright © 2023 Willian Henrique <wsimanbrazil@yahoo.com.br> + * + * 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. + */ + +#ifndef INC_TRACE_H +#define INC_TRACE_H + +#include "intdefs.h" +#include "engineapi.h" + +struct CBaseTrace { + struct vec3f startpos, endpos; + struct { + struct vec3f normal; + float dist; + u8 type, signbits; + //u8 pad[2]; + } plane; // surface normal at impact + float frac; + int contents; + ushort dispflags; + bool allsolid, startsolid; +}; + +struct CGameTrace { + struct CBaseTrace base; + float fracleftsolid; + struct { + const char *name; + short surfprops; + ushort flags; + } surf; + int hitgroup; + short physbone; + ushort worldsurfidx; // not in every branch, but doesn't break ABI + void *ent; // CBaseEntity (C_BaseEntity in client.dll) + int hitbox; +}; + +struct CGameTrace trace_line(struct vec3f start, struct vec3f end, uint mask, + void *filt); + +struct CGameTrace trace_hull(struct vec3f start, struct vec3f end, + struct vec3f mins, struct vec3f maxs, uint mask, void *filt); + +#endif + +// vi: sw=4 ts=4 noet tw=80 cc=80 |