/* * Descent 3 * Copyright (C) 2024 Parallax Software * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "RendererConfig.h" #ifndef USE_SOFTWARE_TNL #include "3d.h" #include "HardwareInternal.h" #include extern vector Clip_plane_point; // code a point. fills in the p3_codes field of the point, and returns the codes ubyte g3_CodePoint(g3Point *p) { ubyte cc = 0; if (p->p3_x > p->p3_z) cc |= CC_OFF_RIGHT; if (p->p3_y > p->p3_z) cc |= CC_OFF_TOP; if (p->p3_x < -p->p3_z) cc |= CC_OFF_LEFT; if (p->p3_y < -p->p3_z) cc |= CC_OFF_BOT; if (p->p3_z < 0) cc |= CC_BEHIND; if (p->p3_z > Far_clip_z) cc |= CC_OFF_FAR; // Check to see if we should be clipped to the custom plane if (Clip_custom) { vector vec = p->p3_vec - Clip_plane_point; vec.x /= Matrix_scale.x; vec.y /= Matrix_scale.y; vec.z /= Matrix_scale.z; float dp = vec * Clip_plane; if (dp < -0.005f) { cc |= CC_OFF_CUSTOM; } } return p->p3_codes = cc; } // rotates a point. returns codes. does not check if already rotated ubyte g3_RotatePoint(g3Point *dest, vector *src) { // store the pre-rotated point dest->p3_vecPreRot = *src; // find the point offset from the view/camera position vector tempv = *src - View_position; // rotate the point by the view/camera's orientation dest->p3_vec = tempv * View_matrix; // determine the flags for the point dest->p3_flags = PF_ORIGPOINT; return g3_CodePoint(dest); } // projects a point void g3_ProjectPoint(g3Point *p) { if (p->p3_flags & PF_PROJECTED || p->p3_codes & CC_BEHIND) return; float one_over_z = 1.0 / p->p3_z; p->p3_sx = Window_w2 + (p->p3_x * (Window_w2 * one_over_z)); p->p3_sy = Window_h2 - (p->p3_y * (Window_h2 * one_over_z)); p->p3_flags |= PF_PROJECTED; } // from a 2d point, compute the vector through that point void g3_Point2Vec(vector *v, short sx, short sy) { vector tempv; matrix tempm; tempv.x = (((sx - Window_w2) / Window_w2) * Matrix_scale.z / Matrix_scale.x); tempv.y = -(((sy - Window_h2) / Window_h2) * Matrix_scale.z / Matrix_scale.y); tempv.z = 1.0f; vm_NormalizeVector(&tempv); tempm = ~Unscaled_matrix; *v = tempv * tempm; } // delta rotation functions vector *g3_RotateDeltaX(vector *dest, float dx) { dest->x = View_matrix.rvec.x * dx; dest->y = View_matrix.uvec.x * dx; dest->z = View_matrix.fvec.x * dx; return dest; } vector *g3_RotateDeltaY(vector *dest, float dy) { dest->x = View_matrix.rvec.y * dy; dest->y = View_matrix.uvec.y * dy; dest->z = View_matrix.fvec.y * dy; return dest; } vector *g3_RotateDeltaZ(vector *dest, float dz) { dest->x = View_matrix.rvec.z * dz; dest->y = View_matrix.uvec.z * dz; dest->z = View_matrix.fvec.z * dz; return dest; } vector *g3_RotateDeltaVec(vector *dest, vector *src) { *dest = *src * View_matrix; return dest; } ubyte g3_AddDeltaVec(g3Point *dest, g3Point *src, vector *deltav) { dest->p3_vec = src->p3_vec + *deltav; dest->p3_flags = 0; // not projected return g3_CodePoint(dest); } // calculate the depth of a point - returns the z coord of the rotated point float g3_CalcPointDepth(vector *pnt) { return ((pnt->x - View_position.x) * View_matrix.fvec.x) + ((pnt->y - View_position.y) * View_matrix.fvec.y) + ((pnt->z - View_position.z) * View_matrix.fvec.z); } #endif