/* ======================================================================================================================================= CM_TransformedPointContents Handles offseting and rotation of the end points for moving and rotating entities. ======================================================================================================================================= */ int CM_TransformedPointContents(const vec3_t p, clipHandle_t model, const vec3_t origin, const vec3_t angles) { vec3_t p_l; // subtract origin offset VectorSubtract(p, origin, p_l); // rotate start and end into the models frame of reference if (model != BOX_MODEL_HANDLE && (angles[0] != 0.f || angles[1] != 0.f || angles[2] != 0.f)) { vec3_t temp, forward, right, up; angles_vectors(angles, forward, right, up); VectorCopy(p_l, temp); p_l[0] = DotProduct(temp, forward); p_l[1] = -DotProduct(temp, right); p_l[2] = DotProduct(temp, up); } return CM_PointContents(p_l, model); }
/** * @brief Calculates the view point of a player model at position 'org' using * information in the player state 'ps' of its client, and stores the * viewpoint coordinates in 'vp'. */ static void calc_viewpoint(playerState_t *ps, vec3_t org, vec3_t vp) { VectorCopy(org, vp); if (ps->leanf != 0) { vec3_t right, v3ViewAngles; VectorCopy(ps->viewangles, v3ViewAngles); v3ViewAngles[2] += ps->leanf / 2.0f; angles_vectors(v3ViewAngles, NULL, right, NULL); VectorMA(org, ps->leanf, right, org); } if (ps->pm_flags & PMF_DUCKED) { vp[2] += CROUCH_VIEWHEIGHT; } else { vp[2] += DEFAULT_VIEWHEIGHT; } }
qboolean isEntVisible(entityState_t *ent) { trace_t tr; vec3_t start, end, temp; vec3_t forward, up, right, right2; float view_height; VectorCopy(cl.cgameClientLerpOrigin, start); start[2] += (cl.snap.ps.viewheight - 1); if (cl.snap.ps.leanf != 0) { vec3_t lright, v3ViewAngles; VectorCopy(cl.snap.ps.viewangles, v3ViewAngles); v3ViewAngles[2] += cl.snap.ps.leanf / 2.0f; angles_vectors(v3ViewAngles, NULL, lright, NULL); VectorMA(start, cl.snap.ps.leanf, lright, start); } VectorCopy(ent->pos.trBase, end); // Compute vector perpindicular to view to ent VectorSubtract(end, start, forward); vec3_norm_fast(forward); VectorSet(up, 0, 0, 1); vec3_cross(forward, up, right); vec3_norm_fast(right); VectorScale(right, 10, right2); VectorScale(right, 18, right); // Set viewheight if (ent->animMovetype) { view_height = 16; } else { view_height = 40; } // First, viewpoint to viewpoint end[2] += view_height; CM_BoxTrace(&tr, start, end, NULL, NULL, 0, CONTENTS_SOLID, qfalse); if (tr.fraction == 1.f) { return qtrue; } // First-b, viewpoint to top of head end[2] += 16; CM_BoxTrace(&tr, start, end, NULL, NULL, 0, CONTENTS_SOLID, qfalse); if (tr.fraction == 1.f) { return qtrue; } end[2] -= 16; // Second, viewpoint to ent's origin end[2] -= view_height; CM_BoxTrace(&tr, start, end, NULL, NULL, 0, CONTENTS_SOLID, qfalse); if (tr.fraction == 1.f) { return qtrue; } // Third, to ent's right knee VectorAdd(end, right, temp); temp[2] += 8; CM_BoxTrace(&tr, start, temp, NULL, NULL, 0, CONTENTS_SOLID, qfalse); if (tr.fraction == 1.f) { return qtrue; } // Fourth, to ent's right shoulder VectorAdd(end, right2, temp); if (ent->animMovetype) { temp[2] += 28; } else { temp[2] += 52; } CM_BoxTrace(&tr, start, temp, NULL, NULL, 0, CONTENTS_SOLID, qfalse); if (tr.fraction == 1.f) { return qtrue; } // Fifth, to ent's left knee VectorScale(right, -1, right); VectorScale(right2, -1, right2); VectorAdd(end, right2, temp); temp[2] += 2; CM_BoxTrace(&tr, start, temp, NULL, NULL, 0, CONTENTS_SOLID, qfalse); if (tr.fraction == 1.f) { return qtrue; } // Sixth, to ent's left shoulder VectorAdd(end, right, temp); if (ent->animMovetype) { temp[2] += 16; } else { temp[2] += 36; } CM_BoxTrace(&tr, start, temp, NULL, NULL, 0, CONTENTS_SOLID, qfalse); if (tr.fraction == 1.f) { return qtrue; } return qfalse; }