Given a position in 3space and a size, returns whether or not that sized point is visible from the current view matrix
| 1778 | // Given a position in 3space and a size, returns whether or not that sized point is |
| 1779 | // visible from the current view matrix |
| 1780 | int IsPointVisible(vector *pos, float size, float *pointz) { |
| 1781 | g3Point pnt; |
| 1782 | uint8_t ccode; |
| 1783 | static float last_render_fov = -1; |
| 1784 | static vector left_normal, right_normal, top_normal, bottom_normal, view_position; |
| 1785 | static matrix unscaled_matrix; |
| 1786 | |
| 1787 | g3_RotatePoint(&pnt, pos); |
| 1788 | ccode = g3_CodePoint(&pnt); |
| 1789 | if (pointz != NULL) |
| 1790 | *pointz = pnt.p3_z; |
| 1791 | if (ccode) // the center point is off, find out if the whole object is off |
| 1792 | { |
| 1793 | float dotp; |
| 1794 | |
| 1795 | if (pnt.p3_z < -size) |
| 1796 | return 0; // behind plane! |
| 1797 | if (pnt.p3_z > Far_clip_z + size) |
| 1798 | return 0; // too far away! |
| 1799 | if (Render_FOV != last_render_fov) { |
| 1800 | last_render_fov = Render_FOV; |
| 1801 | int angle_adjust = (Render_FOV / 2) * (65536 / 360); |
| 1802 | vector rvec = {1, 0, 0}; |
| 1803 | vector lvec = {-1, 0, 0}; |
| 1804 | vector tvec = {0, 1, 0}; |
| 1805 | vector bvec = {0, -1, 0}; |
| 1806 | matrix temp_mat; |
| 1807 | vm_AnglesToMatrix(&temp_mat, 0, 65536 - angle_adjust, 0); |
| 1808 | right_normal = rvec * temp_mat; |
| 1809 | vm_AnglesToMatrix(&temp_mat, 0, angle_adjust, 0); |
| 1810 | left_normal = lvec * temp_mat; |
| 1811 | vm_AnglesToMatrix(&temp_mat, 65536 - angle_adjust, 0, 0); |
| 1812 | bottom_normal = bvec * temp_mat; |
| 1813 | vm_AnglesToMatrix(&temp_mat, angle_adjust, 0, 0); |
| 1814 | top_normal = tvec * temp_mat; |
| 1815 | } |
| 1816 | // Get unscaled matrix stuff |
| 1817 | if (Point_visible_last_frame != FrameCount) { |
| 1818 | Point_visible_last_frame = FrameCount; |
| 1819 | g3_GetUnscaledMatrix(&unscaled_matrix); |
| 1820 | g3_GetViewPosition(&view_position); |
| 1821 | } |
| 1822 | vector temp_vec = *pos - view_position; |
| 1823 | pnt.p3_vec = temp_vec * unscaled_matrix; |
| 1824 | if (ccode & CC_OFF_RIGHT) { |
| 1825 | dotp = vm_DotProduct(&right_normal, &pnt.p3_vec); |
| 1826 | if (dotp > size) |
| 1827 | return 0; |
| 1828 | } |
| 1829 | if (ccode & CC_OFF_LEFT) { |
| 1830 | dotp = vm_DotProduct(&left_normal, &pnt.p3_vec); |
| 1831 | if (dotp > size) |
| 1832 | return 0; |
| 1833 | } |
| 1834 | |
| 1835 | if (ccode & CC_OFF_TOP) { |
| 1836 | dotp = vm_DotProduct(&top_normal, &pnt.p3_vec); |
| 1837 | if (dotp > size) |
no test coverage detected