From 4ce944444d81bdd7e5c5d5d325fec4baaf622283 Mon Sep 17 00:00:00 2001 From: Garux Date: Thu, 25 Feb 2021 19:41:43 +0300 Subject: [PATCH] rewrite q3map2 math in c++ --- Makefile | 1 - include/cullable.h | 3 +- include/selectable.h | 3 +- libs/generic/vector.h | 22 + libs/math/plane.h | 44 +- libs/math/vector.h | 27 +- radiant/brush_primit.h | 3 +- tools/quake3/common/cmdlib.cpp | 1 - tools/quake3/common/inout.cpp | 7 +- tools/quake3/common/inout.h | 10 +- tools/quake3/common/maxworld.h | 5 + tools/quake3/common/polylib.cpp | 434 +++---- tools/quake3/common/polylib.h | 47 +- tools/quake3/common/qmath.h | 303 +++++ tools/quake3/common/scriplib.cpp | 13 +- tools/quake3/common/scriplib.h | 15 +- tools/quake3/common/threads.cpp | 1 - tools/quake3/common/vfs.cpp | 1 - tools/quake3/q3map2/brush.cpp | 118 +- tools/quake3/q3map2/brush_primit.cpp | 78 -- tools/quake3/q3map2/bsp.cpp | 19 +- tools/quake3/q3map2/bspfile_abstract.cpp | 2 +- tools/quake3/q3map2/bspfile_ibsp.cpp | 80 +- tools/quake3/q3map2/convert_ase.cpp | 13 +- tools/quake3/q3map2/convert_bsp.cpp | 129 +-- tools/quake3/q3map2/convert_map.cpp | 172 ++- tools/quake3/q3map2/convert_obj.cpp | 6 +- tools/quake3/q3map2/decals.cpp | 276 ++--- tools/quake3/q3map2/facebsp.cpp | 59 +- tools/quake3/q3map2/fog.cpp | 102 +- tools/quake3/q3map2/leakfile.cpp | 4 +- tools/quake3/q3map2/light.cpp | 290 +++-- tools/quake3/q3map2/light_bounce.cpp | 260 ++--- tools/quake3/q3map2/light_trace.cpp | 279 +++-- tools/quake3/q3map2/light_ydnar.cpp | 1347 +++++++++------------- tools/quake3/q3map2/lightmaps_ydnar.cpp | 663 +++++------ tools/quake3/q3map2/map.cpp | 324 +++--- tools/quake3/q3map2/mesh.cpp | 226 ++-- tools/quake3/q3map2/minimap.cpp | 61 +- tools/quake3/q3map2/model.cpp | 462 ++++---- tools/quake3/q3map2/patch.cpp | 138 +-- tools/quake3/q3map2/portals.cpp | 91 +- tools/quake3/q3map2/prtfile.cpp | 12 +- tools/quake3/q3map2/q3map2.h | 424 ++++--- tools/quake3/q3map2/shaders.cpp | 147 ++- tools/quake3/q3map2/surface.cpp | 617 ++++------ tools/quake3/q3map2/surface_extra.cpp | 10 +- tools/quake3/q3map2/surface_foliage.cpp | 42 +- tools/quake3/q3map2/surface_fur.cpp | 20 +- tools/quake3/q3map2/surface_meta.cpp | 247 ++-- tools/quake3/q3map2/tjunction.cpp | 167 ++- tools/quake3/q3map2/tree.cpp | 13 +- tools/quake3/q3map2/vis.cpp | 110 +- tools/quake3/q3map2/visflow.cpp | 260 ++--- tools/quake3/q3map2/writebsp.cpp | 65 +- 55 files changed, 3630 insertions(+), 4643 deletions(-) create mode 100644 tools/quake3/common/maxworld.h create mode 100644 tools/quake3/common/qmath.h delete mode 100644 tools/quake3/q3map2/brush_primit.cpp diff --git a/Makefile b/Makefile index 8891c158..6f1f7236 100644 --- a/Makefile +++ b/Makefile @@ -540,7 +540,6 @@ $(INSTALLDIR)/q3map2.$(EXE): \ tools/quake3/common/miniz.o \ tools/quake3/q3map2/autopk3.o \ tools/quake3/q3map2/brush.o \ - tools/quake3/q3map2/brush_primit.o \ tools/quake3/q3map2/bspfile_abstract.o \ tools/quake3/q3map2/bspfile_ibsp.o \ tools/quake3/q3map2/bspfile_rbsp.o \ diff --git a/include/cullable.h b/include/cullable.h index 303803a9..92029906 100644 --- a/include/cullable.h +++ b/include/cullable.h @@ -26,7 +26,8 @@ template class BasicVector3; typedef BasicVector3 Vector3; -class Plane3; +template class Plane3___; +typedef Plane3___ Plane3; class Matrix4; class AABB; class Segment; diff --git a/include/selectable.h b/include/selectable.h index 08dd0c92..4256897f 100644 --- a/include/selectable.h +++ b/include/selectable.h @@ -281,7 +281,8 @@ inline SelectionTestable* Instance_getSelectionTestable( scene::Instance& instan } -class Plane3; +template class Plane3___; +typedef Plane3___ Plane3; typedef Callback1 PlaneCallback; class SelectedPlanes diff --git a/libs/generic/vector.h b/libs/generic/vector.h index 85258f5b..55e895ec 100644 --- a/libs/generic/vector.h +++ b/libs/generic/vector.h @@ -103,6 +103,11 @@ Element* data(){ const Element* data() const { return m_elements; } + +BasicVector3& set( const Element value ){ + x() = y() = z() = value; + return *this; +} }; /// \brief A 4-element vector. @@ -171,8 +176,25 @@ Element* data(){ const Element* data() const { return m_elements; } + +BasicVector3& vec3(){ + return reinterpret_cast&>( x() ); +} +const BasicVector3& vec3() const { + return reinterpret_cast&>( x() ); +} + +BasicVector4& set( const Element value ){ + x() = y() = z() = w() = value; + return *this; +} }; +template +inline BasicVector2 vector2_from_array( const Element* array ){ + return BasicVector2( array[0], array[1] ); +} + template inline BasicVector3 vector3_from_array( const Element* array ){ return BasicVector3( array[0], array[1], array[2] ); diff --git a/libs/math/plane.h b/libs/math/plane.h index cb476a68..3b4915b7 100644 --- a/libs/math/plane.h +++ b/libs/math/plane.h @@ -27,36 +27,41 @@ #include "math/matrix.h" -/// \brief A plane equation stored in double-precision floating-point. -class Plane3 +template +class Plane3___ { public: -double a, b, c, d; +T a, b, c, d; -Plane3(){ +Plane3___(){ } -Plane3( double _a, double _b, double _c, double _d ) +Plane3___( double _a, double _b, double _c, double _d ) : a( _a ), b( _b ), c( _c ), d( _d ){ } template -Plane3( const BasicVector3& normal, double dist ) +Plane3___( const BasicVector3& normal, double dist ) : a( normal.x() ), b( normal.y() ), c( normal.z() ), d( dist ){ } -BasicVector3& normal(){ - return reinterpret_cast&>( *this ); +BasicVector3& normal(){ + return reinterpret_cast&>( *this ); } -const BasicVector3& normal() const { - return reinterpret_cast&>( *this ); +const BasicVector3& normal() const { + return reinterpret_cast&>( *this ); } -double& dist(){ +T& dist(){ return d; } -const double& dist() const { +const T& dist() const { return d; } }; +/// \brief A plane equation stored in double-precision floating-point. +using Plane3 = Plane3___; +/// \brief A plane equation stored in single-precision floating-point. +using Plane3f = Plane3___; + inline Plane3 plane3_normalised( const Plane3& plane ){ double rmagnitude = 1.0 / sqrt( plane.a * plane.a + plane.b * plane.b + plane.c * plane.c ); return Plane3( @@ -105,8 +110,9 @@ inline Plane3 plane3_transformed_affine_full( const Plane3& plane, const Matrix4 return Plane3( normal, vector3_dot( normal, anchor ) ); } -inline Plane3 plane3_flipped( const Plane3& plane ){ - return Plane3( vector3_negated( plane.normal() ), -plane.dist() ); +template +inline Plane3___ plane3_flipped( const Plane3___& plane ){ + return Plane3___( vector3_negated( plane.normal() ), -plane.dist() ); } const double c_PLANE_NORMAL_EPSILON = 0.0001f; @@ -148,8 +154,8 @@ inline Plane3 plane3_for_points( const BasicVector3 planepts[3] ){ return plane3_for_points( planepts[0], planepts[1], planepts[2] ); } -template -inline double plane3_distance_to_point( const Plane3& plane, const BasicVector3& point ){ +template +inline double plane3_distance_to_point( const Plane3___

& plane, const BasicVector3& point ){ return vector3_dot( point, plane.normal() ) - plane.dist(); } @@ -160,9 +166,9 @@ inline BasicVector3 plane3_project_point( const Plane3& plane, const BasicVec return point + direction * d; } -template -inline BasicVector3 plane3_project_point( const Plane3& plane, const BasicVector3& point ){ - return ( point - plane.normal() * vector3_dot( point, plane.normal() ) + plane.normal() * plane.dist() ); +template +inline BasicVector3 plane3_project_point( const Plane3___

& plane, const BasicVector3& point ){ + return point - plane.normal() * plane3_distance_to_point( plane, point ); } #endif diff --git a/libs/math/vector.h b/libs/math/vector.h index f05cb72d..187e1c94 100644 --- a/libs/math/vector.h +++ b/libs/math/vector.h @@ -289,19 +289,18 @@ inline void vector2_normalise( BasicVector2& self ){ self = vector2_normalised( self ); } +template +inline BasicVector2 vector2_mid( const BasicVector2& begin, const BasicVector2& end ){ + return vector2_scaled( vector2_added( begin, end ), 0.5 ); +} + const Vector3 g_vector3_identity( 0, 0, 0 ); const Vector3 g_vector3_max = Vector3( FLT_MAX, FLT_MAX, FLT_MAX ); const Vector3 g_vector3_axis_x( 1, 0, 0 ); const Vector3 g_vector3_axis_y( 0, 1, 0 ); const Vector3 g_vector3_axis_z( 0, 0, 1 ); -#ifdef __GNUC__ -#define VARIABLE_IS_NOT_USED __attribute__ ((unused)) -#else -#define VARIABLE_IS_NOT_USED -#endif - -const Vector3 VARIABLE_IS_NOT_USED g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z }; +const Vector3 g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z }; template inline void vector3_swap( BasicVector3& self, BasicVector3& other ){ @@ -560,20 +559,14 @@ inline Vector3 vector3_for_spherical( double theta, double phi ){ template inline std::size_t vector3_max_abs_component_index( const BasicVector3& self ){ - std::size_t maxi = 0; - for( std::size_t i = 1; i < 3; ++i ) - if( fabs( self[i] ) > fabs( self[maxi] ) ) - maxi = i; - return maxi; + const std::size_t maxi = ( fabs( self[1] ) > fabs( self[0] ) )? 1 : 0; + return ( fabs( self[2] ) > fabs( self[maxi] ) )? 2 : maxi;; } template inline std::size_t vector3_min_abs_component_index( const BasicVector3& self ){ - std::size_t mini = 0; - for( std::size_t i = 1; i < 3; ++i ) - if( fabs( self[i] ) < fabs( self[mini] ) ) - mini = i; - return mini; + const std::size_t mini = ( fabs( self[1] ) < fabs( self[0] ) )? 1 : 0; + return ( fabs( self[2] ) < fabs( self[mini] ) )? 2 : mini; } diff --git a/radiant/brush_primit.h b/radiant/brush_primit.h index 6c0569cf..cdf0cb40 100644 --- a/radiant/brush_primit.h +++ b/radiant/brush_primit.h @@ -90,7 +90,8 @@ float Texdef_getDefaultTextureScale(); class texdef_t; struct Winding; class Matrix4; -class Plane3; +template class Plane3___; +typedef Plane3___ Plane3; void Normal_GetTransform( const Vector3& normal, Matrix4& transform ); diff --git a/tools/quake3/common/cmdlib.cpp b/tools/quake3/common/cmdlib.cpp index 0914337c..e71dfe6b 100644 --- a/tools/quake3/common/cmdlib.cpp +++ b/tools/quake3/common/cmdlib.cpp @@ -29,7 +29,6 @@ // replaced qprintf with Sys_Printf #include "cmdlib.h" -#include "mathlib.h" #include "inout.h" #include #include diff --git a/tools/quake3/common/inout.cpp b/tools/quake3/common/inout.cpp index 80912835..0fd6d20d 100644 --- a/tools/quake3/common/inout.cpp +++ b/tools/quake3/common/inout.cpp @@ -30,6 +30,7 @@ #include "inout.h" #include #include +#include "generic/vector.h" #ifdef WIN32 #include @@ -56,7 +57,7 @@ xmlDocPtr doc; xmlNodePtr tree; // some useful stuff -xmlNodePtr xml_NodeForVec( vec3_t v ){ +xmlNodePtr xml_NodeForVec( const Vector3& v ){ xmlNodePtr ret; char buf[1024]; @@ -166,7 +167,7 @@ void xml_Select( const char *msg, int entitynum, int brushnum, bool bError ){ } } -void xml_Point( const char *msg, vec3_t pt ){ +void xml_Point( const char *msg, const Vector3& pt ){ xmlNodePtr node, point; char buf[1024]; char level[2]; @@ -188,7 +189,7 @@ void xml_Point( const char *msg, vec3_t pt ){ } #define WINDING_BUFSIZE 2048 -void xml_Winding( const char *msg, vec3_t p[], int numpoints, bool die ){ +void xml_Winding( const char *msg, const Vector3 p[], int numpoints, bool die ){ xmlNodePtr node, winding; char buf[WINDING_BUFSIZE]; char smlbuf[128]; diff --git a/tools/quake3/common/inout.h b/tools/quake3/common/inout.h index 011f0a03..e5b3b02c 100644 --- a/tools/quake3/common/inout.h +++ b/tools/quake3/common/inout.h @@ -24,18 +24,20 @@ // inout is the only stuff relying on xml, include the headers there #include "libxml/tree.h" -#include "mathlib.h" + +template class BasicVector3; +typedef BasicVector3 Vector3; // some useful xml routines -xmlNodePtr xml_NodeForVec( vec3_t v ); +xmlNodePtr xml_NodeForVec( const Vector3& v ); void xml_SendNode( xmlNodePtr node ); // print a message in q3map output and send the corresponding select information down the xml stream // bError: do we end with an error on this one or do we go ahead? void xml_Select( const char *msg, int entitynum, int brushnum, bool bError ); // end q3map with an error message and send a point information in the xml stream // note: we might want to add a boolean to use this as a warning or an error thing.. -void xml_Winding( const char *msg, vec3_t p[], int numpoints, bool die ); -void xml_Point( const char *msg, vec3_t pt ); +void xml_Winding( const char *msg, const Vector3 p[], int numpoints, bool die ); +void xml_Point( const char *msg, const Vector3& pt ); void Broadcast_Setup( const char *dest ); void Broadcast_Shutdown(); diff --git a/tools/quake3/common/maxworld.h b/tools/quake3/common/maxworld.h new file mode 100644 index 00000000..69b46d90 --- /dev/null +++ b/tools/quake3/common/maxworld.h @@ -0,0 +1,5 @@ +#pragma once + +#define MIN_WORLD_COORD ( -65536 ) +#define MAX_WORLD_COORD ( 65536 ) +#define WORLD_SIZE ( MAX_WORLD_COORD - MIN_WORLD_COORD ) diff --git a/tools/quake3/common/polylib.cpp b/tools/quake3/common/polylib.cpp index 609c010a..85a20fc9 100644 --- a/tools/quake3/common/polylib.cpp +++ b/tools/quake3/common/polylib.cpp @@ -23,11 +23,9 @@ #include #include "cmdlib.h" -#include "mathlib.h" #include "inout.h" #include "polylib.h" -#include "qfiles.h" - +#include "maxworld.h" #define BOGUS_RANGE WORLD_SIZE @@ -105,21 +103,16 @@ void FreeWindingAccu( winding_accu_t *w ){ */ void RemoveColinearPoints( winding_t *w ){ int i, j, k; - vec3_t v1, v2; int nump; - vec3_t p[MAX_POINTS_ON_WINDING]; + Vector3 p[MAX_POINTS_ON_WINDING]; nump = 0; for ( i = 0 ; i < w->numpoints ; i++ ) { j = ( i + 1 ) % w->numpoints; k = ( i + w->numpoints - 1 ) % w->numpoints; - VectorSubtract( w->p[j], w->p[i], v1 ); - VectorSubtract( w->p[i], w->p[k], v2 ); - VectorNormalize( v1,v1 ); - VectorNormalize( v2,v2 ); - if ( DotProduct( v1, v2 ) < 0.999 ) { - VectorCopy( w->p[i], p[nump] ); + if ( vector3_dot( VectorNormalized( w->p[j] - w->p[i] ), VectorNormalized( w->p[j] - w->p[k] ) ) < 0.999 ) { + p[nump] = w->p[i]; nump++; } } @@ -137,15 +130,10 @@ void RemoveColinearPoints( winding_t *w ){ WindingPlane ============ */ -void WindingPlane( winding_t *w, vec3_t normal, vec_t *dist ){ - vec3_t v1, v2; - - VectorSubtract( w->p[1], w->p[0], v1 ); - VectorSubtract( w->p[2], w->p[0], v2 ); - CrossProduct( v2, v1, normal ); - VectorNormalize( normal, normal ); - *dist = DotProduct( w->p[0], normal ); - +Plane3f WindingPlane( const winding_t *w ){ + Plane3f plane; + PlaneFromPoints( plane, w->p[0], w->p[1], w->p[2] ); + return plane; } /* @@ -153,42 +141,23 @@ void WindingPlane( winding_t *w, vec3_t normal, vec_t *dist ){ WindingArea ============= */ -vec_t WindingArea( winding_t *w ){ - int i; - vec3_t d1, d2, cross; - vec_t total; +float WindingArea( const winding_t *w ){ + float total = 0; - total = 0; - for ( i = 2 ; i < w->numpoints ; i++ ) + for ( int i = 2 ; i < w->numpoints ; i++ ) { - VectorSubtract( w->p[i - 1], w->p[0], d1 ); - VectorSubtract( w->p[i], w->p[0], d2 ); - CrossProduct( d1, d2, cross ); - total += 0.5 * VectorLength( cross ); + total += 0.5 * vector3_length( vector3_cross( w->p[i - 1] - w->p[0], w->p[i] - w->p[0] ) ); } return total; } -void WindingBounds( winding_t *w, vec3_t mins, vec3_t maxs ){ - vec_t v; - int i,j; - - mins[0] = mins[1] = mins[2] = 99999; - maxs[0] = maxs[1] = maxs[2] = -99999; - - for ( i = 0 ; i < w->numpoints ; i++ ) +MinMax WindingBounds( const winding_t *w ){ + MinMax minmax; + for ( int i = 0 ; i < w->numpoints ; i++ ) { - for ( j = 0 ; j < 3 ; j++ ) - { - v = w->p[i][j]; - if ( v < mins[j] ) { - mins[j] = v; - } - if ( v > maxs[j] ) { - maxs[j] = v; - } - } + minmax.extend( w->p[i] ); } + return minmax; } /* @@ -196,16 +165,13 @@ void WindingBounds( winding_t *w, vec3_t mins, vec3_t maxs ){ WindingCenter ============= */ -void WindingCenter( winding_t *w, vec3_t center ){ - int i; - float scale; +Vector3 WindingCenter( const winding_t *w ){ + Vector3 center( 0, 0, 0 ); - VectorCopy( vec3_origin, center ); - for ( i = 0 ; i < w->numpoints ; i++ ) - VectorAdd( w->p[i], center, center ); - - scale = 1.0 / w->numpoints; - VectorScale( center, scale, center ); + for ( int i = 0 ; i < w->numpoints ; i++ ) + center += w->p[i]; + + return center / w->numpoints; } /* @@ -213,7 +179,7 @@ void WindingCenter( winding_t *w, vec3_t center ){ BaseWindingForPlaneAccu ================= */ -winding_accu_t *BaseWindingForPlaneAccu( vec3_t normal, vec_t dist ){ +winding_accu_t *BaseWindingForPlaneAccu( const Plane3f& inplane ){ // The goal in this function is to replicate the behavior of the original BaseWindingForPlane() // function (see below) but at the same time increasing accuracy substantially. @@ -228,8 +194,9 @@ winding_accu_t *BaseWindingForPlaneAccu( vec3_t normal, vec_t dist ){ // of 2) than the winding polygon in the original function. int x, i; - vec_t max, v; - vec3_accu_t vright, vup, org, normalAccu; + float max, v; + DoubleVector3 vright, vup, org; + const Plane3 plane( inplane.normal(), inplane.dist() ); winding_accu_t *w; // One of the components of normal must have a magnitiude greater than this value, @@ -239,7 +206,7 @@ winding_accu_t *BaseWindingForPlaneAccu( vec3_t normal, vec_t dist ){ x = -1; for ( i = 0; i < 3; i++ ) { - v = (vec_t) fabs( normal[i] ); + v = fabs( plane.normal()[i] ); if ( v > max ) { x = i; max = v; @@ -252,14 +219,14 @@ winding_accu_t *BaseWindingForPlaneAccu( vec3_t normal, vec_t dist ){ switch ( x ) { case 0: // Fall through to next case. case 1: - vright[0] = (vec_accu_t) -normal[1]; - vright[1] = (vec_accu_t) normal[0]; + vright[0] = -plane.normal()[1]; + vright[1] = plane.normal()[0]; vright[2] = 0; break; case 2: vright[0] = 0; - vright[1] = (vec_accu_t) -normal[2]; - vright[2] = (vec_accu_t) normal[1]; + vright[1] = -plane.normal()[2]; + vright[2] = plane.normal()[1]; break; } @@ -276,19 +243,18 @@ winding_accu_t *BaseWindingForPlaneAccu( vec3_t normal, vec_t dist ){ // We're relying on the fact that MAX_WORLD_COORD is a power of 2 to keep // our calculation precise and relatively free of floating point error. // [However, the code will still work fine if that's not the case.] - VectorScaleAccu( vright, ( (vec_accu_t) MAX_WORLD_COORD ) * 4.0, vright ); + vright *= ( (double) MAX_WORLD_COORD ) * 4.0; // At time time of this writing, MAX_WORLD_COORD was 65536 (2^16). Therefore // the length of vright at this point is at least 185364. In comparison, a // corner of the world at location (65536, 65536, 65536) is distance 113512 // away from the origin. - VectorCopyRegularToAccu( normal, normalAccu ); - CrossProductAccu( normalAccu, vright, vup ); + vup = vector3_cross( plane.normal(), vright ); // vup now has length equal to that of vright. - VectorScaleAccu( normalAccu, (vec_accu_t) dist, org ); + org = plane.normal() * plane.dist(); // org is now a point on the plane defined by normal and dist. Furthermore, // org, vright, and vup are pairwise perpendicular. Now, the 4 vectors @@ -304,17 +270,10 @@ winding_accu_t *BaseWindingForPlaneAccu( vec3_t normal, vec_t dist ){ w = AllocWindingAccu( 4 ); - VectorSubtractAccu( org, vright, w->p[0] ); - VectorAddAccu( w->p[0], vup, w->p[0] ); - - VectorAddAccu( org, vright, w->p[1] ); - VectorAddAccu( w->p[1], vup, w->p[1] ); - - VectorAddAccu( org, vright, w->p[2] ); - VectorSubtractAccu( w->p[2], vup, w->p[2] ); - - VectorSubtractAccu( org, vright, w->p[3] ); - VectorSubtractAccu( w->p[3], vup, w->p[3] ); + w->p[0] = org - vright + vup; + w->p[1] = org + vright + vup; + w->p[2] = org + vright - vup; + w->p[3] = org - vright - vup; w->numpoints = 4; @@ -336,10 +295,10 @@ winding_accu_t *BaseWindingForPlaneAccu( vec3_t normal, vec_t dist ){ error, and can lead to all sorts of disappearing triangle problems. ================= */ -winding_t *BaseWindingForPlane( vec3_t normal, vec_t dist ){ +winding_t *BaseWindingForPlane( const Plane3f& plane ){ int i, x; - vec_t max, v; - vec3_t org, vright, vup; + float max, v; + Vector3 org, vright, vup; winding_t *w; // find the major axis @@ -348,7 +307,7 @@ winding_t *BaseWindingForPlane( vec3_t normal, vec_t dist ){ x = -1; for ( i = 0 ; i < 3; i++ ) { - v = fabs( normal[i] ); + v = fabs( plane.normal()[i] ); if ( v > max ) { x = i; max = v; @@ -358,7 +317,7 @@ winding_t *BaseWindingForPlane( vec3_t normal, vec_t dist ){ Error( "BaseWindingForPlane: no axis found" ); } - VectorCopy( vec3_origin, vup ); + vup.set( 0 ); switch ( x ) { case 0: @@ -370,34 +329,26 @@ winding_t *BaseWindingForPlane( vec3_t normal, vec_t dist ){ break; } - v = DotProduct( vup, normal ); - VectorMA( vup, -v, normal, vup ); - VectorNormalize( vup, vup ); + vup -= plane.normal() * vector3_dot( vup, plane.normal() ); + VectorNormalize( vup ); - VectorScale( normal, dist, org ); + org = plane.normal() * plane.dist(); - CrossProduct( vup, normal, vright ); + vright = vector3_cross( vup, plane.normal() ); // LordHavoc: this has to use *2 because otherwise some created points may // be inside the world (think of a diagonal case), and any brush with such // points should be removed, failure to detect such cases is disasterous - VectorScale( vup, MAX_WORLD_COORD * 2, vup ); - VectorScale( vright, MAX_WORLD_COORD * 2, vright ); + vup *= MAX_WORLD_COORD * 2; + vright *= MAX_WORLD_COORD * 2; // project a really big axis aligned box onto the plane w = AllocWinding( 4 ); - VectorSubtract( org, vright, w->p[0] ); - VectorAdd( w->p[0], vup, w->p[0] ); - - VectorAdd( org, vright, w->p[1] ); - VectorAdd( w->p[1], vup, w->p[1] ); - - VectorAdd( org, vright, w->p[2] ); - VectorSubtract( w->p[2], vup, w->p[2] ); - - VectorSubtract( org, vright, w->p[3] ); - VectorSubtract( w->p[3], vup, w->p[3] ); + w->p[0] = org - vright + vup; + w->p[1] = org + vright + vup; + w->p[2] = org + vright - vup; + w->p[3] = org - vright - vup; w->numpoints = 4; @@ -448,7 +399,7 @@ winding_t *CopyWindingAccuToRegular( const winding_accu_t *w ){ c->numpoints = w->numpoints; for ( i = 0; i < c->numpoints; i++ ) { - VectorCopyAccuToRegular( w->p[i], c->p[i] ); + c->p[i] = w->p[i]; } return c; } @@ -458,14 +409,14 @@ winding_t *CopyWindingAccuToRegular( const winding_accu_t *w ){ ReverseWinding ================== */ -winding_t *ReverseWinding( winding_t *w ){ +winding_t *ReverseWinding( const winding_t *w ){ int i; winding_t *c; c = AllocWinding( w->numpoints ); for ( i = 0 ; i < w->numpoints ; i++ ) { - VectorCopy( w->p[w->numpoints - 1 - i], c->p[i] ); + c->p[i] = w->p[w->numpoints - 1 - i]; } c->numpoints = w->numpoints; return c; @@ -477,15 +428,12 @@ winding_t *ReverseWinding( winding_t *w ){ ClipWindingEpsilon ============= */ -void ClipWindingEpsilonStrict( winding_t *in, vec3_t normal, vec_t dist, - vec_t epsilon, winding_t **front, winding_t **back ){ - vec_t dists[MAX_POINTS_ON_WINDING + 4]; - int sides[MAX_POINTS_ON_WINDING + 4]; +void ClipWindingEpsilonStrict( winding_t *in, const Plane3f& plane, + float epsilon, winding_t **front, winding_t **back ){ + float dists[MAX_POINTS_ON_WINDING + 4]; + EPlaneSide sides[MAX_POINTS_ON_WINDING + 4]; int counts[3]; - static vec_t dot; // VC 4.2 optimizer bug if not static int i, j; - vec_t *p1, *p2; - vec3_t mid; winding_t *f, *b; int maxpts; @@ -495,18 +443,16 @@ void ClipWindingEpsilonStrict( winding_t *in, vec3_t normal, vec_t dist, for ( i = 0 ; i < in->numpoints ; i++ ) { - dot = DotProduct( in->p[i], normal ); - dot -= dist; - dists[i] = dot; - if ( dot > epsilon ) { - sides[i] = SIDE_FRONT; + dists[i] = plane3_distance_to_point( plane, in->p[i] ); + if ( dists[i] > epsilon ) { + sides[i] = eSideFront; } - else if ( dot < -epsilon ) { - sides[i] = SIDE_BACK; + else if ( dists[i] < -epsilon ) { + sides[i] = eSideBack; } else { - sides[i] = SIDE_ON; + sides[i] = eSideOn; } counts[sides[i]]++; } @@ -535,49 +481,49 @@ void ClipWindingEpsilonStrict( winding_t *in, vec3_t normal, vec_t dist, for ( i = 0 ; i < in->numpoints ; i++ ) { - p1 = in->p[i]; + const Vector3& p1 = in->p[i]; - if ( sides[i] == SIDE_ON ) { - VectorCopy( p1, f->p[f->numpoints] ); + if ( sides[i] == eSideOn ) { + f->p[f->numpoints] = p1; f->numpoints++; - VectorCopy( p1, b->p[b->numpoints] ); + b->p[b->numpoints] = p1; b->numpoints++; continue; } - if ( sides[i] == SIDE_FRONT ) { - VectorCopy( p1, f->p[f->numpoints] ); + if ( sides[i] == eSideFront ) { + f->p[f->numpoints] = p1; f->numpoints++; } - if ( sides[i] == SIDE_BACK ) { - VectorCopy( p1, b->p[b->numpoints] ); + if ( sides[i] == eSideBack ) { + b->p[b->numpoints] = p1; b->numpoints++; } - if ( sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i] ) { + if ( sides[i + 1] == eSideOn || sides[i + 1] == sides[i] ) { continue; } // generate a split point - p2 = in->p[( i + 1 ) % in->numpoints]; - - dot = dists[i] / ( dists[i] - dists[i + 1] ); + const Vector3& p2 = in->p[( i + 1 ) % in->numpoints]; + const double dot = dists[i] / ( dists[i] - dists[i + 1] ); + Vector3 mid; for ( j = 0 ; j < 3 ; j++ ) { // avoid round off error when possible - if ( normal[j] == 1 ) { - mid[j] = dist; + if ( plane.normal()[j] == 1 ) { + mid[j] = plane.dist(); } - else if ( normal[j] == -1 ) { - mid[j] = -dist; + else if ( plane.normal()[j] == -1 ) { + mid[j] = -plane.dist(); } else{ mid[j] = p1[j] + dot * ( p2[j] - p1[j] ); } } - VectorCopy( mid, f->p[f->numpoints] ); + f->p[f->numpoints] = mid; f->numpoints++; - VectorCopy( mid, b->p[b->numpoints] ); + b->p[b->numpoints] = mid; b->numpoints++; } @@ -589,9 +535,9 @@ void ClipWindingEpsilonStrict( winding_t *in, vec3_t normal, vec_t dist, } } -void ClipWindingEpsilon( winding_t *in, vec3_t normal, vec_t dist, - vec_t epsilon, winding_t **front, winding_t **back ){ - ClipWindingEpsilonStrict( in, normal, dist, epsilon, front, back ); +void ClipWindingEpsilon( winding_t *in, const Plane3f& plane, + float epsilon, winding_t **front, winding_t **back ){ + ClipWindingEpsilonStrict( in, plane, epsilon, front, back ); /* apparently most code expects that in the winding-on-plane case, the back winding is the original winding */ if ( !*front && !*back ) { *back = CopyWinding( in ); @@ -599,22 +545,26 @@ void ClipWindingEpsilon( winding_t *in, vec3_t normal, vec_t dist, } +// Smallest positive value for vec_t such that 1.0 + VEC_SMALLEST_EPSILON_AROUND_ONE != 1.0. +// In the case of 32 bit floats (which is almost certainly the case), it's 0.00000011921. +// Don't forget that your epsilons should depend on the possible range of values, +// because for example adding VEC_SMALLEST_EPSILON_AROUND_ONE to 1024.0 will have no effect. +#define VEC_SMALLEST_EPSILON_AROUND_ONE FLT_EPSILON + /* ============= ChopWindingInPlaceAccu ============= */ -void ChopWindingInPlaceAccu( winding_accu_t **inout, vec3_t normal, vec_t dist, vec_t crudeEpsilon ){ +void ChopWindingInPlaceAccu( winding_accu_t **inout, const Plane3f& plane, float crudeEpsilon ){ winding_accu_t *in; int counts[3]; int i, j; - vec_accu_t dists[MAX_POINTS_ON_WINDING + 1]; - int sides[MAX_POINTS_ON_WINDING + 1]; + double dists[MAX_POINTS_ON_WINDING + 1]; + EPlaneSide sides[MAX_POINTS_ON_WINDING + 1]; int maxpts; winding_accu_t *f; - vec_accu_t *p1, *p2; - vec_accu_t w; - vec3_accu_t mid, normalAccu; + double w; // We require at least a very small epsilon. It's a good idea for several reasons. // First, we will be dividing by a potentially very small distance below. We don't @@ -634,12 +584,12 @@ void ChopWindingInPlaceAccu( winding_accu_t **inout, vec3_t normal, vec_t dist, // So this minimum epsilon is quite similar to casting the higher resolution numbers to // the lower resolution and comparing them in the lower resolution mode. We explicitly // choose the minimum epsilon as something around the vec_t epsilon of one because we - // want the resolution of vec_accu_t to have a large resolution around the epsilon. + // want the resolution of double to have a large resolution around the epsilon. // Some of that leftover resolution even goes away after we scale to points far away. // Here is a further discussion regarding the choice of smallestEpsilonAllowed. // In the 32 float world (we can assume vec_t is that), the "epsilon around 1.0" is - // 0.00000011921. In the 64 bit float world (we can assume vec_accu_t is that), the + // 0.00000011921. In the 64 bit float world (we can assume double is that), the // "epsilon around 1.0" is 0.00000000000000022204. (By the way these two epsilons // are defined as VEC_SMALLEST_EPSILON_AROUND_ONE VEC_ACCU_SMALLEST_EPSILON_AROUND_ONE // respectively.) If you divide the first by the second, you get approximately @@ -648,23 +598,24 @@ void ChopWindingInPlaceAccu( winding_accu_t **inout, vec3_t normal, vec_t dist, // VEC_SMALLEST_EPSILON_AROUND_ONE, you would be guaranteed at least 2000 "ticks" in // 64-bit land inside of the epsilon for all numbers we're dealing with. - static const vec_accu_t smallestEpsilonAllowed = ( (vec_accu_t) VEC_SMALLEST_EPSILON_AROUND_ONE ) * 0.5; - const vec_accu_t fineEpsilon = ( crudeEpsilon < smallestEpsilonAllowed )? smallestEpsilonAllowed : (vec_accu_t) crudeEpsilon; + static const double smallestEpsilonAllowed = ( (double) VEC_SMALLEST_EPSILON_AROUND_ONE ) * 0.5; + const double fineEpsilon = ( crudeEpsilon < smallestEpsilonAllowed )? smallestEpsilonAllowed : (double) crudeEpsilon; in = *inout; counts[0] = counts[1] = counts[2] = 0; - VectorCopyRegularToAccu( normal, normalAccu ); for ( i = 0; i < in->numpoints; i++ ) { - dists[i] = DotProductAccu( in->p[i], normalAccu ) - dist; + dists[i] = plane3_distance_to_point( plane, in->p[i] ); if ( dists[i] > fineEpsilon ) { - sides[i] = SIDE_FRONT; + sides[i] = eSideFront; } else if ( dists[i] < -fineEpsilon ) { - sides[i] = SIDE_BACK; + sides[i] = eSideBack; + } + else{ + sides[i] = eSideOn; } - else{sides[i] = SIDE_ON; } counts[sides[i]]++; } sides[i] = sides[0]; @@ -673,26 +624,26 @@ void ChopWindingInPlaceAccu( winding_accu_t **inout, vec3_t normal, vec_t dist, // I'm wondering if whatever code that handles duplicate planes is robust enough // that we never get a case where two nearly equal planes result in 2 NULL windings // due to the 'if' statement below. TODO: Investigate this. - if ( !counts[SIDE_FRONT] ) { + if ( !counts[eSideFront] ) { FreeWindingAccu( in ); *inout = NULL; return; } - if ( !counts[SIDE_BACK] ) { + if ( !counts[eSideBack] ) { return; // Winding is unmodified. } // NOTE: The least number of points that a winding can have at this point is 2. // In that case, one point is SIDE_FRONT and the other is SIDE_BACK. - maxpts = counts[SIDE_FRONT] + 2; // We dynamically expand if this is too small. + maxpts = counts[eSideFront] + 2; // We dynamically expand if this is too small. f = AllocWindingAccu( maxpts ); for ( i = 0; i < in->numpoints; i++ ) { - p1 = in->p[i]; + const DoubleVector3& p1 = in->p[i]; - if ( sides[i] == SIDE_ON || sides[i] == SIDE_FRONT ) { + if ( sides[i] == eSideOn || sides[i] == eSideFront ) { if ( f->numpoints >= MAX_POINTS_ON_WINDING ) { Error( "ChopWindingInPlaceAccu: MAX_POINTS_ON_WINDING" ); } @@ -701,31 +652,31 @@ void ChopWindingInPlaceAccu( winding_accu_t **inout, vec3_t normal, vec_t dist, f = CopyWindingAccuIncreaseSizeAndFreeOld( f ); maxpts++; } - VectorCopyAccu( p1, f->p[f->numpoints] ); + f->p[f->numpoints] = p1; f->numpoints++; - if ( sides[i] == SIDE_ON ) { + if ( sides[i] == eSideOn ) { continue; } } - if ( sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i] ) { + if ( sides[i + 1] == eSideOn || sides[i + 1] == sides[i] ) { continue; } // Generate a split point. - p2 = in->p[( ( i + 1 ) == in->numpoints ) ? 0 : ( i + 1 )]; + const DoubleVector3& p2 = in->p[( ( i + 1 ) == in->numpoints ) ? 0 : ( i + 1 )]; // The divisor's absolute value is greater than the dividend's absolute value. // w is in the range (0,1). w = dists[i] / ( dists[i] - dists[i + 1] ); - + DoubleVector3 mid; for ( j = 0; j < 3; j++ ) { // Avoid round-off error when possible. Check axis-aligned normal. - if ( normal[j] == 1 ) { - mid[j] = dist; + if ( plane.normal()[j] == 1 ) { + mid[j] = plane.dist(); } - else if ( normal[j] == -1 ) { - mid[j] = -dist; + else if ( plane.normal()[j] == -1 ) { + mid[j] = -plane.dist(); } else{mid[j] = p1[j] + ( w * ( p2[j] - p1[j] ) ); } } @@ -737,7 +688,7 @@ void ChopWindingInPlaceAccu( winding_accu_t **inout, vec3_t normal, vec_t dist, f = CopyWindingAccuIncreaseSizeAndFreeOld( f ); maxpts++; } - VectorCopyAccu( mid, f->p[f->numpoints] ); + f->p[f->numpoints] = mid; f->numpoints++; } @@ -750,15 +701,12 @@ void ChopWindingInPlaceAccu( winding_accu_t **inout, vec3_t normal, vec_t dist, ChopWindingInPlace ============= */ -void ChopWindingInPlace( winding_t **inout, vec3_t normal, vec_t dist, vec_t epsilon ){ +void ChopWindingInPlace( winding_t **inout, const Plane3f& plane, float epsilon ){ winding_t *in; - vec_t dists[MAX_POINTS_ON_WINDING + 4]; - int sides[MAX_POINTS_ON_WINDING + 4]; + float dists[MAX_POINTS_ON_WINDING + 4]; + EPlaneSide sides[MAX_POINTS_ON_WINDING + 4]; int counts[3]; - static vec_t dot; // VC 4.2 optimizer bug if not static int i, j; - vec_t *p1, *p2; - vec3_t mid; winding_t *f; int maxpts; @@ -768,18 +716,16 @@ void ChopWindingInPlace( winding_t **inout, vec3_t normal, vec_t dist, vec_t eps // determine sides for each point for ( i = 0 ; i < in->numpoints ; i++ ) { - dot = DotProduct( in->p[i], normal ); - dot -= dist; - dists[i] = dot; - if ( dot > epsilon ) { - sides[i] = SIDE_FRONT; + dists[i] = plane3_distance_to_point( plane, in->p[i] ); + if ( dists[i] > epsilon ) { + sides[i] = eSideFront; } - else if ( dot < -epsilon ) { - sides[i] = SIDE_BACK; + else if ( dists[i] < -epsilon ) { + sides[i] = eSideBack; } else { - sides[i] = SIDE_ON; + sides[i] = eSideOn; } counts[sides[i]]++; } @@ -802,41 +748,42 @@ void ChopWindingInPlace( winding_t **inout, vec3_t normal, vec_t dist, vec_t eps for ( i = 0 ; i < in->numpoints ; i++ ) { - p1 = in->p[i]; + const Vector3& p1 = in->p[i]; - if ( sides[i] == SIDE_ON ) { - VectorCopy( p1, f->p[f->numpoints] ); + if ( sides[i] == eSideOn ) { + f->p[f->numpoints] = p1; f->numpoints++; continue; } - if ( sides[i] == SIDE_FRONT ) { - VectorCopy( p1, f->p[f->numpoints] ); + if ( sides[i] == eSideFront ) { + f->p[f->numpoints] = p1; f->numpoints++; } - if ( sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i] ) { + if ( sides[i + 1] == eSideOn || sides[i + 1] == sides[i] ) { continue; } // generate a split point - p2 = in->p[( i + 1 ) % in->numpoints]; + const Vector3& p2 = in->p[( i + 1 ) % in->numpoints]; - dot = dists[i] / ( dists[i] - dists[i + 1] ); + const double dot = dists[i] / ( dists[i] - dists[i + 1] ); + Vector3 mid; for ( j = 0 ; j < 3 ; j++ ) { // avoid round off error when possible - if ( normal[j] == 1 ) { - mid[j] = dist; + if ( plane.normal()[j] == 1 ) { + mid[j] = plane.dist(); } - else if ( normal[j] == -1 ) { - mid[j] = -dist; + else if ( plane.normal()[j] == -1 ) { + mid[j] = -plane.dist(); } else{ mid[j] = p1[j] + dot * ( p2[j] - p1[j] ); } } - VectorCopy( mid, f->p[f->numpoints] ); + f->p[f->numpoints] = mid; f->numpoints++; } @@ -860,10 +807,10 @@ void ChopWindingInPlace( winding_t **inout, vec3_t normal, vec_t dist, vec_t eps of the cliping plane. The original is freed. ================= */ -winding_t *ChopWinding( winding_t *in, vec3_t normal, vec_t dist ){ +winding_t *ChopWinding( winding_t *in, const Plane3f& plane ){ winding_t *f, *b; - ClipWindingEpsilon( in, normal, dist, ON_EPSILON, &f, &b ); + ClipWindingEpsilon( in, plane, ON_EPSILON, &f, &b ); FreeWinding( in ); if ( b ) { FreeWinding( b ); @@ -880,11 +827,9 @@ winding_t *ChopWinding( winding_t *in, vec3_t normal, vec_t dist ){ */ void CheckWinding( winding_t *w ){ int i, j; - vec_t *p1, *p2; - vec_t d, edgedist; - vec3_t dir, edgenormal, facenormal; - vec_t area; - vec_t facedist; + float d, edgedist; + Vector3 dir, edgenormal; + float area; if ( w->numpoints < 3 ) { Error( "CheckWinding: %i points",w->numpoints ); @@ -895,11 +840,11 @@ void CheckWinding( winding_t *w ){ Error( "CheckWinding: %f area", area ); } - WindingPlane( w, facenormal, &facedist ); + const Plane3f faceplane = WindingPlane( w ); for ( i = 0 ; i < w->numpoints ; i++ ) { - p1 = w->p[i]; + const Vector3& p1 = w->p[i]; for ( j = 0 ; j < 3 ; j++ ) if ( p1[j] > MAX_WORLD_COORD || p1[j] < MIN_WORLD_COORD ) { @@ -909,23 +854,21 @@ void CheckWinding( winding_t *w ){ j = i + 1 == w->numpoints ? 0 : i + 1; // check the point is on the face plane - d = DotProduct( p1, facenormal ) - facedist; + d = plane3_distance_to_point( faceplane, p1 ); if ( d < -ON_EPSILON || d > ON_EPSILON ) { Error( "CheckWinding: point off plane" ); } // check the edge isnt degenerate - p2 = w->p[j]; - VectorSubtract( p2, p1, dir ); + const Vector3& p2 = w->p[j]; + dir = p2 - p1; - if ( VectorLength( dir ) < ON_EPSILON ) { + if ( vector3_length( dir ) < ON_EPSILON ) { Error( "CheckWinding: degenerate edge" ); } - CrossProduct( facenormal, dir, edgenormal ); - VectorNormalize( edgenormal, edgenormal ); - edgedist = DotProduct( p1, edgenormal ); - edgedist += ON_EPSILON; + edgenormal = VectorNormalized( vector3_cross( faceplane.normal(), dir ) ); + edgedist = vector3_dot( p1, edgenormal ) + ON_EPSILON; // all other points must be on front side for ( j = 0 ; j < w->numpoints ; j++ ) @@ -933,7 +876,7 @@ void CheckWinding( winding_t *w ){ if ( j == i ) { continue; } - d = DotProduct( w->p[j], edgenormal ); + d = vector3_dot( w->p[j], edgenormal ); if ( d > edgedist ) { Error( "CheckWinding: non-convex" ); } @@ -947,26 +890,22 @@ void CheckWinding( winding_t *w ){ WindingOnPlaneSide ============ */ -int WindingOnPlaneSide( winding_t *w, vec3_t normal, vec_t dist ){ - bool front, back; - int i; - vec_t d; - - front = false; - back = false; - for ( i = 0 ; i < w->numpoints ; i++ ) +EPlaneSide WindingOnPlaneSide( const winding_t *w, const Plane3f& plane ){ + bool front = false; + bool back = false; + for ( int i = 0 ; i < w->numpoints ; i++ ) { - d = DotProduct( w->p[i], normal ) - dist; + const double d = plane3_distance_to_point( plane, w->p[i] ); if ( d < -ON_EPSILON ) { if ( front ) { - return SIDE_CROSS; + return eSideCross; } back = true; continue; } if ( d > ON_EPSILON ) { if ( back ) { - return SIDE_CROSS; + return eSideCross; } front = true; continue; @@ -974,12 +913,12 @@ int WindingOnPlaneSide( winding_t *w, vec3_t normal, vec_t dist ){ } if ( back ) { - return SIDE_BACK; + return eSideBack; } if ( front ) { - return SIDE_FRONT; + return eSideFront; } - return SIDE_ON; + return eSideOn; } @@ -991,42 +930,36 @@ int WindingOnPlaneSide( winding_t *w, vec3_t normal, vec_t dist ){ ================= */ #define MAX_HULL_POINTS 128 -void AddWindingToConvexHull( winding_t *w, winding_t **hull, vec3_t normal ) { +void AddWindingToConvexHull( winding_t *w, winding_t **hull, const Vector3& normal ) { int i, j, k; - float *p, *copy; - vec3_t dir; - float d; int numHullPoints, numNew; - vec3_t hullPoints[MAX_HULL_POINTS]; - vec3_t newHullPoints[MAX_HULL_POINTS]; - vec3_t hullDirs[MAX_HULL_POINTS]; + Vector3 hullPoints[MAX_HULL_POINTS]; + Vector3 newHullPoints[MAX_HULL_POINTS]; + Vector3 hullDirs[MAX_HULL_POINTS]; bool hullSide[MAX_HULL_POINTS]; bool outside; - if ( !*hull ) { + if ( *hull == nullptr ) { *hull = CopyWinding( w ); return; } numHullPoints = ( *hull )->numpoints; - memcpy( hullPoints, ( *hull )->p, numHullPoints * sizeof( vec3_t ) ); + memcpy( hullPoints, ( *hull )->p, numHullPoints * sizeof( Vector3 ) ); for ( i = 0 ; i < w->numpoints ; i++ ) { - p = w->p[i]; + const Vector3 &p = w->p[i]; // calculate hull side vectors for ( j = 0 ; j < numHullPoints ; j++ ) { k = ( j + 1 ) % numHullPoints; - VectorSubtract( hullPoints[k], hullPoints[j], dir ); - VectorNormalize( dir, dir ); - CrossProduct( normal, dir, hullDirs[j] ); + hullDirs[j] = vector3_cross( normal, VectorNormalized( hullPoints[k] - hullPoints[j] ) ); } outside = false; for ( j = 0 ; j < numHullPoints ; j++ ) { - VectorSubtract( p, hullPoints[j], dir ); - d = DotProduct( dir, hullDirs[j] ); + const double d = vector3_dot( p - hullPoints[j], hullDirs[j] ); if ( d >= ON_EPSILON ) { outside = true; } @@ -1049,7 +982,7 @@ void AddWindingToConvexHull( winding_t *w, winding_t **hull, vec3_t normal ) } // insert the point here - VectorCopy( p, newHullPoints[0] ); + newHullPoints[0] = p; numNew = 1; // copy over all points that aren't double fronts @@ -1058,18 +991,17 @@ void AddWindingToConvexHull( winding_t *w, winding_t **hull, vec3_t normal ) if ( hullSide[ ( j + k ) % numHullPoints ] && hullSide[ ( j + k + 1 ) % numHullPoints ] ) { continue; } - copy = hullPoints[ ( j + k + 1 ) % numHullPoints ]; - VectorCopy( copy, newHullPoints[numNew] ); + newHullPoints[numNew] = hullPoints[ ( j + k + 1 ) % numHullPoints ]; numNew++; } numHullPoints = numNew; - memcpy( hullPoints, newHullPoints, numHullPoints * sizeof( vec3_t ) ); + memcpy( hullPoints, newHullPoints, numHullPoints * sizeof( Vector3 ) ); } FreeWinding( *hull ); w = AllocWinding( numHullPoints ); w->numpoints = numHullPoints; *hull = w; - memcpy( w->p, hullPoints, numHullPoints * sizeof( vec3_t ) ); + memcpy( w->p, hullPoints, numHullPoints * sizeof( Vector3 ) ); } diff --git a/tools/quake3/common/polylib.h b/tools/quake3/common/polylib.h index 709e098c..e3ec9507 100644 --- a/tools/quake3/common/polylib.h +++ b/tools/quake3/common/polylib.h @@ -19,11 +19,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#pragma once + +#include "qmath.h" struct winding_t { int numpoints; - vec3_t p[]; + Vector3 p[]; }; #define MAX_POINTS_ON_WINDING 512 @@ -33,27 +36,35 @@ struct winding_t #define ON_EPSILON 0.1 #endif +enum EPlaneSide +{ + eSideFront = 0, //! in front of plane ---->| * + eSideBack = 1, //! behind the plane -*-->| + eSideOn = 2, + eSideCross = 3, +}; + winding_t *AllocWinding( int points ); -vec_t WindingArea( winding_t *w ); -void WindingCenter( winding_t *w, vec3_t center ); -void ClipWindingEpsilon( winding_t *in, vec3_t normal, vec_t dist, - vec_t epsilon, winding_t **front, winding_t **back ); -void ClipWindingEpsilonStrict( winding_t *in, vec3_t normal, vec_t dist, - vec_t epsilon, winding_t **front, winding_t **back ); -winding_t *ChopWinding( winding_t *in, vec3_t normal, vec_t dist ); +float WindingArea( const winding_t *w ); +Vector3 WindingCenter( const winding_t *w ); +void ClipWindingEpsilon( winding_t *in, const Plane3f& plane, + float epsilon, winding_t **front, winding_t **back ); +void ClipWindingEpsilonStrict( winding_t *in, const Plane3f& plane, + float epsilon, winding_t **front, winding_t **back ); +winding_t *ChopWinding( winding_t *in, const Plane3f& plane ); winding_t *CopyWinding( const winding_t *w ); -winding_t *ReverseWinding( winding_t *w ); -winding_t *BaseWindingForPlane( vec3_t normal, vec_t dist ); +winding_t *ReverseWinding( const winding_t *w ); +winding_t *BaseWindingForPlane( const Plane3f& plane ); void CheckWinding( winding_t *w ); -void WindingPlane( winding_t *w, vec3_t normal, vec_t *dist ); +Plane3f WindingPlane( const winding_t *w ); void RemoveColinearPoints( winding_t *w ); -int WindingOnPlaneSide( winding_t *w, vec3_t normal, vec_t dist ); +EPlaneSide WindingOnPlaneSide( const winding_t *w, const Plane3f& plane ); void FreeWinding( winding_t *w ); -void WindingBounds( winding_t *w, vec3_t mins, vec3_t maxs ); +MinMax WindingBounds( const winding_t *w ); -void AddWindingToConvexHull( winding_t *w, winding_t **hull, vec3_t normal ); +void AddWindingToConvexHull( winding_t *w, winding_t **hull, const Vector3& normal ); -void ChopWindingInPlace( winding_t **w, vec3_t normal, vec_t dist, vec_t epsilon ); +void ChopWindingInPlace( winding_t **w, const Plane3f& plane, float epsilon ); // frees the original if clipped void pw( winding_t *w ); @@ -67,10 +78,10 @@ void pw( winding_t *w ); struct winding_accu_t { int numpoints; - vec3_accu_t p[]; + DoubleVector3 p[]; }; -winding_accu_t *BaseWindingForPlaneAccu( vec3_t normal, vec_t dist ); -void ChopWindingInPlaceAccu( winding_accu_t **w, vec3_t normal, vec_t dist, vec_t epsilon ); +winding_accu_t *BaseWindingForPlaneAccu( const Plane3f& plane ); +void ChopWindingInPlaceAccu( winding_accu_t **w, const Plane3f& plane, float epsilon ); winding_t *CopyWindingAccuToRegular( const winding_accu_t *w ); void FreeWindingAccu( winding_accu_t *w ); diff --git a/tools/quake3/common/qmath.h b/tools/quake3/common/qmath.h new file mode 100644 index 00000000..a3f70620 --- /dev/null +++ b/tools/quake3/common/qmath.h @@ -0,0 +1,303 @@ +#pragma once + +#include "bytebool.h" +#include "math/vector.h" +#include "math/plane.h" + + +#define VectorSet( v, a, b, c ) ( ( v )[0] = ( a ),( v )[1] = ( b ),( v )[2] = ( c ) ) +#define VectorCopy( a,b ) ( ( b )[0] = ( a )[0],( b )[1] = ( a )[1],( b )[2] = ( a )[2] ) + +#define RGBTOGRAY( x ) ( (float)( ( x )[0] ) * 0.2989f + (float)( ( x )[1] ) * 0.5870f + (float)( ( x )[2] ) * 0.1140f ) + +#define VectorFastNormalize VectorNormalize + + +template +struct MinMax___ +{ + BasicVector3 mins; + BasicVector3 maxs; + MinMax___(){ + clear(); + } + template + MinMax___( const BasicVector3& min, const BasicVector3& max ) : mins( min ), maxs( max ){ + } + void clear(){ + mins.x() = mins.y() = mins.z() = std::numeric_limits::max(); + maxs.x() = maxs.y() = maxs.z() = std::numeric_limits::lowest(); + } + template + void extend( const BasicVector3& point ){ + for ( size_t i = 0; i < 3; ++i ){ + const auto val = point[i]; + if ( val < mins[i] ) { + mins[i] = val; + } + if ( val > maxs[i] ) { + maxs[i] = val; + } + } + } + template + void extend( const MinMax___& other ){ + extend( other.mins ); + extend( other.maxs ); + } + template + bool test( const BasicVector3& point ) const { + return point.x() >= mins.x() && point.y() >= mins.y() && point.z() >= mins.z() + && point.x() <= maxs.x() && point.y() <= maxs.y() && point.z() <= maxs.z(); + } + // true, if there is an intersection + template + bool test( const MinMax___& other ) const { + return other.maxs.x() >= mins.x() && other.maxs.y() >= mins.y() && other.maxs.z() >= mins.z() + && other.mins.x() <= maxs.x() && other.mins.y() <= maxs.y() && other.mins.z() <= maxs.z(); + } + BasicVector3 origin() const { + return ( mins + maxs ) * 0.5; + } +}; + +using MinMax = MinMax___; + + + +template +struct Color4___ : public BasicVector4 +{ + using BasicVector4::BasicVector4; + + Color4___( const BasicVector4& vector ) : BasicVector4( vector ){ + } + BasicVector3& rgb(){ + return this->vec3(); + } + const BasicVector3& rgb() const { + return this->vec3(); + } + T& alpha(){ + return this->w(); + } + const T& alpha() const { + return this->w(); + } +}; + +using Color4f = Color4___; +using Color4b = Color4___; + + + +template +T VectorNormalize( BasicVector3& vector ) { + const double length = vector3_length( DoubleVector3( vector ) ); + + if ( length == 0 ) { + vector.set( 0 ); + return 0; + } + + vector /= length; + + return length; +} + +template +BasicVector3 VectorNormalized( const BasicVector3& vector ) { + BasicVector3 vec( vector ); + VectorNormalize( vec ); + return vec; +} + +const float EQUAL_EPSILON = 0.001; + +inline bool VectorCompare( const Vector3& v1, const Vector3& v2 ){ + return vector3_equal_epsilon( v1, v2, EQUAL_EPSILON ); +} + +template +T VectorMax( const BasicVector3& v ){ + return ( v[0] > v[1] ) ? ( ( v[0] > v[2] ) ? v[0] : v[2] ) : ( ( v[1] > v[2] ) ? v[1] : v[2] ); +} + +inline bool VectorIsOnAxis( const Vector3& v ){ + int zeroComponentCount = 0; + for ( int i = 0; i < 3; ++i ) + { + if ( v[i] == 0.0 ) { + zeroComponentCount++; + } + } + + return zeroComponentCount > 1; // The zero vector will be on axis. +} + +/* + ===================== + PlaneFromPoints + + Returns false if the triangle is degenrate. + The normal will point out of the clock for clockwise ordered points + ===================== + */ +template +bool PlaneFromPoints( Plane3___

& plane, const BasicVector3& p0, const BasicVector3& p1, const BasicVector3& p2 ) { + plane.normal() = vector3_cross( p2 - p0, p1 - p0 ); + if ( VectorNormalize( plane.normal() ) == 0 ) { + return false; + } + + plane.dist() = vector3_dot( p0, plane.normal() ); + return true; +} + +template +bool PlaneFromPoints( Plane3___

& plane, const BasicVector3 planepts[3] ) { + return PlaneFromPoints( plane, planepts[0], planepts[1], planepts[2] ); +} + + +/* + ComputeAxisBase() + computes the base texture axis for brush primitive texturing + note: ComputeAxisBase here and in editor code must always BE THE SAME! + warning: special case behaviour of atan2( y, x ) <-> atan( y / x ) might not be the same everywhere when x == 0 + rotation by (0,RotY,RotZ) assigns X to normal + */ + +template +inline void ComputeAxisBase( const BasicVector3& normal, BasicVector3& texS, BasicVector3& texT ){ +#if 1 + const BasicVector3 up( 0, 0, 1 ); + const BasicVector3 down( 0, 0, -1 ); + + if ( vector3_equal_epsilon( normal, up, Element(1e-6) ) ) { + texS = BasicVector3( 0, 1, 0 ); + texT = BasicVector3( 1, 0, 0 ); + } + else if ( vector3_equal_epsilon( normal, down, Element(1e-6) ) ) { + texS = BasicVector3( 0, 1, 0 ); + texT = BasicVector3( -1, 0, 0 ); + } + else + { + texS = vector3_normalised( vector3_cross( normal, up ) ); + texT = vector3_normalised( vector3_cross( normal, texS ) ); + vector3_negate( texS ); + } +#else + /* do some cleaning */ + if ( fabs( normal[ 0 ] ) < 1e-6 ) { + normal[ 0 ] = 0.0f; + } + if ( fabs( normal[ 1 ] ) < 1e-6 ) { + normal[ 1 ] = 0.0f; + } + if ( fabs( normal[ 2 ] ) < 1e-6 ) { + normal[ 2 ] = 0.0f; + } + + /* compute the two rotations around y and z to rotate x to normal */ + const float RotY = -atan2( normal[ 2 ], sqrt( normal[ 1 ] * normal[ 1 ] + normal[ 0 ] * normal[ 0 ] ) ); + const float RotZ = atan2( normal[ 1 ], normal[ 0 ] ); + + /* rotate (0,1,0) and (0,0,1) to compute texS and texT */ + texS[ 0 ] = -sin( RotZ ); + texS[ 1 ] = cos( RotZ ); + texS[ 2 ] = 0; + + /* the texT vector is along -z (t texture coorinates axis) */ + texT[ 0 ] = -sin( RotY ) * cos( RotZ ); + texT[ 1 ] = -sin( RotY ) * sin( RotZ ); + texT[ 2 ] = -cos( RotY ); +#endif +} + + +/* + ================ + MakeNormalVectors + + Given a normalized forward vector, create two + other perpendicular vectors + ================ + */ +inline void MakeNormalVectors( const Vector3& forward, Vector3& right, Vector3& up ){ + // this rotate and negate guarantees a vector + // not colinear with the original + right[1] = -forward[0]; + right[2] = forward[1]; + right[0] = forward[2]; + + right = VectorNormalized( right - forward * vector3_dot( right, forward ) ); + up = vector3_cross( right, forward ); +} + + +/* +** NormalToLatLong +** +** We use two byte encoded normals in some space critical applications. +** Lat = 0 at (1,0,0) to 360 (-1,0,0), encoded in 8-bit sine table format +** Lng = 0 at (0,0,1) to 180 (0,0,-1), encoded in 8-bit sine table format +** +*/ +inline void NormalToLatLong( const Vector3& normal, byte bytes[2] ) { + // check for singularities + if ( normal[0] == 0 && normal[1] == 0 ) { + if ( normal[2] > 0 ) { + bytes[0] = 0; + bytes[1] = 0; // lat = 0, long = 0 + } + else { + bytes[0] = 128; + bytes[1] = 0; // lat = 0, long = 128 + } + } + else { + const int a = radians_to_degrees( atan2( normal[1], normal[0] ) ) * ( 255.0 / 360.0 ); + const int b = radians_to_degrees( acos( normal[2] ) ) * ( 255.0 / 360.0 ); + + bytes[0] = b & 0xff; // longitude + bytes[1] = a & 0xff; // lattitude + } +} + +// plane types are used to speed some tests +// 0-2 are axial planes +enum EPlaneType : int +{ + ePlaneX = 0, + ePlaneY = 1, + ePlaneZ = 2, + ePlaneNonAxial = 3 +}; + +inline EPlaneType PlaneTypeForNormal( const Vector3& normal ) { + if ( normal[0] == 1.0 || normal[0] == -1.0 ) { + return ePlaneX; + } + if ( normal[1] == 1.0 || normal[1] == -1.0 ) { + return ePlaneY; + } + if ( normal[2] == 1.0 || normal[2] == -1.0 ) { + return ePlaneZ; + } + + return ePlaneNonAxial; +} + + +inline void ColorNormalize( Vector3& color ) { + const float max = VectorMax( color ); + + if ( max == 0 ) { + color.set( 1 ); + } + else{ + color *= ( 1.f / max ); + } +} \ No newline at end of file diff --git a/tools/quake3/common/scriplib.cpp b/tools/quake3/common/scriplib.cpp index b9df909e..e0e49966 100644 --- a/tools/quake3/common/scriplib.cpp +++ b/tools/quake3/common/scriplib.cpp @@ -22,7 +22,6 @@ // scriplib.c #include "cmdlib.h" -#include "mathlib.h" #include "inout.h" #include "scriplib.h" #include "vfs.h" @@ -365,7 +364,7 @@ void MatchToken( const char *match ) { } -void Parse1DMatrix( int x, vec_t *m ) { +void Parse1DMatrix( int x, float *m ) { int i; MatchToken( "(" ); @@ -378,7 +377,7 @@ void Parse1DMatrix( int x, vec_t *m ) { MatchToken( ")" ); } -void Parse2DMatrix( int y, int x, vec_t *m ) { +void Parse2DMatrix( int y, int x, float *m ) { int i; MatchToken( "(" ); @@ -390,7 +389,7 @@ void Parse2DMatrix( int y, int x, vec_t *m ) { MatchToken( ")" ); } -void Parse3DMatrix( int z, int y, int x, vec_t *m ) { +void Parse3DMatrix( int z, int y, int x, float *m ) { int i; MatchToken( "(" ); @@ -403,7 +402,7 @@ void Parse3DMatrix( int z, int y, int x, vec_t *m ) { } -void Write1DMatrix( FILE *f, int x, vec_t *m ) { +void Write1DMatrix( FILE *f, int x, float *m ) { int i; fprintf( f, "( " ); @@ -418,7 +417,7 @@ void Write1DMatrix( FILE *f, int x, vec_t *m ) { fprintf( f, ")" ); } -void Write2DMatrix( FILE *f, int y, int x, vec_t *m ) { +void Write2DMatrix( FILE *f, int y, int x, float *m ) { int i; fprintf( f, "( " ); @@ -430,7 +429,7 @@ void Write2DMatrix( FILE *f, int y, int x, vec_t *m ) { } -void Write3DMatrix( FILE *f, int z, int y, int x, vec_t *m ) { +void Write3DMatrix( FILE *f, int z, int y, int x, float *m ) { int i; fprintf( f, "(\n" ); diff --git a/tools/quake3/common/scriplib.h b/tools/quake3/common/scriplib.h index 4717a38f..d8dc08e4 100644 --- a/tools/quake3/common/scriplib.h +++ b/tools/quake3/common/scriplib.h @@ -24,9 +24,6 @@ #ifndef __CMDLIB__ #include "../common/cmdlib.h" #endif -#ifndef __MATHLIB__ -#include "mathlib.h" -#endif #define MAXTOKEN 1024 @@ -47,10 +44,10 @@ bool TokenAvailable( void ); void MatchToken( const char *match ); -void Parse1DMatrix( int x, vec_t *m ); -void Parse2DMatrix( int y, int x, vec_t *m ); -void Parse3DMatrix( int z, int y, int x, vec_t *m ); +void Parse1DMatrix( int x, float *m ); +void Parse2DMatrix( int y, int x, float *m ); +void Parse3DMatrix( int z, int y, int x, float *m ); -void Write1DMatrix( FILE *f, int x, vec_t *m ); -void Write2DMatrix( FILE *f, int y, int x, vec_t *m ); -void Write3DMatrix( FILE *f, int z, int y, int x, vec_t *m ); +void Write1DMatrix( FILE *f, int x, float *m ); +void Write2DMatrix( FILE *f, int y, int x, float *m ); +void Write3DMatrix( FILE *f, int z, int y, int x, float *m ); diff --git a/tools/quake3/common/threads.cpp b/tools/quake3/common/threads.cpp index 58d99af8..50536a72 100644 --- a/tools/quake3/common/threads.cpp +++ b/tools/quake3/common/threads.cpp @@ -27,7 +27,6 @@ #endif #include "cmdlib.h" -#include "mathlib.h" #include "inout.h" #include "qthreads.h" diff --git a/tools/quake3/common/vfs.cpp b/tools/quake3/common/vfs.cpp index ad1f876f..d867bc24 100644 --- a/tools/quake3/common/vfs.cpp +++ b/tools/quake3/common/vfs.cpp @@ -47,7 +47,6 @@ #include "cmdlib.h" #include "filematch.h" -#include "mathlib.h" #include "inout.h" #include "vfs.h" #include "unzip.h" diff --git a/tools/quake3/q3map2/brush.cpp b/tools/quake3/q3map2/brush.cpp index 8388af10..94f4a425 100644 --- a/tools/quake3/q3map2/brush.cpp +++ b/tools/quake3/q3map2/brush.cpp @@ -179,7 +179,7 @@ bool BoundBrush( brush_t *brush ){ winding_t *w; - ClearBounds( brush->mins, brush->maxs ); + brush->minmax.clear(); for ( i = 0; i < brush->numsides; i++ ) { w = brush->sides[ i ].winding; @@ -187,12 +187,12 @@ bool BoundBrush( brush_t *brush ){ continue; } for ( j = 0; j < w->numpoints; j++ ) - AddPointToBounds( w->p[ j ], brush->mins, brush->maxs ); + brush->minmax.extend( w->p[ j ] ); } for ( i = 0; i < 3; i++ ) { - if ( brush->mins[ i ] < MIN_WORLD_COORD || brush->maxs[ i ] > MAX_WORLD_COORD || brush->mins[i] >= brush->maxs[ i ] ) { + if ( brush->minmax.mins[ i ] < MIN_WORLD_COORD || brush->minmax.maxs[ i ] > MAX_WORLD_COORD || brush->minmax.mins[i] >= brush->minmax.maxs[ i ] ) { return false; } } @@ -205,28 +205,23 @@ bool BoundBrush( brush_t *brush ){ /* SnapWeldVector() - ydnar - welds two vec3_t's into a third, taking into account nearest-to-integer + welds two Vector3's into a third, taking into account nearest-to-integer instead of averaging */ #define SNAP_EPSILON 0.01 -void SnapWeldVector( vec3_t a, vec3_t b, vec3_t out ){ +void SnapWeldVector( const Vector3& a, const Vector3& b, Vector3& out ){ int i; - vec_t ai, bi, outi; + float ai, bi, outi; - /* dummy check */ - if ( a == NULL || b == NULL || out == NULL ) { - return; - } - /* do each element */ for ( i = 0; i < 3; i++ ) { /* round to integer */ - ai = Q_rint( a[ i ] ); - bi = Q_rint( b[ i ] ); + ai = std::rint( a[ i ] ); + bi = std::rint( b[ i ] ); /* prefer exact integer */ if ( ai == a[ i ] ) { @@ -245,7 +240,7 @@ void SnapWeldVector( vec3_t a, vec3_t b, vec3_t out ){ } /* snap */ - outi = Q_rint( out[ i ] ); + outi = std::rint( out[ i ] ); if ( fabs( outi - out[ i ] ) <= SNAP_EPSILON ) { out[ i ] = outi; } @@ -260,7 +255,7 @@ void SnapWeldVector( vec3_t a, vec3_t b, vec3_t out ){ instead of averaging. ================== */ -void SnapWeldVectorAccu( vec3_accu_t a, vec3_accu_t b, vec3_accu_t out ){ +void SnapWeldVectorAccu( const DoubleVector3& a, const DoubleVector3& b, DoubleVector3& out ){ // I'm just preserving what I think was the intended logic of the original // SnapWeldVector(). I'm not actually sure where this function should even // be used. I'd like to know which kinds of problems this function addresses. @@ -270,16 +265,12 @@ void SnapWeldVectorAccu( vec3_accu_t a, vec3_accu_t b, vec3_accu_t out ){ // be snapping to the nearest 1/8 unit instead? int i; - vec_accu_t ai, bi, ad, bd; - - if ( a == NULL || b == NULL || out == NULL ) { - Error( "SnapWeldVectorAccu: NULL argument" ); - } + double ai, bi, ad, bd; for ( i = 0; i < 3; i++ ) { - ai = Q_rintAccu( a[i] ); - bi = Q_rintAccu( b[i] ); + ai = std::rint( a[i] ); + bi = std::rint( b[i] ); ad = fabs( ai - a[i] ); bd = fabs( bi - b[i] ); @@ -310,7 +301,7 @@ void SnapWeldVectorAccu( vec3_accu_t a, vec3_accu_t b, vec3_accu_t out ){ bool FixWinding( winding_t *w ){ bool valid = true; int i, j, k; - vec3_t vec; + Vector3 vec; float dist; @@ -331,22 +322,21 @@ bool FixWinding( winding_t *w ){ j = ( i + 1 ) % w->numpoints; /* degenerate edge? */ - VectorSubtract( w->p[ i ], w->p[ j ], vec ); - dist = VectorLength( vec ); + dist = vector3_length( w->p[ i ] - w->p[ j ] ); if ( dist < DEGENERATE_EPSILON ) { valid = false; //Sys_FPrintf( SYS_WRN | SYS_VRBflag, "WARNING: Degenerate winding edge found, fixing...\n" ); /* create an average point (ydnar 2002-01-26: using nearest-integer weld preference) */ SnapWeldVector( w->p[ i ], w->p[ j ], vec ); - VectorCopy( vec, w->p[ i ] ); + w->p[ i ] = vec; //VectorAdd( w->p[ i ], w->p[ j ], vec ); //VectorScale( vec, 0.5, w->p[ i ] ); /* move the remaining verts */ for ( k = i + 2; k < w->numpoints; k++ ) { - VectorCopy( w->p[ k ], w->p[ k - 1 ] ); + w->p[ k - 1 ] = w->p[ k ]; } w->numpoints--; } @@ -375,8 +365,6 @@ bool FixWinding( winding_t *w ){ */ bool FixWindingAccu( winding_accu_t *w ){ int i, j, k; - vec3_accu_t vec; - vec_accu_t dist; bool done, altered; if ( w == NULL ) { @@ -395,19 +383,18 @@ bool FixWindingAccu( winding_accu_t *w ){ { j = ( ( ( i + 1 ) == w->numpoints ) ? 0 : ( i + 1 ) ); - VectorSubtractAccu( w->p[i], w->p[j], vec ); - dist = VectorLengthAccu( vec ); - if ( dist < DEGENERATE_EPSILON ) { + DoubleVector3 vec = w->p[i] - w->p[j]; + if ( vector3_length( vec ) < DEGENERATE_EPSILON ) { // TODO: I think the "snap weld vector" was written before // some of the math precision fixes, and its purpose was // probably to address math accuracy issues. We can think // about changing the logic here. Maybe once plane distance // gets 64 bits, we can look at it then. SnapWeldVectorAccu( w->p[i], w->p[j], vec ); - VectorCopyAccu( vec, w->p[i] ); + w->p[i] = vec; for ( k = j + 1; k < w->numpoints; k++ ) { - VectorCopyAccu( w->p[k], w->p[k - 1] ); + w->p[k - 1] = w->p[k]; } w->numpoints--; altered = true; @@ -456,9 +443,9 @@ bool CreateBrushWindings( brush_t *brush ){ /* make huge winding */ #if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES - w = BaseWindingForPlaneAccu( plane->normal, plane->dist ); + w = BaseWindingForPlaneAccu( plane->plane ); #else - w = BaseWindingForPlane( plane->normal, plane->dist ); + w = BaseWindingForPlane( plane->plane ); #endif /* walk the list of brush sides */ @@ -475,9 +462,9 @@ bool CreateBrushWindings( brush_t *brush ){ } plane = &mapplanes[ brush->sides[ j ].planenum ^ 1 ]; #if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES - ChopWindingInPlaceAccu( &w, plane->normal, plane->dist, 0 ); + ChopWindingInPlaceAccu( &w, plane->plane, 0 ); #else - ChopWindingInPlace( &w, plane->normal, plane->dist, 0 ); // CLIP_EPSILON ); + ChopWindingInPlace( &w, plane->plane, 0 ); // CLIP_EPSILON ); #endif /* ydnar: fix broken windings that would generate trifans */ @@ -523,24 +510,20 @@ bool CreateBrushWindings( brush_t *brush ){ Creates a new axial brush ================== */ -brush_t *BrushFromBounds( vec3_t mins, vec3_t maxs ){ +brush_t *BrushFromBounds( const Vector3& mins, const Vector3& maxs ){ brush_t *b; int i; - vec3_t normal; - vec_t dist; + float dist; b = AllocBrush( 6 ); b->numsides = 6; for ( i = 0 ; i < 3 ; i++ ) { - VectorClear( normal ); - normal[i] = 1; dist = maxs[i]; - b->sides[i].planenum = FindFloatPlane( normal, dist, 1, (vec3_t*) &maxs ); + b->sides[i].planenum = FindFloatPlane( g_vector3_axes[i], dist, 1, &maxs ); - normal[i] = -1; dist = -mins[i]; - b->sides[3 + i].planenum = FindFloatPlane( normal, dist, 1, (vec3_t*) &mins ); + b->sides[3 + i].planenum = FindFloatPlane( -g_vector3_axes[i], dist, 1, &mins ); } CreateBrushWindings( b ); @@ -554,12 +537,11 @@ brush_t *BrushFromBounds( vec3_t mins, vec3_t maxs ){ ================== */ -vec_t BrushVolume( brush_t *brush ){ +float BrushVolume( brush_t *brush ){ int i; winding_t *w; - vec3_t corner; - vec_t d, area, volume; - plane_t *plane; + Vector3 corner; + float volume; if ( !brush ) { return 0; @@ -578,7 +560,7 @@ vec_t BrushVolume( brush_t *brush ){ if ( !w ) { return 0; } - VectorCopy( w->p[0], corner ); + corner = w->p[0]; // make tetrahedrons to all other faces @@ -589,10 +571,7 @@ vec_t BrushVolume( brush_t *brush ){ if ( !w ) { continue; } - plane = &mapplanes[brush->sides[i].planenum]; - d = -( DotProduct( corner, plane->normal ) - plane->dist ); - area = WindingArea( w ); - volume += d * area; + volume += -plane3_distance_to_point( mapplanes[brush->sides[i].planenum].plane, corner ) * WindingArea( w ); } volume /= 3; @@ -627,7 +606,7 @@ void WriteBSPBrushMap( const char *name, brush_t *list ){ { // TODO: See if we can use a smaller winding to prevent resolution loss. // Is WriteBSPBrushMap() used only to decompile maps? - w = BaseWindingForPlane( mapplanes[s->planenum].normal, mapplanes[s->planenum].dist ); + w = BaseWindingForPlane( mapplanes[s->planenum].plane ); fprintf( f, "( %i %i %i ) ", (int)w->p[0][0], (int)w->p[0][1], (int)w->p[0][2] ); fprintf( f, "( %i %i %i ) ", (int)w->p[1][0], (int)w->p[1][1], (int)w->p[1][2] ); @@ -791,7 +770,7 @@ void FilterStructuralBrushesIntoTree( entity_t *e, tree_t *tree ) { */ tree_t *AllocTree( void ){ tree_t *tree = safe_calloc( sizeof( *tree ) ); - ClearBounds( tree->mins, tree->maxs ); + tree->minmax.clear(); return tree; } @@ -821,17 +800,12 @@ bool WindingIsTiny( winding_t *w ){ return false; */ int i, j; - vec_t len; - vec3_t delta; - int edges; + int edges = 0; - edges = 0; for ( i = 0 ; i < w->numpoints ; i++ ) { j = i == w->numpoints - 1 ? 0 : i + 1; - VectorSubtract( w->p[j], w->p[i], delta ); - len = VectorLength( delta ); - if ( len > EDGE_LENGTH ) { + if ( vector3_length( w->p[j] - w->p[i] ) > EDGE_LENGTH ) { if ( ++edges == 3 ) { return false; } @@ -872,7 +846,7 @@ bool WindingIsHuge( winding_t *w ){ int BrushMostlyOnSide( brush_t *brush, plane_t *plane ){ int i, j; winding_t *w; - vec_t d, max; + float max; int side; max = 0; @@ -885,7 +859,7 @@ int BrushMostlyOnSide( brush_t *brush, plane_t *plane ){ } for ( j = 0 ; j < w->numpoints ; j++ ) { - d = DotProduct( w->p[j], plane->normal ) - plane->dist; + const double d = plane3_distance_to_point( plane->plane, w->p[j] ); if ( d > max ) { max = d; side = PSIDE_FRONT; @@ -912,7 +886,7 @@ void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back ) winding_t *w, *cw[2], *midwinding; plane_t *plane, *plane2; side_t *s, *cs; - float d, d_front, d_back; + float d_front, d_back; *front = NULL; @@ -929,7 +903,7 @@ void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back ) } for ( j = 0 ; j < w->numpoints ; j++ ) { - d = DotProduct( w->p[j], plane->normal ) - plane->dist; + const double d = plane3_distance_to_point( plane->plane, w->p[j] ); if ( d > 0 && d > d_front ) { d_front = d; } @@ -952,11 +926,11 @@ void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back ) } // create a new winding from the split plane - w = BaseWindingForPlane( plane->normal, plane->dist ); + w = BaseWindingForPlane( plane->plane ); for ( i = 0 ; i < brush->numsides && w ; i++ ) { plane2 = &mapplanes[brush->sides[i].planenum ^ 1]; - ChopWindingInPlace( &w, plane2->normal, plane2->dist, 0 ); // PLANESIDE_EPSILON); + ChopWindingInPlace( &w, plane2->plane, 0 ); // PLANESIDE_EPSILON); } if ( !w || WindingIsTiny( w ) ) { // the brush isn't really split @@ -998,7 +972,7 @@ void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back ) if ( !w ) { continue; } - ClipWindingEpsilonStrict( w, plane->normal, plane->dist, + ClipWindingEpsilonStrict( w, plane->plane, 0 /*PLANESIDE_EPSILON*/, &cw[0], &cw[1] ); /* strict, in parallel case we get the face back because it also is the midwinding */ for ( j = 0 ; j < 2 ; j++ ) { @@ -1060,7 +1034,7 @@ void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back ) } { - vec_t v1; + float v1; int i; diff --git a/tools/quake3/q3map2/brush_primit.cpp b/tools/quake3/q3map2/brush_primit.cpp deleted file mode 100644 index 79b18f8f..00000000 --- a/tools/quake3/q3map2/brush_primit.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* ------------------------------------------------------------------------------- - - Copyright (C) 1999-2007 id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant 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 2 of the License, or - (at your option) any later version. - - GtkRadiant 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 GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - ---------------------------------------------------------------------------------- - - This code has been altered significantly from its original form, to support - several games based on the Quake III Arena engine, in the form of "Q3Map2." - - ------------------------------------------------------------------------------- */ - - - -/* dependencies */ -#include "q3map2.h" - - - -/* ------------------------------------------------------------------------------- - - functions - - ------------------------------------------------------------------------------- */ - -/* - ComputeAxisBase() - computes the base texture axis for brush primitive texturing - note: ComputeAxisBase here and in editor code must always BE THE SAME! - warning: special case behaviour of atan2( y, x ) <-> atan( y / x ) might not be the same everywhere when x == 0 - rotation by (0,RotY,RotZ) assigns X to normal - */ - -void ComputeAxisBase( vec3_t normal, vec3_t texX, vec3_t texY ){ - vec_t RotY, RotZ; - - - /* do some cleaning */ - if ( fabs( normal[ 0 ] ) < 1e-6 ) { - normal[ 0 ] = 0.0f; - } - if ( fabs( normal[ 1 ] ) < 1e-6 ) { - normal[ 1 ] = 0.0f; - } - if ( fabs( normal[ 2 ] ) < 1e-6 ) { - normal[ 2 ] = 0.0f; - } - - /* compute the two rotations around y and z to rotate x to normal */ - RotY = -atan2( normal[ 2 ], sqrt( normal[ 1 ] * normal[ 1 ] + normal[ 0 ] * normal[ 0 ] ) ); - RotZ = atan2( normal[ 1 ], normal[ 0 ] ); - - /* rotate (0,1,0) and (0,0,1) to compute texX and texY */ - texX[ 0 ] = -sin( RotZ ); - texX[ 1 ] = cos( RotZ ); - texX[ 2 ] = 0; - - /* the texY vector is along -z (t texture coorinates axis) */ - texY[ 0 ] = -sin( RotY ) * cos( RotZ ); - texY[ 1 ] = -sin( RotY ) * sin( RotZ ); - texY[ 2 ] = -cos( RotY ); -} diff --git a/tools/quake3/q3map2/bsp.cpp b/tools/quake3/q3map2/bsp.cpp index 3a79c9d0..2ee9bb11 100644 --- a/tools/quake3/q3map2/bsp.cpp +++ b/tools/quake3/q3map2/bsp.cpp @@ -125,7 +125,7 @@ static void ProcessAdvertisements( void ) { // store the normal for use at run time.. all ad verts are assumed to // have identical normals (because they should be a simple rectangle) // so just use the first vert's normal - VectorCopy( bspDrawVerts[adSurface->firstVert].normal, bspAds[numBSPAds].normal ); + bspAds[numBSPAds].normal = bspDrawVerts[adSurface->firstVert].normal; // store the ad quad for quick use at run time if ( adSurface->surfaceType == MST_PATCH ) { @@ -133,10 +133,10 @@ static void ProcessAdvertisements( void ) { int v1 = adSurface->firstVert + adSurface->numVerts - 1; int v2 = adSurface->firstVert + adSurface->numVerts - adSurface->patchWidth; int v3 = adSurface->firstVert; - VectorCopy( bspDrawVerts[v0].xyz, bspAds[numBSPAds].rect[0] ); - VectorCopy( bspDrawVerts[v1].xyz, bspAds[numBSPAds].rect[1] ); - VectorCopy( bspDrawVerts[v2].xyz, bspAds[numBSPAds].rect[2] ); - VectorCopy( bspDrawVerts[v3].xyz, bspAds[numBSPAds].rect[3] ); + bspAds[numBSPAds].rect[0] = bspDrawVerts[v0].xyz; + bspAds[numBSPAds].rect[1] = bspDrawVerts[v1].xyz; + bspAds[numBSPAds].rect[2] = bspDrawVerts[v2].xyz; + bspAds[numBSPAds].rect[3] = bspDrawVerts[v3].xyz; } else { Error( "Ad cell %d has an unsupported Ad Surface type.", bspAds[numBSPAds].cellId ); @@ -441,7 +441,7 @@ void ProcessWorldModel( void ){ for ( const auto& light : entities ) { entity_t *target; - vec3_t origin, targetOrigin, normal, color; + Vector3 origin, targetOrigin, normal, color; /* get light */ if ( light.classname_is( "light" ) ) { @@ -459,13 +459,12 @@ void ProcessWorldModel( void ){ target = FindTargetEntity( value ); if ( target != NULL ) { target->vectorForKey( "origin", targetOrigin ); - VectorSubtract( targetOrigin, origin, normal ); - VectorNormalize( normal, normal ); + normal = VectorNormalized( targetOrigin - origin ); } } else{ - //% VectorClear( normal ); - VectorSet( normal, 0, 0, -1 ); + //% normal.set( 0 ); + normal = -g_vector3_axis_z; } if ( colorsRGB ) { diff --git a/tools/quake3/q3map2/bspfile_abstract.cpp b/tools/quake3/q3map2/bspfile_abstract.cpp index 94b6bbe5..da7517d4 100644 --- a/tools/quake3/q3map2/bspfile_abstract.cpp +++ b/tools/quake3/q3map2/bspfile_abstract.cpp @@ -755,7 +755,7 @@ bool entity_t::read_keyvalue_( float &float_value, std::initializer_list&& keys ) const { +bool entity_t::read_keyvalue_( Vector3& vector3_value, std::initializer_list&& keys ) const { for( const char* key : keys ){ const char* value = valueForKey( key ); if( !strEmpty( value ) ){ diff --git a/tools/quake3/q3map2/bspfile_ibsp.cpp b/tools/quake3/q3map2/bspfile_ibsp.cpp index 7e81e748..ede59d1a 100644 --- a/tools/quake3/q3map2/bspfile_ibsp.cpp +++ b/tools/quake3/q3map2/bspfile_ibsp.cpp @@ -145,8 +145,8 @@ struct ibspDrawSurface_t int lightmapX, lightmapY; int lightmapWidth, lightmapHeight; - vec3_t lightmapOrigin; - vec3_t lightmapVecs[ 3 ]; + Vector3 lightmapOrigin; + Vector3 lightmapVecs[ 3 ]; int patchWidth; int patchHeight; @@ -194,10 +194,10 @@ static void CopyDrawSurfacesLump( ibspHeader_t *header ){ out->lightmapWidth = in->lightmapWidth; out->lightmapHeight = in->lightmapHeight; - VectorCopy( in->lightmapOrigin, out->lightmapOrigin ); - VectorCopy( in->lightmapVecs[ 0 ], out->lightmapVecs[ 0 ] ); - VectorCopy( in->lightmapVecs[ 1 ], out->lightmapVecs[ 1 ] ); - VectorCopy( in->lightmapVecs[ 2 ], out->lightmapVecs[ 2 ] ); + out->lightmapOrigin = in->lightmapOrigin; + out->lightmapVecs[ 0 ] = in->lightmapVecs[ 0 ]; + out->lightmapVecs[ 1 ] = in->lightmapVecs[ 1 ]; + out->lightmapVecs[ 2 ] = in->lightmapVecs[ 2 ]; out->patchWidth = in->patchWidth; out->patchHeight = in->patchHeight; @@ -237,10 +237,10 @@ static void AddDrawSurfacesLump( FILE *file, ibspHeader_t *header ){ out->lightmapWidth = in->lightmapWidth; out->lightmapHeight = in->lightmapHeight; - VectorCopy( in->lightmapOrigin, out->lightmapOrigin ); - VectorCopy( in->lightmapVecs[ 0 ], out->lightmapVecs[ 0 ] ); - VectorCopy( in->lightmapVecs[ 1 ], out->lightmapVecs[ 1 ] ); - VectorCopy( in->lightmapVecs[ 2 ], out->lightmapVecs[ 2 ] ); + out->lightmapOrigin = in->lightmapOrigin; + out->lightmapVecs[ 0 ] = in->lightmapVecs[ 0 ]; + out->lightmapVecs[ 1 ] = in->lightmapVecs[ 1 ]; + out->lightmapVecs[ 2 ] = in->lightmapVecs[ 2 ]; out->patchWidth = in->patchWidth; out->patchHeight = in->patchHeight; @@ -261,11 +261,11 @@ static void AddDrawSurfacesLump( FILE *file, ibspHeader_t *header ){ /* drawverts */ struct ibspDrawVert_t { - vec3_t xyz; - float st[ 2 ]; - float lightmap[ 2 ]; - vec3_t normal; - byte color[ 4 ]; + Vector3 xyz; + Vector2 st; + Vector2 lightmap; + Vector3 normal; + Color4b color; }; @@ -284,20 +284,11 @@ static void CopyDrawVertsLump( ibspHeader_t *header ){ out = bspDrawVerts; for ( i = 0; i < numBSPDrawVerts; i++ ) { - VectorCopy( in->xyz, out->xyz ); - out->st[ 0 ] = in->st[ 0 ]; - out->st[ 1 ] = in->st[ 1 ]; - - out->lightmap[ 0 ][ 0 ] = in->lightmap[ 0 ]; - out->lightmap[ 0 ][ 1 ] = in->lightmap[ 1 ]; - - VectorCopy( in->normal, out->normal ); - - out->color[ 0 ][ 0 ] = in->color[ 0 ]; - out->color[ 0 ][ 1 ] = in->color[ 1 ]; - out->color[ 0 ][ 2 ] = in->color[ 2 ]; - out->color[ 0 ][ 3 ] = in->color[ 3 ]; - + out->xyz = in->xyz; + out->st = in->st; + out->lightmap[ 0 ] = in->lightmap; + out->normal = in->normal; + out->color[ 0 ] = in->color; in++; out++; } @@ -319,20 +310,11 @@ static void AddDrawVertsLump( FILE *file, ibspHeader_t *header ){ out = buffer; for ( i = 0; i < numBSPDrawVerts; i++ ) { - VectorCopy( in->xyz, out->xyz ); - out->st[ 0 ] = in->st[ 0 ]; - out->st[ 1 ] = in->st[ 1 ]; - - out->lightmap[ 0 ] = in->lightmap[ 0 ][ 0 ]; - out->lightmap[ 1 ] = in->lightmap[ 0 ][ 1 ]; - - VectorCopy( in->normal, out->normal ); - - out->color[ 0 ] = in->color[ 0 ][ 0 ]; - out->color[ 1 ] = in->color[ 0 ][ 1 ]; - out->color[ 2 ] = in->color[ 0 ][ 2 ]; - out->color[ 3 ] = in->color[ 0 ][ 3 ]; - + out->xyz = in->xyz; + out->st = in->st; + out->lightmap = in->lightmap[ 0 ]; + out->normal = in->normal; + out->color = in->color[ 0 ]; in++; out++; } @@ -349,8 +331,8 @@ static void AddDrawVertsLump( FILE *file, ibspHeader_t *header ){ /* light grid */ struct ibspGridPoint_t { - byte ambient[ 3 ]; - byte directed[ 3 ]; + Vector3b ambient; + Vector3b directed; byte latLong[ 2 ]; }; @@ -374,8 +356,8 @@ static void CopyLightGridLumps( ibspHeader_t *header ){ { for ( j = 0; j < MAX_LIGHTMAPS; j++ ) { - VectorCopy( in->ambient, out->ambient[ j ] ); - VectorCopy( in->directed, out->directed[ j ] ); + out->ambient[ j ] = in->ambient; + out->directed[ j ] = in->directed; out->styles[ j ] = LS_NONE; } @@ -409,8 +391,8 @@ static void AddLightGridLumps( FILE *file, ibspHeader_t *header ){ out = buffer; for ( i = 0; i < numBSPGridPoints; i++ ) { - VectorCopy( in->ambient[ 0 ], out->ambient ); - VectorCopy( in->directed[ 0 ], out->directed ); + out->ambient = in->ambient[ 0 ]; + out->directed = in->directed[ 0 ]; out->latLong[ 0 ] = in->latLong[ 0 ]; out->latLong[ 1 ] = in->latLong[ 1 ]; diff --git a/tools/quake3/q3map2/convert_ase.cpp b/tools/quake3/q3map2/convert_ase.cpp index 6deb7e3e..3a805598 100644 --- a/tools/quake3/q3map2/convert_ase.cpp +++ b/tools/quake3/q3map2/convert_ase.cpp @@ -41,10 +41,9 @@ int numLightmapsASE = 0; -static void ConvertSurface( FILE *f, bspModel_t *model, int modelNum, bspDrawSurface_t *ds, int surfaceNum, vec3_t origin, const int* lmIndices ){ +static void ConvertSurface( FILE *f, bspModel_t *model, int modelNum, bspDrawSurface_t *ds, int surfaceNum, const Vector3& origin, const int* lmIndices ){ int i, v, face, a, b, c; bspDrawVert_t *dv; - vec3_t normal; char name[ 1024 ]; @@ -102,10 +101,8 @@ static void ConvertSurface( FILE *f, bspModel_t *model, int modelNum, bspDrawSur a = bspDrawIndexes[ i + ds->firstIndex ]; b = bspDrawIndexes[ i + ds->firstIndex + 1 ]; c = bspDrawIndexes[ i + ds->firstIndex + 2 ]; - VectorCopy( bspDrawVerts[ a ].normal, normal ); - VectorAdd( normal, bspDrawVerts[ b ].normal, normal ); - VectorAdd( normal, bspDrawVerts[ c ].normal, normal ); - if ( VectorNormalize( normal, normal ) ) { + Vector3 normal = bspDrawVerts[ a ].normal + bspDrawVerts[ b ].normal + bspDrawVerts[ c ].normal; + if ( VectorNormalize( normal ) != 0 ) { fprintf( f, "\t\t\t*MESH_FACENORMAL\t%d\t%f\t%f\t%f\r\n", face, normal[ 0 ], normal[ 1 ], normal[ 2 ] ); } } @@ -188,7 +185,7 @@ static void ConvertSurface( FILE *f, bspModel_t *model, int modelNum, bspDrawSur exports a bsp model to an ase chunk */ -static void ConvertModel( FILE *f, bspModel_t *model, int modelNum, vec3_t origin, const int* lmIndices ){ +static void ConvertModel( FILE *f, bspModel_t *model, int modelNum, const Vector3& origin, const int* lmIndices ){ int i, s; bspDrawSurface_t *ds; @@ -404,7 +401,7 @@ int ConvertBSPToASE( char *bspName ){ model = &bspModels[ modelNum ]; /* get entity origin */ - vec3_t origin; + Vector3 origin; e->vectorForKey( "origin", origin ); /* convert model */ diff --git a/tools/quake3/q3map2/convert_bsp.cpp b/tools/quake3/q3map2/convert_bsp.cpp index f6a8d1d4..bff45b06 100644 --- a/tools/quake3/q3map2/convert_bsp.cpp +++ b/tools/quake3/q3map2/convert_bsp.cpp @@ -325,16 +325,16 @@ int BSPInfo( int count, char **fileNames ){ } -static void ExtrapolateTexcoords( const float *axyz, const float *ast, const float *bxyz, const float *bst, const float *cxyz, const float *cst, const float *axyz_new, float *ast_out, const float *bxyz_new, float *bst_out, const float *cxyz_new, float *cst_out ){ - vec4_t scoeffs, tcoeffs; - float md; - m4x4_t solvematrix; +static void ExtrapolateTexcoords( const float *axyz, const float *ast, + const float *bxyz, const float *bst, + const float *cxyz, const float *cst, + const Vector3& axyz_new, Vector2& ast_out, + const Vector3& bxyz_new, Vector2& bst_out, + const Vector3& cxyz_new, Vector2& cst_out ){ + Vector4 scoeffs, tcoeffs; + Matrix4 solvematrix; - vec3_t norm; - vec3_t dab, dac; - VectorSubtract( bxyz, axyz, dab ); - VectorSubtract( cxyz, axyz, dac ); - CrossProduct( dab, dac, norm ); + const Vector3 norm = vector3_cross( vector3_from_array( bxyz ) - vector3_from_array( axyz ), vector3_from_array( cxyz ) - vector3_from_array( axyz ) ); // assume: // s = f(x, y, z) @@ -365,24 +365,24 @@ static void ExtrapolateTexcoords( const float *axyz, const float *ast, const flo solvematrix[11] = norm[2]; solvematrix[15] = 0; - md = m4_det( solvematrix ); + const double md = matrix4_determinant( solvematrix ); if ( md * md < 1e-10 ) { Sys_Printf( "Cannot invert some matrix, some texcoords aren't extrapolated!" ); return; } - m4x4_invert( solvematrix ); + matrix4_full_invert( solvematrix ); scoeffs[0] = ast[0]; scoeffs[1] = bst[0]; scoeffs[2] = cst[0]; scoeffs[3] = 0; - m4x4_transform_vec4( solvematrix, scoeffs ); + matrix4_transform_vector4( solvematrix, scoeffs ); tcoeffs[0] = ast[1]; tcoeffs[1] = bst[1]; tcoeffs[2] = cst[1]; tcoeffs[3] = 0; - m4x4_transform_vec4( solvematrix, tcoeffs ); + matrix4_transform_vector4( solvematrix, tcoeffs ); ast_out[0] = scoeffs[0] * axyz_new[0] + scoeffs[1] * axyz_new[1] + scoeffs[2] * axyz_new[2] + scoeffs[3]; ast_out[1] = tcoeffs[0] * axyz_new[0] + tcoeffs[1] * axyz_new[1] + tcoeffs[2] * axyz_new[2] + tcoeffs[3]; @@ -400,8 +400,8 @@ static void ExtrapolateTexcoords( const float *axyz, const float *ast, const flo int ScaleBSPMain( int argc, char **argv ){ int i, j; float f, a; - vec3_t scale; - vec3_t vec; + Vector3 scale; + Vector3 vec; char str[ 1024 ]; int uniform, axis; bool texscale; @@ -469,9 +469,7 @@ int ScaleBSPMain( int argc, char **argv ){ if ( entities[i].classname_prefixed( "info_player_" ) ) { vec[2] += spawn_ref; } - vec[0] *= scale[0]; - vec[1] *= scale[1]; - vec[2] *= scale[2]; + vec *= scale; if ( entities[i].classname_prefixed( "info_player_" ) ) { vec[2] -= spawn_ref; } @@ -483,7 +481,7 @@ int ScaleBSPMain( int argc, char **argv ){ if ( a == -1 || a == -2 ) { // z scale axis = 2; } - else if ( fabs( sin( DEG2RAD( a ) ) ) < 0.707 ) { + else if ( fabs( sin( degrees_to_radians( a ) ) ) < 0.707 ) { axis = 0; } else{ @@ -510,34 +508,22 @@ int ScaleBSPMain( int argc, char **argv ){ /* scale models */ for ( i = 0; i < numBSPModels; i++ ) { - bspModels[ i ].mins[0] *= scale[0]; - bspModels[ i ].mins[1] *= scale[1]; - bspModels[ i ].mins[2] *= scale[2]; - bspModels[ i ].maxs[0] *= scale[0]; - bspModels[ i ].maxs[1] *= scale[1]; - bspModels[ i ].maxs[2] *= scale[2]; + bspModels[ i ].minmax.mins *= scale; + bspModels[ i ].minmax.maxs *= scale; } /* scale nodes */ for ( i = 0; i < numBSPNodes; i++ ) { - bspNodes[ i ].mins[0] *= scale[0]; - bspNodes[ i ].mins[1] *= scale[1]; - bspNodes[ i ].mins[2] *= scale[2]; - bspNodes[ i ].maxs[0] *= scale[0]; - bspNodes[ i ].maxs[1] *= scale[1]; - bspNodes[ i ].maxs[2] *= scale[2]; + bspNodes[ i ].minmax.mins *= scale; + bspNodes[ i ].minmax.maxs *= scale; } /* scale leafs */ for ( i = 0; i < numBSPLeafs; i++ ) { - bspLeafs[ i ].mins[0] *= scale[0]; - bspLeafs[ i ].mins[1] *= scale[1]; - bspLeafs[ i ].mins[2] *= scale[2]; - bspLeafs[ i ].maxs[0] *= scale[0]; - bspLeafs[ i ].maxs[1] *= scale[1]; - bspLeafs[ i ].maxs[2] *= scale[2]; + bspLeafs[ i ].minmax.mins *= scale; + bspLeafs[ i ].minmax.maxs *= scale; } if ( texscale ) { @@ -562,7 +548,7 @@ int ScaleBSPMain( int argc, char **argv ){ bspDrawVerts[i].normal[0] /= scale[0]; bspDrawVerts[i].normal[1] /= scale[1]; bspDrawVerts[i].normal[2] /= scale[2]; - VectorNormalize( bspDrawVerts[i].normal, bspDrawVerts[i].normal ); + VectorNormalize( bspDrawVerts[i].normal ); } if ( texscale ) { @@ -600,29 +586,25 @@ int ScaleBSPMain( int argc, char **argv ){ if ( uniform ) { for ( i = 0; i < numBSPPlanes; i++ ) { - bspPlanes[ i ].dist *= scale[0]; + bspPlanes[ i ].dist() *= scale[0]; } } else { for ( i = 0; i < numBSPPlanes; i++ ) { - bspPlanes[ i ].normal[0] /= scale[0]; - bspPlanes[ i ].normal[1] /= scale[1]; - bspPlanes[ i ].normal[2] /= scale[2]; - f = 1 / VectorLength( bspPlanes[i].normal ); - VectorScale( bspPlanes[i].normal, f, bspPlanes[i].normal ); - bspPlanes[ i ].dist *= f; + bspPlanes[i].normal() /= scale; + const double len = vector3_length( bspPlanes[i].normal() ); + bspPlanes[i].normal() /= len; + bspPlanes[i].dist() /= len; } } /* scale gridsize */ if ( !entities[ 0 ].read_keyvalue( vec, "gridsize" ) ) { - VectorCopy( gridSize, vec ); + vec = gridSize; } - vec[0] *= scale[0]; - vec[1] *= scale[1]; - vec[2] *= scale[2]; + vec *= scale; sprintf( str, "%f %f %f", vec[ 0 ], vec[ 1 ], vec[ 2 ] ); entities[ 0 ].setKeyValue( "gridsize", str ); @@ -647,8 +629,8 @@ int ScaleBSPMain( int argc, char **argv ){ int ShiftBSPMain( int argc, char **argv ){ int i, j; - vec3_t scale; - vec3_t vec; + Vector3 scale; + Vector3 vec; char str[ 1024 ]; float spawn_ref = 0; @@ -704,9 +686,7 @@ int ShiftBSPMain( int argc, char **argv ){ if ( e.classname_prefixed( "info_player_" ) ) { vec[2] += spawn_ref; } - vec[0] += scale[0]; - vec[1] += scale[1]; - vec[2] += scale[2]; + vec += scale; if ( e.classname_prefixed( "info_player_" ) ) { vec[2] -= spawn_ref; } @@ -719,65 +699,48 @@ int ShiftBSPMain( int argc, char **argv ){ /* shift models */ for ( i = 0; i < numBSPModels; i++ ) { - bspModels[ i ].mins[0] += scale[0]; - bspModels[ i ].mins[1] += scale[1]; - bspModels[ i ].mins[2] += scale[2]; - bspModels[ i ].maxs[0] += scale[0]; - bspModels[ i ].maxs[1] += scale[1]; - bspModels[ i ].maxs[2] += scale[2]; + bspModels[ i ].minmax.mins += scale; + bspModels[ i ].minmax.maxs += scale; } /* shift nodes */ for ( i = 0; i < numBSPNodes; i++ ) { - bspNodes[ i ].mins[0] += scale[0]; - bspNodes[ i ].mins[1] += scale[1]; - bspNodes[ i ].mins[2] += scale[2]; - bspNodes[ i ].maxs[0] += scale[0]; - bspNodes[ i ].maxs[1] += scale[1]; - bspNodes[ i ].maxs[2] += scale[2]; + bspNodes[ i ].minmax.mins += scale; + bspNodes[ i ].minmax.maxs += scale; } /* shift leafs */ for ( i = 0; i < numBSPLeafs; i++ ) { - bspLeafs[ i ].mins[0] += scale[0]; - bspLeafs[ i ].mins[1] += scale[1]; - bspLeafs[ i ].mins[2] += scale[2]; - bspLeafs[ i ].maxs[0] += scale[0]; - bspLeafs[ i ].maxs[1] += scale[1]; - bspLeafs[ i ].maxs[2] += scale[2]; + bspLeafs[ i ].minmax.mins += scale; + bspLeafs[ i ].minmax.maxs += scale; } /* shift drawverts */ for ( i = 0; i < numBSPDrawVerts; i++ ) { - bspDrawVerts[i].xyz[0] += scale[0]; - bspDrawVerts[i].xyz[1] += scale[1]; - bspDrawVerts[i].xyz[2] += scale[2]; + bspDrawVerts[i].xyz += scale; } /* shift planes */ - vec3_t point; - for ( i = 0; i < numBSPPlanes; i++ ) { //find point on plane + Vector3 point; for ( j=0; j<3; j++ ){ //point[j] = bspPlanes[ i ].dist * bspPlanes[ i ].normal[j]; - if ( fabs( bspPlanes[ i ].normal[j] ) > 0.5 ){ - point[j] = bspPlanes[ i ].dist / bspPlanes[ i ].normal[j]; + if ( fabs( bspPlanes[ i ].normal()[j] ) > 0.5 ){ + point[j] = bspPlanes[ i ].dist() / bspPlanes[ i ].normal()[j]; point[(j+1)%3] = point[(j+2)%3] = 0; break; } } //shift point - for ( j=0; j<3; j++ ){ - point[j] += scale[j]; - } + point += scale; //calc new plane dist - bspPlanes[ i ].dist = DotProduct( point, bspPlanes[ i ].normal ); + bspPlanes[ i ].dist() = vector3_dot( point, bspPlanes[ i ].normal() ); } /* scale gridsize */ diff --git a/tools/quake3/q3map2/convert_map.cpp b/tools/quake3/q3map2/convert_map.cpp index 3eb509b0..8f2498da 100644 --- a/tools/quake3/q3map2/convert_map.cpp +++ b/tools/quake3/q3map2/convert_map.cpp @@ -38,11 +38,9 @@ exports a map brush */ -typedef vec_t vec2_t[2]; - -static vec_t Det3x3( vec_t a00, vec_t a01, vec_t a02, - vec_t a10, vec_t a11, vec_t a12, - vec_t a20, vec_t a21, vec_t a22 ){ +static float Det3x3( float a00, float a01, float a02, + float a10, float a11, float a12, + float a20, float a21, float a22 ){ return a00 * ( a11 * a22 - a12 * a21 ) - a01 * ( a10 * a22 - a12 * a20 ) @@ -53,10 +51,8 @@ void GetBestSurfaceTriangleMatchForBrushside( side_t *buildSide, bspDrawVert_t * bspDrawSurface_t *s; int i; int t; - vec_t best = 0; - vec_t thisarea; - vec3_t normdiff; - vec3_t v1v0, v2v0, norm; + float best = 0; + float thisarea; bspDrawVert_t *vert[3]; winding_t *polygon; plane_t *buildPlane = &mapplanes[buildSide->planenum]; @@ -80,16 +76,13 @@ void GetBestSurfaceTriangleMatchForBrushside( side_t *buildSide, bspDrawVert_t * vert[1] = &bspDrawVerts[s->firstVert + bspDrawIndexes[s->firstIndex + t + 1]]; vert[2] = &bspDrawVerts[s->firstVert + bspDrawIndexes[s->firstIndex + t + 2]]; if ( s->surfaceType == MST_PLANAR && VectorCompare( vert[0]->normal, vert[1]->normal ) && VectorCompare( vert[1]->normal, vert[2]->normal ) ) { - VectorSubtract( vert[0]->normal, buildPlane->normal, normdiff ); - if ( VectorLength( normdiff ) >= normalEpsilon ) { + if ( vector3_length( vert[0]->normal - buildPlane->normal() ) >= normalEpsilon ) { continue; } - VectorSubtract( vert[1]->normal, buildPlane->normal, normdiff ); - if ( VectorLength( normdiff ) >= normalEpsilon ) { + if ( vector3_length( vert[1]->normal - buildPlane->normal() ) >= normalEpsilon ) { continue; } - VectorSubtract( vert[2]->normal, buildPlane->normal, normdiff ); - if ( VectorLength( normdiff ) >= normalEpsilon ) { + if ( vector3_length( vert[2]->normal - buildPlane->normal() ) >= normalEpsilon ) { continue; } } @@ -97,23 +90,20 @@ void GetBestSurfaceTriangleMatchForBrushside( side_t *buildSide, bspDrawVert_t * { // this is more prone to roundoff errors, but with embedded // models, there is no better way - VectorSubtract( vert[1]->xyz, vert[0]->xyz, v1v0 ); - VectorSubtract( vert[2]->xyz, vert[0]->xyz, v2v0 ); - CrossProduct( v2v0, v1v0, norm ); - VectorNormalize( norm, norm ); - VectorSubtract( norm, buildPlane->normal, normdiff ); - if ( VectorLength( normdiff ) >= normalEpsilon ) { + Plane3f plane; + PlaneFromPoints( plane, vert[0]->xyz, vert[1]->xyz, vert[2]->xyz ); + if ( vector3_length( plane.normal() - buildPlane->normal() ) >= normalEpsilon ) { continue; } } // fixme? better distance epsilon - if ( abs( DotProduct( vert[0]->xyz, buildPlane->normal ) - buildPlane->dist ) > 1 ) { + if ( abs( plane3_distance_to_point( buildPlane->plane, vert[0]->xyz ) ) > 1 ) { continue; } - if ( abs( DotProduct( vert[1]->xyz, buildPlane->normal ) - buildPlane->dist ) > 1 ) { + if ( abs( plane3_distance_to_point( buildPlane->plane, vert[1]->xyz ) ) > 1 ) { continue; } - if ( abs( DotProduct( vert[2]->xyz, buildPlane->normal ) - buildPlane->dist ) > 1 ) { + if ( abs( plane3_distance_to_point( buildPlane->plane, vert[2]->xyz ) ) > 1 ) { continue; } // Okay. Correct surface type, correct shader, correct plane. Let's start with the business... @@ -123,16 +113,12 @@ void GetBestSurfaceTriangleMatchForBrushside( side_t *buildSide, bspDrawVert_t * // 0: 1, 2 // 1: 2, 0 // 2; 0, 1 - vec3_t *v1 = &vert[( i + 1 ) % 3]->xyz; - vec3_t *v2 = &vert[( i + 2 ) % 3]->xyz; - vec3_t triNormal; - vec_t triDist; - vec3_t sideDirection; - // we now need to generate triNormal and triDist so that they represent the plane spanned by normal and (v2 - v1). - VectorSubtract( *v2, *v1, sideDirection ); - CrossProduct( sideDirection, buildPlane->normal, triNormal ); - triDist = DotProduct( *v1, triNormal ); - ChopWindingInPlace( &polygon, triNormal, triDist, distanceEpsilon ); + const Vector3& v1 = vert[( i + 1 ) % 3]->xyz; + const Vector3& v2 = vert[( i + 2 ) % 3]->xyz; + // we now need to generate the plane spanned by normal and (v2 - v1). + Plane3f plane( vector3_cross( v2 - v1, buildPlane->normal() ), 0 ); + plane.dist() = vector3_dot( v1, plane.normal() ); + ChopWindingInPlace( &polygon, plane, distanceEpsilon ); if ( !polygon ) { goto exwinding; } @@ -157,7 +143,7 @@ exwinding: } #define FRAC( x ) ( ( x ) - floor( x ) ) -static void ConvertOriginBrush( FILE *f, int num, vec3_t origin, bool brushPrimitives ){ +static void ConvertOriginBrush( FILE *f, int num, const Vector3& origin, bool brushPrimitives ){ int originSize = 256; char pattern[6][7][4] = { @@ -217,14 +203,14 @@ static void ConvertOriginBrush( FILE *f, int num, vec3_t origin, bool brushPrimi fprintf( f, "\t}\n\n" ); } -static void ConvertBrushFast( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bool brushPrimitives ){ +static void ConvertBrushFast( FILE *f, int num, bspBrush_t *brush, const Vector3& origin, bool brushPrimitives ){ int i; bspBrushSide_t *side; side_t *buildSide; bspShader_t *shader; const char *texture; plane_t *buildPlane; - vec3_t pts[ 3 ]; + Vector3 pts[ 3 ]; /* clear out build brush */ @@ -325,12 +311,11 @@ static void ConvertBrushFast( FILE *f, int num, bspBrush_t *brush, vec3_t origin } { - vec3_t vecs[ 2 ]; - MakeNormalVectors( buildPlane->normal, vecs[ 0 ], vecs[ 1 ] ); - VectorMA( vec3_origin, buildPlane->dist, buildPlane->normal, pts[ 0 ] ); - VectorAdd( pts[ 0 ], origin, pts[ 0 ] ); - VectorMA( pts[ 0 ], 256.0f, vecs[ 0 ], pts[ 1 ] ); - VectorMA( pts[ 0 ], 256.0f, vecs[ 1 ], pts[ 2 ] ); + Vector3 vecs[ 2 ]; + MakeNormalVectors( buildPlane->normal(), vecs[ 0 ], vecs[ 1 ] ); + pts[ 0 ] = buildPlane->normal() * buildPlane->dist() + origin; + pts[ 1 ] = pts[ 0 ] + vecs[ 0 ] * 256.0f; + pts[ 2 ] = pts[ 0 ] + vecs[ 1 ] * 256.0f; } { @@ -366,14 +351,14 @@ static void ConvertBrushFast( FILE *f, int num, bspBrush_t *brush, vec3_t origin fprintf( f, "\t}\n\n" ); } -static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bool brushPrimitives ){ +static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, const Vector3& origin, bool brushPrimitives ){ int i, j; bspBrushSide_t *side; side_t *buildSide; bspShader_t *shader; const char *texture; plane_t *buildPlane; - vec3_t pts[ 3 ]; + Vector3 pts[ 3 ]; bspDrawVert_t *vert[3]; @@ -469,8 +454,8 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo // st-texcoords -> texMat block // start out with dummy - VectorSet( buildSide->texMat[0], 1 / 32.0, 0, 0 ); - VectorSet( buildSide->texMat[1], 0, 1 / 32.0, 0 ); + buildSide->texMat[0] = { 1 / 32.0, 0, 0 }; + buildSide->texMat[1] = { 0, 1 / 32.0, 0 }; // find surface for this side (by brute force) // surface format: @@ -490,11 +475,11 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo /* recheck and fix winding points, fails occur somehow */ int match = 0; for ( j = 0; j < buildSide->winding->numpoints; j++ ){ - if ( fabs( DotProduct( buildSide->winding->p[ j ], buildPlane->normal ) - buildPlane->dist ) >= distanceEpsilon ) { + if ( fabs( plane3_distance_to_point( buildPlane->plane, buildSide->winding->p[ j ] ) ) >= distanceEpsilon ) { continue; } else{ - VectorCopy( buildSide->winding->p[ j ], pts[ match ] ); + pts[ match ] = buildSide->winding->p[ j ]; match++; /* got 3 fine points? */ if( match > 2 ) @@ -504,9 +489,9 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo if( match > 2 ){ //Sys_Printf( "pointsKK " ); - vec4_t testplane; - if ( PlaneFromPoints( testplane, pts[0], pts[1], pts[2] ) ){ - if( !PlaneEqual( buildPlane, testplane, testplane[3] ) ){ + Plane3f testplane; + if ( PlaneFromPoints( testplane, pts ) ){ + if( !PlaneEqual( buildPlane, testplane ) ){ //Sys_Printf( "1: %f %f %f %f\n2: %f %f %f %f\n", buildPlane->normal[0], buildPlane->normal[1], buildPlane->normal[2], buildPlane->dist, testplane[0], testplane[1], testplane[2], testplane[3] ); match--; //Sys_Printf( "planentEQ " ); @@ -522,34 +507,33 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo //Sys_Printf( "ok " ); /* offset by origin */ for ( j = 0; j < 3; j++ ) - VectorAdd( pts[ j ], origin, pts[ j ] ); + pts[ j ] += origin; } else{ - vec3_t vecs[ 2 ]; - MakeNormalVectors( buildPlane->normal, vecs[ 0 ], vecs[ 1 ] ); - VectorMA( vec3_origin, buildPlane->dist, buildPlane->normal, pts[ 0 ] ); - VectorAdd( pts[ 0 ], origin, pts[ 0 ] ); - VectorMA( pts[ 0 ], 256.0f, vecs[ 0 ], pts[ 1 ] ); - VectorMA( pts[ 0 ], 256.0f, vecs[ 1 ], pts[ 2 ] ); + Vector3 vecs[ 2 ]; + MakeNormalVectors( buildPlane->normal(), vecs[ 0 ], vecs[ 1 ] ); + pts[ 0 ] = buildPlane->normal() * buildPlane->dist() + origin; + pts[ 1 ] = pts[ 0 ] + vecs[ 0 ] * 256.0f; + pts[ 2 ] = pts[ 0 ] + vecs[ 1 ] * 256.0f; //Sys_Printf( "not\n" ); } if ( vert[0] && vert[1] && vert[2] ) { if ( brushPrimitives ) { int i; - vec3_t texX, texY; - vec2_t xyI, xyJ, xyK; - vec2_t stI, stJ, stK; - vec_t D, D0, D1, D2; + Vector3 texX, texY; + float xyI[2], xyJ[2], xyK[2]; + float stI[2], stJ[2], stK[2]; + float D, D0, D1, D2; - ComputeAxisBase( buildPlane->normal, texX, texY ); + ComputeAxisBase( buildPlane->normal(), texX, texY ); - xyI[0] = DotProduct( vert[0]->xyz, texX ); - xyI[1] = DotProduct( vert[0]->xyz, texY ); - xyJ[0] = DotProduct( vert[1]->xyz, texX ); - xyJ[1] = DotProduct( vert[1]->xyz, texY ); - xyK[0] = DotProduct( vert[2]->xyz, texX ); - xyK[1] = DotProduct( vert[2]->xyz, texY ); + xyI[0] = vector3_dot( vert[0]->xyz, texX ); + xyI[1] = vector3_dot( vert[0]->xyz, texY ); + xyJ[0] = vector3_dot( vert[1]->xyz, texX ); + xyJ[1] = vector3_dot( vert[1]->xyz, texY ); + xyK[0] = vector3_dot( vert[2]->xyz, texX ); + xyK[1] = vector3_dot( vert[2]->xyz, texY ); stI[0] = vert[0]->st[0]; stI[1] = vert[0]->st[1]; stJ[0] = vert[1]->st[0]; stJ[1] = vert[1]->st[1]; stK[0] = vert[2]->st[0]; stK[1] = vert[2]->st[1]; @@ -581,12 +565,12 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo xyJ[0], xyJ[1], stJ[i], xyK[0], xyK[1], stK[i] ); - VectorSet( buildSide->texMat[i], D0 / D, D1 / D, D2 / D ); + buildSide->texMat[i] = { D0 / D, D1 / D, D2 / D }; } } else{ fprintf( stderr, "degenerate triangle found when solving texMat equations for\n(%f %f %f) (%f %f %f) (%f %f %f)\n( %f %f %f )\n( %f %f %f ) -> ( %f %f )\n( %f %f %f ) -> ( %f %f )\n( %f %f %f ) -> ( %f %f )\n", - buildPlane->normal[0], buildPlane->normal[1], buildPlane->normal[2], + buildPlane->normal()[0], buildPlane->normal()[1], buildPlane->normal()[2], vert[0]->normal[0], vert[0]->normal[1], vert[0]->normal[2], texX[0], texX[1], texX[2], texY[0], texY[1], texY[2], vert[0]->xyz[0], vert[0]->xyz[1], vert[0]->xyz[2], xyI[0], xyI[1], @@ -611,13 +595,13 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo { // invert QuakeTextureVecs int i; - vec3_t vecs[2]; + Vector3 vecs[2]; int sv, tv; - vec2_t stI, stJ, stK; - vec3_t sts[2]; - vec2_t shift, scale; - vec_t rotate; - vec_t D, D0, D1, D2; + float stI[2], stJ[2], stK[2]; + Vector3 sts[2]; + float shift[2], scale[2]; + float rotate; + float D, D0, D1, D2; TextureAxisFromPlane( buildPlane, vecs[0], vecs[1] ); if ( vecs[0][0] ) { @@ -666,18 +650,18 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo vert[1]->xyz[sv], vert[1]->xyz[tv], stJ[i], vert[2]->xyz[sv], vert[2]->xyz[tv], stK[i] ); - VectorSet( sts[i], D0 / D, D1 / D, D2 / D ); + sts[i] = { D0 / D, D1 / D, D2 / D }; //Sys_Printf( "%.3f %.3f %.3f \n", sts[i][0], sts[i][1], sts[i][2] ); } } else{ fprintf( stderr, "degenerate triangle found when solving texDef equations\n" ); // FIXME add stuff here - VectorSet( sts[0], 2.f, 0.f, 0.f ); - VectorSet( sts[1], 0.f, -2.f, 0.f ); + sts[0] = { 2.f, 0.f, 0.f }; + sts[1] = { 0.f, -2.f, 0.f }; } // now we must solve: // // now we must invert: - // ang = rotate / 180 * Q_PI; + // ang = degrees_to_radians( rotate ); // sinv = sin(ang); // cosv = cos(ang); // ns = cosv * vecs[0][sv]; @@ -690,7 +674,7 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo // vecsrotscaled[1][tv] = nt / scale[1]; scale[0] = 1.0 / sqrt( sts[0][0] * sts[0][0] + sts[0][1] * sts[0][1] ); scale[1] = 1.0 / sqrt( sts[1][0] * sts[1][0] + sts[1][1] * sts[1][1] ); - rotate = atan2( sts[0][1] * vecs[0][sv] - sts[1][0] * vecs[1][tv], sts[0][0] * vecs[0][sv] + sts[1][1] * vecs[1][tv] ) * ( 180.0f / Q_PI ); + rotate = radians_to_degrees( atan2( sts[0][1] * vecs[0][sv] - sts[1][0] * vecs[1][tv], sts[0][0] * vecs[0][sv] + sts[1][1] * vecs[1][tv] ) ); shift[0] = buildSide->shaderInfo->shaderWidth * FRAC( sts[0][2] / buildSide->shaderInfo->shaderWidth ); shift[1] = buildSide->shaderInfo->shaderHeight * FRAC( sts[1][2] / buildSide->shaderInfo->shaderHeight ); @@ -708,7 +692,6 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo } else { - //vec3_t vecs[ 2 ]; if ( !striEqualPrefix( buildSide->shaderInfo->shader, "textures/common/" ) ) { if ( !strEqual( buildSide->shaderInfo->shader, "noshader" ) ) { if ( !strEqual( buildSide->shaderInfo->shader, "default" ) ) { @@ -717,12 +700,7 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, bo } } } -/* - MakeNormalVectors( buildPlane->normal, vecs[ 0 ], vecs[ 1 ] ); - VectorMA( vec3_origin, buildPlane->dist, buildPlane->normal, pts[ 0 ] ); - VectorMA( pts[ 0 ], 256.0f, vecs[ 1 ], pts[ 2 ] ); - VectorMA( pts[ 0 ], 256.0f, vecs[ 0 ], pts[ 1 ] ); -*/ + if ( brushPrimitives ) { fprintf( f, "\t\t( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( ( %.8f %.8f %.8f ) ( %.8f %.8f %.8f ) ) %s %d 0 0\n", pts[ 0 ][ 0 ], pts[ 0 ][ 1 ], pts[ 0 ][ 2 ], @@ -828,12 +806,11 @@ for ( i = 0; i < brush->numSides; i++ ) */ -static void ConvertPatch( FILE *f, int num, bspDrawSurface_t *ds, vec3_t origin ){ +static void ConvertPatch( FILE *f, int num, bspDrawSurface_t *ds, const Vector3& origin ){ int x, y; bspShader_t *shader; const char *texture; bspDrawVert_t *dv; - vec3_t xyz; /* only patches */ @@ -877,7 +854,7 @@ static void ConvertPatch( FILE *f, int num, bspDrawSurface_t *ds, vec3_t origin dv = &bspDrawVerts[ ds->firstVert + ( y * ds->patchWidth ) + x ]; /* offset it */ - VectorAdd( origin, dv->xyz, xyz ); + const Vector3 xyz = dv->xyz + origin; /* print vertex */ fprintf( f, " ( %f %f %f %f %f )", xyz[ 0 ], xyz[ 1 ], xyz[ 2 ], dv->st[ 0 ], dv->st[ 1 ] ); @@ -900,7 +877,7 @@ static void ConvertPatch( FILE *f, int num, bspDrawSurface_t *ds, vec3_t origin exports a bsp model to a map file */ -static void ConvertModel( FILE *f, bspModel_t *model, int modelNum, vec3_t origin, bool brushPrimitives ){ +static void ConvertModel( FILE *f, bspModel_t *model, int modelNum, const Vector3& origin, bool brushPrimitives ){ int i, num; bspBrush_t *brush; bspDrawSurface_t *ds; @@ -911,9 +888,8 @@ static void ConvertModel( FILE *f, bspModel_t *model, int modelNum, vec3_t origi AUTOEXPAND_BY_REALLOC( mapplanes, nummapplanes, allocatedmapplanes, 1024 ); for ( i = 0; i < numBSPPlanes; i++ ) { - VectorCopy( bspPlanes[ i ].normal, mapplanes[ i ].normal ); - mapplanes[ i ].dist = bspPlanes[ i ].dist; - mapplanes[ i ].type = PlaneTypeForNormal( mapplanes[ i ].normal ); + mapplanes[ i ].plane = bspPlanes[ i ]; + mapplanes[ i ].type = PlaneTypeForNormal( mapplanes[ i ].normal() ); mapplanes[ i ].hash_chain = 0; } @@ -1048,7 +1024,7 @@ int ConvertBSPToMap_Ext( char *bspName, bool brushPrimitives ){ model = &bspModels[ modelNum ]; /* get entity origin */ - vec3_t origin; + Vector3 origin; e->vectorForKey( "origin", origin ); /* convert model */ diff --git a/tools/quake3/q3map2/convert_obj.cpp b/tools/quake3/q3map2/convert_obj.cpp index dc71baa0..d14d6c01 100644 --- a/tools/quake3/q3map2/convert_obj.cpp +++ b/tools/quake3/q3map2/convert_obj.cpp @@ -44,7 +44,7 @@ int lastLightmap = -1; int objVertexCount = 0; int objLastShaderNum = -1; -static void ConvertSurfaceToOBJ( FILE *f, bspModel_t *model, int modelNum, bspDrawSurface_t *ds, int surfaceNum, vec3_t origin, const int* lmIndices ){ +static void ConvertSurfaceToOBJ( FILE *f, bspModel_t *model, int modelNum, bspDrawSurface_t *ds, int surfaceNum, const Vector3& origin, const int* lmIndices ){ int i, v, a, b, c; bspDrawVert_t *dv; @@ -127,7 +127,7 @@ static void ConvertSurfaceToOBJ( FILE *f, bspModel_t *model, int modelNum, bspDr exports a bsp model to an ase chunk */ -static void ConvertModelToOBJ( FILE *f, bspModel_t *model, int modelNum, vec3_t origin, const int* lmIndices ){ +static void ConvertModelToOBJ( FILE *f, bspModel_t *model, int modelNum, const Vector3& origin, const int* lmIndices ){ int i, s; bspDrawSurface_t *ds; @@ -358,7 +358,7 @@ int ConvertBSPToOBJ( char *bspName ){ model = &bspModels[ modelNum ]; /* get entity origin */ - vec3_t origin; + Vector3 origin; e->vectorForKey( "origin", origin ); /* convert model */ diff --git a/tools/quake3/q3map2/decals.cpp b/tools/quake3/q3map2/decals.cpp index e3872509..afcd7c99 100644 --- a/tools/quake3/q3map2/decals.cpp +++ b/tools/quake3/q3map2/decals.cpp @@ -38,12 +38,12 @@ struct decalProjector_t { shaderInfo_t *si; - vec3_t mins, maxs; - vec3_t center; + MinMax minmax; + Vector3 center; float radius, radius2; int numPlanes; /* either 5 or 6, for quad or triangle projectors */ - vec4_t planes[ 6 ]; - vec4_t texMat[ 2 ]; + Plane3f planes[ 6 ]; + Vector4 texMat[ 2 ]; }; static int numProjectors = 0; @@ -51,37 +51,10 @@ static decalProjector_t projectors[ MAX_PROJECTORS ]; static int numDecalSurfaces = 0; -static vec3_t entityOrigin; +static Vector3 entityOrigin; -/* - DVectorNormalize() - normalizes a vector, returns the length, operates using doubles - */ - -typedef double dvec_t; -typedef dvec_t dvec3_t[ 3 ]; - -dvec_t DVectorNormalize( dvec3_t in, dvec3_t out ){ - dvec_t len, ilen; - - - len = (dvec_t) sqrt( in[ 0 ] * in[ 0 ] + in[ 1 ] * in[ 1 ] + in[ 2 ] * in[ 2 ] ); - if ( len == 0.0 ) { - VectorClear( out ); - return 0.0; - } - - ilen = 1.0 / len; - out[ 0 ] = in[ 0 ] * ilen; - out[ 1 ] = in[ 1 ] * ilen; - out[ 2 ] = in[ 2 ] * ilen; - - return len; -} - - /* MakeTextureMatrix() @@ -91,21 +64,18 @@ dvec_t DVectorNormalize( dvec3_t in, dvec3_t out ){ #define Vector2Subtract( a,b,c ) ( ( c )[ 0 ] = ( a )[ 0 ] - ( b )[ 0 ], ( c )[ 1 ] = ( a )[ 1 ] - ( b )[ 1 ] ) -static bool MakeTextureMatrix( decalProjector_t *dp, vec4_t projection, bspDrawVert_t *a, bspDrawVert_t *b, bspDrawVert_t *c ){ +static bool MakeTextureMatrix( decalProjector_t *dp, const Plane3f& projection, bspDrawVert_t *a, bspDrawVert_t *b, bspDrawVert_t *c ){ int i, j; - double bb, s, t, d; - dvec3_t pa, pb, pc; - dvec3_t bary, xyz; - dvec3_t vecs[ 3 ], axis[ 3 ], lengths; + double bb, s, t; + DoubleVector3 pa, pb, pc; + DoubleVector3 bary, xyz; + DoubleVector3 vecs[ 3 ], axis[ 3 ], lengths; /* project triangle onto plane of projection */ - d = DotProduct( a->xyz, projection ) - projection[ 3 ]; - VectorMA( a->xyz, -d, projection, pa ); - d = DotProduct( b->xyz, projection ) - projection[ 3 ]; - VectorMA( b->xyz, -d, projection, pb ); - d = DotProduct( c->xyz, projection ) - projection[ 3 ]; - VectorMA( c->xyz, -d, projection, pc ); + pa = plane3_project_point( projection, a->xyz ); + pb = plane3_project_point( projection, b->xyz ); + pc = plane3_project_point( projection, c->xyz ); /* two methods */ #if 1 @@ -142,8 +112,8 @@ static bool MakeTextureMatrix( decalProjector_t *dp, vec4_t projection, bspDrawV xyz[ 1 ] = bary[ 0 ] * pa[ 1 ] + bary[ 1 ] * pb[ 1 ] + bary[ 2 ] * pc[ 1 ]; xyz[ 2 ] = bary[ 0 ] * pa[ 2 ] + bary[ 1 ] * pb[ 2 ] + bary[ 2 ] * pc[ 2 ]; - //% VectorSubtract( xyz, origin, vecs[ 0 ] ); - VectorSubtract( xyz, pa, vecs[ 0 ] ); + //% vecs[ 0 ] = xyz - origin; + vecs[ 0 ] = xyz - pa; /* calculate t vector */ s = a->st[ 0 ] + 0.0; @@ -156,29 +126,31 @@ static bool MakeTextureMatrix( decalProjector_t *dp, vec4_t projection, bspDrawV xyz[ 1 ] = bary[ 0 ] * pa[ 1 ] + bary[ 1 ] * pb[ 1 ] + bary[ 2 ] * pc[ 1 ]; xyz[ 2 ] = bary[ 0 ] * pa[ 2 ] + bary[ 1 ] * pb[ 2 ] + bary[ 2 ] * pc[ 2 ]; - //% VectorSubtract( xyz, origin, vecs[ 1 ] ); - VectorSubtract( xyz, pa, vecs[ 1 ] ); + //% vecs[ 1 ] = xyz - origin; + vecs[ 1 ] = xyz - pa; /* calcuate r vector */ - VectorScale( projection, -1.0, vecs[ 2 ] ); + vecs[ 2 ] = -projection.normal(); /* calculate transform axis */ - for ( i = 0; i < 3; i++ ) - lengths[ i ] = DVectorNormalize( vecs[ i ], axis[ i ] ); + for ( i = 0; i < 3; i++ ){ + axis[ i ] = vecs[ i ]; + lengths[ i ] = VectorNormalize( axis[ i ] ); + } for ( i = 0; i < 2; i++ ) for ( j = 0; j < 3; j++ ) - dp->texMat[ i ][ j ] = lengths[ i ] > 0.0 ? ( axis[ i ][ j ] / lengths[ i ] ) : 0.0; + dp->texMat[ i ][ j ] = lengths[ i ] != 0.0 ? ( axis[ i ][ j ] / lengths[ i ] ) : 0.0; //% dp->texMat[ i ][ j ] = fabs( vecs[ i ][ j ] ) > 0.0 ? (1.0 / vecs[ i ][ j ]) : 0.0; //% dp->texMat[ i ][ j ] = axis[ i ][ j ] > 0.0 ? (1.0 / axis[ i ][ j ]) : 0.0; /* calculalate translation component */ - dp->texMat[ 0 ][ 3 ] = a->st[ 0 ] - DotProduct( a->xyz, dp->texMat[ 0 ] ); - dp->texMat[ 1 ][ 3 ] = a->st[ 1 ] - DotProduct( a->xyz, dp->texMat[ 1 ] ); + dp->texMat[ 0 ][ 3 ] = a->st[ 0 ] - vector3_dot( a->xyz, dp->texMat[ 0 ].vec3() ); + dp->texMat[ 1 ][ 3 ] = a->st[ 1 ] - vector3_dot( a->xyz, dp->texMat[ 1 ].vec3() ); } #else { int k; - dvec3_t origin, deltas[ 3 ]; + DoubleVector3 deltas[ 3 ]; double texDeltas[ 3 ][ 2 ]; double delta, texDelta; @@ -186,9 +158,9 @@ static bool MakeTextureMatrix( decalProjector_t *dp, vec4_t projection, bspDrawV /* new code */ /* calculate deltas */ - VectorSubtract( pa, pb, deltas[ 0 ] ); - VectorSubtract( pa, pc, deltas[ 1 ] ); - VectorSubtract( pb, pc, deltas[ 2 ] ); + deltas[ 0 ] = pa - pb; + deltas[ 1 ] = pa - pc; + deltas[ 2 ] = pb - pc; Vector2Subtract( a->st, b->st, texDeltas[ 0 ] ); Vector2Subtract( a->st, c->st, texDeltas[ 1 ] ); Vector2Subtract( b->st, c->st, texDeltas[ 2 ] ); @@ -223,42 +195,42 @@ static bool MakeTextureMatrix( decalProjector_t *dp, vec4_t projection, bspDrawV } /* set translation component */ - dp->texMat[ i ][ 3 ] = a->st[ i ] - DotProduct( pa, dp->texMat[ i ] ); + dp->texMat[ i ][ 3 ] = a->st[ i ] - vector3_dot( pa, dp->texMat[ i ].vec3() ); } } #endif /* debug code */ #if 1 - Sys_Printf( "Mat: [ %f %f %f %f ] [ %f %f %f %f ] Theta: %f (%f)\n", + Sys_Printf( "Mat: [ %f %f %f %f ] [ %f %f %f %f ] Theta: %lf (%lf)\n", dp->texMat[ 0 ][ 0 ], dp->texMat[ 0 ][ 1 ], dp->texMat[ 0 ][ 2 ], dp->texMat[ 0 ][ 3 ], dp->texMat[ 1 ][ 0 ], dp->texMat[ 1 ][ 1 ], dp->texMat[ 1 ][ 2 ], dp->texMat[ 1 ][ 3 ], - RAD2DEG( acos( DotProduct( dp->texMat[ 0 ], dp->texMat[ 1 ] ) ) ), - RAD2DEG( acos( DotProduct( axis[ 0 ], axis[ 1 ] ) ) ) ); + radians_to_degrees( acos( vector3_dot( dp->texMat[ 0 ].vec3(), dp->texMat[ 1 ].vec3() ) ) ), + radians_to_degrees( acos( vector3_dot( axis[ 0 ], axis[ 1 ] ) ) ) ); Sys_Printf( "XYZ: %f %f %f ST: %f %f ST(t): %f %f\n", a->xyz[ 0 ], a->xyz[ 1 ], a->xyz[ 2 ], a->st[ 0 ], a->st[ 1 ], - DotProduct( a->xyz, dp->texMat[ 0 ] ) + dp->texMat[ 0 ][ 3 ], DotProduct( a->xyz, dp->texMat[ 1 ] ) + dp->texMat[ 1 ][ 3 ] ); + vector3_dot( a->xyz, dp->texMat[ 0 ].vec3() ) + dp->texMat[ 0 ][ 3 ], vector3_dot( a->xyz, dp->texMat[ 1 ].vec3() ) + dp->texMat[ 1 ][ 3 ] ); #endif /* test texture matrix */ - s = DotProduct( a->xyz, dp->texMat[ 0 ] ) + dp->texMat[ 0 ][ 3 ]; - t = DotProduct( a->xyz, dp->texMat[ 1 ] ) + dp->texMat[ 1 ][ 3 ]; + s = vector3_dot( a->xyz, dp->texMat[ 0 ].vec3() ) + dp->texMat[ 0 ][ 3 ]; + t = vector3_dot( a->xyz, dp->texMat[ 1 ].vec3() ) + dp->texMat[ 1 ][ 3 ]; if ( fabs( s - a->st[ 0 ] ) > 0.01 || fabs( t - a->st[ 1 ] ) > 0.01 ) { Sys_Printf( "Bad texture matrix! (A) (%f, %f) != (%f, %f)\n", s, t, a->st[ 0 ], a->st[ 1 ] ); //% return false; } - s = DotProduct( b->xyz, dp->texMat[ 0 ] ) + dp->texMat[ 0 ][ 3 ]; - t = DotProduct( b->xyz, dp->texMat[ 1 ] ) + dp->texMat[ 1 ][ 3 ]; + s = vector3_dot( b->xyz, dp->texMat[ 0 ].vec3() ) + dp->texMat[ 0 ][ 3 ]; + t = vector3_dot( b->xyz, dp->texMat[ 1 ].vec3() ) + dp->texMat[ 1 ][ 3 ]; if ( fabs( s - b->st[ 0 ] ) > 0.01 || fabs( t - b->st[ 1 ] ) > 0.01 ) { Sys_Printf( "Bad texture matrix! (B) (%f, %f) != (%f, %f)\n", s, t, b->st[ 0 ], b->st[ 1 ] ); //% return false; } - s = DotProduct( c->xyz, dp->texMat[ 0 ] ) + dp->texMat[ 0 ][ 3 ]; - t = DotProduct( c->xyz, dp->texMat[ 1 ] ) + dp->texMat[ 1 ][ 3 ]; + s = vector3_dot( c->xyz, dp->texMat[ 0 ].vec3() ) + dp->texMat[ 0 ][ 3 ]; + t = vector3_dot( c->xyz, dp->texMat[ 1 ].vec3() ) + dp->texMat[ 1 ][ 3 ]; if ( fabs( s - c->st[ 0 ] ) > 0.01 || fabs( t - c->st[ 1 ] ) > 0.01 ) { Sys_Printf( "Bad texture matrix! (C) (%f, %f) != (%f, %f)\n", s, t, c->st[ 0 ], c->st[ 1 ] ); @@ -277,7 +249,7 @@ static bool MakeTextureMatrix( decalProjector_t *dp, vec4_t projection, bspDrawV note: non-normalized axes will screw up the plane transform */ -static void TransformDecalProjector( decalProjector_t *in, vec3_t axis[ 3 ], vec3_t origin, decalProjector_t *out ){ +static void TransformDecalProjector( decalProjector_t *in, Vector3 axis[ 3 ], const Vector3& origin, decalProjector_t *out ){ int i; @@ -286,28 +258,28 @@ static void TransformDecalProjector( decalProjector_t *in, vec3_t axis[ 3 ], vec out->numPlanes = in->numPlanes; /* translate bounding box and sphere (note: rotated projector bounding box will be invalid!) */ - VectorSubtract( in->mins, origin, out->mins ); - VectorSubtract( in->maxs, origin, out->maxs ); - VectorSubtract( in->center, origin, out->center ); + out->minmax.mins = in->minmax.mins - origin; + out->minmax.maxs = in->minmax.maxs - origin; + out->center = in->center - origin; out->radius = in->radius; out->radius2 = in->radius2; /* translate planes */ for ( i = 0; i < in->numPlanes; i++ ) { - out->planes[ i ][ 0 ] = DotProduct( in->planes[ i ], axis[ 0 ] ); - out->planes[ i ][ 1 ] = DotProduct( in->planes[ i ], axis[ 1 ] ); - out->planes[ i ][ 2 ] = DotProduct( in->planes[ i ], axis[ 2 ] ); - out->planes[ i ][ 3 ] = in->planes[ i ][ 3 ] - DotProduct( out->planes[ i ], origin ); + out->planes[ i ].a = vector3_dot( in->planes[ i ].normal(), axis[ 0 ] ); + out->planes[ i ].b = vector3_dot( in->planes[ i ].normal(), axis[ 1 ] ); + out->planes[ i ].c = vector3_dot( in->planes[ i ].normal(), axis[ 2 ] ); + out->planes[ i ].d = in->planes[ i ].dist() - vector3_dot( out->planes[ i ].normal(), origin ); } /* translate texture matrix */ for ( i = 0; i < 2; i++ ) { - out->texMat[ i ][ 0 ] = DotProduct( in->texMat[ i ], axis[ 0 ] ); - out->texMat[ i ][ 1 ] = DotProduct( in->texMat[ i ], axis[ 1 ] ); - out->texMat[ i ][ 2 ] = DotProduct( in->texMat[ i ], axis[ 2 ] ); - out->texMat[ i ][ 3 ] = in->texMat[ i ][ 3 ] + DotProduct( out->texMat[ i ], origin ); + out->texMat[ i ][ 0 ] = vector3_dot( in->texMat[ i ].vec3(), axis[ 0 ] ); + out->texMat[ i ][ 1 ] = vector3_dot( in->texMat[ i ].vec3(), axis[ 1 ] ); + out->texMat[ i ][ 2 ] = vector3_dot( in->texMat[ i ].vec3(), axis[ 2 ] ); + out->texMat[ i ][ 3 ] = vector3_dot( out->texMat[ i ].vec3(), origin ) + in->texMat[ i ][ 3 ]; } } @@ -318,10 +290,9 @@ static void TransformDecalProjector( decalProjector_t *in, vec3_t axis[ 3 ], vec creates a new decal projector from a triangle */ -static int MakeDecalProjector( shaderInfo_t *si, vec4_t projection, float distance, int numVerts, bspDrawVert_t **dv ){ +static int MakeDecalProjector( shaderInfo_t *si, const Plane3f& projection, float distance, int numVerts, bspDrawVert_t **dv ){ int i, j; decalProjector_t *dp; - vec3_t xyz; /* dummy check */ @@ -349,19 +320,16 @@ static int MakeDecalProjector( shaderInfo_t *si, vec4_t projection, float distan } /* bound the projector */ - ClearBounds( dp->mins, dp->maxs ); + dp->minmax.clear(); for ( i = 0; i < numVerts; i++ ) { - AddPointToBounds( dv[ i ]->xyz, dp->mins, dp->maxs ); - VectorMA( dv[ i ]->xyz, distance, projection, xyz ); - AddPointToBounds( xyz, dp->mins, dp->maxs ); + dp->minmax.extend( dv[ i ]->xyz ); + dp->minmax.extend( dv[ i ]->xyz + projection.normal() * distance ); } /* make bouding sphere */ - VectorAdd( dp->mins, dp->maxs, dp->center ); - VectorScale( dp->center, 0.5f, dp->center ); - VectorSubtract( dp->maxs, dp->center, xyz ); - dp->radius = VectorLength( xyz ); + dp->center = dp->minmax.origin(); + dp->radius = vector3_length( dp->minmax.maxs - dp->center ); dp->radius2 = dp->radius * dp->radius; /* make the front plane */ @@ -370,16 +338,14 @@ static int MakeDecalProjector( shaderInfo_t *si, vec4_t projection, float distan } /* make the back plane */ - VectorSubtract( vec3_origin, dp->planes[ 0 ], dp->planes[ 1 ] ); - VectorMA( dv[ 0 ]->xyz, distance, projection, xyz ); - dp->planes[ 1 ][ 3 ] = DotProduct( xyz, dp->planes[ 1 ] ); + dp->planes[ 1 ].normal() = -dp->planes[ 0 ].normal(); + dp->planes[ 1 ].dist() = vector3_dot( dv[ 0 ]->xyz + projection.normal() * distance, dp->planes[ 1 ].normal() ); /* make the side planes */ for ( i = 0; i < numVerts; i++ ) { j = ( i + 1 ) % numVerts; - VectorMA( dv[ i ]->xyz, distance, projection, xyz ); - if ( !PlaneFromPoints( dp->planes[ i + 2 ], dv[ j ]->xyz, dv[ i ]->xyz, xyz ) ) { + if ( !PlaneFromPoints( dp->planes[ i + 2 ], dv[ j ]->xyz, dv[ i ]->xyz, dv[ i ]->xyz + projection.normal() * distance ) ) { return -1; } } @@ -401,8 +367,7 @@ static int MakeDecalProjector( shaderInfo_t *si, vec4_t projection, float distan void ProcessDecals( void ){ int j, x, y, pw[ 5 ], r, iterations; float distance; - vec4_t projection, plane; - vec3_t origin, target, delta; + Plane3f projection, plane; entity_t *e2; parseMesh_t *p; mesh_t *mesh, *subdivided; @@ -439,20 +404,18 @@ void ProcessDecals( void ){ for ( p = e.patches; p != NULL; p = e.patches ) { /* setup projector */ - if ( VectorCompare( e.origin, vec3_origin ) ) { - VectorAdd( p->eMins, p->eMaxs, origin ); - VectorScale( origin, 0.5f, origin ); + Vector3 origin; + if ( VectorCompare( e.origin, g_vector3_identity ) ) { + origin = p->eMinmax.origin(); } else{ - VectorCopy( e.origin, origin ); + origin = e.origin; } - VectorCopy( e2->origin, target ); - VectorSubtract( target, origin, delta ); - /* setup projection plane */ - distance = VectorNormalize( delta, projection ); - projection[ 3 ] = DotProduct( origin, projection ); + projection.normal() = e2->origin - origin; + distance = VectorNormalize( projection.normal() ); + projection.dist() = vector3_dot( origin, projection.normal() ); /* create projectors */ if ( distance > 0.125f ) { @@ -467,7 +430,7 @@ void ProcessDecals( void ){ /* offset by projector origin */ for ( j = 0; j < ( mesh->width * mesh->height ); j++ ) - VectorAdd( mesh->verts[ j ].xyz, e.origin, mesh->verts[ j ].xyz ); + mesh->verts[ j ].xyz += e.origin; /* iterate through the mesh quads */ for ( y = 0; y < ( mesh->height - 1 ); y++ ) @@ -491,9 +454,8 @@ void ProcessDecals( void ){ dv[ 3 ] = &mesh->verts[ pw[ r + 3 ] ]; /* planar? (nuking this optimization as it doesn't work on non-rectangular quads) */ - plane[ 0 ] = 0.0f; /* stupid msvc */ if ( 0 && PlaneFromPoints( plane, dv[ 0 ]->xyz, dv[ 1 ]->xyz, dv[ 2 ]->xyz ) && - fabs( DotProduct( dv[ 1 ]->xyz, plane ) - plane[ 3 ] ) <= PLANAR_EPSILON ) { + fabs( plane3_distance_to_point( plane, dv[ 1 ]->xyz ) ) <= PLANAR_EPSILON ) { /* make a quad projector */ MakeDecalProjector( p->shaderInfo, projection, distance, 4, dv ); } @@ -542,7 +504,7 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds, winding_t *front, *back; mapDrawSurface_t *ds2; bspDrawVert_t *dv; - vec4_t plane; + Plane3f plane; /* dummy check */ @@ -553,7 +515,7 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds, /* offset by entity origin */ for ( i = 0; i < w->numpoints; i++ ) - VectorAdd( w->p[ i ], entityOrigin, w->p[ i ] ); + w->p[ i ] += entityOrigin; /* make a plane from the winding */ if ( !PlaneFromPoints( plane, w->p[ 0 ], w->p[ 1 ], w->p[ 2 ] ) ) { @@ -562,8 +524,7 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds, } /* backface check */ - d = DotProduct( dp->planes[ 0 ], plane ); - if ( d < -0.0001f ) { + if ( vector3_dot( dp->planes[ 0 ].normal(), plane.normal() ) < -0.0001f ) { FreeWinding( w ); return; } @@ -572,7 +533,7 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds, for ( i = 0; i < dp->numPlanes; i++ ) { /* chop winding by the plane */ - ClipWindingEpsilonStrict( w, dp->planes[ i ], dp->planes[ i ][ 3 ], 0.0625f, &front, &back ); /* strict, if identical plane we don't want to keep it */ + ClipWindingEpsilonStrict( w, dp->planes[ i ], 0.0625f, &front, &back ); /* strict, if identical plane we don't want to keep it */ FreeWinding( w ); /* lose the front fragment */ @@ -618,8 +579,8 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds, dv = &ds2->verts[ i ]; /* set alpha */ - d = DotProduct( w->p[ i ], dp->planes[ 0 ] ) - dp->planes[ 0 ][ 3 ]; - d2 = DotProduct( w->p[ i ], dp->planes[ 1 ] ) - dp->planes[ 1 ][ 3 ]; + d = plane3_distance_to_point( dp->planes[ 0 ], w->p[ i ] ); + d2 = plane3_distance_to_point( dp->planes[ 1 ], w->p[ i ] ); alpha = 255.0f * d2 / ( d + d2 ); if ( alpha > 255 ) { alpha = 255; @@ -629,18 +590,15 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds, } /* set misc */ - VectorSubtract( w->p[ i ], entityOrigin, dv->xyz ); - VectorCopy( plane, dv->normal ); - dv->st[ 0 ] = DotProduct( dv->xyz, dp->texMat[ 0 ] ) + dp->texMat[ 0 ][ 3 ]; - dv->st[ 1 ] = DotProduct( dv->xyz, dp->texMat[ 1 ] ) + dp->texMat[ 1 ][ 3 ]; + dv->xyz = w->p[ i ] - entityOrigin; + dv->normal = plane.normal(); + dv->st[ 0 ] = vector3_dot( dv->xyz, dp->texMat[ 0 ].vec3() ) + dp->texMat[ 0 ][ 3 ]; + dv->st[ 1 ] = vector3_dot( dv->xyz, dp->texMat[ 1 ].vec3() ) + dp->texMat[ 1 ][ 3 ]; /* set color */ for ( j = 0; j < MAX_LIGHTMAPS; j++ ) { - dv->color[ j ][ 0 ] = 255; - dv->color[ j ][ 1 ] = 255; - dv->color[ j ][ 2 ] = 255; - dv->color[ j ][ 3 ] = alpha; + dv->color[ j ] = { 255, 255, 255, alpha }; } } } @@ -653,11 +611,6 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds, */ static void ProjectDecalOntoFace( decalProjector_t *dp, mapDrawSurface_t *ds ){ - vec4_t plane; - float d; - winding_t *w; - - /* dummy check */ if ( ds->sideRef == NULL || ds->sideRef->side == NULL ) { return; @@ -665,16 +618,15 @@ static void ProjectDecalOntoFace( decalProjector_t *dp, mapDrawSurface_t *ds ){ /* backface check */ if ( ds->planar ) { - VectorCopy( mapplanes[ ds->planeNum ].normal, plane ); - plane[ 3 ] = mapplanes[ ds->planeNum ].dist + DotProduct( plane, entityOrigin ); - d = DotProduct( dp->planes[ 0 ], plane ); - if ( d < -0.0001f ) { + Plane3f plane = mapplanes[ ds->planeNum ].plane; + plane.dist() += vector3_dot( plane.normal(), entityOrigin ); + if ( vector3_dot( dp->planes[ 0 ].normal(), plane.normal() ) < -0.0001f ) { return; } } /* generate decal */ - w = WindingFromDrawSurf( ds ); + winding_t *w = WindingFromDrawSurf( ds ); ProjectDecalOntoWinding( dp, ds, w ); } @@ -687,18 +639,15 @@ static void ProjectDecalOntoFace( decalProjector_t *dp, mapDrawSurface_t *ds ){ static void ProjectDecalOntoPatch( decalProjector_t *dp, mapDrawSurface_t *ds ){ int x, y, pw[ 5 ], r, iterations; - vec4_t plane; - float d; mesh_t src, *mesh, *subdivided; winding_t *w; /* backface check */ if ( ds->planar ) { - VectorCopy( mapplanes[ ds->planeNum ].normal, plane ); - plane[ 3 ] = mapplanes[ ds->planeNum ].dist + DotProduct( plane, entityOrigin ); - d = DotProduct( dp->planes[ 0 ], plane ); - if ( d < -0.0001f ) { + Plane3f plane = mapplanes[ ds->planeNum ].plane; + plane.dist() += vector3_dot( plane.normal(), entityOrigin ); + if ( vector3_dot( dp->planes[ 0 ].normal(), plane.normal() ) < -0.0001f ) { return; } } @@ -733,17 +682,17 @@ static void ProjectDecalOntoPatch( decalProjector_t *dp, mapDrawSurface_t *ds ){ /* generate decal for first triangle */ w = AllocWinding( 3 ); w->numpoints = 3; - VectorCopy( mesh->verts[ pw[ r + 0 ] ].xyz, w->p[ 0 ] ); - VectorCopy( mesh->verts[ pw[ r + 1 ] ].xyz, w->p[ 1 ] ); - VectorCopy( mesh->verts[ pw[ r + 2 ] ].xyz, w->p[ 2 ] ); + w->p[ 0 ] = mesh->verts[ pw[ r + 0 ] ].xyz; + w->p[ 1 ] = mesh->verts[ pw[ r + 1 ] ].xyz; + w->p[ 2 ] = mesh->verts[ pw[ r + 2 ] ].xyz; ProjectDecalOntoWinding( dp, ds, w ); /* generate decal for second triangle */ w = AllocWinding( 3 ); w->numpoints = 3; - VectorCopy( mesh->verts[ pw[ r + 0 ] ].xyz, w->p[ 0 ] ); - VectorCopy( mesh->verts[ pw[ r + 2 ] ].xyz, w->p[ 1 ] ); - VectorCopy( mesh->verts[ pw[ r + 3 ] ].xyz, w->p[ 2 ] ); + w->p[ 0 ] = mesh->verts[ pw[ r + 0 ] ].xyz; + w->p[ 1 ] = mesh->verts[ pw[ r + 2 ] ].xyz; + w->p[ 2 ] = mesh->verts[ pw[ r + 3 ] ].xyz; ProjectDecalOntoWinding( dp, ds, w ); } } @@ -760,12 +709,7 @@ static void ProjectDecalOntoPatch( decalProjector_t *dp, mapDrawSurface_t *ds ){ */ static void ProjectDecalOntoTriangles( decalProjector_t *dp, mapDrawSurface_t *ds ){ - int i; - vec4_t plane; - float d; - winding_t *w; - - + /* triangle surfaces without shaders don't get marks by default */ if ( ds->type == ESurfaceType::Triangles && ds->shaderInfo->shaderText == NULL ) { return; @@ -773,23 +717,22 @@ static void ProjectDecalOntoTriangles( decalProjector_t *dp, mapDrawSurface_t *d /* backface check */ if ( ds->planar ) { - VectorCopy( mapplanes[ ds->planeNum ].normal, plane ); - plane[ 3 ] = mapplanes[ ds->planeNum ].dist + DotProduct( plane, entityOrigin ); - d = DotProduct( dp->planes[ 0 ], plane ); - if ( d < -0.0001f ) { + Plane3f plane = mapplanes[ ds->planeNum ].plane; + plane.dist() += vector3_dot( plane.normal(), entityOrigin ); + if ( vector3_dot( dp->planes[ 0 ].normal(), plane.normal() ) < -0.0001f ) { return; } } /* iterate through triangles */ - for ( i = 0; i < ds->numIndexes; i += 3 ) + for ( int i = 0; i < ds->numIndexes; i += 3 ) { /* generate decal */ - w = AllocWinding( 3 ); + winding_t *w = AllocWinding( 3 ); w->numpoints = 3; - VectorCopy( ds->verts[ ds->indexes[ i ] ].xyz, w->p[ 0 ] ); - VectorCopy( ds->verts[ ds->indexes[ i + 1 ] ].xyz, w->p[ 1 ] ); - VectorCopy( ds->verts[ ds->indexes[ i + 2 ] ].xyz, w->p[ 2 ] ); + w->p[ 0 ] = ds->verts[ ds->indexes[ i ] ].xyz; + w->p[ 1 ] = ds->verts[ ds->indexes[ i + 1 ] ].xyz; + w->p[ 2 ] = ds->verts[ ds->indexes[ i + 2 ] ].xyz; ProjectDecalOntoWinding( dp, ds, w ); } } @@ -805,17 +748,14 @@ void MakeEntityDecals( entity_t *e ){ int i, j, k, f, fOld, start; decalProjector_t dp; mapDrawSurface_t *ds; - vec3_t identityAxis[ 3 ] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }; + Vector3 identityAxis[ 3 ] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z }; /* note it */ Sys_FPrintf( SYS_VRB, "--- MakeEntityDecals ---\n" ); - /* set entity origin */ - VectorCopy( e->origin, entityOrigin ); - /* transform projector instead of geometry */ - VectorClear( entityOrigin ); + entityOrigin.set( 0 ); /* init pacifier */ fOld = -1; @@ -850,8 +790,8 @@ void MakeEntityDecals( entity_t *e ){ /* bounds check */ for ( k = 0; k < 3; k++ ) - if ( ds->mins[ k ] >= ( dp.center[ k ] + dp.radius ) || - ds->maxs[ k ] <= ( dp.center[ k ] - dp.radius ) ) { + if ( ds->minmax.mins[ k ] >= ( dp.center[ k ] + dp.radius ) || + ds->minmax.maxs[ k ] <= ( dp.center[ k ] - dp.radius ) ) { break; } if ( k < 3 ) { diff --git a/tools/quake3/q3map2/facebsp.cpp b/tools/quake3/q3map2/facebsp.cpp index 6acd6d3d..648b0f16 100644 --- a/tools/quake3/q3map2/facebsp.cpp +++ b/tools/quake3/q3map2/facebsp.cpp @@ -71,11 +71,8 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, face_t *check; face_t *bestSplit; int splits, facing, front, back; - int side; - plane_t *plane; int value, bestValue; int i; - vec3_t normal; float dist; int planenum; float sizeBias; @@ -96,11 +93,9 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, if ( blockSize[ i ] <= 0 ) { continue; } - dist = blockSize[ i ] * ( floor( node->mins[ i ] / blockSize[ i ] ) + 1 ); - if ( node->maxs[ i ] > dist ) { - VectorClear( normal ); - normal[ i ] = 1; - planenum = FindFloatPlane( normal, dist, 0, NULL ); + dist = blockSize[ i ] * ( floor( node->minmax.mins[ i ] / blockSize[ i ] ) + 1 ); + if ( node->minmax.maxs[ i ] > dist ) { + planenum = FindFloatPlane( g_vector3_axes[i], dist, 0, NULL ); *splitPlaneNum = planenum; return; } @@ -120,7 +115,7 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, //if ( split->checked ) // continue; - plane = &mapplanes[ split->planenum ]; + const plane_t& plane = mapplanes[ split->planenum ]; splits = 0; facing = 0; front = 0; @@ -131,14 +126,14 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, //check->checked = true; // won't need to test this plane again continue; } - side = WindingOnPlaneSide( check->w, plane->normal, plane->dist ); - if ( side == SIDE_CROSS ) { + const EPlaneSide side = WindingOnPlaneSide( check->w, plane.plane ); + if ( side == eSideCross ) { splits++; } - else if ( side == SIDE_FRONT ) { + else if ( side == eSideFront ) { front++; } - else if ( side == SIDE_BACK ) { + else if ( side == eSideBack ) { back++; } } @@ -151,7 +146,7 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, //Base score = 20000 perfectly balanced value = 20000 - ( abs( front - back ) ); - value -= plane->counter; // If we've already used this plane sometime in the past try not to use it again + value -= plane.counter; // If we've already used this plane sometime in the past try not to use it again value -= facing ; // if we're going to have alot of other surfs use this plane, we want to get it in quickly. value -= splits * 5; //more splits = bad value += sizeBias * 10; //We want a huge score bias based on plane size @@ -159,7 +154,7 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, else { value = 5 * facing - 5 * splits; // - abs(front-back); - if ( plane->type < 3 ) { + if ( plane.type < ePlaneNonAxial ) { value += 5; // axial is better } } @@ -231,8 +226,6 @@ int CountFaceList( face_t *list ){ void BuildFaceTree_r( node_t *node, face_t *list ){ face_t *split; face_t *next; - int side; - plane_t *plane; face_t *newFace; face_t *childLists[2]; winding_t *frontWinding, *backWinding; @@ -261,7 +254,7 @@ void BuildFaceTree_r( node_t *node, face_t *list ){ node->planenum = splitPlaneNum; node->compileFlags = compileFlags; node->has_structural_children = !( compileFlags & C_DETAIL ) && !node->opaque; - plane = &mapplanes[ splitPlaneNum ]; + const plane_t& plane = mapplanes[ splitPlaneNum ]; childLists[0] = NULL; childLists[1] = NULL; @@ -283,11 +276,11 @@ void BuildFaceTree_r( node_t *node, face_t *list ){ #endif /* determine which side the face falls on */ - side = WindingOnPlaneSide( split->w, plane->normal, plane->dist ); + const EPlaneSide side = WindingOnPlaneSide( split->w, plane.plane ); /* switch on side */ - if ( side == SIDE_CROSS ) { - ClipWindingEpsilonStrict( split->w, plane->normal, plane->dist, CLIP_EPSILON * 2, + if ( side == eSideCross ) { + ClipWindingEpsilonStrict( split->w, plane.plane, CLIP_EPSILON * 2, &frontWinding, &backWinding ); /* strict; if no winding is left, we have a "virtually identical" plane and don't want to split by it */ if ( frontWinding ) { newFace = AllocBspFace(); @@ -309,11 +302,11 @@ void BuildFaceTree_r( node_t *node, face_t *list ){ } FreeBspFace( split ); } - else if ( side == SIDE_FRONT ) { + else if ( side == eSideFront ) { split->next = childLists[0]; childLists[0] = split; } - else if ( side == SIDE_BACK ) { + else if ( side == eSideBack ) { split->next = childLists[1]; childLists[1] = split; } @@ -324,19 +317,18 @@ void BuildFaceTree_r( node_t *node, face_t *list ){ for ( i = 0 ; i < 2 ; i++ ) { node->children[i] = AllocNode(); node->children[i]->parent = node; - VectorCopy( node->mins, node->children[i]->mins ); - VectorCopy( node->maxs, node->children[i]->maxs ); + node->children[i]->minmax = node->minmax; } for ( i = 0 ; i < 3 ; i++ ) { - if ( plane->normal[i] == 1 ) { - node->children[0]->mins[i] = plane->dist; - node->children[1]->maxs[i] = plane->dist; + if ( plane.normal()[i] == 1 ) { + node->children[0]->minmax.mins[i] = plane.dist(); + node->children[1]->minmax.maxs[i] = plane.dist(); break; } - if ( plane->normal[i] == -1 ) { - node->children[0]->maxs[i] = -plane->dist; - node->children[1]->mins[i] = -plane->dist; + if ( plane.normal()[i] == -1 ) { + node->children[0]->minmax.maxs[i] = -plane.dist(); + node->children[1]->minmax.mins[i] = -plane.dist(); break; } } @@ -386,7 +378,7 @@ tree_t *FaceBSP( face_t *list ) { count++; for ( i = 0; i < face->w->numpoints; i++ ) { - AddPointToBounds( face->w->p[ i ], tree->mins, tree->maxs ); + tree->minmax.extend( face->w->p[ i ] ); } } Sys_FPrintf( SYS_VRB, "%9d faces\n", count ); @@ -397,8 +389,7 @@ tree_t *FaceBSP( face_t *list ) { } tree->headnode = AllocNode(); - VectorCopy( tree->mins, tree->headnode->mins ); - VectorCopy( tree->maxs, tree->headnode->maxs ); + tree->headnode->minmax = tree->minmax; c_faceLeafs = 0; BuildFaceTree_r( tree->headnode, list ); diff --git a/tools/quake3/q3map2/fog.cpp b/tools/quake3/q3map2/fog.cpp index 78849fc2..ec71ddf0 100644 --- a/tools/quake3/q3map2/fog.cpp +++ b/tools/quake3/q3map2/fog.cpp @@ -63,7 +63,7 @@ mesh_t *DrawSurfToMesh( mapDrawSurface_t *ds ){ chops a mesh by a plane */ -void SplitMeshByPlane( mesh_t *in, vec3_t normal, float dist, mesh_t **front, mesh_t **back ){ +void SplitMeshByPlane( mesh_t *in, const Plane3f& plane, mesh_t **front, mesh_t **back ){ int w, h, split; float d[MAX_PATCH_SIZE][MAX_PATCH_SIZE]; bspDrawVert_t *dv, *v1, *v2; @@ -80,7 +80,7 @@ void SplitMeshByPlane( mesh_t *in, vec3_t normal, float dist, mesh_t **front, me c_on = 0; for ( h = 0 ; h < in->height ; h++ ) { for ( w = 0 ; w < in->width ; w++, dv++ ) { - d[h][w] = DotProduct( dv->xyz, normal ) - dist; + d[h][w] = plane3_distance_to_point( plane, dv->xyz ); if ( d[h][w] > ON_EPSILON ) { c_front++; } @@ -247,7 +247,6 @@ void SplitMeshByPlane( mesh_t *in, vec3_t normal, float dist, mesh_t **front, me bool ChopPatchSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){ int i, j; side_t *s; - plane_t *plane; mesh_t *outside[MAX_BRUSH_SIDES]; int numOutside; mesh_t *m, *front, *back; @@ -261,9 +260,9 @@ bool ChopPatchSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){ for ( i = 4 ; i <= 5 ; i++ ) { s = &b->sides[ i ]; - plane = &mapplanes[ s->planenum ]; + const plane_t& plane = mapplanes[ s->planenum ]; - SplitMeshByPlane( m, plane->normal, plane->dist, &front, &back ); + SplitMeshByPlane( m, plane.plane, &front, &back ); if ( !back ) { // nothing actually contained inside @@ -340,14 +339,14 @@ winding_t *WindingFromDrawSurf( mapDrawSurface_t *ds ){ // (actually send the whole draw surface would be cool?) if ( ds->numVerts >= MAX_POINTS_ON_WINDING ) { int max = ds->numVerts; - vec3_t p[256]; + Vector3 p[256]; if ( max > 256 ) { max = 256; } for ( i = 0 ; i < max ; i++ ) { - VectorCopy( ds->verts[i].xyz, p[i] ); + p[i] = ds->verts[i].xyz; } xml_Winding( "WindingFromDrawSurf failed: MAX_POINTS_ON_WINDING exceeded", p, max, true ); @@ -356,7 +355,7 @@ winding_t *WindingFromDrawSurf( mapDrawSurface_t *ds ){ w = AllocWinding( ds->numVerts ); w->numpoints = ds->numVerts; for ( i = 0 ; i < ds->numVerts ; i++ ) { - VectorCopy( ds->verts[i].xyz, w->p[i] ); + w->p[i] = ds->verts[i].xyz; } return w; } @@ -371,7 +370,6 @@ winding_t *WindingFromDrawSurf( mapDrawSurface_t *ds ){ bool ChopFaceSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){ int i, j; side_t *s; - plane_t *plane; winding_t *w; winding_t *front, *back; winding_t *outside[ MAX_BRUSH_SIDES ]; @@ -393,7 +391,7 @@ bool ChopFaceSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){ { /* get brush side and plane */ s = &b->sides[ i ]; - plane = &mapplanes[ s->planenum ]; + const plane_t& plane = mapplanes[ s->planenum ]; /* handle coplanar outfacing (don't fog) */ if ( ds->sideRef->side->planenum == s->planenum ) { @@ -406,7 +404,7 @@ bool ChopFaceSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){ } /* general case */ - ClipWindingEpsilonStrict( w, plane->normal, plane->dist, ON_EPSILON, &front, &back ); /* strict; if plane is "almost identical" to face, both ways to continue can be wrong, so we better not fog it */ + ClipWindingEpsilonStrict( w, plane.plane, ON_EPSILON, &front, &back ); /* strict; if plane is "almost identical" to face, both ways to continue can be wrong, so we better not fog it */ FreeWinding( w ); if ( back == NULL ) { @@ -468,10 +466,9 @@ bool ChopFaceSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){ */ void FogDrawSurfaces( entity_t *e ){ - int i, j, k, fogNum; + int i, j, fogNum; fog_t *fog; mapDrawSurface_t *ds; - vec3_t mins, maxs; int fogged, numFogged; int numBaseDrawSurfs; @@ -512,24 +509,13 @@ void FogDrawSurfaces( entity_t *e ){ else { /* find drawsurface bounds */ - ClearBounds( mins, maxs ); + MinMax minmax; for ( j = 0; j < ds->numVerts; j++ ) - AddPointToBounds( ds->verts[ j ].xyz, mins, maxs ); + minmax.extend( ds->verts[ j ].xyz ); /* check against the fog brush */ - for ( k = 0; k < 3; k++ ) - { - if ( mins[ k ] > fog->brush->maxs[ k ] ) { - break; - } - if ( maxs[ k ] < fog->brush->mins[ k ] ) { - break; - } - } - - /* no intersection? */ - if ( k < 3 ) { - continue; + if( !minmax.test( fog->brush->minmax ) ){ + continue; /* no intersection */ } /* ydnar: gs mods: handle the various types of surfaces */ @@ -580,12 +566,10 @@ void FogDrawSurfaces( entity_t *e ){ gets the fog number for a point in space */ -int FogForPoint( vec3_t point, float epsilon ){ +int FogForPoint( const Vector3& point, float epsilon ){ int fogNum, i, j; - float dot; bool inside; brush_t *brush; - plane_t *plane; /* start with bogus fog num */ @@ -607,10 +591,7 @@ int FogForPoint( vec3_t point, float epsilon ){ inside = true; for ( j = 0; j < brush->numsides && inside; j++ ) { - plane = &mapplanes[ brush->sides[ j ].planenum ]; /* note usage of map planes here */ - dot = DotProduct( point, plane->normal ); - dot -= plane->dist; - if ( dot > epsilon ) { + if ( plane3_distance_to_point( mapplanes[ brush->sides[ j ].planenum ].plane, point ) > epsilon ) { inside = false; } } @@ -633,18 +614,14 @@ int FogForPoint( vec3_t point, float epsilon ){ gets the fog number for a bounding box */ -int FogForBounds( vec3_t mins, vec3_t maxs, float epsilon ){ - int fogNum, i, j; - float highMin, lowMax, volume, bestVolume; - vec3_t fogMins, fogMaxs, overlap; - brush_t *brush; - +int FogForBounds( const MinMax& minmax, float epsilon ){ + int fogNum, i; /* start with bogus fog num */ fogNum = defaultFogNum; /* init */ - bestVolume = 0.0f; + float bestVolume = 0.0f; /* walk the list of fog volumes */ for ( i = 0; i < numMapFogs; i++ ) @@ -656,37 +633,21 @@ int FogForBounds( vec3_t mins, vec3_t maxs, float epsilon ){ } /* get fog brush */ - brush = mapFogs[ i ].brush; + brush_t *brush = mapFogs[ i ].brush; /* get bounds */ - fogMins[ 0 ] = brush->mins[ 0 ] - epsilon; - fogMins[ 1 ] = brush->mins[ 1 ] - epsilon; - fogMins[ 2 ] = brush->mins[ 2 ] - epsilon; - fogMaxs[ 0 ] = brush->maxs[ 0 ] + epsilon; - fogMaxs[ 1 ] = brush->maxs[ 1 ] + epsilon; - fogMaxs[ 2 ] = brush->maxs[ 2 ] + epsilon; - + const MinMax fogMinmax( brush->minmax.mins - Vector3( epsilon, epsilon, epsilon ), + brush->minmax.maxs + Vector3( epsilon, epsilon, epsilon ) ); /* check against bounds */ - for ( j = 0; j < 3; j++ ) - { - if ( mins[ j ] > fogMaxs[ j ] || maxs[ j ] < fogMins[ j ] ) { - break; - } - highMin = mins[ j ] > fogMins[ j ] ? mins[ j ] : fogMins[ j ]; - lowMax = maxs[ j ] < fogMaxs[ j ] ? maxs[ j ] : fogMaxs[ j ]; - overlap[ j ] = lowMax - highMin; - if ( overlap[ j ] < 1.0f ) { - overlap[ j ] = 1.0f; - } - } - - /* no overlap */ - if ( j < 3 ) { - continue; + if( !minmax.test( fogMinmax ) ){ + continue; /* no overlap */ } + const Vector3 overlap( std::max( 1.f, std::min( minmax.maxs[0], fogMinmax.maxs[0] ) - std::max( minmax.mins[0], fogMinmax.mins[0] ) ), + std::max( 1.f, std::min( minmax.maxs[1], fogMinmax.maxs[1] ) - std::max( minmax.mins[1], fogMinmax.mins[1] ) ), + std::max( 1.f, std::min( minmax.maxs[2], fogMinmax.maxs[2] ) - std::max( minmax.mins[2], fogMinmax.mins[2] ) ) ); /* get volume */ - volume = overlap[ 0 ] * overlap[ 1 ] * overlap[ 2 ]; + const float volume = overlap[0] * overlap[1] * overlap[2]; /* test against best volume */ if ( volume > bestVolume ) { @@ -710,7 +671,6 @@ void CreateMapFogs( void ){ int j; brush_t *brush; fog_t *fog; - vec3_t invFogDir; /* skip? */ @@ -744,14 +704,14 @@ void CreateMapFogs( void ){ fog->visibleSide = -1; /* if shader specifies an explicit direction, then find a matching brush side with an opposed normal */ - if ( VectorLength( fog->si->fogDir ) ) { + if ( vector3_length( fog->si->fogDir ) ) { /* flip it */ - VectorScale( fog->si->fogDir, -1.0f, invFogDir ); + const Vector3 invFogDir = -fog->si->fogDir; /* find the brush side */ for ( j = 0; j < brush->numsides; j++ ) { - if ( VectorCompare( invFogDir, mapplanes[ brush->sides[ j ].planenum ].normal ) ) { + if ( VectorCompare( invFogDir, mapplanes[ brush->sides[ j ].planenum ].normal() ) ) { fog->visibleSide = j; //% Sys_Printf( "Brush num: %d Side num: %d\n", fog->brushNum, fog->visibleSide ); break; diff --git a/tools/quake3/q3map2/leakfile.cpp b/tools/quake3/q3map2/leakfile.cpp index 76b885d2..63719255 100644 --- a/tools/quake3/q3map2/leakfile.cpp +++ b/tools/quake3/q3map2/leakfile.cpp @@ -55,7 +55,7 @@ ============= */ xmlNodePtr LeakFile( tree_t *tree ){ - vec3_t mid; + Vector3 mid; FILE *linefile; node_t *node; int count; @@ -97,7 +97,7 @@ xmlNodePtr LeakFile( tree_t *tree ){ } } node = nextnode; - WindingCenter( nextportal->winding, mid ); + mid = WindingCenter( nextportal->winding ); fprintf( linefile, "%f %f %f\n", mid[0], mid[1], mid[2] ); point = xml_NodeForVec( mid ); xmlAddChild( xml_node, point ); diff --git a/tools/quake3/q3map2/light.cpp b/tools/quake3/q3map2/light.cpp index 500adcfe..b1e249bf 100644 --- a/tools/quake3/q3map2/light.cpp +++ b/tools/quake3/q3map2/light.cpp @@ -41,7 +41,7 @@ static void CreateSunLight( sun_t *sun ){ int i; float photons, d, angle, elevation, da, de; - vec3_t direction; + Vector3 direction; light_t *light; @@ -63,7 +63,7 @@ static void CreateSunLight( sun_t *sun ){ { /* calculate sun direction */ if ( i == 0 ) { - VectorCopy( sun->direction, direction ); + direction = sun->direction; } else { @@ -92,7 +92,7 @@ static void CreateSunLight( sun_t *sun ){ elevation += de; /* debug code */ - //% Sys_Printf( "%d: Angle: %3.4f Elevation: %3.3f\n", sun->numSamples, (angle / Q_PI * 180.0f), (elevation / Q_PI * 180.0f) ); + //% Sys_Printf( "%d: Angle: %3.4lf Elevation: %3.3lf\n", sun->numSamples, radians_to_degrees( angle ), radians_to_degrees( elevation ) ); /* create new vector */ direction[ 0 ] = cos( angle ) * cos( elevation ); @@ -115,14 +115,14 @@ static void CreateSunLight( sun_t *sun ){ light->style = noStyles ? LS_NORMAL : sun->style; /* set the light's position out to infinity */ - VectorMA( vec3_origin, ( MAX_WORLD_COORD * 8.0f ), direction, light->origin ); /* MAX_WORLD_COORD * 2.0f */ + light->origin = -direction * ( MAX_WORLD_COORD * 8.0f ); /* MAX_WORLD_COORD * 2.0f */ /* set the facing to be the inverse of the sun direction */ - VectorScale( direction, -1.0, light->normal ); - light->dist = DotProduct( light->origin, light->normal ); + light->normal = -direction; + light->dist = vector3_dot( light->origin, light->normal ); /* set color and photons */ - VectorCopy( sun->color, light->color ); + light->color = sun->color; light->photons = photons * skyScale; } @@ -139,7 +139,7 @@ static void CreateSunLight( sun_t *sun ){ simulates sky light with multiple suns */ -static void CreateSkyLights( vec3_t color, float value, int iterations, float filterRadius, int style ){ +static void CreateSkyLights( const Vector3& color, float value, int iterations, float filterRadius, int style ){ int i, j, numSuns; int angleSteps, elevationSteps; float angle, elevation; @@ -153,7 +153,7 @@ static void CreateSkyLights( vec3_t color, float value, int iterations, float fi } /* basic sun setup */ - VectorCopy( color, sun.color ); + sun.color = color; sun.deviance = 0.0f; sun.filterRadius = filterRadius; sun.numSamples = 1; @@ -164,8 +164,8 @@ static void CreateSkyLights( vec3_t color, float value, int iterations, float fi elevationSteps = iterations - 1; angleSteps = elevationSteps * 4; angle = 0.0f; - elevationStep = DEG2RAD( 90.0f / iterations ); /* skip elevation 0 */ - angleStep = DEG2RAD( 360.0f / angleSteps ); + elevationStep = degrees_to_radians( 90.0f / iterations ); /* skip elevation 0 */ + angleStep = degrees_to_radians( 360.0f / angleSteps ); /* calc individual sun brightness */ numSuns = angleSteps * elevationSteps + 1; @@ -195,7 +195,7 @@ static void CreateSkyLights( vec3_t color, float value, int iterations, float fi } /* create vertical sun */ - VectorSet( sun.direction, 0.0f, 0.0f, 1.0f ); + sun.direction = g_vector3_axis_z; CreateSunLight( &sun ); /* short circuit */ @@ -371,11 +371,11 @@ void CreateEntityLights( void ){ light->color[2] = Image_LinearFloatFromsRGBFloat( light->color[2] ); } if ( !( light->flags & LightFlags::Unnormalized ) ) { - ColorNormalize( light->color, light->color ); + ColorNormalize( light->color ); } } else{ - VectorSet( light->color, 1.f, 1.f, 1.f ); + light->color.set( 1 ); } @@ -406,10 +406,10 @@ void CreateEntityLights( void ){ numSpotLights++; /* make a spotlight */ - vec3_t dest; + Vector3 dest; e2->vectorForKey( "origin", dest ); - VectorSubtract( dest, light->origin, light->normal ); - float dist = VectorNormalize( light->normal, light->normal ); + light->normal = dest - light->origin; + float dist = VectorNormalize( light->normal ); float radius = e->floatForKey( "radius" ); if ( !radius ) { radius = 64; @@ -435,10 +435,10 @@ void CreateEntityLights( void ){ /* make a sun */ sun_t sun; - VectorScale( light->normal, -1.0f, sun.direction ); - VectorCopy( light->color, sun.color ); + sun.direction = -light->normal; + sun.color = light->color; sun.photons = intensity; - sun.deviance = deviance / 180.0f * Q_PI; + sun.deviance = degrees_to_radians( deviance ); sun.numSamples = numSamples; sun.style = noStyles ? LS_NORMAL : light->style; sun.next = NULL; @@ -504,7 +504,6 @@ void CreateSurfaceLights( void ){ shaderInfo_t *si; light_t *light; float subdivide; - vec3_t origin; clipWork_t cw; @@ -540,10 +539,6 @@ void CreateSurfaceLights( void ){ /* autosprite shaders become point lights */ if ( si->autosprite ) { - /* create an average xyz */ - VectorAdd( info->mins, info->maxs, origin ); - VectorScale( origin, 0.5f, origin ); - /* create a light */ light = safe_calloc( sizeof( *light ) ); light->next = lights; @@ -555,8 +550,8 @@ void CreateSurfaceLights( void ){ light->photons = si->value * pointScale; light->fade = 1.0f; light->si = si; - VectorCopy( origin, light->origin ); - VectorCopy( si->color, light->color ); + light->origin = info->minmax.origin(); + light->color = si->color; light->falloffTolerance = falloffTolerance; light->style = si->lightStyle; @@ -622,7 +617,7 @@ void SetEntityOrigins( void ){ dm = &bspModels[ modelnum ]; /* get entity origin */ - vec3_t origin = { 0.f, 0.f, 0.f }; + Vector3 origin( 0, 0, 0 ); if ( !e.read_keyvalue( origin, "origin" ) ) { continue; } @@ -637,7 +632,7 @@ void SetEntityOrigins( void ){ for ( k = 0; k < ds->numVerts; k++ ) { f = ds->firstVert + k; - VectorAdd( origin, bspDrawVerts[ f ].xyz, yDrawVerts[ f ].xyz ); + yDrawVerts[ f ].xyz = origin + bspDrawVerts[ f ].xyz; } } } @@ -656,10 +651,9 @@ void SetEntityOrigins( void ){ #define ONE_OVER_2PI 0.159154942f //% (1.0f / (2.0f * 3.141592657f)) -float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const winding_t *w ){ - vec3_t triVector, triNormal; +float PointToPolygonFormFactor( const Vector3& point, const Vector3& normal, const winding_t *w ){ int i, j; - vec3_t dirs[ MAX_POINTS_ON_WINDING ]; + Vector3 dirs[ MAX_POINTS_ON_WINDING ]; float total; float dot, angle, facing; @@ -667,12 +661,12 @@ float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const w /* this is expensive */ for ( i = 0; i < w->numpoints; i++ ) { - VectorSubtract( w->p[ i ], point, dirs[ i ] ); - VectorFastNormalize( dirs[ i ], dirs[ i ] ); + dirs[ i ] = w->p[ i ] - point; + VectorFastNormalize( dirs[ i ] ); } /* duplicate first vertex to avoid mod operation */ - VectorCopy( dirs[ 0 ], dirs[ i ] ); + dirs[ i ] = dirs[ 0 ]; /* calculcate relative area */ total = 0.0f; @@ -680,7 +674,7 @@ float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const w { /* get a triangle */ j = i + 1; - dot = DotProduct( dirs[ i ], dirs[ j ] ); + dot = vector3_dot( dirs[ i ], dirs[ j ] ); /* roundoff can cause slight creep, which gives an IND from acos */ if ( dot > 1.0f ) { @@ -693,12 +687,12 @@ float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const w /* get the angle */ angle = acos( dot ); - CrossProduct( dirs[ i ], dirs[ j ], triVector ); - if ( VectorFastNormalize( triVector, triNormal ) < 0.0001f ) { + Vector3 triNormal = vector3_cross( dirs[ i ], dirs[ j ] ); + if ( VectorFastNormalize( triNormal ) < 0.0001f ) { continue; } - facing = DotProduct( normal, triNormal ); + facing = vector3_dot( normal, triNormal ); total += facing * angle; /* ydnar: this was throwing too many errors with radiosity + crappy maps. ignoring it. */ @@ -735,9 +729,9 @@ int LightContributionToSample( trace_t *trace ){ /* clear color */ trace->forceSubsampling = 0.0f; /* to make sure */ - VectorClear( trace->color ); - VectorClear( trace->colorNoShadow ); - VectorClear( trace->directionContribution ); + trace->color.set( 0 ); + trace->colorNoShadow.set( 0 ); + trace->directionContribution.set( 0 ); colorBrightness = RGBTOGRAY( light->color ) * ( 1.0f / 255.0f ); @@ -750,7 +744,7 @@ int LightContributionToSample( trace_t *trace ){ if ( light->type != ELightType::Sun ) { /* MrE: if the light is behind the surface */ if ( !trace->twoSided ) { - if ( DotProduct( light->origin, trace->normal ) - DotProduct( trace->origin, trace->normal ) < 0.0f ) { + if ( vector3_dot( light->origin, trace->normal ) - vector3_dot( trace->origin, trace->normal ) < 0.0f ) { return 0; } } @@ -765,10 +759,10 @@ int LightContributionToSample( trace_t *trace ){ if ( light->type == ELightType::Area ) { float factor; float d; - vec3_t pushedOrigin; + Vector3 pushedOrigin; /* project sample point into light plane */ - d = DotProduct( trace->origin, light->normal ) - light->dist; + d = vector3_dot( trace->origin, light->normal ) - light->dist; if ( d < 3.0f ) { /* sample point behind plane? */ if ( !( light->flags & LightFlags::Twosided ) && d < -1.0f ) { @@ -776,7 +770,7 @@ int LightContributionToSample( trace_t *trace ){ } /* sample plane coincident? */ - if ( d > -3.0f && DotProduct( trace->normal, light->normal ) > 0.9f ) { + if ( d > -3.0f && vector3_dot( trace->normal, light->normal ) > 0.9f ) { return 0; } } @@ -784,14 +778,14 @@ int LightContributionToSample( trace_t *trace ){ /* nudge the point so that it is clearly forward of the light */ /* so that surfaces meeting a light emitter don't get black edges */ if ( d > -8.0f && d < 8.0f ) { - VectorMA( trace->origin, ( 8.0f - d ), light->normal, pushedOrigin ); + pushedOrigin = trace->origin + light->normal * ( 8.0f - d ); } else{ - VectorCopy( trace->origin, pushedOrigin ); + pushedOrigin = trace->origin; } /* get direction and distance */ - VectorCopy( light->origin, trace->end ); + trace->end = light->origin; dist = SetupTrace( trace ); if ( dist >= light->envelope ) { return 0; @@ -800,7 +794,7 @@ int LightContributionToSample( trace_t *trace ){ /* ptpff approximation */ if ( faster ) { /* angle attenuation */ - angle = DotProduct( trace->normal, trace->direction ); + angle = vector3_dot( trace->normal, trace->direction ); /* twosided lighting */ if ( trace->twoSided && angle < 0 ) { @@ -811,7 +805,7 @@ int LightContributionToSample( trace_t *trace ){ } /* attenuate */ - angle *= -DotProduct( light->normal, trace->direction ); + angle *= -vector3_dot( light->normal, trace->direction ); if ( angle == 0.0f ) { return 0; } @@ -853,7 +847,7 @@ int LightContributionToSample( trace_t *trace ){ factor = -factor; /* push light origin to other side of the plane */ - VectorMA( light->origin, -2.0f, light->normal, trace->end ); + trace->end = light->origin - light->normal * 2.f; dist = SetupTrace( trace ); if ( dist >= light->envelope ) { return 0; @@ -868,7 +862,7 @@ int LightContributionToSample( trace_t *trace ){ } /* also don't deluxe if the direction is on the wrong side */ - if ( DotProduct( trace->normal, trace->direction ) < 0 ) { + if ( vector3_dot( trace->normal, trace->direction ) < 0 ) { /* no deluxemap contribution from "other side" light */ doAddDeluxe = false; } @@ -885,7 +879,7 @@ int LightContributionToSample( trace_t *trace ){ /* point/spot lights */ else if ( light->type == ELightType::Point || light->type == ELightType::Spot ) { /* get direction and distance */ - VectorCopy( light->origin, trace->end ); + trace->end = light->origin; dist = SetupTrace( trace ); if ( dist >= light->envelope ) { return 0; @@ -900,7 +894,7 @@ int LightContributionToSample( trace_t *trace ){ /* angle attenuation */ if ( light->flags & LightFlags::AttenAngle ) { /* standard Lambert attenuation */ - float dot = DotProduct( trace->normal, trace->direction ); + float dot = vector3_dot( trace->normal, trace->direction ); /* twosided lighting */ if ( trace->twoSided && dot < 0 ) { @@ -980,18 +974,15 @@ int LightContributionToSample( trace_t *trace ){ /* handle spotlights */ if ( light->type == ELightType::Spot ) { - float distByNormal, radiusAtDist, sampleRadius; - vec3_t pointAtDist, distToSample; - /* do cone calculation */ - distByNormal = -DotProduct( trace->displacement, light->normal ); + const float distByNormal = -vector3_dot( trace->displacement, light->normal ); if ( distByNormal < 0.0f ) { return 0; } - VectorMA( light->origin, distByNormal, light->normal, pointAtDist ); - radiusAtDist = light->radiusByDist * distByNormal; - VectorSubtract( trace->origin, pointAtDist, distToSample ); - sampleRadius = VectorLength( distToSample ); + const Vector3 pointAtDist = light->origin + light->normal * distByNormal; + const float radiusAtDist = light->radiusByDist * distByNormal; + const Vector3 distToSample = trace->origin - pointAtDist; + const float sampleRadius = vector3_length( distToSample ); /* outside the cone */ if ( sampleRadius >= radiusAtDist ) { @@ -1017,13 +1008,13 @@ int LightContributionToSample( trace_t *trace ){ /* ydnar: sunlight */ else if ( light->type == ELightType::Sun ) { /* get origin and direction */ - VectorAdd( trace->origin, light->origin, trace->end ); + trace->end = trace->origin + light->origin; dist = SetupTrace( trace ); /* angle attenuation */ if ( light->flags & LightFlags::AttenAngle ) { /* standard Lambert attenuation */ - float dot = DotProduct( trace->normal, trace->direction ); + float dot = vector3_dot( trace->normal, trace->direction ); /* twosided lighting */ if ( trace->twoSided && dot < 0 ) { @@ -1074,7 +1065,7 @@ int LightContributionToSample( trace_t *trace ){ } /* VorteX: set noShadow color */ - VectorScale( light->color, add, trace->colorNoShadow ); + trace->colorNoShadow = light->color * add; addDeluxe *= colorBrightness; @@ -1085,11 +1076,11 @@ int LightContributionToSample( trace_t *trace ){ } } - VectorScale( trace->direction, addDeluxe, trace->directionContribution ); + trace->directionContribution = trace->direction * addDeluxe; /* setup trace */ trace->testAll = true; - VectorScale( light->color, add, trace->color ); + trace->color = light->color * add; /* trace to point */ if ( trace->testOcclusion && !trace->forceSunlight ) { @@ -1097,8 +1088,8 @@ int LightContributionToSample( trace_t *trace ){ TraceLine( trace ); trace->forceSubsampling *= add; if ( !( trace->compileFlags & C_SKY ) || trace->opaque ) { - VectorClear( trace->color ); - VectorClear( trace->directionContribution ); + trace->color.set( 0 ); + trace->directionContribution.set( 0 ); return -1; } @@ -1112,7 +1103,7 @@ int LightContributionToSample( trace_t *trace ){ } /* VorteX: set noShadow color */ - VectorScale( light->color, add, trace->colorNoShadow ); + trace->colorNoShadow = light->color * add; /* ydnar: changed to a variable number */ if ( add <= 0.0f || ( add <= light->falloffTolerance && ( light->flags & LightFlags::FastActual ) ) ) { @@ -1142,19 +1133,19 @@ int LightContributionToSample( trace_t *trace ){ } if ( doAddDeluxe ) { - VectorScale( trace->direction, addDeluxe, trace->directionContribution ); + trace->directionContribution = trace->direction * addDeluxe; } /* setup trace */ trace->testAll = false; - VectorScale( light->color, add, trace->color ); + trace->color = light->color * add; /* raytrace */ TraceLine( trace ); trace->forceSubsampling *= add; if ( trace->passSolid || trace->opaque ) { - VectorClear( trace->color ); - VectorClear( trace->directionContribution ); + trace->color.set( 0 ); + trace->directionContribution.set( 0 ); return -1; } @@ -1170,13 +1161,13 @@ int LightContributionToSample( trace_t *trace ){ determines the amount of light reaching a sample (luxel or vertex) */ -void LightingAtSample( trace_t *trace, byte styles[ MAX_LIGHTMAPS ], vec3_t colors[ MAX_LIGHTMAPS ] ){ +void LightingAtSample( trace_t *trace, byte styles[ MAX_LIGHTMAPS ], Vector3 (&colors)[ MAX_LIGHTMAPS ] ){ int i, lightmapNum; /* clear colors */ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) - VectorClear( colors[ lightmapNum ] ); + colors[ lightmapNum ].set( 0 ); /* ydnar: normalmap */ if ( normalmap ) { @@ -1188,7 +1179,7 @@ void LightingAtSample( trace_t *trace, byte styles[ MAX_LIGHTMAPS ], vec3_t colo /* ydnar: don't bounce ambient all the time */ if ( !bouncing ) { - VectorCopy( ambientColor, colors[ 0 ] ); + colors[ 0 ] = ambientColor; } /* ydnar: trace to all the list of lights pre-stored in tw */ @@ -1219,14 +1210,14 @@ void LightingAtSample( trace_t *trace, byte styles[ MAX_LIGHTMAPS ], vec3_t colo /* handle negative light */ if ( trace->light->flags & LightFlags::Negative ) { - VectorScale( trace->color, -1.0f, trace->color ); + vector3_negate( trace->color ); } /* set style */ styles[ lightmapNum ] = trace->light->style; /* add it */ - VectorAdd( colors[ lightmapNum ], trace->color, colors[ lightmapNum ] ); + colors[ lightmapNum ] += trace->color; /* cheap mode */ if ( cheap && @@ -1255,7 +1246,7 @@ bool LightContributionToPoint( trace_t *trace ){ light = trace->light; /* clear color */ - VectorClear( trace->color ); + trace->color.set( 0 ); /* ydnar: early out */ if ( !( light->flags & LightFlags::Grid ) || light->envelope <= 0.0f ) { @@ -1276,19 +1267,17 @@ bool LightContributionToPoint( trace_t *trace ){ } /* ydnar: check origin against light's pvs envelope */ - if ( trace->origin[ 0 ] > light->maxs[ 0 ] || trace->origin[ 0 ] < light->mins[ 0 ] || - trace->origin[ 1 ] > light->maxs[ 1 ] || trace->origin[ 1 ] < light->mins[ 1 ] || - trace->origin[ 2 ] > light->maxs[ 2 ] || trace->origin[ 2 ] < light->mins[ 2 ] ) { + if ( !light->minmax.test( trace->origin ) ) { gridBoundsCulled++; return false; } /* set light origin */ if ( light->type == ELightType::Sun ) { - VectorAdd( trace->origin, light->origin, trace->end ); + trace->end = trace->origin + light->origin; } else{ - VectorCopy( light->origin, trace->end ); + trace->end = light->origin; } /* set direction */ @@ -1315,11 +1304,11 @@ bool LightContributionToPoint( trace_t *trace ){ /* exact point to polygon form factor */ else if ( light->type == ELightType::Area ) { float factor, d; - vec3_t pushedOrigin; + Vector3 pushedOrigin; /* see if the point is behind the light */ - d = DotProduct( trace->origin, light->normal ) - light->dist; + d = vector3_dot( trace->origin, light->normal ) - light->dist; if ( !( light->flags & LightFlags::Twosided ) && d < -1.0f ) { return false; } @@ -1327,10 +1316,10 @@ bool LightContributionToPoint( trace_t *trace ){ /* nudge the point so that it is clearly forward of the light */ /* so that surfaces meeting a light emiter don't get black edges */ if ( d > -8.0f && d < 8.0f ) { - VectorMA( trace->origin, ( 8.0f - d ), light->normal, pushedOrigin ); + pushedOrigin = trace->origin + light->normal * ( 8.0f - d ); } else{ - VectorCopy( trace->origin, pushedOrigin ); + pushedOrigin = trace->origin; } /* calculate the contribution (ydnar 2002-10-21: [bug 642] bad normal calc) */ @@ -1372,19 +1361,15 @@ bool LightContributionToPoint( trace_t *trace ){ /* handle spotlights */ if ( light->type == ELightType::Spot ) { - float distByNormal, radiusAtDist, sampleRadius; - vec3_t pointAtDist, distToSample; - - /* do cone calculation */ - distByNormal = -DotProduct( trace->displacement, light->normal ); + const float distByNormal = -vector3_dot( trace->displacement, light->normal ); if ( distByNormal < 0.0f ) { return false; } - VectorMA( light->origin, distByNormal, light->normal, pointAtDist ); - radiusAtDist = light->radiusByDist * distByNormal; - VectorSubtract( trace->origin, pointAtDist, distToSample ); - sampleRadius = VectorLength( distToSample ); + const Vector3 pointAtDist = light->origin + light->normal * distByNormal; + const float radiusAtDist = light->radiusByDist * distByNormal; + const Vector3 distToSample = trace->origin - pointAtDist; + const float sampleRadius = vector3_length( distToSample ); /* outside the cone */ if ( sampleRadius >= radiusAtDist ) { @@ -1408,14 +1393,14 @@ bool LightContributionToPoint( trace_t *trace ){ /* setup trace */ trace->testAll = true; - VectorScale( light->color, add, trace->color ); + trace->color = light->color * add; /* trace to point */ if ( trace->testOcclusion && !trace->forceSunlight ) { /* trace */ TraceLine( trace ); if ( !( trace->compileFlags & C_SKY ) || trace->opaque ) { - VectorClear( trace->color ); + trace->color.set( 0 ); return false; } } @@ -1436,12 +1421,12 @@ bool LightContributionToPoint( trace_t *trace ){ /* setup trace */ trace->testAll = false; - VectorScale( light->color, add, trace->color ); + trace->color = light->color * add; /* trace */ TraceLine( trace ); if ( trace->passSolid ) { - VectorClear( trace->color ); + trace->color.set( 0 ); return false; } @@ -1461,16 +1446,16 @@ bool LightContributionToPoint( trace_t *trace ){ struct contribution_t { - vec3_t dir; - vec3_t color; - vec3_t ambient; + Vector3 dir; + Vector3 color; + Vector3 ambient; int style; }; void TraceGrid( int num ){ int i, j, x, y, z, mod, numCon, numStyles; float d, step; - vec3_t baseOrigin, cheapColor, color, thisdir; + Vector3 cheapColor, thisdir; rawGridPoint_t *gp; bspGridPoint_t *bgp; contribution_t contributions[ MAX_CONTRIBUTIONS ]; @@ -1507,10 +1492,10 @@ void TraceGrid( int num ){ trace.cluster = ClusterForPointExt( trace.origin, GRID_EPSILON ); if ( trace.cluster < 0 ) { /* try to nudge the origin around to find a valid point */ - VectorCopy( trace.origin, baseOrigin ); + const Vector3 baseOrigin( trace.origin ); for ( step = 0; ( step += 0.005 ) <= 1.0; ) { - VectorCopy( baseOrigin, trace.origin ); + trace.origin = baseOrigin; trace.origin[ 0 ] += step * ( Random() - 0.5 ) * gridSize[0]; trace.origin[ 1 ] += step * ( Random() - 0.5 ) * gridSize[1]; trace.origin[ 2 ] += step * ( Random() - 0.5 ) * gridSize[2]; @@ -1539,7 +1524,7 @@ void TraceGrid( int num ){ /* clear */ numCon = 0; - VectorClear( cheapColor ); + cheapColor.set( 0 ); /* trace to all the lights, find the major light direction, and divide the total light between that along the direction and the remaining in the ambient */ @@ -1555,19 +1540,19 @@ void TraceGrid( int num ){ /* handle negative light */ if ( trace.light->flags & LightFlags::Negative ) { - VectorScale( trace.color, -1.0f, trace.color ); + vector3_negate( trace.color ); } /* add a contribution */ - VectorCopy( trace.color, contributions[ numCon ].color ); - VectorCopy( trace.direction, contributions[ numCon ].dir ); - VectorClear( contributions[ numCon ].ambient ); + contributions[ numCon ].color = trace.color; + contributions[ numCon ].dir = trace.direction; + contributions[ numCon ].ambient.set( 0 ); contributions[ numCon ].style = trace.light->style; numCon++; /* push average direction around */ - addSize = VectorLength( trace.color ); - VectorMA( gp->dir, addSize, trace.direction, gp->dir ); + addSize = vector3_length( trace.color ); + gp->dir += trace.direction * addSize; /* stop after a while */ if ( numCon >= ( MAX_CONTRIBUTIONS - 1 ) ) { @@ -1575,7 +1560,7 @@ void TraceGrid( int num ){ } /* ydnar: cheap mode */ - VectorAdd( cheapColor, trace.color, cheapColor ); + cheapColor += trace.color; if ( cheapgrid && cheapColor[ 0 ] >= 255.0f && cheapColor[ 1 ] >= 255.0f && cheapColor[ 2 ] >= 255.0f ) { break; } @@ -1586,7 +1571,7 @@ void TraceGrid( int num ){ if ( floodlighty ) { int k; float addSize, f; - vec3_t dir = { 0, 0, 1 }; + Vector3 dir = g_vector3_axis_z; float ambientFrac = 0.25f; trace.testOcclusion = true; @@ -1597,37 +1582,27 @@ void TraceGrid( int num ){ for ( k = 0; k < 2; k++ ) { if ( k == 0 ) { // upper hemisphere - trace.normal[0] = 0; - trace.normal[1] = 0; - trace.normal[2] = 1; + trace.normal = g_vector3_axis_z; } else //lower hemisphere { - trace.normal[0] = 0; - trace.normal[1] = 0; - trace.normal[2] = -1; + trace.normal = -g_vector3_axis_z; } f = FloodLightForSample( &trace, floodlightDistance, floodlight_lowquality ); /* add a fraction as pure ambient, half as top-down direction */ - contributions[ numCon ].color[0] = floodlightRGB[0] * floodlightIntensity * f * ( 1.0f - ambientFrac ); - contributions[ numCon ].color[1] = floodlightRGB[1] * floodlightIntensity * f * ( 1.0f - ambientFrac ); - contributions[ numCon ].color[2] = floodlightRGB[2] * floodlightIntensity * f * ( 1.0f - ambientFrac ); + contributions[ numCon ].color = floodlightRGB * ( floodlightIntensity * f * ( 1.0f - ambientFrac ) ); - contributions[ numCon ].ambient[0] = floodlightRGB[0] * floodlightIntensity * f * ambientFrac; - contributions[ numCon ].ambient[1] = floodlightRGB[1] * floodlightIntensity * f * ambientFrac; - contributions[ numCon ].ambient[2] = floodlightRGB[2] * floodlightIntensity * f * ambientFrac; + contributions[ numCon ].ambient = floodlightRGB * ( floodlightIntensity * f * ambientFrac ); - contributions[ numCon ].dir[0] = dir[0]; - contributions[ numCon ].dir[1] = dir[1]; - contributions[ numCon ].dir[2] = dir[2]; + contributions[ numCon ].dir = dir; contributions[ numCon ].style = 0; /* push average direction around */ - addSize = VectorLength( contributions[ numCon ].color ); - VectorMA( gp->dir, addSize, dir, gp->dir ); + addSize = vector3_length( contributions[ numCon ].color ); + gp->dir += dir * addSize; numCon++; } @@ -1635,7 +1610,7 @@ void TraceGrid( int num ){ ///////////////////// /* normalize to get primary light direction */ - VectorNormalize( gp->dir, thisdir ); + thisdir = VectorNormalized( gp->dir ); /* now that we have identified the primary light direction, go back and separate all the light into directed and ambient */ @@ -1644,7 +1619,7 @@ void TraceGrid( int num ){ for ( i = 0; i < numCon; i++ ) { /* get relative directed strength */ - d = DotProduct( contributions[ i ].dir, thisdir ); + d = vector3_dot( contributions[ i ].dir, thisdir ); /* we map 1 to gridDirectionality, and 0 to gridAmbientDirectionality */ d = gridAmbientDirectionality + d * ( gridDirectionality - gridAmbientDirectionality ); if ( d < 0.0f ) { @@ -1676,7 +1651,7 @@ void TraceGrid( int num ){ } /* add the directed color */ - VectorMA( gp->directed[ j ], d, contributions[ i ].color, gp->directed[ j ] ); + gp->directed[ j ] += contributions[ i ].color * d; /* ambient light will be at 1/4 the value of directed light */ /* (ydnar: nuke this in favor of more dramatic lighting?) */ @@ -1684,9 +1659,9 @@ void TraceGrid( int num ){ // d = 0.25f; /* (Hobbes: always setting it to .25 is hardly any better) */ d = 0.25f * ( 1.0f - d ); - VectorMA( gp->ambient[ j ], d, contributions[ i ].color, gp->ambient[ j ] ); + gp->ambient[ j ] += contributions[ i ].color * d; - VectorAdd( gp->ambient[ j ], contributions[ i ].ambient, gp->ambient[ j ] ); + gp->ambient[ j ] += contributions[ i ].ambient; /* * div0: @@ -1714,7 +1689,7 @@ void TraceGrid( int num ){ #endif /* set minimum light and copy off to bytes */ - VectorCopy( gp->ambient[ i ], color ); + Vector3 color = gp->ambient[ i ]; for ( j = 0; j < 3; j++ ) if ( color[ j ] < minGridLight[ j ] ) { color[ j ] = minGridLight[ j ]; @@ -1731,7 +1706,7 @@ void TraceGrid( int num ){ */ if( bgp->ambient[i][0] + bgp->ambient[i][1] + bgp->ambient[i][2] == 0 && bgp->directed[i][0] + bgp->directed[i][1] + bgp->directed[i][2] != 0 ) - VectorSet( bgp->ambient[i], 1, 1, 1 ); + bgp->ambient[i].set( 1 ); } /* debug code */ @@ -1756,7 +1731,6 @@ void TraceGrid( int num ){ void SetupGrid( void ){ int i, j; - vec3_t maxs, oldGridSize; char temp[ 64 ]; @@ -1769,7 +1743,7 @@ void SetupGrid( void ){ entities[ 0 ].read_keyvalue( gridSize, "gridsize" ); /* quantize it */ - VectorCopy( gridSize, oldGridSize ); + const Vector3 oldGridSize = gridSize; for ( i = 0; i < 3; i++ ) gridSize[ i ] = gridSize[ i ] >= 8.0f ? floor( gridSize[ i ] ) : 8.0f; @@ -1781,9 +1755,9 @@ void SetupGrid( void ){ /* get world bounds */ for ( i = 0; i < 3; i++ ) { - gridMins[ i ] = gridSize[ i ] * ceil( bspModels[ 0 ].mins[ i ] / gridSize[ i ] ); - maxs[ i ] = gridSize[ i ] * floor( bspModels[ 0 ].maxs[ i ] / gridSize[ i ] ); - gridBounds[ i ] = ( maxs[ i ] - gridMins[ i ] ) / gridSize[ i ] + 1; + gridMins[ i ] = gridSize[ i ] * ceil( bspModels[ 0 ].minmax.mins[ i ] / gridSize[ i ] ); + const float max = gridSize[ i ] * floor( bspModels[ 0 ].minmax.maxs[ i ] / gridSize[ i ] ); + gridBounds[ i ] = ( max - gridMins[ i ] ) / gridSize[ i ] + 1; } /* set grid size */ @@ -1818,7 +1792,7 @@ void SetupGrid( void ){ for ( i = 0; i < numRawGridPoints; i++ ) { for ( j = 0; j < MAX_LIGHTMAPS; j++ ) - VectorCopy( ambientColor, rawGridPoints[ i ].ambient[ j ] ); + rawGridPoints[ i ].ambient[ j ] = ambientColor; rawGridPoints[ i ].styles[ 0 ] = LS_NORMAL; bspGridPoints[ i ].styles[ 0 ] = LS_NORMAL; @@ -1841,7 +1815,7 @@ void SetupGrid( void ){ */ void LightWorld( bool fastAllocate ){ - vec3_t color; + Vector3 color; float f; int b, bt; bool minVertex, minGrid; @@ -1860,31 +1834,31 @@ void LightWorld( bool fastAllocate ){ color[1] = Image_LinearFloatFromsRGBFloat( color[1] ); color[2] = Image_LinearFloatFromsRGBFloat( color[2] ); } - if ( VectorLength( color ) == 0.0f ) { - VectorSet( color, 1.0, 1.0, 1.0 ); + if ( vector3_length( color ) == 0.0f ) { + color.set( 1 ); } /* ambient */ f = entities[ 0 ].floatForKey( "_ambient", "ambient" ); - VectorScale( color, f, ambientColor ); + ambientColor = color * f; /* minvertexlight */ if ( ( minVertex = entities[ 0 ].read_keyvalue( f, "_minvertexlight" ) ) ) { - VectorScale( color, f, minVertexLight ); + minVertexLight = color * f; } /* mingridlight */ if ( ( minGrid = entities[ 0 ].read_keyvalue( f, "_mingridlight" ) ) ) { - VectorScale( color, f, minGridLight ); + minGridLight = color * f; } /* minlight */ if ( entities[ 0 ].read_keyvalue( f, "_minlight" ) ) { - VectorScale( color, f, minLight ); + minLight = color * f; if ( !minVertex ) - VectorScale( color, f, minVertexLight ); + minVertexLight = color * f; if ( !minGrid ) - VectorScale( color, f, minGridLight ); + minGridLight = color * f; } /* maxlight */ @@ -1982,7 +1956,7 @@ void LightWorld( bool fastAllocate ){ /* flag bouncing */ bouncing = true; - VectorClear( ambientColor ); + ambientColor.set( 0 ); floodlighty = false; /* generate diffuse lights */ diff --git a/tools/quake3/q3map2/light_bounce.cpp b/tools/quake3/q3map2/light_bounce.cpp index c4c5464e..b8223016 100644 --- a/tools/quake3/q3map2/light_bounce.cpp +++ b/tools/quake3/q3map2/light_bounce.cpp @@ -65,13 +65,13 @@ void RadFreeLights( void ){ based off the regular clip winding code */ -static void RadClipWindingEpsilon( radWinding_t *in, vec3_t normal, vec_t dist, - vec_t epsilon, radWinding_t *front, radWinding_t *back, clipWork_t *cw ){ - vec_t *dists; - int *sides; +static void RadClipWindingEpsilon( radWinding_t *in, const Vector3& normal, float dist, + float epsilon, radWinding_t *front, radWinding_t *back, clipWork_t *cw ){ + float *dists; + EPlaneSide *sides; int counts[ 3 ]; - vec_t dot; /* ydnar: changed from static b/c of threading */ /* VC 4.2 optimizer bug if not static? */ - int i, j, k; + float dot; /* ydnar: changed from static b/c of threading */ /* VC 4.2 optimizer bug if not static? */ + int i, k; radVert_t *v1, *v2, mid; int maxPoints; @@ -86,17 +86,15 @@ static void RadClipWindingEpsilon( radWinding_t *in, vec3_t normal, vec_t dist, /* determine sides for each point */ for ( i = 0; i < in->numVerts; i++ ) { - dot = DotProduct( in->verts[ i ].xyz, normal ); - dot -= dist; - dists[ i ] = dot; - if ( dot > epsilon ) { - sides[ i ] = SIDE_FRONT; + dists[ i ] = vector3_dot( in->verts[ i ].xyz, normal ) - dist; + if ( dists[ i ] > epsilon ) { + sides[ i ] = eSideFront; } - else if ( dot < -epsilon ) { - sides[ i ] = SIDE_BACK; + else if ( dists[ i ] < -epsilon ) { + sides[ i ] = eSideBack; } else{ - sides[ i ] = SIDE_ON; + sides[ i ] = eSideOn; } counts[ sides[ i ] ]++; } @@ -125,21 +123,21 @@ static void RadClipWindingEpsilon( radWinding_t *in, vec3_t normal, vec_t dist, /* do simple vertex copies first */ v1 = &in->verts[ i ]; - if ( sides[ i ] == SIDE_ON ) { + if ( sides[ i ] == eSideOn ) { memcpy( &front->verts[ front->numVerts++ ], v1, sizeof( radVert_t ) ); memcpy( &back->verts[ back->numVerts++ ], v1, sizeof( radVert_t ) ); continue; } - if ( sides[ i ] == SIDE_FRONT ) { + if ( sides[ i ] == eSideFront ) { memcpy( &front->verts[ front->numVerts++ ], v1, sizeof( radVert_t ) ); } - if ( sides[ i ] == SIDE_BACK ) { + if ( sides[ i ] == eSideBack ) { memcpy( &back->verts[ back->numVerts++ ], v1, sizeof( radVert_t ) ); } - if ( sides[ i + 1 ] == SIDE_ON || sides[ i + 1 ] == sides[ i ] ) { + if ( sides[ i + 1 ] == eSideOn || sides[ i + 1 ] == sides[ i ] ) { continue; } @@ -149,30 +147,20 @@ static void RadClipWindingEpsilon( radWinding_t *in, vec3_t normal, vec_t dist, dot = dists[ i ] / ( dists[ i ] - dists[ i + 1 ] ); /* average vertex values */ - for ( j = 0; j < 4; j++ ) - { - /* color */ - if ( j < 4 ) { - for ( k = 0; k < MAX_LIGHTMAPS; k++ ) - mid.color[ k ][ j ] = v1->color[ k ][ j ] + dot * ( v2->color[ k ][ j ] - v1->color[ k ][ j ] ); - } - - /* xyz, normal */ - if ( j < 3 ) { - mid.xyz[ j ] = v1->xyz[ j ] + dot * ( v2->xyz[ j ] - v1->xyz[ j ] ); - mid.normal[ j ] = v1->normal[ j ] + dot * ( v2->normal[ j ] - v1->normal[ j ] ); - } - - /* st, lightmap */ - if ( j < 2 ) { - mid.st[ j ] = v1->st[ j ] + dot * ( v2->st[ j ] - v1->st[ j ] ); - for ( k = 0; k < MAX_LIGHTMAPS; k++ ) - mid.lightmap[ k ][ j ] = v1->lightmap[ k ][ j ] + dot * ( v2->lightmap[ k ][ j ] - v1->lightmap[ k ][ j ] ); - } + /* color */ + for ( k = 0; k < MAX_LIGHTMAPS; k++ ){ + mid.color[ k ] = v1->color[ k ] + ( v2->color[ k ] - v1->color[ k ] ) * dot; } + /* xyz, normal */ + mid.xyz = v1->xyz + ( v2->xyz - v1->xyz ) * dot; + mid.normal = v1->normal + ( v2->normal - v1->normal ) * dot; + /* st, lightmap */ + mid.st = v1->st + ( v2->st - v1->st ) * dot; + for ( k = 0; k < MAX_LIGHTMAPS; k++ ) + mid.lightmap[ k ] = v1->lightmap[ k ] + ( v2->lightmap[ k ] - v1->lightmap[ k ] ) * dot; /* normalize the averaged normal */ - VectorNormalize( mid.normal, mid.normal ); + VectorNormalize( mid.normal ); /* copy the midpoint to both windings */ memcpy( &front->verts[ front->numVerts++ ], &mid, sizeof( radVert_t ) ); @@ -201,11 +189,11 @@ float Modulo1IfNegative( float f ){ returns false if pixels are bad */ -bool RadSampleImage( byte *pixels, int width, int height, float st[ 2 ], float color[ 4 ] ){ +bool RadSampleImage( byte *pixels, int width, int height, const Vector2& st, Color4f& color ){ int x, y; /* clear color first */ - color[ 0 ] = color[ 1 ] = color[ 2 ] = color[ 3 ] = 255; + color.set( 255 ); /* dummy check */ if ( pixels == NULL || width < 1 || height < 1 ) { @@ -220,8 +208,8 @@ bool RadSampleImage( byte *pixels, int width, int height, float st[ 2 ], float c /* get pixel */ pixels += ( y * width * 4 ) + ( x * 4 ); - VectorCopy( pixels, color ); - color[ 3 ] = pixels[ 3 ]; + VectorCopy( pixels, color.rgb() ); + color.alpha() = pixels[ 3 ]; if ( texturesRGB ) { color[0] = Image_LinearFloatFromsRGBFloat( color[0] * ( 1.0 / 255.0 ) ) * 255.0; @@ -243,22 +231,20 @@ bool RadSampleImage( byte *pixels, int width, int height, float st[ 2 ], float c #define MAX_SAMPLES 150 #define SAMPLE_GRANULARITY 6 -static void RadSample( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm, shaderInfo_t *si, radWinding_t *rw, vec3_t average, vec3_t gradient, int *style ){ - int i, j, k, l, v, x, y, samples, avgcolor; - vec3_t color, mins, maxs; - vec4_t textureColor; - float alpha, alphaI, bf; - vec3_t blend; - float st[ 2 ], lightmap[ 2 ], *radLuxel; +static void RadSample( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm, shaderInfo_t *si, radWinding_t *rw, Vector3& average, Vector3& gradient, int *style ){ + int i, j, k, l, v, x, y, samples; + Vector3 color; + MinMax minmax; + Color4f textureColor; + float alpha, alphaI; radVert_t *rv[ 3 ]; - if (!bouncing) + if ( !bouncing ) Sys_Printf( "BUG: RadSample: !bouncing shouldn't happen\n" ); /* initial setup */ - ClearBounds( mins, maxs ); - VectorClear( average ); - VectorClear( gradient ); + average.set( 0 ); + gradient.set( 0 ); alpha = 0; /* dummy check */ @@ -275,19 +261,18 @@ static void RadSample( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm, { /* multiply by texture color */ if ( !RadSampleImage( si->lightImage->pixels, si->lightImage->width, si->lightImage->height, rw->verts[ samples ].st, textureColor ) ) { - VectorCopy( si->averageColor, textureColor ); - textureColor[ 3 ] = 255.0f; + textureColor.rgb() = si->averageColor.rgb(); + textureColor.alpha() = 255.0f; } - avgcolor = ( textureColor[ 0 ] + textureColor[ 1 ] + textureColor[ 2 ] ) / 3; - for ( i = 0; i < 3; i++ ) - color[ i ] = ( ( textureColor[ i ] * bounceColorRatio + ( avgcolor * ( 1 - bounceColorRatio ) ) ) / 255 ) * ( rw->verts[ samples ].color[ lightmapNum ][ i ] / 255.0f ); -// color[ i ] = ( textureColor[ i ] / 255 ) * ( rw->verts[ samples ].color[ lightmapNum ][ i ] / 255.0f ); + const float avgcolor = ( textureColor[ 0 ] + textureColor[ 1 ] + textureColor[ 2 ] ) / 3; + color = ( ( textureColor.rgb() * bounceColorRatio + Vector3().set( avgcolor * ( 1 - bounceColorRatio ) ) ) / 255 ) * ( rw->verts[ samples ].color[ lightmapNum ].rgb() / 255.0f ); +// color = ( textureColor.rgb / 255 ) * ( rw->verts[ samples ].color[ lightmapNum ].rgb / 255.0f ); - AddPointToBounds( color, mins, maxs ); - VectorAdd( average, color, average ); + minmax.extend( color ); + average += color; /* get alpha */ - alpha += ( textureColor[ 3 ] / 255.0f ) * ( rw->verts[ samples ].color[ lightmapNum ][ 3 ] / 255.0f ); + alpha += ( textureColor.alpha() / 255.0f ) * ( rw->verts[ samples ].color[ lightmapNum ].alpha() / 255.0f ); } /* set style */ @@ -313,23 +298,18 @@ static void RadSample( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm, for ( k = 1; k < SAMPLE_GRANULARITY && samples < MAX_SAMPLES; k++ ) { /* create a blend vector (barycentric coordinates) */ - blend[ 0 ] = i; - blend[ 1 ] = j; - blend[ 2 ] = k; - bf = ( 1.0 / ( blend[ 0 ] + blend[ 1 ] + blend[ 2 ] ) ); - VectorScale( blend, bf, blend ); + DoubleVector3 blend( i, j, k ); + blend *= 1.0 / ( blend[ 0 ] + blend[ 1 ] + blend[ 2 ] ); /* create a blended sample */ - st[ 0 ] = st[ 1 ] = 0.0f; - lightmap[ 0 ] = lightmap[ 1 ] = 0.0f; + Vector2 st( 0, 0 ); + Vector2 lightmap( 0, 0 ); alphaI = 0.0f; for ( l = 0; l < 3; l++ ) { - st[ 0 ] += ( rv[ l ]->st[ 0 ] * blend[ l ] ); - st[ 1 ] += ( rv[ l ]->st[ 1 ] * blend[ l ] ); - lightmap[ 0 ] += ( rv[ l ]->lightmap[ lightmapNum ][ 0 ] * blend[ l ] ); - lightmap[ 1 ] += ( rv[ l ]->lightmap[ lightmapNum ][ 1 ] * blend[ l ] ); - alphaI += ( rv[ l ]->color[ lightmapNum ][ 3 ] * blend[ l ] ); + st += rv[ l ]->st * blend[ l ]; + lightmap += rv[ l ]->lightmap[ lightmapNum ] * blend[ l ]; + alphaI += rv[ l ]->color[ lightmapNum ].alpha() * blend[ l ]; } /* get lightmap xy coords */ @@ -349,7 +329,7 @@ static void RadSample( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm, } /* get radiosity luxel */ - radLuxel = RAD_LUXEL( lightmapNum, x, y ); + const Vector3& radLuxel = lm->getRadLuxel( lightmapNum, x, y ); /* ignore unlit/unused luxels */ if ( radLuxel[ 0 ] < 0.0f ) { @@ -361,19 +341,17 @@ static void RadSample( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm, /* multiply by texture color */ if ( !RadSampleImage( si->lightImage->pixels, si->lightImage->width, si->lightImage->height, st, textureColor ) ) { - VectorCopy( si->averageColor, textureColor ); - textureColor[ 3 ] = 255; + textureColor.rgb() = si->averageColor.rgb(); + textureColor.alpha() = 255; } - avgcolor = ( textureColor[ 0 ] + textureColor[ 1 ] + textureColor[ 2 ] ) / 3; - for ( l = 0; l < 3; l++ ){ - color[ l ] = ( ( textureColor[ l ] * bounceColorRatio + ( avgcolor * ( 1 - bounceColorRatio ) ) ) / 255 ) * ( radLuxel[ l ] / 255 ); - //Sys_Printf( "%i %i %i %i %i \n", (int) textureColor[ 0 ], (int) textureColor[ 1 ], (int) textureColor[ 2 ], (int) avgcolor, (int) color[ i ] ); - } - AddPointToBounds( color, mins, maxs ); - VectorAdd( average, color, average ); + const float avgcolor = ( textureColor[ 0 ] + textureColor[ 1 ] + textureColor[ 2 ] ) / 3; + color = ( ( textureColor.rgb() * bounceColorRatio + Vector3().set( avgcolor * ( 1 - bounceColorRatio ) ) ) / 255 ) * ( radLuxel / 255 ); + //Sys_Printf( "%i %i %i %i %i \n", (int) textureColor.rgb[ 0 ], (int) textureColor.rgb[ 1 ], (int) textureColor.rgb[ 2 ], (int) avgcolor, (int) color[ i ] ); + minmax.extend( color ); + average += color; /* get alpha */ - alpha += ( textureColor[ 3 ] / 255 ) * ( alphaI / 255 ); + alpha += ( textureColor.alpha() / 255 ) * ( alphaI / 255 ); } } } @@ -389,19 +367,18 @@ static void RadSample( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm, } /* average the color */ - VectorScale( average, ( 1.0 / samples ), average ); + average *= ( 1.0 / samples ); /* create the color gradient */ - //% VectorSubtract( maxs, mins, delta ); + //% VectorSubtract( minmax.maxs, minmax.mins, delta ); /* new: color gradient will always be 0-1.0, expressed as the range of light relative to overall light */ - //% gradient[ 0 ] = maxs[ 0 ] > 0.0f ? (maxs[ 0 ] - mins[ 0 ]) / maxs[ 0 ] : 0.0f; - //% gradient[ 1 ] = maxs[ 1 ] > 0.0f ? (maxs[ 1 ] - mins[ 1 ]) / maxs[ 1 ] : 0.0f; - //% gradient[ 2 ] = maxs[ 2 ] > 0.0f ? (maxs[ 2 ] - mins[ 2 ]) / maxs[ 2 ] : 0.0f; + //% gradient[ 0 ] = minmax.maxs[ 0 ] > 0.0f ? (minmax.maxs[ 0 ] - minmax.mins[ 0 ]) / minmax.maxs[ 0 ] : 0.0f; + //% gradient[ 1 ] = minmax.maxs[ 1 ] > 0.0f ? (minmax.maxs[ 1 ] - minmax.mins[ 1 ]) / minmax.maxs[ 1 ] : 0.0f; + //% gradient[ 2 ] = minmax.maxs[ 2 ] > 0.0f ? (minmax.maxs[ 2 ] - minmax.mins[ 2 ]) / minmax.maxs[ 2 ] : 0.0f; /* newer: another contrast function */ - for ( i = 0; i < 3; i++ ) - gradient[ i ] = ( maxs[ i ] - mins[ i ] ) * maxs[ i ]; + gradient = ( minmax.maxs - minmax.mins ) * minmax.maxs; } @@ -422,7 +399,7 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw float scale, float subdivide, radWinding_t *rw, clipWork_t *cw ){ int i, style = 0; float dist, area, value; - vec3_t mins, maxs, normal, d1, d2, cross, color, gradient; + Vector3 normal, color, gradient; light_t *light, *splash; winding_t *w, *splash_w; @@ -433,24 +410,22 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw } /* get bounds for winding */ - ClearBounds( mins, maxs ); + MinMax minmax; for ( i = 0; i < rw->numVerts; i++ ) - AddPointToBounds( rw->verts[ i ].xyz, mins, maxs ); + minmax.extend( rw->verts[ i ].xyz ); /* subdivide if necessary */ for ( i = 0; i < 3; i++ ) { - if ( maxs[ i ] - mins[ i ] > subdivide ) { + if ( minmax.maxs[ i ] - minmax.mins[ i ] > subdivide ) { auto front = std::make_unique(); auto back = std::make_unique(); /* make axial plane */ - VectorClear( normal ); - normal[ i ] = 1; - dist = ( maxs[ i ] + mins[ i ] ) * 0.5f; + dist = ( minmax.maxs[ i ] + minmax.mins[ i ] ) * 0.5f; /* clip the winding */ - RadClipWindingEpsilon( rw, normal, dist, RADIOSITY_CLIP_EPSILON, front.get(), back.get(), cw ); + RadClipWindingEpsilon( rw, g_vector3_axes[i], dist, RADIOSITY_CLIP_EPSILON, front.get(), back.get(), cw ); /* recurse */ RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, front.get(), cw ); @@ -463,10 +438,7 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw area = 0.0f; for ( i = 2; i < rw->numVerts; i++ ) { - VectorSubtract( rw->verts[ i - 1 ].xyz, rw->verts[ 0 ].xyz, d1 ); - VectorSubtract( rw->verts[ i ].xyz, rw->verts[ 0 ].xyz, d2 ); - CrossProduct( d1, d2, cross ); - area += 0.5f * VectorLength( cross ); + area += 0.5f * vector3_length( vector3_cross( rw->verts[ i - 1 ].xyz - rw->verts[ 0 ].xyz, rw->verts[ i ].xyz - rw->verts[ 0 ].xyz ) ); } if ( area < 1.0f || area > 20000000.0f ) { return; @@ -488,24 +460,24 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw /* create a regular winding and an average normal */ w = AllocWinding( rw->numVerts ); w->numpoints = rw->numVerts; - VectorClear( normal ); + normal.set( 0 ); for ( i = 0; i < rw->numVerts; i++ ) { - VectorCopy( rw->verts[ i ].xyz, w->p[ i ] ); - VectorAdd( normal, rw->verts[ i ].normal, normal ); + w->p[ i ] = rw->verts[ i ].xyz; + normal += rw->verts[ i ].normal; } - VectorScale( normal, ( 1.0f / rw->numVerts ), normal ); - if ( VectorNormalize( normal, normal ) == 0.0f ) { + normal /= rw->numVerts; + if ( VectorNormalize( normal ) == 0.0f ) { return; } /* early out? */ - if ( bouncing && VectorLength( color ) < RADIOSITY_MIN ) { + if ( bouncing && vector3_length( color ) < RADIOSITY_MIN ) { return; } /* debug code */ - //% Sys_Printf( "Size: %d %d %d\n", (int) (maxs[ 0 ] - mins[ 0 ]), (int) (maxs[ 1 ] - mins[ 1 ]), (int) (maxs[ 2 ] - mins[ 2 ]) ); + //% Sys_Printf( "Size: %d %d %d\n", (int) (minmax.maxs[ 0 ] - minmax.mins[ 0 ]), (int) (minmax.maxs[ 1 ] - minmax.mins[ 1 ]), (int) (minmax.maxs[ 2 ] - minmax.mins[ 2 ]) ); //% Sys_Printf( "Grad: %f %f %f\n", gradient[ 0 ], gradient[ 1 ], gradient[ 2 ] ); /* increment counts */ @@ -553,21 +525,20 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw value = si->value; light->photons = value * area * areaScale; light->add = value * formFactorValueScale * areaScale; - VectorCopy( si->color, light->color ); - VectorScale( light->color, light->add, light->emitColor ); + light->color = si->color; + light->emitColor = light->color * light->add; light->style = noStyles ? LS_NORMAL : si->lightStyle; if ( light->style < LS_NORMAL || light->style >= LS_NONE ) { light->style = LS_NORMAL; } /* set origin */ - VectorAdd( mins, maxs, light->origin ); - VectorScale( light->origin, 0.5f, light->origin ); + light->origin = minmax.origin(); /* nudge it off the plane a bit */ - VectorCopy( normal, light->normal ); - VectorMA( light->origin, 1.0f, light->normal, light->origin ); - light->dist = DotProduct( light->origin, normal ); + light->normal = normal; + light->origin += light->normal; + light->dist = vector3_dot( light->origin, normal ); #if 0 /* optionally create a point backsplash light */ @@ -587,8 +558,8 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw splash->fade = 1.0f; splash->si = si; - VectorMA( light->origin, si->backsplashDistance, normal, splash->origin ); - VectorCopy( si->color, splash->color ); + splash->origin = normal * si->backsplashDistance + light->origin; + splash->color = si->color; splash->falloffTolerance = falloffTolerance; splash->style = noStyles ? LS_NORMAL : light->style; @@ -616,8 +587,8 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw splash->add = light->add * 7.0f * si->backsplashFraction; splash->fade = 1.0f; splash->si = si; - VectorCopy( si->color, splash->color ); - VectorScale( splash->color, splash->add, splash->emitColor ); + splash->color = si->color; + splash->emitColor = splash->color * splash->add; splash->falloffTolerance = falloffTolerance; splash->style = noStyles ? LS_NORMAL : si->lightStyle; if ( splash->style < LS_NORMAL || splash->style >= LS_NONE ) { @@ -628,12 +599,12 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw splash_w = AllocWinding( rw->numVerts ); splash_w->numpoints = rw->numVerts; for ( i = 0; i < rw->numVerts; i++ ) - VectorMA( rw->verts[rw->numVerts - 1 - i].xyz, si->backsplashDistance, normal, splash_w->p[ i ] ); + splash_w->p[ i ] = normal * si->backsplashDistance + rw->verts[rw->numVerts - 1 - i].xyz; splash->w = splash_w; - VectorMA( light->origin, si->backsplashDistance, normal, splash->origin ); - VectorNegate( normal, splash->normal ); - splash->dist = DotProduct( splash->origin, splash->normal ); + splash->origin = normal * si->backsplashDistance + light->origin; + splash->normal = -normal; + splash->dist = vector3_dot( splash->origin, splash->normal ); // splash->flags |= LightFlags::Twosided; } @@ -646,20 +617,20 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw value = RADIOSITY_VALUE * si->bounceScale * 0.375f; light->photons = value * area * bounceScale; light->add = value * formFactorValueScale * bounceScale; - VectorCopy( color, light->color ); - VectorScale( light->color, light->add, light->emitColor ); + light->color = color; + light->emitColor = light->color * light->add; light->style = noStyles ? LS_NORMAL : style; if ( light->style < LS_NORMAL || light->style >= LS_NONE ) { light->style = LS_NORMAL; } /* set origin */ - WindingCenter( w, light->origin ); + light->origin = WindingCenter( w ); /* nudge it off the plane a bit */ - VectorCopy( normal, light->normal ); - VectorMA( light->origin, 1.0f, light->normal, light->origin ); - light->dist = DotProduct( light->origin, normal ); + light->normal = normal; + light->origin += light->normal; + light->dist = vector3_dot( light->origin, normal ); } if (light->photons < 0 || light->add < 0 || light->color[0] < 0 || light->color[1] < 0 || light->color[2] < 0) @@ -685,7 +656,6 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw void RadLightForTriangles( int num, int lightmapNum, rawLightmap_t *lm, shaderInfo_t *si, float scale, float subdivide, clipWork_t *cw ){ int i, j, k, v; bspDrawSurface_t *ds; - float *radVertexLuxel; radWinding_t rw; @@ -708,9 +678,8 @@ void RadLightForTriangles( int num, int lightmapNum, rawLightmap_t *lm, shaderIn /* fix colors */ for ( k = 0; k < MAX_LIGHTMAPS; k++ ) { - radVertexLuxel = RAD_VERTEX_LUXEL( k, ds->firstVert + bspDrawIndexes[ ds->firstIndex + i + j ] ); - VectorCopy( radVertexLuxel, rw.verts[ j ].color[ k ] ); - rw.verts[ j ].color[ k ][ 3 ] = yDrawVerts[ v ].color[ k ][ 3 ]; + rw.verts[ j ].color[ k ].rgb() = getRadVertexLuxel( k, ds->firstVert + bspDrawIndexes[ ds->firstIndex + i + j ] ); + rw.verts[ j ].color[ k ].alpha() = yDrawVerts[ v ].color[ k ].alpha(); } } @@ -735,9 +704,6 @@ void RadLightForPatch( int num, int lightmapNum, rawLightmap_t *lm, shaderInfo_t bspDrawVert_t *bogus; bspDrawVert_t *dv[ 4 ]; mesh_t src, *subdivided, *mesh; - float *radVertexLuxel; - float dist; - vec4_t plane; bool planar; radWinding_t rw; @@ -798,10 +764,10 @@ void RadLightForPatch( int num, int lightmapNum, rawLightmap_t *lm, shaderInfo_t dv[ 3 ] = &mesh->verts[ pw[ r + 3 ] ]; /* planar? */ + Plane3f plane; planar = PlaneFromPoints( plane, dv[ 0 ]->xyz, dv[ 1 ]->xyz, dv[ 2 ]->xyz ); if ( planar ) { - dist = DotProduct( dv[ 1 ]->xyz, plane ) - plane[ 3 ]; - if ( fabs( dist ) > PLANAR_EPSILON ) { + if ( fabs( plane3_distance_to_point( plane, dv[ 1 ]->xyz ) ) > PLANAR_EPSILON ) { planar = false; } } @@ -817,9 +783,8 @@ void RadLightForPatch( int num, int lightmapNum, rawLightmap_t *lm, shaderInfo_t /* fix colors */ for ( i = 0; i < MAX_LIGHTMAPS; i++ ) { - radVertexLuxel = RAD_VERTEX_LUXEL( i, ds->firstVert + dv[ v ]->color[ 0 ][ 0 ] ); - VectorCopy( radVertexLuxel, rw.verts[ v ].color[ i ] ); - rw.verts[ v ].color[ i ][ 3 ] = dv[ v ]->color[ i ][ 3 ]; + rw.verts[ v ].color[ i ].rgb() = getRadVertexLuxel( i, ds->firstVert + dv[ v ]->color[ 0 ][ 0 ] ); + rw.verts[ v ].color[ i ].alpha() = dv[ v ]->color[ i ].alpha(); } } @@ -846,9 +811,8 @@ void RadLightForPatch( int num, int lightmapNum, rawLightmap_t *lm, shaderInfo_t /* fix colors */ for ( i = 0; i < MAX_LIGHTMAPS; i++ ) { - radVertexLuxel = RAD_VERTEX_LUXEL( i, ds->firstVert + dv[ v ]->color[ 0 ][ 0 ] ); - VectorCopy( radVertexLuxel, rw.verts[ v ].color[ i ] ); - rw.verts[ v ].color[ i ][ 3 ] = dv[ v ]->color[ i ][ 3 ]; + rw.verts[ v ].color[ i ].rgb() = getRadVertexLuxel( i, ds->firstVert + dv[ v ]->color[ 0 ][ 0 ] ); + rw.verts[ v ].color[ i ].alpha() = dv[ v ]->color[ i ].alpha(); } } diff --git a/tools/quake3/q3map2/light_trace.cpp b/tools/quake3/q3map2/light_trace.cpp index 4536741a..5221c37d 100644 --- a/tools/quake3/q3map2/light_trace.cpp +++ b/tools/quake3/q3map2/light_trace.cpp @@ -38,7 +38,6 @@ #define Vector2Copy( a, b ) ( ( b )[ 0 ] = ( a )[ 0 ], ( b )[ 1 ] = ( a )[ 1 ] ) -#define Vector4Copy( a, b ) ( ( b )[ 0 ] = ( a )[ 0 ], ( b )[ 1 ] = ( a )[ 1 ], ( b )[ 2 ] = ( a )[ 2 ], ( b )[ 3 ] = ( a )[ 3 ] ) #define MAX_NODE_ITEMS 5 #define MAX_NODE_TRIANGLES 5 @@ -60,8 +59,8 @@ struct traceVert_t { - vec3_t xyz; - float st[ 2 ]; + Vector3 xyz; + Vector2 st; }; struct traceInfo_t @@ -73,14 +72,14 @@ struct traceInfo_t struct traceWinding_t { - vec4_t plane; + Plane3f plane; int infoNum, numVerts; traceVert_t v[ MAX_TW_VERTS ]; }; struct traceTriangle_t { - vec3_t edge1, edge2; + Vector3 edge1, edge2; int infoNum; traceVert_t v[ 3 ]; }; @@ -88,8 +87,8 @@ struct traceTriangle_t struct traceNode_t { int type; - vec4_t plane; - vec3_t mins, maxs; + Plane3f plane; + MinMax minmax; int children[ 2 ]; int numItems, maxItems; int *items; @@ -165,7 +164,7 @@ static int AllocTraceNode( void ){ /* add the node */ memset( &traceNodes[ numTraceNodes ], 0, sizeof( traceNode_t ) ); traceNodes[ numTraceNodes ].type = TRACE_LEAF; - ClearBounds( traceNodes[ numTraceNodes ].mins, traceNodes[ numTraceNodes ].maxs ); + traceNodes[ numTraceNodes ].minmax.clear(); /* Sys_Printf("alloc node %d\n", numTraceNodes); */ @@ -233,8 +232,8 @@ static int AddTraceTriangle( traceTriangle_t *tt ){ } /* find vectors for two edges sharing the first vert */ - VectorSubtract( tt->v[ 1 ].xyz, tt->v[ 0 ].xyz, tt->edge1 ); - VectorSubtract( tt->v[ 2 ].xyz, tt->v[ 0 ].xyz, tt->edge2 ); + tt->edge1 = tt->v[ 1 ].xyz - tt->v[ 0 ].xyz; + tt->edge2 = tt->v[ 2 ].xyz - tt->v[ 0 ].xyz; /* add the triangle */ memcpy( &traceTriangles[ num ], tt, sizeof( *traceTriangles ) ); @@ -302,28 +301,25 @@ static int AddItemToTraceNode( traceNode_t *node, int num ){ static int SetupTraceNodes_r( int bspNodeNum ){ int i, nodeNum, bspLeafNum, newNode; - bspPlane_t *plane; - bspNode_t *bspNode; /* get bsp node and plane */ - bspNode = &bspNodes[ bspNodeNum ]; - plane = &bspPlanes[ bspNode->planeNum ]; + const bspNode_t& bspNode = bspNodes[ bspNodeNum ]; + const bspPlane_t& plane = bspPlanes[ bspNode.planeNum ]; /* allocate a new trace node */ nodeNum = AllocTraceNode(); /* setup trace node */ - traceNodes[ nodeNum ].type = PlaneTypeForNormal( plane->normal ); - VectorCopy( plane->normal, traceNodes[ nodeNum ].plane ); - traceNodes[ nodeNum ].plane[ 3 ] = plane->dist; + traceNodes[ nodeNum ].type = PlaneTypeForNormal( plane.normal() ); + traceNodes[ nodeNum ].plane = plane; /* setup children */ for ( i = 0; i < 2; i++ ) { /* leafnode */ - if ( bspNode->children[ i ] < 0 ) { - bspLeafNum = -bspNode->children[ i ] - 1; + if ( bspNode.children[ i ] < 0 ) { + bspLeafNum = -bspNode.children[ i ] - 1; /* new code */ newNode = AllocTraceNode(); @@ -338,7 +334,7 @@ static int SetupTraceNodes_r( int bspNodeNum ){ /* normal node */ else { - newNode = SetupTraceNodes_r( bspNode->children[ i ] ); + newNode = SetupTraceNodes_r( bspNode.children[ i ] ); traceNodes[ nodeNum ].children[ i ] = newNode; } @@ -362,9 +358,10 @@ static int SetupTraceNodes_r( int bspNodeNum ){ #define TW_ON_EPSILON 0.25f -void ClipTraceWinding( traceWinding_t *tw, vec4_t plane, traceWinding_t *front, traceWinding_t *back ){ +void ClipTraceWinding( traceWinding_t *tw, const Plane3f& plane, traceWinding_t *front, traceWinding_t *back ){ int i, j, k; - int sides[ MAX_TW_VERTS ], counts[ 3 ] = { 0, 0, 0 }; + EPlaneSide sides[ MAX_TW_VERTS ]; + int counts[ 3 ] = { 0, 0, 0 }; float dists[ MAX_TW_VERTS ]; float frac; traceVert_t *a, *b, mid; @@ -377,26 +374,26 @@ void ClipTraceWinding( traceWinding_t *tw, vec4_t plane, traceWinding_t *front, /* classify points */ for ( i = 0; i < tw->numVerts; i++ ) { - dists[ i ] = DotProduct( tw->v[ i ].xyz, plane ) - plane[ 3 ]; + dists[ i ] = plane3_distance_to_point( plane, tw->v[ i ].xyz ); if ( dists[ i ] < -TW_ON_EPSILON ) { - sides[ i ] = SIDE_BACK; + sides[ i ] = eSideBack; } else if ( dists[ i ] > TW_ON_EPSILON ) { - sides[ i ] = SIDE_FRONT; + sides[ i ] = eSideFront; } else{ - sides[ i ] = SIDE_ON; + sides[ i ] = eSideOn; } counts[ sides[ i ] ]++; } /* entirely on front? */ - if ( counts[ SIDE_BACK ] == 0 ) { + if ( counts[ eSideBack ] == 0 ) { memcpy( front, tw, sizeof( *front ) ); } /* entirely on back? */ - else if ( counts[ SIDE_FRONT ] == 0 ) { + else if ( counts[ eSideFront ] == 0 ) { memcpy( back, tw, sizeof( *back ) ); } @@ -422,21 +419,21 @@ void ClipTraceWinding( traceWinding_t *tw, vec4_t plane, traceWinding_t *front, /* handle points on the splitting plane */ switch ( sides[ i ] ) { - case SIDE_FRONT: + case eSideFront: if ( front->numVerts >= MAX_TW_VERTS ) { Error( "MAX_TW_VERTS (%d) exceeded", MAX_TW_VERTS ); } front->v[ front->numVerts++ ] = *a; break; - case SIDE_BACK: + case eSideBack: if ( back->numVerts >= MAX_TW_VERTS ) { Error( "MAX_TW_VERTS (%d) exceeded", MAX_TW_VERTS ); } back->v[ back->numVerts++ ] = *a; break; - case SIDE_ON: + case eSideOn: if ( front->numVerts >= MAX_TW_VERTS || back->numVerts >= MAX_TW_VERTS ) { Error( "MAX_TW_VERTS (%d) exceeded", MAX_TW_VERTS ); } @@ -446,7 +443,7 @@ void ClipTraceWinding( traceWinding_t *tw, vec4_t plane, traceWinding_t *front, } /* check next point to see if we need to split the edge */ - if ( sides[ j ] == SIDE_ON || sides[ j ] == sides[ i ] ) { + if ( sides[ j ] == eSideOn || sides[ j ] == sides[ i ] ) { continue; } @@ -460,19 +457,18 @@ void ClipTraceWinding( traceWinding_t *tw, vec4_t plane, traceWinding_t *front, for ( k = 0; k < 3; k++ ) { /* minimize fp precision errors */ - if ( plane[ k ] == 1.0f ) { - mid.xyz[ k ] = plane[ 3 ]; + if ( plane.normal()[ k ] == 1.0f ) { + mid.xyz[ k ] = plane.dist(); } - else if ( plane[ k ] == -1.0f ) { - mid.xyz[ k ] = -plane[ 3 ]; + else if ( plane.normal()[ k ] == -1.0f ) { + mid.xyz[ k ] = -plane.dist(); } else{ mid.xyz[ k ] = a->xyz[ k ] + frac * ( b->xyz[ k ] - a->xyz[ k ] ); } } /* set texture coordinates */ - mid.st[ 0 ] = a->st[ 0 ] + frac * ( b->st[ 0 ] - a->st[ 0 ] ); - mid.st[ 1 ] = a->st[ 1 ] + frac * ( b->st[ 1 ] - a->st[ 1 ] ); + mid.st = a->st + ( b->st - a->st ) * frac; /* copy midpoint to front and back polygons */ front->v[ front->numVerts++ ] = mid; @@ -490,7 +486,7 @@ void ClipTraceWinding( traceWinding_t *tw, vec4_t plane, traceWinding_t *front, static void FilterTraceWindingIntoNodes_r( traceWinding_t *tw, int nodeNum ){ int num; - vec4_t plane1, plane2, reverse; + Plane3f plane1, plane2, reverse; traceNode_t *node; traceWinding_t front, back; @@ -518,23 +514,22 @@ static void FilterTraceWindingIntoNodes_r( traceWinding_t *tw, int nodeNum ){ } /* get node plane */ - Vector4Copy( node->plane, plane1 ); + plane1 = node->plane; /* get winding plane */ - Vector4Copy( tw->plane, plane2 ); + plane2 = tw->plane; /* invert surface plane */ - VectorSubtract( vec3_origin, plane2, reverse ); - reverse[ 3 ] = -plane2[ 3 ]; + reverse = plane3_flipped( plane2 ); /* front only */ - if ( DotProduct( plane1, plane2 ) > 0.999f && fabs( plane1[ 3 ] - plane2[ 3 ] ) < 0.001f ) { + if ( vector3_dot( plane1.normal(), plane2.normal() ) > 0.999f && fabs( plane1.dist() - plane2.dist() ) < 0.001f ) { FilterTraceWindingIntoNodes_r( tw, node->children[ 0 ] ); return; } /* back only */ - if ( DotProduct( plane1, reverse ) > 0.999f && fabs( plane1[ 3 ] - reverse[ 3 ] ) < 0.001f ) { + if ( vector3_dot( plane1.normal(), reverse.normal() ) > 0.999f && fabs( plane1.dist() - reverse.dist() ) < 0.001f ) { FilterTraceWindingIntoNodes_r( tw, node->children[ 1 ] ); return; } @@ -568,9 +563,7 @@ static void FilterTraceWindingIntoNodes_r( traceWinding_t *tw, int nodeNum ){ static void SubdivideTraceNode_r( int nodeNum, int depth ){ int i, j, count, num, frontNum, backNum, type; - vec3_t size; float dist; - double average[ 3 ]; traceNode_t *node, *frontNode, *backNode; traceWinding_t *tw, front, back; @@ -602,8 +595,8 @@ static void SubdivideTraceNode_r( int nodeNum, int depth ){ } /* bound the node */ - ClearBounds( node->mins, node->maxs ); - VectorClear( average ); + node->minmax.clear(); + DoubleVector3 average( 0, 0, 0 ); count = 0; for ( i = 0; i < node->numItems; i++ ) { @@ -613,10 +606,8 @@ static void SubdivideTraceNode_r( int nodeNum, int depth ){ /* walk its verts */ for ( j = 0; j < tw->numVerts; j++ ) { - AddPointToBounds( tw->v[ j ].xyz, node->mins, node->maxs ); - average[ 0 ] += tw->v[ j ].xyz[ 0 ]; - average[ 1 ] += tw->v[ j ].xyz[ 1 ]; - average[ 2 ] += tw->v[ j ].xyz[ 2 ]; + node->minmax.extend( tw->v[ j ].xyz ); + average += tw->v[ j ].xyz; count++; } } @@ -630,15 +621,15 @@ static void SubdivideTraceNode_r( int nodeNum, int depth ){ } /* the largest dimension of the bounding box will be the split axis */ - VectorSubtract( node->maxs, node->mins, size ); + const Vector3 size = node->minmax.maxs - node->minmax.mins; if ( size[ 0 ] >= size[ 1 ] && size[ 0 ] >= size[ 2 ] ) { - type = PLANE_X; + type = ePlaneX; } else if ( size[ 1 ] >= size[ 0 ] && size[ 1 ] >= size[ 2 ] ) { - type = PLANE_Y; + type = ePlaneY; } else{ - type = PLANE_Z; + type = ePlaneZ; } /* don't split small nodes */ @@ -657,8 +648,8 @@ static void SubdivideTraceNode_r( int nodeNum, int depth ){ dist = floor( average[ type ] / count ); /* dummy check it */ - if ( dist <= node->mins[ type ] || dist >= node->maxs[ type ] ) { - dist = floor( 0.5f * ( node->mins[ type ] + node->maxs[ type ] ) ); + if ( dist <= node->minmax.mins[ type ] || dist >= node->minmax.maxs[ type ] ) { + dist = floor( 0.5f * ( node->minmax.mins[ type ] + node->minmax.maxs[ type ] ) ); } /* allocate child nodes */ @@ -672,8 +663,8 @@ static void SubdivideTraceNode_r( int nodeNum, int depth ){ /* attach children */ node->type = type; - node->plane[ type ] = 1.0f; - node->plane[ 3 ] = dist; + node->plane.normal()[ type ] = 1.0f; + node->plane.dist() = dist; node->children[ 0 ] = frontNum; node->children[ 1 ] = backNum; @@ -802,8 +793,8 @@ static int TriangulateTraceNode_r( int nodeNum ){ tt.v[ 2 ] = tw->v[ j + 1 ]; /* find vectors for two edges sharing the first vert */ - VectorSubtract( tt.v[ 1 ].xyz, tt.v[ 0 ].xyz, tt.edge1 ); - VectorSubtract( tt.v[ 2 ].xyz, tt.v[ 0 ].xyz, tt.edge2 ); + tt.edge1 = tt.v[ 1 ].xyz - tt.v[ 0 ].xyz; + tt.edge2 = tt.v[ 2 ].xyz - tt.v[ 0 ].xyz; /* add it to the node */ num = AddTraceTriangle( &tt ); @@ -831,7 +822,7 @@ static int TriangulateTraceNode_r( int nodeNum ){ filters a bsp model's surfaces into the raytracing tree */ -static void PopulateWithBSPModel( bspModel_t *model, m4x4_t transform ){ +static void PopulateWithBSPModel( bspModel_t *model, const Matrix4& transform ){ int i, j, x, y, pw[ 5 ], r, nodeNum; bspDrawSurface_t *ds; surfaceInfo_t *info; @@ -843,7 +834,7 @@ static void PopulateWithBSPModel( bspModel_t *model, m4x4_t transform ){ /* dummy check */ - if ( model == NULL || transform == NULL ) { + if ( model == NULL ) { return; } @@ -943,27 +934,27 @@ static void PopulateWithBSPModel( bspModel_t *model, m4x4_t transform ){ r = ( x + y ) & 1; /* make first triangle */ - VectorCopy( verts[ pw[ r + 0 ] ].xyz, tw.v[ 0 ].xyz ); - Vector2Copy( verts[ pw[ r + 0 ] ].st, tw.v[ 0 ].st ); - VectorCopy( verts[ pw[ r + 1 ] ].xyz, tw.v[ 1 ].xyz ); - Vector2Copy( verts[ pw[ r + 1 ] ].st, tw.v[ 1 ].st ); - VectorCopy( verts[ pw[ r + 2 ] ].xyz, tw.v[ 2 ].xyz ); - Vector2Copy( verts[ pw[ r + 2 ] ].st, tw.v[ 2 ].st ); - m4x4_transform_point( transform, tw.v[ 0 ].xyz ); - m4x4_transform_point( transform, tw.v[ 1 ].xyz ); - m4x4_transform_point( transform, tw.v[ 2 ].xyz ); + tw.v[ 0 ].xyz = verts[ pw[ r + 0 ] ].xyz; + tw.v[ 0 ].st = verts[ pw[ r + 0 ] ].st; + tw.v[ 1 ].xyz = verts[ pw[ r + 1 ] ].xyz; + tw.v[ 1 ].st = verts[ pw[ r + 1 ] ].st; + tw.v[ 2 ].xyz = verts[ pw[ r + 2 ] ].xyz; + tw.v[ 2 ].st = verts[ pw[ r + 2 ] ].st; + matrix4_transform_point( transform, tw.v[ 0 ].xyz ); + matrix4_transform_point( transform, tw.v[ 1 ].xyz ); + matrix4_transform_point( transform, tw.v[ 2 ].xyz ); FilterTraceWindingIntoNodes_r( &tw, nodeNum ); /* make second triangle */ - VectorCopy( verts[ pw[ r + 0 ] ].xyz, tw.v[ 0 ].xyz ); - Vector2Copy( verts[ pw[ r + 0 ] ].st, tw.v[ 0 ].st ); - VectorCopy( verts[ pw[ r + 2 ] ].xyz, tw.v[ 1 ].xyz ); - Vector2Copy( verts[ pw[ r + 2 ] ].st, tw.v[ 1 ].st ); - VectorCopy( verts[ pw[ r + 3 ] ].xyz, tw.v[ 2 ].xyz ); - Vector2Copy( verts[ pw[ r + 3 ] ].st, tw.v[ 2 ].st ); - m4x4_transform_point( transform, tw.v[ 0 ].xyz ); - m4x4_transform_point( transform, tw.v[ 1 ].xyz ); - m4x4_transform_point( transform, tw.v[ 2 ].xyz ); + tw.v[ 0 ].xyz = verts[ pw[ r + 0 ] ].xyz; + tw.v[ 0 ].st = verts[ pw[ r + 0 ] ].st; + tw.v[ 1 ].xyz = verts[ pw[ r + 2 ] ].xyz; + tw.v[ 1 ].st = verts[ pw[ r + 2 ] ].st; + tw.v[ 2 ].xyz = verts[ pw[ r + 3 ] ].xyz; + tw.v[ 2 ].st = verts[ pw[ r + 3 ] ].st; + matrix4_transform_point( transform, tw.v[ 0 ].xyz ); + matrix4_transform_point( transform, tw.v[ 1 ].xyz ); + matrix4_transform_point( transform, tw.v[ 2 ].xyz ); FilterTraceWindingIntoNodes_r( &tw, nodeNum ); } } @@ -982,15 +973,15 @@ static void PopulateWithBSPModel( bspModel_t *model, m4x4_t transform ){ /* walk the triangle list */ for ( j = 0; j < ds->numIndexes; j += 3 ) { - VectorCopy( verts[ indexes[ j ] ].xyz, tw.v[ 0 ].xyz ); - Vector2Copy( verts[ indexes[ j ] ].st, tw.v[ 0 ].st ); - VectorCopy( verts[ indexes[ j + 1 ] ].xyz, tw.v[ 1 ].xyz ); - Vector2Copy( verts[ indexes[ j + 1 ] ].st, tw.v[ 1 ].st ); - VectorCopy( verts[ indexes[ j + 2 ] ].xyz, tw.v[ 2 ].xyz ); - Vector2Copy( verts[ indexes[ j + 2 ] ].st, tw.v[ 2 ].st ); - m4x4_transform_point( transform, tw.v[ 0 ].xyz ); - m4x4_transform_point( transform, tw.v[ 1 ].xyz ); - m4x4_transform_point( transform, tw.v[ 2 ].xyz ); + tw.v[ 0 ].xyz = verts[ indexes[ j ] ].xyz; + tw.v[ 0 ].st = verts[ indexes[ j ] ].st; + tw.v[ 1 ].xyz = verts[ indexes[ j + 1 ] ].xyz; + tw.v[ 1 ].st = verts[ indexes[ j + 1 ] ].st; + tw.v[ 2 ].xyz = verts[ indexes[ j + 2 ] ].xyz; + tw.v[ 2 ].st = verts[ indexes[ j + 2 ] ].st; + matrix4_transform_point( transform, tw.v[ 0 ].xyz ); + matrix4_transform_point( transform, tw.v[ 1 ].xyz ); + matrix4_transform_point( transform, tw.v[ 2 ].xyz ); FilterTraceWindingIntoNodes_r( &tw, nodeNum ); } break; @@ -1009,18 +1000,17 @@ static void PopulateWithBSPModel( bspModel_t *model, m4x4_t transform ){ filters a picomodel's surfaces into the raytracing tree */ -static void PopulateWithPicoModel( int castShadows, picoModel_t *model, m4x4_t transform ){ +static void PopulateWithPicoModel( int castShadows, picoModel_t *model, const Matrix4& transform ){ int i, j, k, numSurfaces, numIndexes; picoSurface_t *surface; picoShader_t *shader; - picoVec_t *xyz, *st; picoIndex_t *indexes; traceInfo_t ti; traceWinding_t tw; /* dummy check */ - if ( model == NULL || transform == NULL ) { + if ( model == NULL ) { return; } @@ -1080,11 +1070,9 @@ static void PopulateWithPicoModel( int castShadows, picoModel_t *model, m4x4_t t { for ( k = 0; k < 3; k++ ) { - xyz = PicoGetSurfaceXYZ( surface, indexes[ k ] ); - st = PicoGetSurfaceST( surface, 0, indexes[ k ] ); - VectorCopy( xyz, tw.v[ k ].xyz ); - Vector2Copy( st, tw.v[ k ].st ); - m4x4_transform_point( transform, tw.v[ k ].xyz ); + tw.v[ k ].xyz = vector3_from_array( PicoGetSurfaceXYZ( surface, indexes[ k ] ) ); + tw.v[ k ].st = vector2_from_array( PicoGetSurfaceST( surface, 0, indexes[ k ] ) ); + matrix4_transform_point( transform, tw.v[ k ].xyz ); } FilterTraceWindingIntoNodes_r( &tw, headNodeNum ); } @@ -1105,8 +1093,7 @@ static void PopulateTraceNodes( void ){ /* add worldspawn triangles */ - m4x4_t transform; - m4x4_identity( transform ); + Matrix4 transform( g_matrix4_identity ); PopulateWithBSPModel( &bspModels[ 0 ], transform ); /* walk each entity list */ @@ -1125,24 +1112,24 @@ static void PopulateTraceNodes( void ){ } /* get entity origin */ - vec3_t origin; + Vector3 origin; e->vectorForKey( "origin", origin ); /* get scale */ - vec3_t scale = { 1.f, 1.f, 1.f }; + Vector3 scale = { 1.f, 1.f, 1.f }; if( !e->read_keyvalue( scale, "modelscale_vec" ) ) if( e->read_keyvalue( scale[0], "modelscale" ) ) scale[1] = scale[2] = scale[0]; /* get "angle" (yaw) or "angles" (pitch yaw roll), store as (roll pitch yaw) */ - vec3_t angles = { 0.f, 0.f, 0.f }; + Vector3 angles = { 0.f, 0.f, 0.f }; if ( !e->read_keyvalue( value, "angles" ) || 3 != sscanf( value, "%f %f %f", &angles[ 1 ], &angles[ 2 ], &angles[ 0 ] ) ) e->read_keyvalue( angles[ 2 ], "angle" ); /* set transform matrix (thanks spog) */ - m4x4_identity( transform ); - m4x4_pivoted_transform_by_vec3( transform, origin, angles, eXYZ, scale, vec3_origin ); + transform = g_matrix4_identity; + matrix4_transform_by_euler_xyz_degrees( transform, origin, angles, scale ); /* hack: Stable-1_2 and trunk have differing row/column major matrix order this transpose is necessary with Stable-1_2 @@ -1320,7 +1307,7 @@ void SetupTraceNodes( void ){ bool TraceTriangle( traceInfo_t *ti, traceTriangle_t *tt, trace_t *trace ){ int i; - float tvec[ 3 ], pvec[ 3 ], qvec[ 3 ]; + Vector3 tvec, pvec, qvec; float det, invDet, depth; float u, v, w, s, t; int is, it; @@ -1366,10 +1353,10 @@ bool TraceTriangle( traceInfo_t *ti, traceTriangle_t *tt, trace_t *trace ){ } /* begin calculating determinant - also used to calculate u parameter */ - CrossProduct( trace->direction, tt->edge2, pvec ); + pvec = vector3_cross( trace->direction, tt->edge2 ); /* if determinant is near zero, trace lies in plane of triangle */ - det = DotProduct( tt->edge1, pvec ); + det = vector3_dot( tt->edge1, pvec ); /* the non-culling branch */ if ( fabs( det ) < COPLANAR_EPSILON ) { @@ -1378,25 +1365,25 @@ bool TraceTriangle( traceInfo_t *ti, traceTriangle_t *tt, trace_t *trace ){ invDet = 1.0f / det; /* calculate distance from first vertex to ray origin */ - VectorSubtract( trace->origin, tt->v[ 0 ].xyz, tvec ); + tvec = trace->origin - tt->v[ 0 ].xyz; /* calculate u parameter and test bounds */ - u = DotProduct( tvec, pvec ) * invDet; + u = vector3_dot( tvec, pvec ) * invDet; if ( u < -BARY_EPSILON || u > ( 1.0f + BARY_EPSILON ) ) { return false; } /* prepare to test v parameter */ - CrossProduct( tvec, tt->edge1, qvec ); + qvec = vector3_cross( tvec, tt->edge1 ); /* calculate v parameter and test bounds */ - v = DotProduct( trace->direction, qvec ) * invDet; + v = vector3_dot( trace->direction, qvec ) * invDet; if ( v < -BARY_EPSILON || ( u + v ) > ( 1.0f + BARY_EPSILON ) ) { return false; } /* calculate t (depth) */ - depth = DotProduct( tt->edge2, qvec ) * invDet; + depth = vector3_dot( tt->edge2, qvec ) * invDet; if ( depth <= trace->inhibitRadius || depth >= trace->distance ) { return false; } @@ -1423,8 +1410,8 @@ bool TraceTriangle( traceInfo_t *ti, traceTriangle_t *tt, trace_t *trace ){ /* most surfaces are completely opaque */ if ( !( si->compileFlags & ( C_ALPHASHADOW | C_LIGHTFILTER ) ) || si->lightImage == NULL || si->lightImage->pixels == NULL ) { - VectorMA( trace->origin, depth, trace->direction, trace->hit ); - VectorClear( trace->color ); + trace->hit = trace->origin + trace->direction * depth; + trace->color.set( 0 ); trace->opaque = true; return true; } @@ -1483,8 +1470,8 @@ bool TraceTriangle( traceInfo_t *ti, traceTriangle_t *tt, trace_t *trace ){ /* check filter for opaque */ if ( trace->color[ 0 ] <= 0.001f && trace->color[ 1 ] <= 0.001f && trace->color[ 2 ] <= 0.001f ) { - VectorClear( trace->color ); - VectorMA( trace->origin, depth, trace->direction, trace->hit ); + trace->color.set( 0 ); + trace->hit = trace->origin + trace->direction * depth; trace->opaque = true; return true; } @@ -1517,8 +1504,8 @@ bool TraceWinding( traceWinding_t *tw, trace_t *trace ){ tt.v[ 2 ] = tw->v[ i + 1 ]; /* find vectors for two edges sharing the first vert */ - VectorSubtract( tt.v[ 1 ].xyz, tt.v[ 0 ].xyz, tt.edge1 ); - VectorSubtract( tt.v[ 2 ].xyz, tt.v[ 0 ].xyz, tt.edge2 ); + tt.edge1 = tt.v[ 1 ].xyz - tt.v[ 0 ].xyz; + tt.edge2 = tt.v[ 2 ].xyz - tt.v[ 0 ].xyz; /* trace it */ if ( TraceTriangle( &traceInfos[ tt.infoNum ], &tt, trace ) ) { @@ -1543,26 +1530,25 @@ bool TraceWinding( traceWinding_t *tw, trace_t *trace ){ #define TRACELINE_R_HALF_ITERATIVE 1 #if TRACELINE_R_HALF_ITERATIVE -static bool TraceLine_r( int nodeNum, const vec3_t start, const vec3_t end, trace_t *trace ) +static bool TraceLine_r( int nodeNum, const Vector3& start, const Vector3& end, trace_t *trace ) #else -static bool TraceLine_r( int nodeNum, const vec3_t origin, const vec3_t end, trace_t *trace ) +static bool TraceLine_r( int nodeNum, const Vector3& origin, const Vector3& end, trace_t *trace ) #endif { traceNode_t *node; int side; float front, back, frac; - vec3_t mid; + Vector3 mid; #if TRACELINE_R_HALF_ITERATIVE - vec3_t origin; - VectorCopy( start, origin ); + Vector3 origin( start ); while ( 1 ) #endif { /* bogus node number means solid, end tracing unless testing all */ if ( nodeNum < 0 ) { - VectorCopy( origin, trace->hit ); + trace->hit = origin; trace->passSolid = true; return true; } @@ -1572,7 +1558,7 @@ static bool TraceLine_r( int nodeNum, const vec3_t origin, const vec3_t end, tra /* solid? */ if ( node->type == TRACE_LEAF_SOLID ) { - VectorCopy( origin, trace->hit ); + trace->hit = origin; trace->passSolid = true; return true; } @@ -1594,24 +1580,24 @@ static bool TraceLine_r( int nodeNum, const vec3_t origin, const vec3_t end, tra /* classify beginning and end points */ switch ( node->type ) { - case PLANE_X: - front = origin[ 0 ] - node->plane[ 3 ]; - back = end[ 0 ] - node->plane[ 3 ]; + case ePlaneX: + front = origin[ 0 ] - node->plane.dist(); + back = end[ 0 ] - node->plane.dist(); break; - case PLANE_Y: - front = origin[ 1 ] - node->plane[ 3 ]; - back = end[ 1 ] - node->plane[ 3 ]; + case ePlaneY: + front = origin[ 1 ] - node->plane.dist(); + back = end[ 1 ] - node->plane.dist(); break; - case PLANE_Z: - front = origin[ 2 ] - node->plane[ 3 ]; - back = end[ 2 ] - node->plane[ 3 ]; + case ePlaneZ: + front = origin[ 2 ] - node->plane.dist(); + back = end[ 2 ] - node->plane.dist(); break; default: - front = DotProduct( origin, node->plane ) - node->plane[ 3 ]; - back = DotProduct( end, node->plane ) - node->plane[ 3 ]; + front = plane3_distance_to_point( node->plane, origin ); + back = plane3_distance_to_point( node->plane, end ); break; } @@ -1640,14 +1626,12 @@ static bool TraceLine_r( int nodeNum, const vec3_t origin, const vec3_t end, tra /* calculate intercept point */ frac = front / ( front - back ); - mid[ 0 ] = origin[ 0 ] + ( end[ 0 ] - origin[ 0 ] ) * frac; - mid[ 1 ] = origin[ 1 ] + ( end[ 1 ] - origin[ 1 ] ) * frac; - mid[ 2 ] = origin[ 2 ] + ( end[ 2 ] - origin[ 2 ] ) * frac; + mid = origin + ( end - origin ) * frac; /* fixme: check inhibit radius, then solid nodes and ignore */ /* set trace hit here */ - //% VectorCopy( mid, trace->hit ); + //% trace->hit = mid; /* trace first side */ if ( TraceLine_r( node->children[ side ], origin, mid, trace ) ) { @@ -1657,7 +1641,7 @@ static bool TraceLine_r( int nodeNum, const vec3_t origin, const vec3_t end, tra /* trace other side */ #if TRACELINE_R_HALF_ITERATIVE nodeNum = node->children[ !side ]; - VectorCopy( mid, origin ); + origin = mid; #else return TraceLine_r( node->children[ !side ], mid, end, trace ); #endif @@ -1737,8 +1721,9 @@ void TraceLine( trace_t *trace ){ */ float SetupTrace( trace_t *trace ){ - VectorSubtract( trace->end, trace->origin, trace->displacement ); - trace->distance = VectorFastNormalize( trace->displacement, trace->direction ); - VectorCopy( trace->origin, trace->hit ); + trace->displacement = trace->end - trace->origin; + trace->direction = trace->displacement; + trace->distance = VectorFastNormalize( trace->direction ); + trace->hit = trace->origin; return trace->distance; } diff --git a/tools/quake3/q3map2/light_ydnar.cpp b/tools/quake3/q3map2/light_ydnar.cpp index da318aca..fc660c0d 100644 --- a/tools/quake3/q3map2/light_ydnar.cpp +++ b/tools/quake3/q3map2/light_ydnar.cpp @@ -39,10 +39,9 @@ ydnar: moved to here 2001-02-04 */ -void ColorToBytes( const float *color, byte *colorBytes, float scale ){ +void ColorToBytes( const Vector3& color, Vector3b& colorBytes, float scale ){ int i; float max, gamma; - vec3_t sample; float inv, dif; @@ -52,7 +51,7 @@ void ColorToBytes( const float *color, byte *colorBytes, float scale ){ } /* make a local copy */ - VectorScale( color, scale, sample ); + Vector3 sample = color * scale; /* muck with it */ gamma = 1.0f / lightmapGamma; @@ -72,7 +71,7 @@ void ColorToBytes( const float *color, byte *colorBytes, float scale ){ /* clamp with color normalization */ max = VectorMax( sample ); if ( max > maxLight ) { - VectorScale( sample, ( maxLight / max ), sample ); + sample *= ( maxLight / max ); } } else @@ -92,15 +91,12 @@ void ColorToBytes( const float *color, byte *colorBytes, float scale ){ dif = 0; } - for ( i = 0; i < 3; i++ ) - { - sample[i] *= dif; - } + sample *= dif; } /* compensate for ingame overbrighting/bitshifting */ - VectorScale( sample, ( 1.0f / lightmapCompensate ), sample ); + sample *= ( 1.0f / lightmapCompensate ); /* contrast */ if ( lightmapContrast != 1.0f ){ @@ -113,7 +109,7 @@ void ColorToBytes( const float *color, byte *colorBytes, float scale ){ /* clamp with color normalization */ max = VectorMax( sample ); if ( max > 255.0f ) { - VectorScale( sample, ( 255.0f / max ), sample ); + sample *= ( 255.0f / max ); } } @@ -125,9 +121,7 @@ void ColorToBytes( const float *color, byte *colorBytes, float scale ){ } /* store it off */ - colorBytes[ 0 ] = sample[ 0 ]; - colorBytes[ 1 ] = sample[ 1 ]; - colorBytes[ 2 ] = sample[ 2 ]; + colorBytes = sample; } @@ -145,7 +139,7 @@ void ColorToBytes( const float *color, byte *colorBytes, float scale ){ #define MAX_SAMPLES 256 #define THETA_EPSILON 0.000001 -#define EQUAL_NORMAL_EPSILON 0.01 +#define EQUAL_NORMAL_EPSILON 0.01f void SmoothNormals( void ){ int i, j, k, f, numVerts, numVotes, fOld, start; @@ -154,9 +148,9 @@ void SmoothNormals( void ){ shaderInfo_t *si; float *shadeAngles; byte *smoothed; - vec3_t average, diff; + Vector3 average; int indexes[ MAX_SAMPLES ]; - vec3_t votes[ MAX_SAMPLES ]; + Vector3 votes[ MAX_SAMPLES ]; /* allocate shade angle table */ @@ -166,7 +160,7 @@ void SmoothNormals( void ){ smoothed = safe_calloc( ( numBSPDrawVerts / 8 ) + 1 ); /* set default shade angle */ - defaultShadeAngle = DEG2RAD( shadeAngleDegrees ); + defaultShadeAngle = degrees_to_radians( shadeAngleDegrees ); maxShadeAngle = 0; /* run through every surface and flag verts belonging to non-lightmapped surfaces @@ -179,7 +173,7 @@ void SmoothNormals( void ){ /* get shader for shade angle */ si = surfaceInfos[ i ].si; if ( si->shadeAngleDegrees ) { - shadeAngle = DEG2RAD( si->shadeAngleDegrees ); + shadeAngle = degrees_to_radians( si->shadeAngleDegrees ); } else{ shadeAngle = defaultShadeAngle; @@ -232,7 +226,7 @@ void SmoothNormals( void ){ } /* clear */ - VectorClear( average ); + average.set( 0 ); numVerts = 0; numVotes = 0; @@ -253,7 +247,7 @@ void SmoothNormals( void ){ shadeAngle = ( shadeAngles[ i ] < shadeAngles[ j ] ? shadeAngles[ i ] : shadeAngles[ j ] ); /* check shade angle */ - dot = DotProduct( bspDrawVerts[ i ].normal, bspDrawVerts[ j ].normal ); + dot = vector3_dot( bspDrawVerts[ i ].normal, bspDrawVerts[ j ].normal ); if ( dot > 1.0 ) { dot = 1.0; } @@ -276,18 +270,15 @@ void SmoothNormals( void ){ /* see if this normal has already been voted */ for ( k = 0; k < numVotes; k++ ) { - VectorSubtract( bspDrawVerts[ j ].normal, votes[ k ], diff ); - if ( fabs( diff[ 0 ] ) < EQUAL_NORMAL_EPSILON && - fabs( diff[ 1 ] ) < EQUAL_NORMAL_EPSILON && - fabs( diff[ 2 ] ) < EQUAL_NORMAL_EPSILON ) { + if ( vector3_equal_epsilon( bspDrawVerts[ j ].normal, votes[ k ], EQUAL_NORMAL_EPSILON ) ) { break; } } /* add a new vote? */ if ( k == numVotes && numVotes < MAX_SAMPLES ) { - VectorAdd( average, bspDrawVerts[ j ].normal, average ); - VectorCopy( bspDrawVerts[ j ].normal, votes[ numVotes ] ); + average += bspDrawVerts[ j ].normal; + votes[ numVotes ] = bspDrawVerts[ j ].normal; numVotes++; } } @@ -298,10 +289,10 @@ void SmoothNormals( void ){ } /* average normal */ - if ( VectorNormalize( average, average ) > 0 ) { + if ( VectorNormalize( average ) != 0 ) { /* smooth */ for ( j = 0; j < numVerts; j++ ) - VectorCopy( average, yDrawVerts[ indexes[ j ] ].normal ); + yDrawVerts[ indexes[ j ] ].normal = average; } } @@ -328,10 +319,10 @@ void SmoothNormals( void ){ calculates the st tangent vectors for normalmapping */ -static bool CalcTangentVectors( int numVerts, bspDrawVert_t **dv, vec3_t *stv, vec3_t *ttv ){ +static bool CalcTangentVectors( int numVerts, bspDrawVert_t **dv, Vector3 *stv, Vector3 *ttv ){ int i; float bb, s, t; - vec3_t bary; + Vector3 bary; /* calculate barycentric basis for the triangle */ @@ -354,8 +345,8 @@ static bool CalcTangentVectors( int numVerts, bspDrawVert_t **dv, vec3_t *stv, v stv[ i ][ 1 ] = bary[ 0 ] * dv[ 0 ]->xyz[ 1 ] + bary[ 1 ] * dv[ 1 ]->xyz[ 1 ] + bary[ 2 ] * dv[ 2 ]->xyz[ 1 ]; stv[ i ][ 2 ] = bary[ 0 ] * dv[ 0 ]->xyz[ 2 ] + bary[ 1 ] * dv[ 1 ]->xyz[ 2 ] + bary[ 2 ] * dv[ 2 ]->xyz[ 2 ]; - VectorSubtract( stv[ i ], dv[ i ]->xyz, stv[ i ] ); - VectorNormalize( stv[ i ], stv[ i ] ); + stv[ i ] -= dv[ i ]->xyz; + VectorNormalize( stv[ i ] ); /* calculate t tangent vector */ s = dv[ i ]->st[ 0 ]; @@ -368,8 +359,8 @@ static bool CalcTangentVectors( int numVerts, bspDrawVert_t **dv, vec3_t *stv, v ttv[ i ][ 1 ] = bary[ 0 ] * dv[ 0 ]->xyz[ 1 ] + bary[ 1 ] * dv[ 1 ]->xyz[ 1 ] + bary[ 2 ] * dv[ 2 ]->xyz[ 1 ]; ttv[ i ][ 2 ] = bary[ 0 ] * dv[ 0 ]->xyz[ 2 ] + bary[ 1 ] * dv[ 1 ]->xyz[ 2 ] + bary[ 2 ] * dv[ 2 ]->xyz[ 2 ]; - VectorSubtract( ttv[ i ], dv[ i ]->xyz, ttv[ i ] ); - VectorNormalize( ttv[ i ], ttv[ i ] ); + ttv[ i ] -= dv[ i ]->xyz; + VectorNormalize( ttv[ i ] ); /* debug code */ //% Sys_FPrintf( SYS_VRB, "%d S: (%f %f %f) T: (%f %f %f)\n", i, @@ -388,30 +379,24 @@ static bool CalcTangentVectors( int numVerts, bspDrawVert_t **dv, vec3_t *stv, v perterbs the normal by the shader's normalmap in tangent space */ -static void PerturbNormal( bspDrawVert_t *dv, shaderInfo_t *si, vec3_t pNormal, vec3_t stv[ 3 ], vec3_t ttv[ 3 ] ){ - int i; - vec4_t bump; - - +static void PerturbNormal( bspDrawVert_t *dv, shaderInfo_t *si, Vector3& pNormal, const Vector3 stv[ 3 ], const Vector3 ttv[ 3 ] ){ /* passthrough */ - VectorCopy( dv->normal, pNormal ); + pNormal = dv->normal; /* sample normalmap */ + Color4f bump; if ( !RadSampleImage( si->normalImage->pixels, si->normalImage->width, si->normalImage->height, dv->st, bump ) ) { return; } /* remap sampled normal from [0,255] to [-1,-1] */ - for ( i = 0; i < 3; i++ ) - bump[ i ] = ( bump[ i ] - 127.0f ) * ( 1.0f / 127.5f ); + bump.rgb() = ( bump.rgb() - Vector3().set( 127.0f ) ) * ( 1.0f / 127.5f ); /* scale tangent vectors and add to original normal */ - VectorMA( dv->normal, bump[ 0 ], stv[ 0 ], pNormal ); - VectorMA( pNormal, bump[ 1 ], ttv[ 0 ], pNormal ); - VectorMA( pNormal, bump[ 2 ], dv->normal, pNormal ); + pNormal = dv->normal + stv[ 0 ] * bump[ 0 ] + ttv[ 0 ] * bump[ 1 ] + dv->normal * bump[ 2 ]; /* renormalize and return */ - VectorNormalize( pNormal, pNormal ); + VectorNormalize( pNormal ); } @@ -424,18 +409,15 @@ static void PerturbNormal( bspDrawVert_t *dv, shaderInfo_t *si, vec3_t pNormal, #define NUDGE 0.5f #define BOGUS_NUDGE -99999.0f -static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv, vec4_t plane, float pass, vec3_t stv[ 3 ], vec3_t ttv[ 3 ], vec3_t worldverts[ 3 ] ){ - int i, x, y, numClusters, *clusters, pointCluster, *cluster; - float *luxel, *origin, *normal, d, lightmapSampleOffset; +static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv, const Plane3f* plane, float pass, const Vector3 stv[ 3 ], const Vector3 ttv[ 3 ], const Vector3 worldverts[ 3 ] ){ + int i, x, y, numClusters, *clusters, pointCluster; + float lightmapSampleOffset; shaderInfo_t *si; - vec3_t pNormal; - vec3_t vecs[ 3 ]; - vec3_t nudged; - vec3_t cverts[ 3 ]; - vec3_t temp; - vec4_t sideplane, hostplane; - vec3_t origintwo; - int j, next; + Vector3 pNormal; + Vector3 vecs[ 3 ]; + Vector3 nudged; + Vector3 origintwo; + int j; float *nudge; static float nudges[][ 2 ] = { @@ -482,30 +464,30 @@ static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t } /* get luxel, origin, cluster, and normal */ - luxel = SUPER_LUXEL( 0, x, y ); - origin = SUPER_ORIGIN( x, y ); - normal = SUPER_NORMAL( x, y ); - cluster = SUPER_CLUSTER( x, y ); + SuperLuxel& luxel = lm->getSuperLuxel( 0, x, y ); + Vector3& origin = lm->getSuperOrigin( x, y ); + Vector3& normal = lm->getSuperNormal( x, y ); + int& cluster = lm->getSuperCluster( x, y ); /* don't attempt to remap occluded luxels for planar surfaces */ - if ( ( *cluster ) == CLUSTER_OCCLUDED && lm->plane != NULL ) { - return ( *cluster ); + if ( cluster == CLUSTER_OCCLUDED && lm->plane != NULL ) { + return cluster; } /* only average the normal for premapped luxels */ - else if ( ( *cluster ) >= 0 ) { + else if ( cluster >= 0 ) { /* do bumpmap calculations */ if ( stv != NULL ) { PerturbNormal( dv, si, pNormal, stv, ttv ); } else{ - VectorCopy( dv->normal, pNormal ); + pNormal = dv->normal; } /* add the additional normal data */ - VectorAdd( normal, pNormal, normal ); - luxel[ 3 ] += 1.0f; - return ( *cluster ); + normal += pNormal; + luxel.count += 1.0f; + return cluster; } /* otherwise, unmapped luxels (*cluster == CLUSTER_UNMAPPED) will have their full attributes calculated */ @@ -515,7 +497,7 @@ static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t /* axial lightmap projection */ if ( lm->vecs != NULL ) { /* calculate an origin for the sample from the lightmap vectors */ - VectorCopy( lm->origin, origin ); + origin = lm->origin; for ( i = 0; i < 3; i++ ) { /* add unless it's the axis, which is taken care of later */ @@ -526,14 +508,12 @@ static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t } /* project the origin onto the plane */ - d = DotProduct( origin, plane ) - plane[ 3 ]; - d /= plane[ lm->axisNum ]; - origin[ lm->axisNum ] -= d; + origin[ lm->axisNum ] -= plane3_distance_to_point( *plane, origin ) / plane->normal()[ lm->axisNum ]; } /* non axial lightmap projection (explicit xyz) */ else{ - VectorCopy( dv->xyz, origin ); + origin = dv->xyz; } ////////////////////// @@ -542,31 +522,26 @@ static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t //2) if it does, nudge it onto the correct side. if ( worldverts != NULL && lightmapTriangleCheck ) { - for ( j = 0; j < 3; j++ ) - { - VectorCopy( worldverts[j],cverts[j] ); - } - PlaneFromPoints( hostplane,cverts[0],cverts[1],cverts[2] ); + Plane3f hostplane; + PlaneFromPoints( hostplane, worldverts[0], worldverts[1], worldverts[2] ); for ( j = 0; j < 3; j++ ) { for ( i = 0; i < 3; i++ ) { + Plane3f sideplane; //build plane using 2 edges and a normal - next = ( i + 1 ) % 3; - - VectorCopy( cverts[next],temp ); - VectorAdd( temp,hostplane,temp ); - PlaneFromPoints( sideplane,cverts[i],cverts[ next ], temp ); + const int next = ( i + 1 ) % 3; + PlaneFromPoints( sideplane, worldverts[i], worldverts[ next ], worldverts[ next ] + hostplane.normal() ); //planetest sample point - const float e = DotProduct( origin, sideplane ) - sideplane[3]; + const float e = plane3_distance_to_point( sideplane, origin ); if ( e > -LUXEL_EPSILON ) { //we're bad. //Move the sample point back inside triangle bounds - VectorMA( origin, ( -e - 1 ), sideplane, origin ); + origin -= sideplane.normal() * ( e + 1 ); #ifdef DEBUG_27_1 - VectorClear( origin ); + origin.set( 0 ); #endif } } @@ -577,19 +552,19 @@ static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t /* planar surfaces have precalculated lightmap vectors for nudging */ if ( lm->plane != NULL ) { - VectorCopy( lm->vecs[ 0 ], vecs[ 0 ] ); - VectorCopy( lm->vecs[ 1 ], vecs[ 1 ] ); - VectorCopy( lm->plane, vecs[ 2 ] ); + vecs[ 0 ] = lm->vecs[ 0 ]; + vecs[ 1 ] = lm->vecs[ 1 ]; + vecs[ 2 ] = lm->plane->normal(); } /* non-planar surfaces must calculate them */ else { if ( plane != NULL ) { - VectorCopy( plane, vecs[ 2 ] ); + vecs[ 2 ] = plane->normal(); } else{ - VectorCopy( dv->normal, vecs[ 2 ] ); + vecs[ 2 ] = dv->normal; } MakeNormalVectors( vecs[ 2 ], vecs[ 0 ], vecs[ 1 ] ); } @@ -602,7 +577,7 @@ static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t lightmapSampleOffset = DEFAULT_LIGHTMAP_SAMPLE_OFFSET; } if ( lm->axisNum < 0 ) { - VectorMA( origin, lightmapSampleOffset, vecs[ 2 ], origin ); + origin += vecs[ 2 ] * lightmapSampleOffset; } else if ( vecs[ 2 ][ lm->axisNum ] < 0.0f ) { origin[ lm->axisNum ] -= lightmapSampleOffset; @@ -611,16 +586,16 @@ static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t origin[ lm->axisNum ] += lightmapSampleOffset; } - VectorCopy( origin,origintwo ); + origintwo = origin; if ( lightmapExtraVisClusterNudge ) { - VectorAdd( origintwo, vecs[2], origintwo ); + origintwo += vecs[2]; } /* get cluster */ pointCluster = ClusterForPointExtFilter( origintwo, LUXEL_EPSILON, numClusters, clusters ); /* another retarded hack, storing nudge count in luxel[ 1 ] */ - luxel[ 1 ] = 0.0f; + luxel.value[ 1 ] = 0.0f; /* point in solid? (except in dark mode) */ if ( pointCluster < 0 && !dark ) { @@ -629,39 +604,36 @@ static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t while ( nudge[ 0 ] > BOGUS_NUDGE && pointCluster < 0 ) { /* nudge the vector around a bit */ - for ( i = 0; i < 3; i++ ) - { - /* set nudged point*/ - nudged[ i ] = origintwo[ i ] + ( nudge[ 0 ] * vecs[ 0 ][ i ] ) + ( nudge[ 1 ] * vecs[ 1 ][ i ] ); - } + /* set nudged point*/ + nudged = origintwo + vecs[ 0 ] * nudge[ 0 ] + vecs[ 1 ] * nudge[ 1 ]; nudge += 2; /* get pvs cluster */ pointCluster = ClusterForPointExtFilter( nudged, LUXEL_EPSILON, numClusters, clusters ); //% + 0.625 ); if ( pointCluster >= 0 ) { - VectorCopy( nudged, origin ); + origin = nudged; } - luxel[ 1 ] += 1.0f; + luxel.value[ 1 ] += 1.0f; } } /* as a last resort, if still in solid, try drawvert origin offset by normal (except in dark mode) */ if ( pointCluster < 0 && si != NULL && !dark ) { - VectorMA( dv->xyz, lightmapSampleOffset, dv->normal, nudged ); + nudged = dv->xyz + dv->normal * lightmapSampleOffset; pointCluster = ClusterForPointExtFilter( nudged, LUXEL_EPSILON, numClusters, clusters ); if ( pointCluster >= 0 ) { - VectorCopy( nudged, origin ); + origin = nudged; } - luxel[ 1 ] += 1.0f; + luxel.value[ 1 ] += 1.0f; } /* valid? */ if ( pointCluster < 0 ) { - ( *cluster ) = CLUSTER_OCCLUDED; - VectorClear( origin ); - VectorClear( normal ); + cluster = CLUSTER_OCCLUDED; + origin.set( 0 ); + normal.set( 0 ); numLuxelsOccluded++; - return ( *cluster ); + return cluster; } /* debug code */ @@ -672,22 +644,22 @@ static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t PerturbNormal( dv, si, pNormal, stv, ttv ); } else{ - VectorCopy( dv->normal, pNormal ); + pNormal = dv->normal; } /* store the cluster and normal */ - ( *cluster ) = pointCluster; - VectorCopy( pNormal, normal ); + cluster = pointCluster; + normal = pNormal; /* store explicit mapping pass and implicit mapping pass */ - luxel[ 0 ] = pass; - luxel[ 3 ] = 1.0f; + luxel.value[ 0 ] = pass; + luxel.count = 1.0f; /* add to count */ numLuxelsMapped++; /* return ok */ - return ( *cluster ); + return cluster; } @@ -698,7 +670,7 @@ static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t than the distance between two luxels (thanks jc :) */ -static void MapTriangle_r( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv[ 3 ], vec4_t plane, vec3_t stv[ 3 ], vec3_t ttv[ 3 ], vec3_t worldverts[ 3 ] ){ +static void MapTriangle_r( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv[ 3 ], Plane3f *plane, const Vector3 stv[ 3 ], const Vector3 ttv[ 3 ], const Vector3 worldverts[ 3 ] ){ bspDrawVert_t mid, *dv2[ 3 ]; int max; @@ -712,24 +684,13 @@ static void MapTriangle_r( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t /* subdivide calc */ { - int i; - float *a, *b, dx, dy, dist, maxDist; - - /* find the longest edge and split it */ max = -1; - maxDist = 0; - for ( i = 0; i < 3; i++ ) + float maxDist = 0; + for ( int i = 0; i < 3; i++ ) { - /* get verts */ - a = dv[ i ]->lightmap[ 0 ]; - b = dv[ ( i + 1 ) % 3 ]->lightmap[ 0 ]; - - /* get dists */ - dx = a[ 0 ] - b[ 0 ]; - dy = a[ 1 ] - b[ 1 ]; - dist = ( dx * dx ) + ( dy * dy ); //% sqrt( (dx * dx) + (dy * dy) ); - + /* get dist */ + const float dist = vector2_length_squared( dv[ i ]->lightmap[ 0 ] - dv[ ( i + 1 ) % 3 ]->lightmap[ 0 ] ); /* longer? */ if ( dist > maxDist ) { maxDist = dist; @@ -770,29 +731,23 @@ static void MapTriangle_r( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t */ static bool MapTriangle( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv[ 3 ], bool mapNonAxial ){ - int i; - vec4_t plane; - vec3_t *stv, *ttv, stvStatic[ 3 ], ttvStatic[ 3 ]; - vec3_t worldverts[ 3 ]; - - + Plane3f plane; /* get plane if possible */ if ( lm->plane != NULL ) { - VectorCopy( lm->plane, plane ); - plane[ 3 ] = lm->plane[ 3 ]; + plane = *lm->plane; } - /* otherwise make one from the points */ else if ( !PlaneFromPoints( plane, dv[ 0 ]->xyz, dv[ 1 ]->xyz, dv[ 2 ]->xyz ) ) { return false; } /* this must not happen in the first place, but it does and spreads result of division by zero in MapSingleLuxel all over the map during -bounce */ - if( lm->vecs != NULL && plane[lm->axisNum] == 0 ){ + if( lm->vecs != NULL && plane.normal()[lm->axisNum] == 0 ){ Sys_Warning( "plane[lm->axisNum] == 0\n" ); return false; } + Vector3 *stv, *ttv, stvStatic[ 3 ], ttvStatic[ 3 ]; /* check to see if we need to calculate texture->world tangent vectors */ if ( info->si->normalImage != NULL && CalcTangentVectors( 3, dv, stvStatic, ttvStatic ) ) { stv = stvStatic; @@ -804,31 +759,28 @@ static bool MapTriangle( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t * ttv = NULL; } - VectorCopy( dv[ 0 ]->xyz, worldverts[ 0 ] ); - VectorCopy( dv[ 1 ]->xyz, worldverts[ 1 ] ); - VectorCopy( dv[ 2 ]->xyz, worldverts[ 2 ] ); + const Vector3 worldverts[ 3 ] = { dv[ 0 ]->xyz, dv[ 1 ]->xyz, dv[ 2 ]->xyz }; /* map the vertexes */ - MapSingleLuxel( lm, info, dv[ 0 ], plane, 1, stv, ttv, worldverts ); - MapSingleLuxel( lm, info, dv[ 1 ], plane, 1, stv, ttv, worldverts ); - MapSingleLuxel( lm, info, dv[ 2 ], plane, 1, stv, ttv, worldverts ); + MapSingleLuxel( lm, info, dv[ 0 ], &plane, 1, stv, ttv, worldverts ); + MapSingleLuxel( lm, info, dv[ 1 ], &plane, 1, stv, ttv, worldverts ); + MapSingleLuxel( lm, info, dv[ 2 ], &plane, 1, stv, ttv, worldverts ); /* 2002-11-20: prefer axial triangle edges */ if ( mapNonAxial ) { /* subdivide the triangle */ - MapTriangle_r( lm, info, dv, plane, stv, ttv, worldverts ); + MapTriangle_r( lm, info, dv, &plane, stv, ttv, worldverts ); return true; } - for ( i = 0; i < 3; i++ ) + for ( int i = 0; i < 3; i++ ) { - float *a, *b; bspDrawVert_t *dv2[ 3 ]; /* get verts */ - a = dv[ i ]->lightmap[ 0 ]; - b = dv[ ( i + 1 ) % 3 ]->lightmap[ 0 ]; + const Vector2& a = dv[ i ]->lightmap[ 0 ]; + const Vector2& b = dv[ ( i + 1 ) % 3 ]->lightmap[ 0 ]; /* make degenerate triangles for mapping edges */ if ( fabs( a[ 0 ] - b[ 0 ] ) < 0.01f || fabs( a[ 1 ] - b[ 1 ] ) < 0.01f ) { @@ -837,7 +789,7 @@ static bool MapTriangle( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t * dv2[ 2 ] = dv[ ( i + 1 ) % 3 ]; /* map the degenerate triangle */ - MapTriangle_r( lm, info, dv2, plane, stv, ttv, worldverts ); + MapTriangle_r( lm, info, dv2, &plane, stv, ttv, worldverts ); } } @@ -852,31 +804,20 @@ static bool MapTriangle( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t * than the distance between two luxels */ -static void MapQuad_r( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv[ 4 ], vec4_t plane, vec3_t stv[ 4 ], vec3_t ttv[ 4 ] ){ +static void MapQuad_r( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv[ 4 ], Plane3f *plane, const Vector3 stv[ 4 ], const Vector3 ttv[ 4 ] ){ bspDrawVert_t mid[ 2 ], *dv2[ 4 ]; int max; /* subdivide calc */ { - int i; - float *a, *b, dx, dy, dist, maxDist; - - /* find the longest edge and split it */ max = -1; - maxDist = 0; - for ( i = 0; i < 4; i++ ) + float maxDist = 0; + for ( int i = 0; i < 4; i++ ) { - /* get verts */ - a = dv[ i ]->lightmap[ 0 ]; - b = dv[ ( i + 1 ) % 4 ]->lightmap[ 0 ]; - - /* get dists */ - dx = a[ 0 ] - b[ 0 ]; - dy = a[ 1 ] - b[ 1 ]; - dist = ( dx * dx ) + ( dy * dy ); //% sqrt( (dx * dx) + (dy * dy) ); - + /* get dist */ + const float dist = vector2_length_squared( dv[ i ]->lightmap[ 0 ] - dv[ ( i + 1 ) % 4 ]->lightmap[ 0 ] ); /* longer? */ if ( dist > maxDist ) { maxDist = dist; @@ -948,28 +889,22 @@ static void MapQuad_r( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv #define QUAD_PLANAR_EPSILON 0.5f static bool MapQuad( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv[ 4 ] ){ - float dist; - vec4_t plane; - vec3_t *stv, *ttv, stvStatic[ 4 ], ttvStatic[ 4 ]; - - + Plane3f plane; /* get plane if possible */ if ( lm->plane != NULL ) { - VectorCopy( lm->plane, plane ); - plane[ 3 ] = lm->plane[ 3 ]; + plane = *lm->plane; } - /* otherwise make one from the points */ else if ( !PlaneFromPoints( plane, dv[ 0 ]->xyz, dv[ 1 ]->xyz, dv[ 2 ]->xyz ) ) { return false; } /* 4th point must fall on the plane */ - dist = DotProduct( plane, dv[ 3 ]->xyz ) - plane[ 3 ]; - if ( fabs( dist ) > QUAD_PLANAR_EPSILON ) { + if ( fabs( plane3_distance_to_point( plane, dv[ 3 ]->xyz ) ) > QUAD_PLANAR_EPSILON ) { return false; } + Vector3 *stv, *ttv, stvStatic[ 4 ], ttvStatic[ 4 ]; /* check to see if we need to calculate texture->world tangent vectors */ if ( info->si->normalImage != NULL && CalcTangentVectors( 4, dv, stvStatic, ttvStatic ) ) { stv = stvStatic; @@ -982,13 +917,13 @@ static bool MapQuad( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv[ } /* map the vertexes */ - MapSingleLuxel( lm, info, dv[ 0 ], plane, 1, stv, ttv, NULL ); - MapSingleLuxel( lm, info, dv[ 1 ], plane, 1, stv, ttv, NULL ); - MapSingleLuxel( lm, info, dv[ 2 ], plane, 1, stv, ttv, NULL ); - MapSingleLuxel( lm, info, dv[ 3 ], plane, 1, stv, ttv, NULL ); + MapSingleLuxel( lm, info, dv[ 0 ], &plane, 1, stv, ttv, NULL ); + MapSingleLuxel( lm, info, dv[ 1 ], &plane, 1, stv, ttv, NULL ); + MapSingleLuxel( lm, info, dv[ 2 ], &plane, 1, stv, ttv, NULL ); + MapSingleLuxel( lm, info, dv[ 3 ], &plane, 1, stv, ttv, NULL ); /* subdivide the quad */ - MapQuad_r( lm, info, dv, plane, stv, ttv ); + MapQuad_r( lm, info, dv, &plane, stv, ttv ); return true; } @@ -999,11 +934,9 @@ static bool MapQuad( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv[ maps the locations, normals, and pvs clusters for a raw lightmap */ -#define VectorDivide( in, d, out ) VectorScale( in, ( 1.0f / ( d ) ), out ) //% (out)[ 0 ] = (in)[ 0 ] / (d), (out)[ 1 ] = (in)[ 1 ] / (d), (out)[ 2 ] = (in)[ 2 ] / (d) - void MapRawLightmap( int rawLightmapNum ){ - int n, num, i, x, y, sx, sy, pw[ 5 ], r, *cluster, mapNonAxial; - float *luxel, *origin, *normal, samples, radius, pass; + int n, num, i, x, y, sx, sy, pw[ 5 ], r, mapNonAxial; + float samples, radius, pass; rawLightmap_t *lm; bspDrawSurface_t *ds; surfaceInfo_t *info; @@ -1033,9 +966,9 @@ void MapRawLightmap( int rawLightmapNum ){ for ( x = 0; x < lm->sw; x++ ) { /* get cluster */ - cluster = SUPER_CLUSTER( x, y ); - if ( *cluster < 0 ) { - *cluster = CLUSTER_UNMAPPED; + int& cluster = lm->getSuperCluster( x, y ); + if ( cluster < 0 ) { + cluster = CLUSTER_UNMAPPED; } } } @@ -1193,22 +1126,20 @@ void MapRawLightmap( int rawLightmapNum ){ for ( x = 0; x < lm->sw; x++ ) { /* get luxel */ - luxel = SUPER_LUXEL( 0, x, y ); - normal = SUPER_NORMAL( x, y ); - cluster = SUPER_CLUSTER( x, y ); + SuperLuxel& luxel = lm->getSuperLuxel( 0, x, y ); /* only look at mapped luxels */ - if ( *cluster < 0 ) { + if ( lm->getSuperCluster( x, y ) < 0 ) { continue; } /* the normal data could be the sum of multiple samples */ - if ( luxel[ 3 ] > 1.0f ) { - VectorNormalize( normal, normal ); + if ( luxel.count > 1.0f ) { + VectorNormalize( lm->getSuperNormal( x, y ) ); } /* mark this luxel as having only one normal */ - luxel[ 3 ] = 1.0f; + luxel.count = 1.0f; } } @@ -1231,21 +1162,15 @@ void MapRawLightmap( int rawLightmapNum ){ { for ( x = 0; x < lm->sw; x++ ) { - /* get luxel */ - luxel = SUPER_LUXEL( 0, x, y ); - normal = SUPER_NORMAL( x, y ); - cluster = SUPER_CLUSTER( x, y ); - /* only look at unmapped luxels */ - if ( *cluster != CLUSTER_UNMAPPED ) { + if ( lm->getSuperCluster( x, y ) != CLUSTER_UNMAPPED ) { continue; } /* divine a normal and origin from neighboring luxels */ - VectorClear( fake.xyz ); - VectorClear( fake.normal ); - fake.lightmap[ 0 ][ 0 ] = x; //% 0.0001 + x; - fake.lightmap[ 0 ][ 1 ] = y; //% 0.0001 + y; + fake.xyz.set( 0 ); + fake.normal.set( 0 ); + fake.lightmap[ 0 ] = { x, y }; //% 0.0001 + x; //% 0.0001 + y; samples = 0.0f; for ( sy = ( y - 1 ); sy <= ( y + 1 ); sy++ ) { @@ -1260,20 +1185,17 @@ void MapRawLightmap( int rawLightmapNum ){ } /* get neighboring luxel */ - luxel = SUPER_LUXEL( 0, sx, sy ); - origin = SUPER_ORIGIN( sx, sy ); - normal = SUPER_NORMAL( sx, sy ); - cluster = SUPER_CLUSTER( sx, sy ); + const SuperLuxel& luxel = lm->getSuperLuxel( 0, sx, sy ); /* only consider luxels mapped in previous passes */ - if ( *cluster < 0 || luxel[ 0 ] >= pass ) { + if ( lm->getSuperCluster( sx, sy ) < 0 || luxel.value[ 0 ] >= pass ) { continue; } /* add its distinctiveness to our own */ - VectorAdd( fake.xyz, origin, fake.xyz ); - VectorAdd( fake.normal, normal, fake.normal ); - samples += luxel[ 3 ]; + fake.xyz += lm->getSuperOrigin( sx, sy ); + fake.normal += lm->getSuperNormal( sx, sy ); + samples += luxel.count; } } @@ -1283,9 +1205,9 @@ void MapRawLightmap( int rawLightmapNum ){ } /* average */ - VectorDivide( fake.xyz, samples, fake.xyz ); - //% VectorDivide( fake.normal, samples, fake.normal ); - if ( VectorNormalize( fake.normal, fake.normal ) == 0.0f ) { + fake.xyz *= ( 1.f / samples ); + //% fake.normal *= ( 1.f / samples ); + if ( VectorNormalize( fake.normal ) == 0.0f ) { continue; } @@ -1305,22 +1227,20 @@ void MapRawLightmap( int rawLightmapNum ){ for ( x = 0; x < lm->sw; x++ ) { /* get luxel */ - luxel = SUPER_LUXEL( 0, x, y ); - normal = SUPER_NORMAL( x, y ); - cluster = SUPER_CLUSTER( x, y ); + SuperLuxel& luxel = lm->getSuperLuxel( 0, x, y ); /* only look at mapped luxels */ - if ( *cluster < 0 ) { + if ( lm->getSuperCluster( x, y ) < 0 ) { continue; } /* the normal data could be the sum of multiple samples */ - if ( luxel[ 3 ] > 1.0f ) { - VectorNormalize( normal, normal ); + if ( luxel.count > 1.0f ) { + VectorNormalize( lm->getSuperNormal( x, y ) ); } /* mark this luxel as having only one normal */ - luxel[ 3 ] = 1.0f; + luxel.count = 1.0f; } } @@ -1331,30 +1251,25 @@ void MapRawLightmap( int rawLightmapNum ){ { for ( x = 0; x < lm->sw; x++ ) { - vec3_t mins, maxs; + const int cluster = lm->getSuperCluster( x, y ); + const Vector3& origin = lm->getSuperOrigin( x, y ); + const SuperLuxel& luxel = lm->getSuperLuxel( 0, x, y ); - - cluster = SUPER_CLUSTER( x, y ); - origin = SUPER_ORIGIN( x, y ); - normal = SUPER_NORMAL( x, y ); - luxel = SUPER_LUXEL( x, y ); - - if ( *cluster < 0 ) { + if ( cluster < 0 ) { continue; } /* check if within the bounding boxes of all surfaces referenced */ - ClearBounds( mins, maxs ); + MinMax minmax; for ( n = 0; n < lm->numLightSurfaces; n++ ) { - int TOL; info = &surfaceInfos[ lightSurfaces[ lm->firstLightSurface + n ] ]; - TOL = info->sampleSize + 2; - AddPointToBounds( info->mins, mins, maxs ); - AddPointToBounds( info->maxs, mins, maxs ); - if ( origin[ 0 ] > ( info->mins[ 0 ] - TOL ) && origin[ 0 ] < ( info->maxs[ 0 ] + TOL ) && - origin[ 1 ] > ( info->mins[ 1 ] - TOL ) && origin[ 1 ] < ( info->maxs[ 1 ] + TOL ) && - origin[ 2 ] > ( info->mins[ 2 ] - TOL ) && origin[ 2 ] < ( info->maxs[ 2 ] + TOL ) ) { + minmax.extend( info->minmax ); + MinMax minmax2 = info->minmax; + const float TOL = info->sampleSize + 2; + minmax2.mins -= Vector3( TOL, TOL, TOL ); + minmax2.maxs += Vector3( TOL, TOL, TOL ); + if( minmax2.test( origin ) ){ break; } } @@ -1366,11 +1281,11 @@ void MapRawLightmap( int rawLightmapNum ){ /* report bogus origin */ Sys_Printf( "%6d [%2d,%2d] (%4d): XYZ(%+4.1f %+4.1f %+4.1f) LO(%+4.1f %+4.1f %+4.1f) HI(%+4.1f %+4.1f %+4.1f) <%3.0f>\n", - rawLightmapNum, x, y, *cluster, + rawLightmapNum, x, y, cluster, origin[ 0 ], origin[ 1 ], origin[ 2 ], - mins[ 0 ], mins[ 1 ], mins[ 2 ], - maxs[ 0 ], maxs[ 1 ], maxs[ 2 ], - luxel[ 3 ] ); + minmax.mins[ 0 ], minmax.mins[ 1 ], minmax.mins[ 2 ], + minmax.maxs[ 0 ], minmax.maxs[ 1 ], minmax.maxs[ 2 ], + luxel.count ); } } #endif @@ -1388,7 +1303,7 @@ void MapRawLightmap( int rawLightmapNum ){ #define DIRT_NUM_ELEVATION_STEPS 3 #define DIRT_NUM_VECTORS ( DIRT_NUM_ANGLE_STEPS * DIRT_NUM_ELEVATION_STEPS ) -static vec3_t dirtVectors[ DIRT_NUM_VECTORS ]; +static Vector3 dirtVectors[ DIRT_NUM_VECTORS ]; static int numDirtVectors = 0; void SetupDirt( void ){ @@ -1400,8 +1315,8 @@ void SetupDirt( void ){ Sys_FPrintf( SYS_VRB, "--- SetupDirt ---\n" ); /* calculate angular steps */ - angleStep = DEG2RAD( 360.0f / DIRT_NUM_ANGLE_STEPS ); - elevationStep = DEG2RAD( DIRT_CONE_ANGLE / DIRT_NUM_ELEVATION_STEPS ); + angleStep = degrees_to_radians( 360.0f / DIRT_NUM_ANGLE_STEPS ); + elevationStep = degrees_to_radians( DIRT_CONE_ANGLE / DIRT_NUM_ELEVATION_STEPS ); /* iterate angle */ angle = 0.0f; @@ -1430,7 +1345,7 @@ void SetupDirt( void ){ float DirtForSample( trace_t *trace ){ int i; float gatherDirt, outDirt, angle, elevation, ooDepth; - vec3_t normal, worldUp, myUp, myRt, temp, direction, displacement; + Vector3 myUp, myRt; /* dummy check */ @@ -1444,26 +1359,23 @@ float DirtForSample( trace_t *trace ){ /* setup */ gatherDirt = 0.0f; ooDepth = 1.0f / dirtDepth; - VectorCopy( trace->normal, normal ); + const Vector3 normal( trace->normal ); /* check if the normal is aligned to the world-up */ if ( normal[ 0 ] == 0.0f && normal[ 1 ] == 0.0f && ( normal[ 2 ] == 1.0f || normal[ 2 ] == -1.0f ) ) { if ( normal[ 2 ] == 1.0f ) { - VectorSet( myRt, 1.0f, 0.0f, 0.0f ); - VectorSet( myUp, 0.0f, 1.0f, 0.0f ); + myRt = g_vector3_axis_x; + myUp = g_vector3_axis_y; } else if ( normal[ 2 ] == -1.0f ) { - VectorSet( myRt, -1.0f, 0.0f, 0.0f ); - VectorSet( myUp, 0.0f, 1.0f, 0.0f ); + myRt = -g_vector3_axis_x; + myUp = g_vector3_axis_y; } } else { - VectorSet( worldUp, 0.0f, 0.0f, 1.0f ); - CrossProduct( normal, worldUp, myRt ); - VectorNormalize( myRt, myRt ); - CrossProduct( myRt, normal, myUp ); - VectorNormalize( myUp, myUp ); + myRt = VectorNormalized( vector3_cross( normal, g_vector3_axis_z ) ); + myUp = VectorNormalized( vector3_cross( myRt, normal ) ); } /* 1 = random mode, 0 (well everything else) = non-random mode */ @@ -1472,27 +1384,24 @@ float DirtForSample( trace_t *trace ){ for ( i = 0; i < numDirtVectors; i++ ) { /* get random vector */ - angle = Random() * DEG2RAD( 360.0f ); - elevation = Random() * DEG2RAD( DIRT_CONE_ANGLE ); - temp[ 0 ] = cos( angle ) * sin( elevation ); - temp[ 1 ] = sin( angle ) * sin( elevation ); - temp[ 2 ] = cos( elevation ); + angle = Random() * degrees_to_radians( 360.0f ); + elevation = Random() * degrees_to_radians( DIRT_CONE_ANGLE ); + const Vector3 temp( cos( angle ) * sin( elevation ), + sin( angle ) * sin( elevation ), + cos( elevation ) ); /* transform into tangent space */ - direction[ 0 ] = myRt[ 0 ] * temp[ 0 ] + myUp[ 0 ] * temp[ 1 ] + normal[ 0 ] * temp[ 2 ]; - direction[ 1 ] = myRt[ 1 ] * temp[ 0 ] + myUp[ 1 ] * temp[ 1 ] + normal[ 1 ] * temp[ 2 ]; - direction[ 2 ] = myRt[ 2 ] * temp[ 0 ] + myUp[ 2 ] * temp[ 1 ] + normal[ 2 ] * temp[ 2 ]; + const Vector3 direction = myRt * temp[ 0 ] + myUp * temp[ 1 ] + normal * temp[ 2 ]; /* set endpoint */ - VectorMA( trace->origin, dirtDepth, direction, trace->end ); + trace->end = trace->origin + direction * dirtDepth; SetupTrace( trace ); - VectorSet(trace->color, 1.0f, 1.0f, 1.0f); + trace->color.set( 1 ); /* trace */ TraceLine( trace ); if ( trace->opaque && !( trace->compileFlags & C_SKY ) ) { - VectorSubtract( trace->hit, trace->origin, displacement ); - gatherDirt += 1.0f - ooDepth * VectorLength( displacement ); + gatherDirt += 1.0f - ooDepth * vector3_length( trace->hit - trace->origin ); } } } @@ -1502,34 +1411,30 @@ float DirtForSample( trace_t *trace ){ for ( i = 0; i < numDirtVectors; i++ ) { /* transform vector into tangent space */ - direction[ 0 ] = myRt[ 0 ] * dirtVectors[ i ][ 0 ] + myUp[ 0 ] * dirtVectors[ i ][ 1 ] + normal[ 0 ] * dirtVectors[ i ][ 2 ]; - direction[ 1 ] = myRt[ 1 ] * dirtVectors[ i ][ 0 ] + myUp[ 1 ] * dirtVectors[ i ][ 1 ] + normal[ 1 ] * dirtVectors[ i ][ 2 ]; - direction[ 2 ] = myRt[ 2 ] * dirtVectors[ i ][ 0 ] + myUp[ 2 ] * dirtVectors[ i ][ 1 ] + normal[ 2 ] * dirtVectors[ i ][ 2 ]; + const Vector3 direction = myRt * dirtVectors[ i ][ 0 ] + myUp * dirtVectors[ i ][ 1 ] + normal * dirtVectors[ i ][ 2 ]; /* set endpoint */ - VectorMA( trace->origin, dirtDepth, direction, trace->end ); + trace->end = trace->origin + direction * dirtDepth; SetupTrace( trace ); - VectorSet(trace->color, 1.0f, 1.0f, 1.0f); + trace->color.set( 1 ); /* trace */ TraceLine( trace ); if ( trace->opaque ) { - VectorSubtract( trace->hit, trace->origin, displacement ); - gatherDirt += 1.0f - ooDepth * VectorLength( displacement ); + gatherDirt += 1.0f - ooDepth * vector3_length( trace->hit - trace->origin ); } } } /* direct ray */ - VectorMA( trace->origin, dirtDepth, normal, trace->end ); + trace->end = trace->origin + normal * dirtDepth; SetupTrace( trace ); - VectorSet(trace->color, 1.0f, 1.0f, 1.0f); + trace->color.set( 1 ); /* trace */ TraceLine( trace ); if ( trace->opaque ) { - VectorSubtract( trace->hit, trace->origin, displacement ); - gatherDirt += 1.0f - ooDepth * VectorLength( displacement ); + gatherDirt += 1.0f - ooDepth * vector3_length( trace->hit - trace->origin ); } /* early out */ @@ -1561,8 +1466,8 @@ float DirtForSample( trace_t *trace ){ */ void DirtyRawLightmap( int rawLightmapNum ){ - int i, x, y, sx, sy, *cluster; - float *origin, *normal, *dirt, *dirt2, average, samples; + int i, x, y, sx, sy; + float average, samples; rawLightmap_t *lm; surfaceInfo_t *info; trace_t trace; @@ -1619,32 +1524,30 @@ void DirtyRawLightmap( int rawLightmapNum ){ for ( x = 0; x < lm->sw; x++ ) { /* get luxel */ - cluster = SUPER_CLUSTER( x, y ); - origin = SUPER_ORIGIN( x, y ); - normal = SUPER_NORMAL( x, y ); - dirt = SUPER_DIRT( x, y ); + const int cluster = lm->getSuperCluster( x, y ); + float& dirt = lm->getSuperDirt( x, y ); /* set default dirt */ - *dirt = 0.0f; + dirt = 0.0f; /* only look at mapped luxels */ - if ( *cluster < 0 ) { + if ( cluster < 0 ) { continue; } /* don't apply dirty on this surface */ if ( noDirty ) { - *dirt = 1.0f; + dirt = 1.0f; continue; } /* copy to trace */ - trace.cluster = *cluster; - VectorCopy( origin, trace.origin ); - VectorCopy( normal, trace.normal ); + trace.cluster = cluster; + trace.origin = lm->getSuperOrigin( x, y ); + trace.normal = lm->getSuperNormal( x, y ); /* get dirt */ - *dirt = DirtForSample( &trace ); + dirt = DirtForSample( &trace ); } } @@ -1657,11 +1560,10 @@ void DirtyRawLightmap( int rawLightmapNum ){ for ( x = 0; x < lm->sw; x++ ) { /* get luxel */ - cluster = SUPER_CLUSTER( x, y ); - dirt = SUPER_DIRT( x, y ); + float& dirt = lm->getSuperDirt( x, y ); /* filter dirt by adjacency to unmapped luxels */ - average = *dirt; + average = dirt; samples = 1.0f; for ( sy = ( y - 1 ); sy <= ( y + 1 ); sy++ ) { @@ -1676,14 +1578,13 @@ void DirtyRawLightmap( int rawLightmapNum ){ } /* get neighboring luxel */ - cluster = SUPER_CLUSTER( sx, sy ); - dirt2 = SUPER_DIRT( sx, sy ); - if ( *cluster < 0 || *dirt2 <= 0.0f ) { + const float dirt2 = lm->getSuperDirt( sx, sy ); + if ( lm->getSuperCluster( sx, sy ) < 0 || dirt2 <= 0.0f ) { continue; } /* add it */ - average += *dirt2; + average += dirt2; samples += 1.0f; } @@ -1699,7 +1600,7 @@ void DirtyRawLightmap( int rawLightmapNum ){ } /* scale dirt */ - *dirt = average / samples; + dirt = average / samples; } } } @@ -1711,27 +1612,22 @@ void DirtyRawLightmap( int rawLightmapNum ){ calculates the pvs cluster, origin, normal of a sub-luxel */ -static bool SubmapRawLuxel( rawLightmap_t *lm, int x, int y, float bx, float by, int *sampleCluster, vec3_t sampleOrigin, vec3_t sampleNormal ){ - int i, *cluster, *cluster2; - float *origin, *origin2, *normal; //% , *normal2; - vec3_t originVecs[ 2 ]; //% , normalVecs[ 2 ]; +static bool SubmapRawLuxel( const rawLightmap_t *lm, int x, int y, float bx, float by, int& sampleCluster, Vector3& sampleOrigin, Vector3& sampleNormal ){ + const Vector3 *origin, *origin2; + Vector3 originVecs[ 2 ]; /* calulate x vector */ if ( ( x < ( lm->sw - 1 ) && bx >= 0.0f ) || ( x == 0 && bx <= 0.0f ) ) { - cluster = SUPER_CLUSTER( x, y ); - origin = SUPER_ORIGIN( x, y ); + origin = &lm->getSuperOrigin( x, y ); //% normal = SUPER_NORMAL( x, y ); - cluster2 = SUPER_CLUSTER( x + 1, y ); - origin2 = *cluster2 < 0 ? SUPER_ORIGIN( x, y ) : SUPER_ORIGIN( x + 1, y ); + origin2 = lm->getSuperCluster( x + 1, y ) < 0 ? &lm->getSuperOrigin( x, y ) : &lm->getSuperOrigin( x + 1, y ); //% normal2 = *cluster2 < 0 ? SUPER_NORMAL( x, y ) : SUPER_NORMAL( x + 1, y ); } else if ( ( x > 0 && bx <= 0.0f ) || ( x == ( lm->sw - 1 ) && bx >= 0.0f ) ) { - cluster = SUPER_CLUSTER( x - 1, y ); - origin = *cluster < 0 ? SUPER_ORIGIN( x, y ) : SUPER_ORIGIN( x - 1, y ); + origin = lm->getSuperCluster( x - 1, y ) < 0 ? &lm->getSuperOrigin( x, y ) : &lm->getSuperOrigin( x - 1, y ); //% normal = *cluster < 0 ? SUPER_NORMAL( x, y ) : SUPER_NORMAL( x - 1, y ); - cluster2 = SUPER_CLUSTER( x, y ); - origin2 = SUPER_ORIGIN( x, y ); + origin2 = &lm->getSuperOrigin( x, y ); //% normal2 = SUPER_NORMAL( x, y ); } else @@ -1739,42 +1635,37 @@ static bool SubmapRawLuxel( rawLightmap_t *lm, int x, int y, float bx, float by, Error( "Spurious lightmap S vector\n" ); } - VectorSubtract( origin2, origin, originVecs[ 0 ] ); + originVecs[ 0 ] = *origin2 - *origin; //% VectorSubtract( normal2, normal, normalVecs[ 0 ] ); /* calulate y vector */ if ( ( y < ( lm->sh - 1 ) && bx >= 0.0f ) || ( y == 0 && bx <= 0.0f ) ) { - cluster = SUPER_CLUSTER( x, y ); - origin = SUPER_ORIGIN( x, y ); + origin = &lm->getSuperOrigin( x, y ); //% normal = SUPER_NORMAL( x, y ); - cluster2 = SUPER_CLUSTER( x, y + 1 ); - origin2 = *cluster2 < 0 ? SUPER_ORIGIN( x, y ) : SUPER_ORIGIN( x, y + 1 ); + origin2 = lm->getSuperCluster( x, y + 1 ) < 0 ? &lm->getSuperOrigin( x, y ) : &lm->getSuperOrigin( x, y + 1 ); //% normal2 = *cluster2 < 0 ? SUPER_NORMAL( x, y ) : SUPER_NORMAL( x, y + 1 ); } else if ( ( y > 0 && bx <= 0.0f ) || ( y == ( lm->sh - 1 ) && bx >= 0.0f ) ) { - cluster = SUPER_CLUSTER( x, y - 1 ); - origin = *cluster < 0 ? SUPER_ORIGIN( x, y ) : SUPER_ORIGIN( x, y - 1 ); + origin = lm->getSuperCluster( x, y - 1 ) < 0 ? &lm->getSuperOrigin( x, y ) : &lm->getSuperOrigin( x, y - 1 ); //% normal = *cluster < 0 ? SUPER_NORMAL( x, y ) : SUPER_NORMAL( x, y - 1 ); - cluster2 = SUPER_CLUSTER( x, y ); - origin2 = SUPER_ORIGIN( x, y ); + origin2 = &lm->getSuperOrigin( x, y ); //% normal2 = SUPER_NORMAL( x, y ); } else{ Sys_Warning( "Spurious lightmap T vector\n" ); } - VectorSubtract( origin2, origin, originVecs[ 1 ] ); + originVecs[ 1 ] = *origin2 - *origin; //% VectorSubtract( normal2, normal, normalVecs[ 1 ] ); /* calculate new origin */ //% VectorMA( origin, bx, originVecs[ 0 ], sampleOrigin ); //% VectorMA( sampleOrigin, by, originVecs[ 1 ], sampleOrigin ); - for ( i = 0; i < 3; i++ ) - sampleOrigin[ i ] = sampleOrigin[ i ] + ( bx * originVecs[ 0 ][ i ] ) + ( by * originVecs[ 1 ][ i ] ); + sampleOrigin += ( originVecs[ 0 ] * bx ) + ( originVecs[ 1 ] * by ); /* get cluster */ - *sampleCluster = ClusterForPointExtFilter( sampleOrigin, ( LUXEL_EPSILON * 2 ), lm->numLightClusters, lm->lightClusters ); - if ( *sampleCluster < 0 ) { + sampleCluster = ClusterForPointExtFilter( sampleOrigin, ( LUXEL_EPSILON * 2 ), lm->numLightClusters, lm->lightClusters ); + if ( sampleCluster < 0 ) { return false; } @@ -1783,8 +1674,7 @@ static bool SubmapRawLuxel( rawLightmap_t *lm, int x, int y, float bx, float by, //% VectorMA( sampleNormal, by, normalVecs[ 1 ], sampleNormal ); //% if( VectorNormalize( sampleNormal, sampleNormal ) <= 0.0f ) //% return false; - normal = SUPER_NORMAL( x, y ); - VectorCopy( normal, sampleNormal ); + sampleNormal = lm->getSuperNormal( x, y ); /* return ok */ return true; @@ -1796,23 +1686,22 @@ static bool SubmapRawLuxel( rawLightmap_t *lm, int x, int y, float bx, float by, recursively subsamples a luxel until its color gradient is low enough or subsampling limit is reached */ -static void SubsampleRawLuxel_r( rawLightmap_t *lm, trace_t *trace, vec3_t sampleOrigin, int x, int y, float bias, float *lightLuxel, float *lightDeluxel ){ +static void SubsampleRawLuxel_r( rawLightmap_t *lm, trace_t *trace, const Vector3& sampleOrigin, int x, int y, float bias, SuperLuxel& lightLuxel, Vector3 *lightDeluxel ){ int b, samples, mapped, lighted; int cluster[ 4 ]; - vec4_t luxel[ 4 ]; - vec3_t deluxel[ 4 ]; - vec3_t origin[ 4 ], normal[ 4 ]; + SuperLuxel luxel[ 4 ]; + Vector3 deluxel[ 4 ]; + Vector3 origin[ 4 ], normal[ 4 ]; float biasDirs[ 4 ][ 2 ] = { { -1.0f, -1.0f }, { 1.0f, -1.0f }, { -1.0f, 1.0f }, { 1.0f, 1.0f } }; - vec3_t color, direction = { 0, 0, 0 }, total; + Vector3 color, direction( 0, 0, 0 ), total( 0, 0, 0 ); /* limit check */ - if ( lightLuxel[ 3 ] >= lightSamples ) { + if ( lightLuxel.count >= lightSamples ) { return; } /* setup */ - VectorClear( total ); mapped = 0; lighted = 0; @@ -1820,22 +1709,22 @@ static void SubsampleRawLuxel_r( rawLightmap_t *lm, trace_t *trace, vec3_t sampl for ( b = 0; b < 4; b++ ) { /* set origin */ - VectorCopy( sampleOrigin, origin[ b ] ); + origin[ b ] = sampleOrigin; /* calculate position */ - if ( !SubmapRawLuxel( lm, x, y, ( bias * biasDirs[ b ][ 0 ] ), ( bias * biasDirs[ b ][ 1 ] ), &cluster[ b ], origin[ b ], normal[ b ] ) ) { + if ( !SubmapRawLuxel( lm, x, y, ( bias * biasDirs[ b ][ 0 ] ), ( bias * biasDirs[ b ][ 1 ] ), cluster[ b ], origin[ b ], normal[ b ] ) ) { cluster[ b ] = -1; continue; } mapped++; /* increment sample count */ - luxel[ b ][ 3 ] = lightLuxel[ 3 ] + 1.0f; + luxel[ b ].count = lightLuxel.count + 1.0f; /* setup trace */ trace->cluster = *cluster; - VectorCopy( origin[ b ], trace->origin ); - VectorCopy( normal[ b ], trace->normal ); + trace->origin = origin[ b ]; + trace->normal = normal[ b ]; /* sample light */ @@ -1848,18 +1737,18 @@ static void SubsampleRawLuxel_r( rawLightmap_t *lm, trace_t *trace, vec3_t sampl } /* add to totals (fixme: make contrast function) */ - VectorCopy( trace->color, luxel[ b ] ); + luxel[ b ].value = trace->color; if ( lightDeluxel ) { - VectorCopy( trace->directionContribution, deluxel[ b ] ); + deluxel[ b ] = trace->directionContribution; } - VectorAdd( total, trace->color, total ); - if ( ( luxel[ b ][ 0 ] + luxel[ b ][ 1 ] + luxel[ b ][ 2 ] ) > 0.0f ) { + total += trace->color; + if ( ( luxel[ b ].value[ 0 ] + luxel[ b ].value[ 1 ] + luxel[ b ].value[ 2 ] ) > 0.0f ) { lighted++; } } /* subsample further? */ - if ( ( lightLuxel[ 3 ] + 1.0f ) < lightSamples && + if ( ( lightLuxel.count + 1.0f ) < lightSamples && ( total[ 0 ] > 4.0f || total[ 1 ] > 4.0f || total[ 2 ] > 4.0f ) && lighted != 0 && lighted != mapped ) { for ( b = 0; b < 4; b++ ) @@ -1867,16 +1756,16 @@ static void SubsampleRawLuxel_r( rawLightmap_t *lm, trace_t *trace, vec3_t sampl if ( cluster[ b ] < 0 ) { continue; } - SubsampleRawLuxel_r( lm, trace, origin[ b ], x, y, ( bias * 0.5f ), luxel[ b ], lightDeluxel ? deluxel[ b ] : NULL ); + SubsampleRawLuxel_r( lm, trace, origin[ b ], x, y, ( bias * 0.5f ), luxel[ b ], lightDeluxel ? &deluxel[ b ] : NULL ); } } /* average */ - //% VectorClear( color ); + //% color.set( 0 ); //% samples = 0; - VectorCopy( lightLuxel, color ); + color = lightLuxel.value; if ( lightDeluxel ) { - VectorCopy( lightDeluxel, direction ); + direction = *lightDeluxel; } samples = 1; for ( b = 0; b < 4; b++ ) @@ -1884,9 +1773,9 @@ static void SubsampleRawLuxel_r( rawLightmap_t *lm, trace_t *trace, vec3_t sampl if ( cluster[ b ] < 0 ) { continue; } - VectorAdd( color, luxel[ b ], color ); + color += luxel[ b ].value; if ( lightDeluxel ) { - VectorAdd( direction, deluxel[ b ], direction ); + direction += deluxel[ b ]; } samples++; } @@ -1894,19 +1783,15 @@ static void SubsampleRawLuxel_r( rawLightmap_t *lm, trace_t *trace, vec3_t sampl /* add to luxel */ if ( samples > 0 ) { /* average */ - color[ 0 ] /= samples; - color[ 1 ] /= samples; - color[ 2 ] /= samples; + color /= samples; /* add to color */ - VectorCopy( color, lightLuxel ); - lightLuxel[ 3 ] += 1.0f; + lightLuxel.value = color; + lightLuxel.count += 1.0f; if ( lightDeluxel ) { - direction[ 0 ] /= samples; - direction[ 1 ] /= samples; - direction[ 2 ] /= samples; - VectorCopy( direction, lightDeluxel ); + direction /= samples; + *lightDeluxel = direction; } } } @@ -1914,7 +1799,7 @@ static void SubsampleRawLuxel_r( rawLightmap_t *lm, trace_t *trace, vec3_t sampl /* A mostly Gaussian-like bounded random distribution (sigma is expected standard deviation) */ static void GaussLikeRandom( float sigma, float *x, float *y ){ float r; - r = Random() * 2 * Q_PI; + r = Random() * 2 * c_pi; *x = sigma * 2.73861278752581783822 * cos( r ); *y = sigma * 2.73861278752581783822 * sin( r ); r = Random(); @@ -1923,51 +1808,44 @@ static void GaussLikeRandom( float sigma, float *x, float *y ){ *x *= r; *y *= r; } -static void RandomSubsampleRawLuxel( rawLightmap_t *lm, trace_t *trace, vec3_t sampleOrigin, int x, int y, float bias, float *lightLuxel, float *lightDeluxel ){ - int b, mapped; +static void RandomSubsampleRawLuxel( rawLightmap_t *lm, trace_t *trace, const Vector3& sampleOrigin, int x, int y, float bias, SuperLuxel& lightLuxel, Vector3 *lightDeluxel ){ + int b, mapped = 0; int cluster; - vec3_t origin, normal; - vec3_t total, totaldirection; + Vector3 origin, normal; + Vector3 total( 0, 0, 0 ), totaldirection( 0, 0, 0 ); float dx, dy; - VectorClear( total ); - VectorClear( totaldirection ); - mapped = 0; for ( b = 0; b < lightSamples; ++b ) { /* set origin */ - VectorCopy( sampleOrigin, origin ); + origin = sampleOrigin; GaussLikeRandom( bias, &dx, &dy ); /* calculate position */ - if ( !SubmapRawLuxel( lm, x, y, dx, dy, &cluster, origin, normal ) ) { + if ( !SubmapRawLuxel( lm, x, y, dx, dy, cluster, origin, normal ) ) { cluster = -1; continue; } mapped++; trace->cluster = cluster; - VectorCopy( origin, trace->origin ); - VectorCopy( normal, trace->normal ); + trace->origin = origin; + trace->normal = normal; LightContributionToSample( trace ); - VectorAdd( total, trace->color, total ); + total += trace->color; if ( lightDeluxel ) { - VectorAdd( totaldirection, trace->directionContribution, totaldirection ); + totaldirection += trace->directionContribution; } } /* add to luxel */ if ( mapped > 0 ) { /* average */ - lightLuxel[ 0 ] = total[ 0 ] / mapped; - lightLuxel[ 1 ] = total[ 1 ] / mapped; - lightLuxel[ 2 ] = total[ 2 ] / mapped; + lightLuxel.value = total / mapped; if ( lightDeluxel ) { - lightDeluxel[ 0 ] = totaldirection[ 0 ] / mapped; - lightDeluxel[ 1 ] = totaldirection[ 1 ] / mapped; - lightDeluxel[ 2 ] = totaldirection[ 2 ] / mapped; + *lightDeluxel = totaldirection / mapped; } } } @@ -1979,25 +1857,18 @@ static void RandomSubsampleRawLuxel( rawLightmap_t *lm, trace_t *trace, vec3_t s illuminates the luxels */ -#define STACK_LL_SIZE ( SUPER_LUXEL_SIZE * 64 * 64 ) -#define LIGHT_LUXEL( x, y ) ( lightLuxels + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_LUXEL_SIZE ) ) -#define LIGHT_DELUXEL( x, y ) ( lightDeluxels + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_DELUXEL_SIZE ) ) - void IlluminateRawLightmap( int rawLightmapNum ){ int i, t, x, y, sx, sy, size, luxelFilterRadius, lightmapNum; - int *cluster, *cluster2, mapped, lighted, totalLighted; - size_t llSize, ldSize; + int mapped, lighted, totalLighted; rawLightmap_t *lm; surfaceInfo_t *info; bool filterColor, filterDir; float brightness; - float *origin, *normal, *dirt, *luxel, *luxel2, *deluxel, *deluxel2; - unsigned char *flag; - float *lightLuxels, *lightDeluxels, *lightLuxel, *lightDeluxel, samples, filterRadius, weight; - vec3_t color, direction, averageColor, averageDir, total, temp, temp2; - float tests[ 4 ][ 2 ] = { { 0.0f, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } }; + float samples, filterRadius, weight; + Vector3 averageColor, averageDir; + float tests[ 4 ][ 2 ] = { { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } }; trace_t trace; - float stackLightLuxels[ STACK_LL_SIZE ]; + SuperLuxel stackLightLuxels[ 64 * 64 ]; /* bail if this number exceeds the number of raw lightmaps */ @@ -2031,7 +1902,7 @@ void IlluminateRawLightmap( int rawLightmapNum ){ } /* create a culled light list for this raw lightmap */ - CreateTraceLightsForBounds( lm->mins, lm->maxs, lm->plane, lm->numLightClusters, lm->lightClusters, LightFlags::Surfaces, &trace ); + CreateTraceLightsForBounds( lm->minmax, ( lm->plane == NULL? NULL : &lm->plane->normal() ), lm->numLightClusters, lm->lightClusters, LightFlags::Surfaces, &trace ); /* ----------------------------------------------------------------- fill pass @@ -2048,78 +1919,70 @@ void IlluminateRawLightmap( int rawLightmapNum ){ for ( x = 0; x < lm->sw; x++ ) { /* get cluster */ - cluster = SUPER_CLUSTER( x, y ); + const int cluster = lm->getSuperCluster( x, y ); /* only fill mapped luxels */ - if ( *cluster < 0 ) { + if ( cluster < 0 ) { continue; } /* get particulars */ - luxel = SUPER_LUXEL( 0, x, y ); - origin = SUPER_ORIGIN( x, y ); - normal = SUPER_NORMAL( x, y ); + SuperLuxel& luxel = lm->getSuperLuxel( 0, x, y ); /* color the luxel with raw lightmap num? */ if ( debugSurfaces ) { - VectorCopy( debugColors[ rawLightmapNum % 12 ], luxel ); + luxel.value = debugColors[ rawLightmapNum % 12 ]; } /* color the luxel with lightmap axis? */ else if ( debugAxis ) { - luxel[ 0 ] = ( lm->axis[ 0 ] + 1.0f ) * 127.5f; - luxel[ 1 ] = ( lm->axis[ 1 ] + 1.0f ) * 127.5f; - luxel[ 2 ] = ( lm->axis[ 2 ] + 1.0f ) * 127.5f; + luxel.value = ( lm->axis + Vector3( 1, 1, 1 ) ) * 127.5f; } /* color the luxel with luxel cluster? */ else if ( debugCluster ) { - VectorCopy( debugColors[ *cluster % 12 ], luxel ); + luxel.value = debugColors[ cluster % 12 ]; } /* color the luxel with luxel origin? */ else if ( debugOrigin ) { - VectorSubtract( lm->maxs, lm->mins, temp ); - VectorScale( temp, ( 1.0f / 255.0f ), temp ); - VectorSubtract( origin, lm->mins, temp2 ); - luxel[ 0 ] = lm->mins[ 0 ] + ( temp[ 0 ] * temp2[ 0 ] ); - luxel[ 1 ] = lm->mins[ 1 ] + ( temp[ 1 ] * temp2[ 1 ] ); - luxel[ 2 ] = lm->mins[ 2 ] + ( temp[ 2 ] * temp2[ 2 ] ); + const Vector3 temp = ( lm->minmax.maxs - lm->minmax.mins ) * ( 1.0f / 255.0f ); + const Vector3 temp2 = lm->getSuperOrigin( x, y ) - lm->minmax.mins; + luxel.value = lm->minmax.mins + ( temp * temp2 ); } /* color the luxel with the normal */ else if ( normalmap ) { - luxel[ 0 ] = ( normal[ 0 ] + 1.0f ) * 127.5f; - luxel[ 1 ] = ( normal[ 1 ] + 1.0f ) * 127.5f; - luxel[ 2 ] = ( normal[ 2 ] + 1.0f ) * 127.5f; + luxel.value = ( lm->getSuperNormal( x, y ) + Vector3( 1, 1, 1 ) ) * 127.5f; } /* otherwise clear it */ else{ - VectorClear( luxel ); + luxel.value.set( 0 ); } /* add to counts */ - luxel[ 3 ] = 1.0f; + luxel.count = 1.0f; } } } else { /* allocate temporary per-light luxel storage */ - llSize = lm->sw * lm->sh * SUPER_LUXEL_SIZE * sizeof( float ); - ldSize = lm->sw * lm->sh * SUPER_DELUXEL_SIZE * sizeof( float ); - if ( llSize <= ( STACK_LL_SIZE * sizeof( float ) ) ) { - lightLuxels = stackLightLuxels; + rawLightmap_t tmplm = *lm; + const size_t llSize = lm->sw * lm->sh * sizeof( *lm->superLuxels[0] ); + const size_t ldSize = lm->sw * lm->sh * sizeof( *lm->superDeluxels ); + if ( llSize <= sizeof( stackLightLuxels ) ) { + tmplm.superLuxels[0] = stackLightLuxels; } else{ - lightLuxels = safe_malloc( llSize ); + tmplm.superLuxels[0] = safe_malloc( llSize ); } if ( deluxemap ) { - lightDeluxels = safe_malloc( ldSize ); + tmplm.superDeluxels = safe_malloc( ldSize ); } else{ - lightDeluxels = NULL; + tmplm.superDeluxels = NULL; } /* clear luxels */ @@ -2131,20 +1994,16 @@ void IlluminateRawLightmap( int rawLightmapNum ){ for ( x = 0; x < lm->sw; x++ ) { /* get cluster */ - cluster = SUPER_CLUSTER( x, y ); - luxel = SUPER_LUXEL( 0, x, y ); - normal = SUPER_NORMAL( x, y ); - deluxel = SUPER_DELUXEL( x, y ); + SuperLuxel& luxel = lm->getSuperLuxel( 0, x, y ); /* blacken unmapped clusters */ - if ( *cluster < 0 ) { - VectorClear( luxel ); + if ( lm->getSuperCluster( x, y ) < 0 ) { + luxel.value.set( 0 ); } - /* set ambient */ else { - VectorCopy( ambientColor, luxel ); + luxel.value = ambientColor; if ( deluxemap ) { brightness = RGBTOGRAY( ambientColor ) * ( 1.0f / 255.0f ); @@ -2153,15 +2012,15 @@ void IlluminateRawLightmap( int rawLightmapNum ){ brightness = 0.00390625f; } - VectorScale( normal, brightness, deluxel ); + lm->getSuperDeluxel( x, y ) = lm->getSuperNormal( x, y ) * brightness; } - luxel[ 3 ] = 1.0f; + luxel.count = 1.0f; } } } /* clear styled lightmaps */ - size = lm->sw * lm->sh * SUPER_LUXEL_SIZE * sizeof( float ); + size = lm->sw * lm->sh * sizeof( *lm->superLuxels[0] ); for ( lightmapNum = 1; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) { if ( lm->superLuxels[ lightmapNum ] != NULL ) { @@ -2195,9 +2054,9 @@ void IlluminateRawLightmap( int rawLightmapNum ){ } /* setup */ - memset( lightLuxels, 0, llSize ); + memset( tmplm.superLuxels[0], 0, llSize ); if ( deluxemap ) { - memset( lightDeluxels, 0, ldSize ); + memset( tmplm.superDeluxels, 0, ldSize ); } totalLighted = 0; @@ -2217,7 +2076,7 @@ void IlluminateRawLightmap( int rawLightmapNum ){ /* allocate sampling flags storage */ if ( lightSamples > 1 || lightRandomSamples ) { - size = lm->sw * lm->sh * SUPER_LUXEL_SIZE * sizeof( unsigned char ); + size = lm->sw * lm->sh * sizeof( *lm->superFlags ); if ( lm->superFlags == NULL ) { lm->superFlags = safe_malloc( size ); } @@ -2230,49 +2089,45 @@ void IlluminateRawLightmap( int rawLightmapNum ){ for ( x = 0; x < lm->sw; x++ ) { /* get cluster */ - cluster = SUPER_CLUSTER( x, y ); - if ( *cluster < 0 ) { + const int cluster = lm->getSuperCluster( x, y ); + if ( cluster < 0 ) { continue; } /* get particulars */ - lightLuxel = LIGHT_LUXEL( x, y ); - lightDeluxel = LIGHT_DELUXEL( x, y ); - origin = SUPER_ORIGIN( x, y ); - normal = SUPER_NORMAL( x, y ); - flag = SUPER_FLAG( x, y ); + SuperLuxel& lightLuxel = tmplm.getSuperLuxel( 0, x, y ); #if 0 ////////// 27's temp hack for testing edge clipping //// if ( origin[0] == 0 && origin[1] == 0 && origin[2] == 0 ) { - lightLuxel[ 1 ] = 255; - lightLuxel[ 3 ] = 1.0f; + lightLuxel.value[ 1 ] = 255; + lightLuxel.count = 1.0f; totalLighted++; } else #endif { /* set contribution count */ - lightLuxel[ 3 ] = 1.0f; + lightLuxel.count = 1.0f; /* setup trace */ - trace.cluster = *cluster; - VectorCopy( origin, trace.origin ); - VectorCopy( normal, trace.normal ); + trace.cluster = cluster; + trace.origin = lm->getSuperOrigin( x, y ); + trace.normal = lm->getSuperNormal( x, y ); /* get light for this sample */ LightContributionToSample( &trace ); - VectorCopy( trace.color, lightLuxel ); + lightLuxel.value = trace.color; /* add the contribution to the deluxemap */ if ( deluxemap ) { - VectorCopy( trace.directionContribution, lightDeluxel ); + tmplm.getSuperDeluxel( x, y ) = trace.directionContribution; } /* check for evilness */ if ( trace.forceSubsampling > 1.0f && ( lightSamples > 1 || lightRandomSamples ) ) { totalLighted++; - *flag |= FLAG_FORCE_SUBSAMPLING; /* force */ + lm->getSuperFlag( x, y ) |= FLAG_FORCE_SUBSAMPLING; /* force */ } /* add to count */ else if ( trace.color[ 0 ] || trace.color[ 1 ] || trace.color[ 2 ] ) { @@ -2298,7 +2153,7 @@ void IlluminateRawLightmap( int rawLightmapNum ){ /* setup */ mapped = 0; lighted = 0; - VectorClear( total ); + Vector3 total( 0, 0, 0 ); /* test 2x2 stamp */ for ( t = 0; t < 4; t++ ) @@ -2308,23 +2163,21 @@ void IlluminateRawLightmap( int rawLightmapNum ){ sy = y + tests[ t ][ 1 ]; /* get cluster */ - cluster = SUPER_CLUSTER( sx, sy ); - if ( *cluster < 0 ) { + if ( lm->getSuperCluster( sx, sy ) < 0 ) { continue; } mapped++; /* get luxel */ - flag = SUPER_FLAG( sx, sy ); - if ( *flag & FLAG_FORCE_SUBSAMPLING ) { + if ( lm->getSuperFlag( sx, sy ) & FLAG_FORCE_SUBSAMPLING ) { /* force a lighted/mapped discrepancy so we subsample */ ++lighted; ++mapped; ++mapped; } - lightLuxel = LIGHT_LUXEL( sx, sy ); - VectorAdd( total, lightLuxel, total ); - if ( ( lightLuxel[ 0 ] + lightLuxel[ 1 ] + lightLuxel[ 2 ] ) > 0.0f ) { + const SuperLuxel& lightLuxel = tmplm.getSuperLuxel( 0, sx, sy ); + total += lightLuxel.value; + if ( ( lightLuxel.value[ 0 ] + lightLuxel.value[ 1 ] + lightLuxel.value[ 2 ] ) > 0.0f ) { lighted++; } } @@ -2343,17 +2196,16 @@ void IlluminateRawLightmap( int rawLightmapNum ){ sy = y + tests[ t ][ 1 ]; /* get luxel */ - cluster = SUPER_CLUSTER( sx, sy ); - if ( *cluster < 0 ) { + if ( lm->getSuperCluster( sx, sy ) < 0 ) { continue; } - flag = SUPER_FLAG( sx, sy ); - if ( *flag & FLAG_ALREADY_SUBSAMPLED ) { // already subsampled + byte& flag = lm->getSuperFlag( sx, sy ); + if ( flag & FLAG_ALREADY_SUBSAMPLED ) { // already subsampled continue; } - lightLuxel = LIGHT_LUXEL( sx, sy ); - lightDeluxel = LIGHT_DELUXEL( sx, sy ); - origin = SUPER_ORIGIN( sx, sy ); + SuperLuxel& lightLuxel = tmplm.getSuperLuxel( 0, sx, sy ); + Vector3* lightDeluxel = &tmplm.getSuperDeluxel( sx, sy ); + const Vector3& origin = lm->getSuperOrigin( sx, sy ); /* only subsample shadowed luxels */ //% if( (lightLuxel[ 0 ] + lightLuxel[ 1 ] + lightLuxel[ 2 ]) <= 0.0f ) @@ -2367,11 +2219,10 @@ void IlluminateRawLightmap( int rawLightmapNum ){ SubsampleRawLuxel_r( lm, &trace, origin, sx, sy, 0.25f * lightSamplesSearchBoxSize, lightLuxel, deluxemap ? lightDeluxel : NULL ); } - *flag |= FLAG_ALREADY_SUBSAMPLED; + flag |= FLAG_ALREADY_SUBSAMPLED; /* debug code to colorize subsampled areas to yellow */ - //% luxel = SUPER_LUXEL( lightmapNum, sx, sy ); - //% VectorSet( luxel, 255, 204, 0 ); + //% lm->getSuperLuxel( lightmapNum, sx, sy ).value = { 255, 204, 0 }; } } } @@ -2386,17 +2237,12 @@ void IlluminateRawLightmap( int rawLightmapNum ){ for ( x = 0; x < lm->sw; x++ ) { /* get cluster */ - cluster = SUPER_CLUSTER( x, y ); - if ( *cluster < 0 ) { + if ( lm->getSuperCluster( x, y ) < 0 ) { continue; } - /* get particulars */ - lightLuxel = LIGHT_LUXEL( x, y ); - dirt = SUPER_DIRT( x, y ); - /* scale light value */ - VectorScale( lightLuxel, *dirt, lightLuxel ); + tmplm.getSuperLuxel( 0, x, y ).value *= lm->getSuperDirt( x, y ); } } } @@ -2404,7 +2250,7 @@ void IlluminateRawLightmap( int rawLightmapNum ){ /* allocate sampling lightmap storage */ if ( lm->superLuxels[ lightmapNum ] == NULL ) { /* allocate sampling lightmap storage */ - size = lm->sw * lm->sh * SUPER_LUXEL_SIZE * sizeof( float ); + size = lm->sw * lm->sh * sizeof( *lm->superLuxels[0] ); lm->superLuxels[ lightmapNum ] = safe_calloc( size ); } @@ -2420,17 +2266,15 @@ void IlluminateRawLightmap( int rawLightmapNum ){ for ( x = 0; x < lm->sw; x++ ) { /* get cluster and origin */ - cluster = SUPER_CLUSTER( x, y ); - if ( *cluster < 0 ) { + if ( lm->getSuperCluster( x, y ) < 0 ) { continue; } - origin = SUPER_ORIGIN( x, y ); /* filter? */ if ( luxelFilterRadius ) { /* setup */ - VectorClear( averageColor ); - VectorClear( averageDir ); + averageColor.set( 0 ); + averageDir.set( 0 ); samples = 0.0f; /* cheaper distance-based filtering */ @@ -2447,23 +2291,18 @@ void IlluminateRawLightmap( int rawLightmapNum ){ } /* get particulars */ - cluster = SUPER_CLUSTER( sx, sy ); - if ( *cluster < 0 ) { + if ( lm->getSuperCluster( sx, sy ) < 0 ) { continue; } - lightLuxel = LIGHT_LUXEL( sx, sy ); - lightDeluxel = LIGHT_DELUXEL( sx, sy ); /* create weight */ weight = ( abs( sx - x ) == luxelFilterRadius ? 0.5f : 1.0f ); weight *= ( abs( sy - y ) == luxelFilterRadius ? 0.5f : 1.0f ); /* scale luxel by filter weight */ - VectorScale( lightLuxel, weight, color ); - VectorAdd( averageColor, color, averageColor ); + averageColor += tmplm.getSuperLuxel( 0, sx, sy ).value * weight; if ( deluxemap ) { - VectorScale( lightDeluxel, weight, direction ); - VectorAdd( averageDir, direction, averageDir ); + averageDir += tmplm.getSuperDeluxel( sx, sy ) * weight; } samples += weight; } @@ -2475,30 +2314,22 @@ void IlluminateRawLightmap( int rawLightmapNum ){ } /* scale into luxel */ - luxel = SUPER_LUXEL( lightmapNum, x, y ); - luxel[ 3 ] = 1.0f; + SuperLuxel& luxel = lm->getSuperLuxel( lightmapNum, x, y ); + luxel.count = 1.0f; /* handle negative light */ if ( trace.light->flags & LightFlags::Negative ) { - luxel[ 0 ] -= averageColor[ 0 ] / samples; - luxel[ 1 ] -= averageColor[ 1 ] / samples; - luxel[ 2 ] -= averageColor[ 2 ] / samples; + luxel.value -= averageColor / samples; } - /* handle normal light */ else { - luxel[ 0 ] += averageColor[ 0 ] / samples; - luxel[ 1 ] += averageColor[ 1 ] / samples; - luxel[ 2 ] += averageColor[ 2 ] / samples; + luxel.value += averageColor / samples; } if ( deluxemap ) { /* scale into luxel */ - deluxel = SUPER_DELUXEL( x, y ); - deluxel[ 0 ] += averageDir[ 0 ] / samples; - deluxel[ 1 ] += averageDir[ 1 ] / samples; - deluxel[ 2 ] += averageDir[ 2 ] / samples; + lm->getSuperDeluxel( x, y ) += averageDir / samples; } } @@ -2506,31 +2337,28 @@ void IlluminateRawLightmap( int rawLightmapNum ){ else { /* get particulars */ - lightLuxel = LIGHT_LUXEL( x, y ); - lightDeluxel = LIGHT_DELUXEL( x, y ); - luxel = SUPER_LUXEL( lightmapNum, x, y ); - deluxel = SUPER_DELUXEL( x, y ); + const SuperLuxel& lightLuxel = tmplm.getSuperLuxel( 0, x, y ); + SuperLuxel& luxel = lm->getSuperLuxel( lightmapNum, x, y ); /* handle negative light */ if ( trace.light->flags & LightFlags::Negative ) { - VectorScale( averageColor, -1.0f, averageColor ); + vector3_negate( averageColor ); } /* add color */ - luxel[ 3 ] = 1.0f; + luxel.count = 1.0f; /* handle negative light */ if ( trace.light->flags & LightFlags::Negative ) { - VectorSubtract( luxel, lightLuxel, luxel ); + luxel.value -= lightLuxel.value; } - /* handle normal light */ else{ - VectorAdd( luxel, lightLuxel, luxel ); + luxel.value += lightLuxel.value; } if ( deluxemap ) { - VectorAdd( deluxel, lightDeluxel, deluxel ); + lm->getSuperDeluxel( x, y ) += tmplm.getSuperDeluxel( x, y ); } } } @@ -2538,12 +2366,12 @@ void IlluminateRawLightmap( int rawLightmapNum ){ } /* free temporary luxels */ - if ( lightLuxels != stackLightLuxels ) { - free( lightLuxels ); + if ( tmplm.superLuxels[0] != stackLightLuxels ) { + free( tmplm.superLuxels[0] ); } if ( deluxemap ) { - free( lightDeluxels ); + free( tmplm.superDeluxels ); } } @@ -2568,17 +2396,10 @@ void IlluminateRawLightmap( int rawLightmapNum ){ for ( x = 0; x < lm->sw; x++ ) { /* get cluster */ - cluster = SUPER_CLUSTER( x, y ); - //% if( *cluster < 0 ) + //% if( lm->getSuperCluster( x, y ) < 0 ) //% continue; - /* get particulars */ - luxel = SUPER_LUXEL( lightmapNum, x, y ); - normal = SUPER_NORMAL( x, y ); - - luxel[0] = ( normal[0] * 127 ) + 127; - luxel[1] = ( normal[1] * 127 ) + 127; - luxel[2] = ( normal[2] * 127 ) + 127; + lm->getSuperLuxel( lightmapNum, x, y ).value = lm->getSuperNormal( x, y ) * 127 + Vector3( 127, 127, 127 ); } } } @@ -2603,20 +2424,19 @@ void IlluminateRawLightmap( int rawLightmapNum ){ for ( x = 0; x < lm->sw; x++ ) { /* get cluster */ - cluster = SUPER_CLUSTER( x, y ); - //% if( *cluster < 0 ) // TODO why not do this check? These pixels should be zero anyway + //% if( lm->getSuperCluster( x, y ) < 0 ) // TODO why not do this check? These pixels should be zero anyway //% continue; /* get particulars */ - luxel = SUPER_LUXEL( lightmapNum, x, y ); - dirt = SUPER_DIRT( x, y ); + SuperLuxel& luxel = lm->getSuperLuxel( lightmapNum, x, y ); + const float dirt = lm->getSuperDirt( x, y ); /* apply dirt */ - VectorScale( luxel, *dirt, luxel ); + luxel.value *= dirt; /* debugging */ if ( dirtDebug ) { - VectorSet( luxel, *dirt * 255.0f, *dirt * 255.0f, *dirt * 255.0f ); + luxel.value.set( dirt * 255.0f ); } } } @@ -2641,20 +2461,20 @@ void IlluminateRawLightmap( int rawLightmapNum ){ for ( x = 0; x < lm->sw; x++ ) { /* get particulars */ - cluster = SUPER_CLUSTER( x, y ); - luxel = SUPER_LUXEL( lightmapNum, x, y ); - deluxel = SUPER_DELUXEL( x, y ); - normal = SUPER_NORMAL( x, y ); + int& cluster = lm->getSuperCluster( x, y ); + SuperLuxel& luxel = lm->getSuperLuxel( lightmapNum, x, y ); /* determine if filtering is necessary */ filterColor = false; filterDir = false; - if ( *cluster < 0 || - ( lm->splotchFix && ( luxel[ 0 ] <= ambientColor[ 0 ] || luxel[ 1 ] <= ambientColor[ 1 ] || luxel[ 2 ] <= ambientColor[ 2 ] ) ) ) { + if ( cluster < 0 || + ( lm->splotchFix && ( luxel.value[ 0 ] <= ambientColor[ 0 ] + || luxel.value[ 1 ] <= ambientColor[ 1 ] + || luxel.value[ 2 ] <= ambientColor[ 2 ] ) ) ) { filterColor = true; } - if ( deluxemap && lightmapNum == 0 && ( *cluster < 0 || filter ) ) { + if ( deluxemap && lightmapNum == 0 && ( cluster < 0 || filter ) ) { filterDir = true; } @@ -2663,8 +2483,8 @@ void IlluminateRawLightmap( int rawLightmapNum ){ } /* choose seed amount */ - VectorClear( averageColor ); - VectorClear( averageDir ); + averageColor.set( 0 ); + averageDir.set( 0 ); samples = 0.0f; /* walk 3x3 matrix */ @@ -2681,21 +2501,19 @@ void IlluminateRawLightmap( int rawLightmapNum ){ } /* get neighbor's particulars */ - cluster2 = SUPER_CLUSTER( sx, sy ); - luxel2 = SUPER_LUXEL( lightmapNum, sx, sy ); - deluxel2 = SUPER_DELUXEL( sx, sy ); + const SuperLuxel& luxel2 = lm->getSuperLuxel( lightmapNum, sx, sy ); /* ignore unmapped/unlit luxels */ - if ( *cluster2 < 0 || luxel2[ 3 ] == 0.0f || - ( lm->splotchFix && VectorCompare( luxel2, ambientColor ) ) ) { + if ( lm->getSuperCluster( sx, sy ) < 0 || luxel2.count == 0.0f || + ( lm->splotchFix && VectorCompare( luxel2.value, ambientColor ) ) ) { continue; } /* add its distinctiveness to our own */ - VectorAdd( averageColor, luxel2, averageColor ); - samples += luxel2[ 3 ]; + averageColor += luxel2.value; + samples += luxel2.count; if ( filterDir ) { - VectorAdd( averageDir, deluxel2, averageDir ); + averageDir += lm->getSuperDeluxel( sx, sy ); } } } @@ -2708,23 +2526,23 @@ void IlluminateRawLightmap( int rawLightmapNum ){ /* dark lightmap seams */ if ( dark ) { if ( lightmapNum == 0 ) { - VectorMA( averageColor, 2.0f, ambientColor, averageColor ); + averageColor += ambientColor * 2; } samples += 2.0f; } /* average it */ if ( filterColor ) { - VectorDivide( averageColor, samples, luxel ); - luxel[ 3 ] = 1.0f; + luxel.value = averageColor * ( 1.f / samples ); + luxel.count = 1.0f; } if ( filterDir ) { - VectorDivide( averageDir, samples, deluxel ); + lm->getSuperDeluxel( x, y ) = averageDir * ( 1.f / samples ); } /* set cluster to -3 */ - if ( *cluster < 0 ) { - *cluster = CLUSTER_FLOODED; + if ( cluster < 0 ) { + cluster = CLUSTER_FLOODED; } } } @@ -2780,17 +2598,17 @@ void IlluminateRawLightmap( int rawLightmapNum ){ #define VERTEX_NUDGE 4.0f void IlluminateVertexes( int num ){ - int i, x, y, z, x1, y1, z1, sx, sy, radius, maxRadius, *cluster; + int i, x, y, z, x1, y1, z1, sx, sy, radius, maxRadius; int lightmapNum, numAvg; - float samples, *vertLuxel, *radVertLuxel, *luxel, dirt; - vec3_t origin, temp, temp2, colors[ MAX_LIGHTMAPS ], avgColors[ MAX_LIGHTMAPS ]; + float samples, dirt; + Vector3 origin, colors[ MAX_LIGHTMAPS ], avgColors[ MAX_LIGHTMAPS ]; bspDrawSurface_t *ds; surfaceInfo_t *info; rawLightmap_t *lm; bspDrawVert_t *verts; trace_t trace; float floodLightAmount; - vec3_t floodColor; + Vector3 floodColor; /* get surface, info, and raw lightmap */ @@ -2827,50 +2645,45 @@ void IlluminateVertexes( int num ){ for ( i = 0; i < ds->numVerts; i++ ) { /* get vertex luxel */ - radVertLuxel = RAD_VERTEX_LUXEL( 0, ds->firstVert + i ); + Vector3& radVertLuxel = getRadVertexLuxel( 0, ds->firstVert + i ); /* color the luxel with raw lightmap num? */ if ( debugSurfaces ) { - VectorCopy( debugColors[ num % 12 ], radVertLuxel ); + radVertLuxel = debugColors[ num % 12 ]; } /* color the luxel with luxel origin? */ else if ( debugOrigin ) { - VectorSubtract( info->maxs, info->mins, temp ); - VectorScale( temp, ( 1.0f / 255.0f ), temp ); - VectorSubtract( origin, lm->mins, temp2 ); - radVertLuxel[ 0 ] = info->mins[ 0 ] + ( temp[ 0 ] * temp2[ 0 ] ); - radVertLuxel[ 1 ] = info->mins[ 1 ] + ( temp[ 1 ] * temp2[ 1 ] ); - radVertLuxel[ 2 ] = info->mins[ 2 ] + ( temp[ 2 ] * temp2[ 2 ] ); + const Vector3 temp = ( info->minmax.maxs - info->minmax.mins ) * ( 1.0f / 255.0f ); + const Vector3 temp2 = origin - lm->minmax.mins; + radVertLuxel = info->minmax.mins + ( temp * temp2 ); } /* color the luxel with the normal */ else if ( normalmap ) { - radVertLuxel[ 0 ] = ( verts[ i ].normal[ 0 ] + 1.0f ) * 127.5f; - radVertLuxel[ 1 ] = ( verts[ i ].normal[ 1 ] + 1.0f ) * 127.5f; - radVertLuxel[ 2 ] = ( verts[ i ].normal[ 2 ] + 1.0f ) * 127.5f; + radVertLuxel = ( verts[ i ].normal + Vector3( 1, 1, 1 ) ) * 127.5f; } else if ( info->si->noVertexLight ) { - VectorSet( radVertLuxel, 127.5f, 127.5f, 127.5f ); + radVertLuxel.set( 127.5f ); } else if ( noVertexLighting > 0 ) { - VectorSet( radVertLuxel, 127.5f * noVertexLighting, 127.5f * noVertexLighting, 127.5f * noVertexLighting ); + radVertLuxel.set( 127.5f * noVertexLighting ); } /* illuminate the vertex */ else { /* clear vertex luxel */ - VectorSet( radVertLuxel, -1.0f, -1.0f, -1.0f ); + radVertLuxel.set( -1.0f ); /* try at initial origin */ trace.cluster = ClusterForPointExtFilter( verts[ i ].xyz, VERTEX_EPSILON, info->numSurfaceClusters, &surfaceClusters[ info->firstSurfaceCluster ] ); if ( trace.cluster >= 0 ) { /* setup trace */ - VectorCopy( verts[ i ].xyz, trace.origin ); - VectorCopy( verts[ i ].normal, trace.normal ); + trace.origin = verts[ i ].xyz; + trace.normal = verts[ i ].normal; /* r7 dirt */ if ( dirty && !bouncing ) { @@ -2882,10 +2695,10 @@ void IlluminateVertexes( int num ){ /* jal: floodlight */ floodLightAmount = 0.0f; - VectorClear( floodColor ); + floodColor.set( 0 ); if ( floodlighty && !bouncing ) { floodLightAmount = floodlightIntensity * FloodLightForSample( &trace, floodlightDistance, floodlight_lowquality ); - VectorScale( floodlightRGB, floodLightAmount, floodColor ); + floodColor = floodlightRGB * floodLightAmount; } /* trace */ @@ -2895,23 +2708,22 @@ void IlluminateVertexes( int num ){ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) { /* r7 dirt */ - VectorScale( colors[ lightmapNum ], dirt, colors[ lightmapNum ] ); + colors[ lightmapNum ] *= dirt; /* jal: floodlight */ - VectorAdd( colors[ lightmapNum ], floodColor, colors[ lightmapNum ] ); + colors[ lightmapNum ] += floodColor; /* store */ - radVertLuxel = RAD_VERTEX_LUXEL( lightmapNum, ds->firstVert + i ); - VectorCopy( colors[ lightmapNum ], radVertLuxel ); - VectorAdd( avgColors[ lightmapNum ], colors[ lightmapNum ], colors[ lightmapNum ] ); + getRadVertexLuxel( lightmapNum, ds->firstVert + i ) = colors[ lightmapNum ]; + colors[ lightmapNum ] += avgColors[ lightmapNum ]; } } /* is this sample bright enough? */ - radVertLuxel = RAD_VERTEX_LUXEL( 0, ds->firstVert + i ); - if ( radVertLuxel[ 0 ] <= ambientColor[ 0 ] && - radVertLuxel[ 1 ] <= ambientColor[ 1 ] && - radVertLuxel[ 2 ] <= ambientColor[ 2 ] ) { + const auto vector3_component_greater = []( const Vector3& greater, const Vector3& lesser ){ + return greater[0] > lesser[0] || greater[1] > lesser[1] || greater[2] > lesser[2]; + }; + if ( !vector3_component_greater( getRadVertexLuxel( 0, ds->firstVert + i ), ambientColor ) ) { /* nudge the sample point around a bit */ for ( x = 0; x < 5; x++ ) { @@ -2947,10 +2759,10 @@ void IlluminateVertexes( int num ){ /* jal: floodlight */ floodLightAmount = 0.0f; - VectorClear( floodColor ); + floodColor.set( 0 ); if ( floodlighty && !bouncing ) { floodLightAmount = floodlightIntensity * FloodLightForSample( &trace, floodlightDistance, floodlight_lowquality ); - VectorScale( floodlightRGB, floodLightAmount, floodColor ); + floodColor = floodlightRGB * floodLightAmount; } /* trace */ @@ -2960,21 +2772,18 @@ void IlluminateVertexes( int num ){ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) { /* r7 dirt */ - VectorScale( colors[ lightmapNum ], dirt, colors[ lightmapNum ] ); + colors[ lightmapNum ] *= dirt; /* jal: floodlight */ - VectorAdd( colors[ lightmapNum ], floodColor, colors[ lightmapNum ] ); + colors[ lightmapNum ] += floodColor; /* store */ - radVertLuxel = RAD_VERTEX_LUXEL( lightmapNum, ds->firstVert + i ); - VectorCopy( colors[ lightmapNum ], radVertLuxel ); + + getRadVertexLuxel( lightmapNum, ds->firstVert + i ) = colors[ lightmapNum ]; } /* bright enough? */ - radVertLuxel = RAD_VERTEX_LUXEL( 0, ds->firstVert + i ); - if ( radVertLuxel[ 0 ] > ambientColor[ 0 ] || - radVertLuxel[ 1 ] > ambientColor[ 1 ] || - radVertLuxel[ 2 ] > ambientColor[ 2 ] ) { + if ( vector3_component_greater( getRadVertexLuxel( 0, ds->firstVert + i ), ambientColor ) ) { x = y = z = 1000; } } @@ -2983,15 +2792,11 @@ void IlluminateVertexes( int num ){ } /* add to average? */ - radVertLuxel = RAD_VERTEX_LUXEL( 0, ds->firstVert + i ); - if ( radVertLuxel[ 0 ] > ambientColor[ 0 ] || - radVertLuxel[ 1 ] > ambientColor[ 1 ] || - radVertLuxel[ 2 ] > ambientColor[ 2 ] ) { + if ( vector3_component_greater( getRadVertexLuxel( 0, ds->firstVert + i ), ambientColor ) ) { numAvg++; for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) { - radVertLuxel = RAD_VERTEX_LUXEL( lightmapNum, ds->firstVert + i ); - VectorAdd( avgColors[ lightmapNum ], radVertLuxel, avgColors[ lightmapNum ] ); + avgColors[ lightmapNum ] += getRadVertexLuxel( lightmapNum, ds->firstVert + i ); } } } @@ -3003,28 +2808,24 @@ void IlluminateVertexes( int num ){ /* set average color */ if ( numAvg > 0 ) { for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) - VectorScale( avgColors[ lightmapNum ], ( 1.0f / numAvg ), avgColors[ lightmapNum ] ); + avgColors[ lightmapNum ] *= ( 1.0f / numAvg ); } else { - VectorCopy( ambientColor, avgColors[ 0 ] ); + avgColors[ 0 ] = ambientColor; } /* clean up and store vertex color */ for ( i = 0; i < ds->numVerts; i++ ) { - /* get vertex luxel */ - radVertLuxel = RAD_VERTEX_LUXEL( 0, ds->firstVert + i ); - /* store average in occluded vertexes */ - if ( radVertLuxel[ 0 ] < 0.0f ) { + if ( getRadVertexLuxel( 0, ds->firstVert + i )[ 0 ] < 0.0f ) { for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) { - radVertLuxel = RAD_VERTEX_LUXEL( lightmapNum, ds->firstVert + i ); - VectorCopy( avgColors[ lightmapNum ], radVertLuxel ); + getRadVertexLuxel( lightmapNum, ds->firstVert + i ) = avgColors[ lightmapNum ]; /* debug code */ - //% VectorSet( radVertLuxel, 255.0f, 0.0f, 0.0f ); + //% getRadVertexLuxel( lightmapNum, ds->firstVert + i ) = { 255.0f, 0.0f, 0.0f }; } } @@ -3032,15 +2833,15 @@ void IlluminateVertexes( int num ){ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) { /* get luxels */ - vertLuxel = VERTEX_LUXEL( lightmapNum, ds->firstVert + i ); - radVertLuxel = RAD_VERTEX_LUXEL( lightmapNum, ds->firstVert + i ); + Vector3& vertLuxel = getVertexLuxel( lightmapNum, ds->firstVert + i ); + const Vector3& radVertLuxel = getRadVertexLuxel( lightmapNum, ds->firstVert + i ); /* store */ if ( bouncing || bounce == 0 || !bounceOnly ) { - VectorAdd( vertLuxel, radVertLuxel, vertLuxel ); + vertLuxel += radVertLuxel; } if ( !info->si->noVertexLight ) { - ColorToBytes( vertLuxel, verts[ i ].color[ lightmapNum ], info->si->vertexScale ); + ColorToBytes( vertLuxel, verts[ i ].color[ lightmapNum ].rgb(), info->si->vertexScale ); } } } @@ -3093,34 +2894,32 @@ void IlluminateVertexes( int num ){ } /* get vertex luxels */ - vertLuxel = VERTEX_LUXEL( lightmapNum, ds->firstVert + i ); - radVertLuxel = RAD_VERTEX_LUXEL( lightmapNum, ds->firstVert + i ); + Vector3& vertLuxel = getVertexLuxel( lightmapNum, ds->firstVert + i ); + Vector3& radVertLuxel = getRadVertexLuxel( lightmapNum, ds->firstVert + i ); /* color the luxel with the normal? */ if ( normalmap ) { - radVertLuxel[ 0 ] = ( verts[ i ].normal[ 0 ] + 1.0f ) * 127.5f; - radVertLuxel[ 1 ] = ( verts[ i ].normal[ 1 ] + 1.0f ) * 127.5f; - radVertLuxel[ 2 ] = ( verts[ i ].normal[ 2 ] + 1.0f ) * 127.5f; + radVertLuxel = ( verts[ i ].normal + Vector3( 1, 1, 1 ) ) * 127.5f; } /* color the luxel with surface num? */ else if ( debugSurfaces ) { - VectorCopy( debugColors[ num % 12 ], radVertLuxel ); + radVertLuxel = debugColors[ num % 12 ]; } else if ( info->si->noVertexLight ) { - VectorSet( radVertLuxel, 127.5f, 127.5f, 127.5f ); + radVertLuxel.set( 127.5f ); } else if ( noVertexLighting > 0 ) { - VectorSet( radVertLuxel, 127.5f * noVertexLighting, 127.5f * noVertexLighting, 127.5f * noVertexLighting ); + radVertLuxel.set( 127.5f * noVertexLighting ); } /* divine color from the superluxels */ else { /* increasing radius */ - VectorClear( radVertLuxel ); + radVertLuxel.set( 0 ); samples = 0.0f; for ( radius = 0; radius < maxRadius && samples <= 0.0f; radius++ ) { @@ -3138,9 +2937,8 @@ void IlluminateVertexes( int num ){ } /* get luxel particulars */ - luxel = SUPER_LUXEL( lightmapNum, sx, sy ); - cluster = SUPER_CLUSTER( sx, sy ); - if ( *cluster < 0 ) { + const SuperLuxel& luxel = lm->getSuperLuxel( lightmapNum, sx, sy ); + if ( lm->getSuperCluster( sx, sy ) < 0 ) { continue; } @@ -3149,28 +2947,28 @@ void IlluminateVertexes( int num ){ //% continue; /* add its distinctiveness to our own */ - VectorAdd( radVertLuxel, luxel, radVertLuxel ); - samples += luxel[ 3 ]; + radVertLuxel += luxel.value; + samples += luxel.count; } } } /* any color? */ if ( samples > 0.0f ) { - VectorDivide( radVertLuxel, samples, radVertLuxel ); + radVertLuxel *= ( 1.f / samples ); } else{ - VectorCopy( ambientColor, radVertLuxel ); + radVertLuxel = ambientColor; } } /* store into floating point storage */ - VectorAdd( vertLuxel, radVertLuxel, vertLuxel ); + vertLuxel += radVertLuxel; numVertsIlluminated++; /* store into bytes (for vertex approximation) */ if ( !info->si->noVertexLight ) { - ColorToBytes( vertLuxel, verts[ i ].color[ lightmapNum ], 1.0f ); + ColorToBytes( vertLuxel, verts[ i ].color[ lightmapNum ].rgb(), 1.0f ); } } } @@ -3302,31 +3100,27 @@ bool ClusterVisible( int a, int b ){ borrowed from vlight.c */ -int PointInLeafNum_r( vec3_t point, int nodenum ){ +int PointInLeafNum_r( const Vector3& point, int nodenum ){ int leafnum; - vec_t dist; - bspNode_t *node; - bspPlane_t *plane; - while ( nodenum >= 0 ) { - node = &bspNodes[ nodenum ]; - plane = &bspPlanes[ node->planeNum ]; - dist = DotProduct( point, plane->normal ) - plane->dist; + const bspNode_t& node = bspNodes[ nodenum ]; + const bspPlane_t& plane = bspPlanes[ node.planeNum ]; + const double dist = plane3_distance_to_point( plane, point ); if ( dist > 0.1 ) { - nodenum = node->children[ 0 ]; + nodenum = node.children[ 0 ]; } else if ( dist < -0.1 ) { - nodenum = node->children[ 1 ]; + nodenum = node.children[ 1 ]; } else { - leafnum = PointInLeafNum_r( point, node->children[ 0 ] ); + leafnum = PointInLeafNum_r( point, node.children[ 0 ] ); if ( bspLeafs[ leafnum ].cluster != -1 ) { return leafnum; } - nodenum = node->children[ 1 ]; + nodenum = node.children[ 1 ]; } } @@ -3341,7 +3135,7 @@ int PointInLeafNum_r( vec3_t point, int nodenum ){ borrowed from vlight.c */ -int PointInLeafNum( vec3_t point ){ +int PointInLeafNum( const Vector3& point ){ return PointInLeafNum_r( point, 0 ); } @@ -3352,7 +3146,7 @@ int PointInLeafNum( vec3_t point ){ returns true if point can "see" cluster */ -bool ClusterVisibleToPoint( vec3_t point, int cluster ){ +bool ClusterVisibleToPoint( const Vector3& point, int cluster ){ int pointCluster; @@ -3373,7 +3167,7 @@ bool ClusterVisibleToPoint( vec3_t point, int cluster ){ returns the pvs cluster for point */ -int ClusterForPoint( vec3_t point ){ +int ClusterForPoint( const Vector3& point ){ int leafNum; @@ -3394,14 +3188,12 @@ int ClusterForPoint( vec3_t point ){ also takes brushes into account for occlusion testing */ -int ClusterForPointExt( vec3_t point, float epsilon ){ +int ClusterForPointExt( const Vector3& point, float epsilon ){ int i, j, b, leafNum, cluster; - float dot; bool inside; int *brushes, numBSPBrushes; bspLeaf_t *leaf; bspBrush_t *brush; - bspPlane_t *plane; /* get leaf for point */ @@ -3436,10 +3228,8 @@ int ClusterForPointExt( vec3_t point, float epsilon ){ inside = true; for ( j = 0; j < brush->numSides && inside; j++ ) { - plane = &bspPlanes[ bspBrushSides[ brush->firstSide + j ].planeNum ]; - dot = DotProduct( point, plane->normal ); - dot -= plane->dist; - if ( dot > epsilon ) { + const bspPlane_t& plane = bspPlanes[ bspBrushSides[ brush->firstSide + j ].planeNum ]; + if ( plane3_distance_to_point( plane, point ) > epsilon ) { inside = false; } } @@ -3461,7 +3251,7 @@ int ClusterForPointExt( vec3_t point, float epsilon ){ adds cluster checking against a list of known valid clusters */ -int ClusterForPointExtFilter( vec3_t point, float epsilon, int numClusters, int *clusters ){ +int ClusterForPointExtFilter( const Vector3& point, float epsilon, int numClusters, int *clusters ){ int i, cluster; @@ -3493,15 +3283,13 @@ int ClusterForPointExtFilter( vec3_t point, float epsilon, int numClusters, int also sets the cumulative surface and content flags for the brush hit */ -int ShaderForPointInLeaf( vec3_t point, int leafNum, float epsilon, int wantContentFlags, int wantSurfaceFlags, int *contentFlags, int *surfaceFlags ){ +int ShaderForPointInLeaf( const Vector3& point, int leafNum, float epsilon, int wantContentFlags, int wantSurfaceFlags, int *contentFlags, int *surfaceFlags ){ int i, j; - float dot; bool inside; int *brushes, numBSPBrushes; bspLeaf_t *leaf; bspBrush_t *brush; bspBrushSide_t *side; - bspPlane_t *plane; bspShader_t *shader; int allSurfaceFlags, allContentFlags; @@ -3531,10 +3319,8 @@ int ShaderForPointInLeaf( vec3_t point, int leafNum, float epsilon, int wantCont for ( j = 0; j < brush->numSides && inside; j++ ) { side = &bspBrushSides[ brush->firstSide + j ]; - plane = &bspPlanes[ side->planeNum ]; - dot = DotProduct( point, plane->normal ); - dot -= plane->dist; - if ( dot > epsilon ) { + const bspPlane_t& plane = bspPlanes[ side->planeNum ]; + if ( plane3_distance_to_point( plane, point ) > epsilon ) { inside = false; } else @@ -3576,7 +3362,7 @@ int ShaderForPointInLeaf( vec3_t point, int leafNum, float epsilon, int wantCont this is not exactly the fastest way to do this... */ -bool ChopBounds( vec3_t mins, vec3_t maxs, vec3_t origin, vec3_t normal ){ +bool ChopBounds( MinMax& minmax, const Vector3& origin, const Vector3& normal ){ /* FIXME: rewrite this so it doesn't use bloody brushes */ return true; } @@ -3596,7 +3382,7 @@ void SetupEnvelopes( bool forGrid, bool fastFlag ){ int i, x, y, z, x1, y1, z1; light_t *light, *light2, **owner; bspLeaf_t *leaf; - vec3_t origin, dir, mins, maxs; + Vector3 origin; float radius, intensity; light_t *buckets[ 256 ]; @@ -3630,8 +3416,8 @@ void SetupEnvelopes( bool forGrid, bool fastFlag ){ /* special cased */ light->cluster = 0; light->envelope = MAX_WORLD_COORD * 8.0f; - VectorSet( light->mins, MIN_WORLD_COORD * 8.0f, MIN_WORLD_COORD * 8.0f, MIN_WORLD_COORD * 8.0f ); - VectorSet( light->maxs, MAX_WORLD_COORD * 8.0f, MAX_WORLD_COORD * 8.0f, MAX_WORLD_COORD * 8.0f ); + light->minmax.mins.set( MIN_WORLD_COORD * 8.0f ); + light->minmax.maxs.set( MAX_WORLD_COORD * 8.0f ); } /* everything else */ @@ -3668,7 +3454,7 @@ void SetupEnvelopes( bool forGrid, bool fastFlag ){ } /* set origin */ - VectorCopy( origin, light->origin ); + light->origin = origin; } } } @@ -3700,12 +3486,12 @@ void SetupEnvelopes( bool forGrid, bool fastFlag ){ /* check for fast mode */ if ( light->flags & LightFlags::FastActual ) { /* ugly hack to calculate extent for area lights, but only done once */ - VectorScale( light->normal, -1.0f, dir ); + const Vector3 dir = -light->normal; for ( radius = 100.0f; radius < MAX_WORLD_COORD * 8.0f; radius += 10.0f ) { float factor; - VectorMA( light->origin, radius, light->normal, origin ); + origin = light->origin + light->normal * radius; factor = PointToPolygonFormFactor( origin, dir, light->w ); if ( factor < 0.0f ) { factor *= -1.0f; @@ -3775,7 +3561,7 @@ void SetupEnvelopes( bool forGrid, bool fastFlag ){ /* chop radius against pvs */ { /* clear bounds */ - ClearBounds( mins, maxs ); + MinMax minmax; /* check all leaves */ for ( i = 0; i < numBSPLeafs; i++ ) @@ -3792,46 +3578,34 @@ void SetupEnvelopes( bool forGrid, bool fastFlag ){ } /* add this leafs bbox to the bounds */ - VectorCopy( leaf->mins, origin ); - AddPointToBounds( origin, mins, maxs ); - VectorCopy( leaf->maxs, origin ); - AddPointToBounds( origin, mins, maxs ); + minmax.extend( leaf->minmax ); } /* test to see if bounds encompass light */ - for ( i = 0; i < 3; i++ ) - { - if ( mins[ i ] > light->origin[ i ] || maxs[ i ] < light->origin[ i ] ) { - //% Sys_Warning( "Light PVS bounds (%.0f, %.0f, %.0f) -> (%.0f, %.0f, %.0f)\ndo not encompass light %d (%f, %f, %f)\n", - //% mins[ 0 ], mins[ 1 ], mins[ 2 ], - //% maxs[ 0 ], maxs[ 1 ], maxs[ 2 ], - //% numLights, light->origin[ 0 ], light->origin[ 1 ], light->origin[ 2 ] ); - AddPointToBounds( light->origin, mins, maxs ); - } + if ( !minmax.test( light->origin ) ) { + //% Sys_Warning( "Light PVS bounds (%.0f, %.0f, %.0f) -> (%.0f, %.0f, %.0f)\ndo not encompass light %d (%f, %f, %f)\n", + //% minmax.mins[ 0 ], minmax.mins[ 1 ], minmax.mins[ 2 ], + //% minmax.maxs[ 0 ], minmax.maxs[ 1 ], minmax.maxs[ 2 ], + //% numLights, light->origin[ 0 ], light->origin[ 1 ], light->origin[ 2 ] ); + minmax.extend( light->origin ); } /* chop the bounds by a plane for area lights and spotlights */ if ( light->type == ELightType::Area || light->type == ELightType::Spot ) { - ChopBounds( mins, maxs, light->origin, light->normal ); + ChopBounds( minmax, light->origin, light->normal ); } /* copy bounds */ - VectorCopy( mins, light->mins ); - VectorCopy( maxs, light->maxs ); + light->minmax = minmax; /* reflect bounds around light origin */ //% VectorMA( light->origin, -1.0f, origin, origin ); - VectorScale( light->origin, 2, origin ); - VectorSubtract( origin, maxs, origin ); - AddPointToBounds( origin, mins, maxs ); + minmax.extend( light->origin * 2 - minmax.maxs ); //% VectorMA( light->origin, -1.0f, mins, origin ); - VectorScale( light->origin, 2, origin ); - VectorSubtract( origin, mins, origin ); - AddPointToBounds( origin, mins, maxs ); + minmax.extend( light->origin * 2 - minmax.mins ); /* calculate spherical bounds */ - VectorSubtract( maxs, light->origin, dir ); - radius = (float) VectorLength( dir ); + radius = vector3_length( minmax.maxs - light->origin ); /* if this radius is smaller than the envelope, then set the envelope to it */ if ( radius < light->envelope ) { @@ -3923,11 +3697,10 @@ void SetupEnvelopes( bool forGrid, bool fastFlag ){ creates a list of lights that affect the given bounding box and pvs clusters (bsp leaves) */ -void CreateTraceLightsForBounds( vec3_t mins, vec3_t maxs, vec3_t normal, int numClusters, int *clusters, LightFlags flags, trace_t *trace ){ +void CreateTraceLightsForBounds( const MinMax& minmax, const Vector3 *normal, int numClusters, int *clusters, LightFlags flags, trace_t *trace ){ int i; light_t *light; - vec3_t origin, dir, nullVector = { 0.0f, 0.0f, 0.0f }; - float radius, dist, length; + float dist, length; /* potential pre-setup */ @@ -3936,25 +3709,23 @@ void CreateTraceLightsForBounds( vec3_t mins, vec3_t maxs, vec3_t normal, int nu } /* debug code */ - //% Sys_Printf( "CTWLFB: (%4.1f %4.1f %4.1f) (%4.1f %4.1f %4.1f)\n", mins[ 0 ], mins[ 1 ], mins[ 2 ], maxs[ 0 ], maxs[ 1 ], maxs[ 2 ] ); + //% Sys_Printf( "CTWLFB: (%4.1f %4.1f %4.1f) (%4.1f %4.1f %4.1f)\n", minmax.mins[ 0 ], minmax.mins[ 1 ], minmax.mins[ 2 ], minmax.maxs[ 0 ], minmax.maxs[ 1 ], minmax.maxs[ 2 ] ); /* allocate the light list */ trace->lights = safe_malloc( sizeof( light_t* ) * ( numLights + 1 ) ); trace->numLights = 0; /* calculate spherical bounds */ - VectorAdd( mins, maxs, origin ); - VectorScale( origin, 0.5f, origin ); - VectorSubtract( maxs, origin, dir ); - radius = (float) VectorLength( dir ); + const Vector3 origin = minmax.origin(); + const float radius = vector3_length( minmax.maxs - origin ); /* get length of normal vector */ if ( normal != NULL ) { - length = VectorLength( normal ); + length = vector3_length( *normal ); } else { - normal = nullVector; + normal = &g_vector3_identity; length = 0; } @@ -3997,10 +3768,7 @@ void CreateTraceLightsForBounds( vec3_t mins, vec3_t maxs, vec3_t normal, int nu } /* if the light's bounding sphere intersects with the bounding sphere then this light needs to be tested */ - VectorSubtract( light->origin, origin, dir ); - dist = VectorLength( dir ); - dist -= light->envelope; - dist -= radius; + dist = vector3_length( light->origin - origin ) - light->envelope - radius; if ( dist > 0 ) { lightsEnvelopeCulled++; continue; @@ -4008,14 +3776,7 @@ void CreateTraceLightsForBounds( vec3_t mins, vec3_t maxs, vec3_t normal, int nu /* check bounding box against light's pvs envelope (note: this code never eliminated any lights, so disabling it) */ #if 0 - bool skip = false; - for ( i = 0; i < 3; i++ ) - { - if ( mins[ i ] > light->maxs[ i ] || maxs[ i ] < light->mins[ i ] ) { - skip = true; - } - } - if ( skip ) { + if( !minmax.test( light->minmax ) ){ lightsBoundsCulled++; continue; } @@ -4025,13 +3786,13 @@ void CreateTraceLightsForBounds( vec3_t mins, vec3_t maxs, vec3_t normal, int nu /* planar surfaces (except twosided surfaces) have a couple more checks */ if ( length > 0.0f && !trace->twoSided ) { /* lights coplanar with a surface won't light it */ - if ( !( light->flags & LightFlags::Twosided ) && DotProduct( light->normal, normal ) > 0.999f ) { + if ( !( light->flags & LightFlags::Twosided ) && vector3_dot( light->normal, *normal ) > 0.999f ) { lightsPlaneCulled++; continue; } /* check to see if light is behind the plane */ - if ( DotProduct( light->origin, normal ) - DotProduct( origin, normal ) < -1.0f ) { + if ( vector3_dot( light->origin, *normal ) - vector3_dot( origin, *normal ) < -1.0f ) { lightsPlaneCulled++; continue; } @@ -4060,7 +3821,6 @@ void FreeTraceLights( trace_t *trace ){ void CreateTraceLightsForSurface( int num, trace_t *trace ){ int i; - vec3_t mins, maxs, normal; bspDrawVert_t *dv; bspDrawSurface_t *ds; surfaceInfo_t *info; @@ -4076,19 +3836,19 @@ void CreateTraceLightsForSurface( int num, trace_t *trace ){ info = &surfaceInfos[ num ]; /* get the mins/maxs for the dsurf */ - ClearBounds( mins, maxs ); - VectorCopy( bspDrawVerts[ ds->firstVert ].normal, normal ); + MinMax minmax; + Vector3 normal = bspDrawVerts[ ds->firstVert ].normal; for ( i = 0; i < ds->numVerts; i++ ) { dv = &yDrawVerts[ ds->firstVert + i ]; - AddPointToBounds( dv->xyz, mins, maxs ); + minmax.extend( dv->xyz ); if ( !VectorCompare( dv->normal, normal ) ) { - VectorClear( normal ); + normal.set( 0 ); } } /* create the lights for the bounding box */ - CreateTraceLightsForBounds( mins, maxs, normal, info->numSurfaceClusters, &surfaceClusters[ info->firstSurfaceCluster ], LightFlags::Surfaces, trace ); + CreateTraceLightsForBounds( minmax, &normal, info->numSurfaceClusters, &surfaceClusters[ info->firstSurfaceCluster ], LightFlags::Surfaces, trace ); } ///////////////////////////////////////////////////////////// @@ -4098,7 +3858,7 @@ void CreateTraceLightsForSurface( int num, trace_t *trace ){ #define FLOODLIGHT_NUM_ELEVATION_STEPS 4 #define FLOODLIGHT_NUM_VECTORS ( FLOODLIGHT_NUM_ANGLE_STEPS * FLOODLIGHT_NUM_ELEVATION_STEPS ) -static vec3_t floodVectors[ FLOODLIGHT_NUM_VECTORS ]; +static Vector3 floodVectors[ FLOODLIGHT_NUM_VECTORS ]; static int numFloodVectors = 0; void SetupFloodLight( void ){ @@ -4109,8 +3869,8 @@ void SetupFloodLight( void ){ Sys_FPrintf( SYS_VRB, "--- SetupFloodLight ---\n" ); /* calculate angular steps */ - angleStep = DEG2RAD( 360.0f / FLOODLIGHT_NUM_ANGLE_STEPS ); - elevationStep = DEG2RAD( FLOODLIGHT_CONE_ANGLE / FLOODLIGHT_NUM_ELEVATION_STEPS ); + angleStep = degrees_to_radians( 360.0f / FLOODLIGHT_NUM_ANGLE_STEPS ); + elevationStep = degrees_to_radians( FLOODLIGHT_CONE_ANGLE / FLOODLIGHT_NUM_ELEVATION_STEPS ); /* iterate angle */ angle = 0.0f; @@ -4140,12 +3900,10 @@ void SetupFloodLight( void ){ sscanf( value, "%lf %lf %lf %lf %lf %lf", &v1, &v2, &v3, &v4, &v5, &v6 ); - floodlightRGB[0] = v1; - floodlightRGB[1] = v2; - floodlightRGB[2] = v3; + floodlightRGB = { v1, v2, v3 }; - if ( VectorLength( floodlightRGB ) == 0 ) { - VectorSet( floodlightRGB,0.94,0.94,1.0 ); + if ( vector3_length( floodlightRGB ) == 0 ) { + floodlightRGB = { 0.94, 0.94, 1.0 }; } if ( v4 < 1 ) { @@ -4167,14 +3925,14 @@ void SetupFloodLight( void ){ } else { - VectorSet( floodlightRGB,0.94,0.94,1.0 ); + floodlightRGB = { 0.94, 0.94, 1.0 }; } if ( colorsRGB ) { floodlightRGB[0] = Image_LinearFloatFromsRGBFloat( floodlightRGB[0] ); floodlightRGB[1] = Image_LinearFloatFromsRGBFloat( floodlightRGB[1] ); floodlightRGB[2] = Image_LinearFloatFromsRGBFloat( floodlightRGB[2] ); } - ColorNormalize( floodlightRGB,floodlightRGB ); + ColorNormalize( floodlightRGB ); } /* @@ -4185,12 +3943,10 @@ void SetupFloodLight( void ){ float FloodLightForSample( trace_t *trace, float floodLightDistance, bool floodLightLowQuality ){ int i; - float d; float contribution; int sub = 0; float gatherLight, outLight; - vec3_t normal, worldUp, myUp, myRt, direction, displacement; - float dd; + Vector3 myUp, myRt; int vecs = 0; gatherLight = 0; @@ -4203,27 +3959,24 @@ float FloodLightForSample( trace_t *trace, float floodLightDistance, bool floodL /* setup */ - dd = floodLightDistance; - VectorCopy( trace->normal, normal ); + const float dd = floodLightDistance; + const Vector3 normal( trace->normal ); /* check if the normal is aligned to the world-up */ if ( normal[ 0 ] == 0.0f && normal[ 1 ] == 0.0f && ( normal[ 2 ] == 1.0f || normal[ 2 ] == -1.0f ) ) { if ( normal[ 2 ] == 1.0f ) { - VectorSet( myRt, 1.0f, 0.0f, 0.0f ); - VectorSet( myUp, 0.0f, 1.0f, 0.0f ); + myRt = g_vector3_axis_x; + myUp = g_vector3_axis_y; } else if ( normal[ 2 ] == -1.0f ) { - VectorSet( myRt, -1.0f, 0.0f, 0.0f ); - VectorSet( myUp, 0.0f, 1.0f, 0.0f ); + myRt = -g_vector3_axis_x; + myUp = g_vector3_axis_y; } } else { - VectorSet( worldUp, 0.0f, 0.0f, 1.0f ); - CrossProduct( normal, worldUp, myRt ); - VectorNormalize( myRt, myRt ); - CrossProduct( myRt, normal, myUp ); - VectorNormalize( myUp, myUp ); + myRt = VectorNormalized( vector3_cross( normal, g_vector3_axis_z ) ); + myUp = VectorNormalized( vector3_cross( myRt, normal ) ); } /* vortex: optimise floodLightLowQuality a bit */ @@ -4242,17 +3995,15 @@ float FloodLightForSample( trace_t *trace, float floodLightDistance, bool floodL vecs++; /* transform vector into tangent space */ - direction[ 0 ] = myRt[ 0 ] * floodVectors[ i ][ 0 ] + myUp[ 0 ] * floodVectors[ i ][ 1 ] + normal[ 0 ] * floodVectors[ i ][ 2 ]; - direction[ 1 ] = myRt[ 1 ] * floodVectors[ i ][ 0 ] + myUp[ 1 ] * floodVectors[ i ][ 1 ] + normal[ 1 ] * floodVectors[ i ][ 2 ]; - direction[ 2 ] = myRt[ 2 ] * floodVectors[ i ][ 0 ] + myUp[ 2 ] * floodVectors[ i ][ 1 ] + normal[ 2 ] * floodVectors[ i ][ 2 ]; + const Vector3 direction = myRt * floodVectors[ i ][ 0 ] + myUp * floodVectors[ i ][ 1 ] + normal * floodVectors[ i ][ 2 ]; /* set endpoint */ - VectorMA( trace->origin, dd, direction, trace->end ); + trace->end = trace->origin + direction * dd; - //VectorMA( trace->origin, 1, direction, trace->origin ); + // trace->origin += direction; SetupTrace( trace ); - VectorSet(trace->color, 1.0f, 1.0f, 1.0f); + trace->color.set( 1 ); /* trace */ TraceLine( trace ); contribution = 1; @@ -4261,8 +4012,7 @@ float FloodLightForSample( trace_t *trace, float floodLightDistance, bool floodL contribution = 1.0f; } else if ( trace->opaque ) { - VectorSubtract( trace->hit, trace->origin, displacement ); - d = VectorLength( displacement ); + const float d = vector3_length( trace->hit - trace->origin ); // d=trace->distance; //if (d>256) gatherDirt+=1; @@ -4308,9 +4058,8 @@ float FloodLightForSample( trace_t *trace, float floodLightDistance, bool floodL */ // floodlight pass on a lightmap -void FloodLightRawLightmapPass( rawLightmap_t *lm, vec3_t lmFloodLightRGB, float lmFloodLightIntensity, float lmFloodLightDistance, bool lmFloodLightLowQuality, float floodlightDirectionScale ){ - int i, x, y, *cluster; - float *origin, *normal, *floodlight, floodLightAmount; +void FloodLightRawLightmapPass( rawLightmap_t *lm, Vector3& lmFloodLightRGB, float lmFloodLightIntensity, float lmFloodLightDistance, bool lmFloodLightLowQuality, float floodlightDirectionScale ){ + int i, x, y; surfaceInfo_t *info; trace_t trace; // int sx, sy; @@ -4349,32 +4098,28 @@ void FloodLightRawLightmapPass( rawLightmap_t *lm, vec3_t lmFloodLightRGB, float for ( x = 0; x < lm->sw; x++ ) { /* get luxel */ - cluster = SUPER_CLUSTER( x, y ); - origin = SUPER_ORIGIN( x, y ); - normal = SUPER_NORMAL( x, y ); - floodlight = SUPER_FLOODLIGHT( x, y ); + const int cluster = lm->getSuperCluster( x, y ); + SuperFloodLight& floodlight = lm->getSuperFloodLight( x, y ); /* set default dirt */ - *floodlight = 0.0f; + floodlight.value[0] = 0.0f; /* only look at mapped luxels */ - if ( *cluster < 0 ) { + if ( cluster < 0 ) { continue; } /* copy to trace */ - trace.cluster = *cluster; - VectorCopy( origin, trace.origin ); - VectorCopy( normal, trace.normal ); + trace.cluster = cluster; + trace.origin = lm->getSuperOrigin( x, y ); + trace.normal = lm->getSuperNormal( x, y ); /* get floodlight */ - floodLightAmount = FloodLightForSample( &trace, lmFloodLightDistance, lmFloodLightLowQuality ) * lmFloodLightIntensity; + const float floodLightAmount = FloodLightForSample( &trace, lmFloodLightDistance, lmFloodLightLowQuality ) * lmFloodLightIntensity; /* add floodlight */ - floodlight[0] += lmFloodLightRGB[0] * floodLightAmount; - floodlight[1] += lmFloodLightRGB[1] * floodLightAmount; - floodlight[2] += lmFloodLightRGB[2] * floodLightAmount; - floodlight[3] += floodlightDirectionScale; + floodlight.value += lmFloodLightRGB * floodLightAmount; + floodlight.scale += floodlightDirectionScale; } } @@ -4389,11 +4134,10 @@ void FloodLightRawLightmapPass( rawLightmap_t *lm, vec3_t lmFloodLightRGB, float for ( x = 0; x < lm->sw; x++ ) { /* get luxel */ - cluster = SUPER_CLUSTER( x, y ); - floodlight = SUPER_FLOODLIGHT( x, y ); + SuperFloodLight& floodlight = lm->getSuperFloodLight( x, y ); /* filter dirt by adjacency to unmapped luxels */ - average = *floodlight; + average = floodlight.value[0]; samples = 1.0f; for ( sy = ( y - 1 ); sy <= ( y + 1 ); sy++ ) { @@ -4408,14 +4152,13 @@ void FloodLightRawLightmapPass( rawLightmap_t *lm, vec3_t lmFloodLightRGB, float } /* get neighboring luxel */ - cluster = SUPER_CLUSTER( sx, sy ); - floodlight2 = SUPER_FLOODLIGHT( sx, sy ); - if ( *cluster < 0 || *floodlight2 <= 0.0f ) { + const SuperFloodLight& floodlight2 = lm->getSuperFloodLight( sx, sy ); + if ( lm->getSuperCluster( sx, sy ) < 0 || floodlight2.value[0] <= 0.0f ) { continue; } /* add it */ - average += *floodlight2; + average += floodlight2.value[0]; samples += 1.0f; } @@ -4431,7 +4174,7 @@ void FloodLightRawLightmapPass( rawLightmap_t *lm, vec3_t lmFloodLightRGB, float } /* scale dirt */ - *floodlight = average / samples; + floodlight.value[0] = average / samples; } } #endif @@ -4472,9 +4215,6 @@ void FloodlightRawLightmaps(){ */ void FloodlightIlluminateLightmap( rawLightmap_t *lm ){ - float *luxel, *floodlight, *deluxel, *normal; - int *cluster; - float brightness; int x, y, lightmapNum; /* walk lightmaps */ @@ -4494,46 +4234,37 @@ void FloodlightIlluminateLightmap( rawLightmap_t *lm ){ for ( x = 0; x < lm->sw; x++ ) { /* get floodlight */ - floodlight = SUPER_FLOODLIGHT( x, y ); - if ( !floodlight[0] && !floodlight[1] && !floodlight[2] ) { + const SuperFloodLight& floodlight = lm->getSuperFloodLight( x, y ); + if ( floodlight.value == g_vector3_identity ) { continue; } - /* get cluster */ - cluster = SUPER_CLUSTER( x, y ); - /* only process mapped luxels */ - if ( *cluster < 0 ) { + if ( lm->getSuperCluster( x, y ) < 0 ) { continue; } /* get particulars */ - luxel = SUPER_LUXEL( lightmapNum, x, y ); - deluxel = SUPER_DELUXEL( x, y ); + SuperLuxel& luxel = lm->getSuperLuxel( lightmapNum, x, y ); /* add to lightmap */ - luxel[0] += floodlight[0]; - luxel[1] += floodlight[1]; - luxel[2] += floodlight[2]; + luxel.value += floodlight.value; - if ( luxel[3] == 0 ) { - luxel[3] = 1; + if ( luxel.count == 0 ) { + luxel.count = 1; } /* add to deluxemap */ - if ( deluxemap && floodlight[3] > 0 ) { - vec3_t lightvector; - - normal = SUPER_NORMAL( x, y ); - brightness = RGBTOGRAY( floodlight ) * ( 1.0f / 255.0f ) * floodlight[3]; + if ( deluxemap && floodlight.scale > 0 ) { + float brightness = RGBTOGRAY( floodlight.value ) * ( 1.0f / 255.0f ) * floodlight.scale; // use AT LEAST this amount of contribution from ambient for the deluxemap, fixes points that receive ZERO light if ( brightness < 0.00390625f ) { brightness = 0.00390625f; } - VectorScale( normal, brightness, lightvector ); - VectorAdd( deluxel, lightvector, deluxel ); + const Vector3 lightvector = lm->getSuperNormal( x, y ) * brightness; + lm->getSuperDeluxel( x, y ) += lightvector; } } } diff --git a/tools/quake3/q3map2/lightmaps_ydnar.cpp b/tools/quake3/q3map2/lightmaps_ydnar.cpp index 9c7bb2a5..1cf58553 100644 --- a/tools/quake3/q3map2/lightmaps_ydnar.cpp +++ b/tools/quake3/q3map2/lightmaps_ydnar.cpp @@ -350,23 +350,20 @@ void FinishRawLightmap( rawLightmap_t *lm ){ /* scale the vectors and shift the origin */ #if 1 /* new code that works for arbitrary supersampling values */ - VectorMA( lm->origin, -0.5, lm->vecs[ 0 ], lm->origin ); - VectorMA( lm->origin, -0.5, lm->vecs[ 1 ], lm->origin ); - VectorScale( lm->vecs[ 0 ], is, lm->vecs[ 0 ] ); - VectorScale( lm->vecs[ 1 ], is, lm->vecs[ 1 ] ); - VectorMA( lm->origin, is, lm->vecs[ 0 ], lm->origin ); - VectorMA( lm->origin, is, lm->vecs[ 1 ], lm->origin ); + lm->origin -= vector3_mid( lm->vecs[ 0 ], lm->vecs[ 1 ] ); + lm->vecs[ 0 ] *= is; + lm->vecs[ 1 ] *= is; + lm->origin += ( lm->vecs[ 0 ] + lm->vecs[ 1 ] ) * is; #else /* old code that only worked with a value of 2 */ - VectorScale( lm->vecs[ 0 ], is, lm->vecs[ 0 ] ); - VectorScale( lm->vecs[ 1 ], is, lm->vecs[ 1 ] ); - VectorMA( lm->origin, -is, lm->vecs[ 0 ], lm->origin ); - VectorMA( lm->origin, -is, lm->vecs[ 1 ], lm->origin ); + lm->vecs[ 0 ] *= is; + lm->vecs[ 1 ] *= is; + lm->origin -= (lm->vecs[ 0 ] + lm->vecs[ 1 ] ) * is; #endif } /* allocate bsp lightmap storage */ - size = lm->w * lm->h * BSP_LUXEL_SIZE * sizeof( float ); + size = lm->w * lm->h * sizeof( *( lm->bspLuxels[ 0 ] ) ); if ( lm->bspLuxels[ 0 ] == NULL ) { lm->bspLuxels[ 0 ] = safe_malloc( size ); } @@ -374,7 +371,7 @@ void FinishRawLightmap( rawLightmap_t *lm ){ /* allocate radiosity lightmap storage */ if ( bounce ) { - size = lm->w * lm->h * RAD_LUXEL_SIZE * sizeof( float ); + size = lm->w * lm->h * sizeof( *lm->radLuxels[ 0 ] ); if ( lm->radLuxels[ 0 ] == NULL ) { lm->radLuxels[ 0 ] = safe_malloc( size ); } @@ -382,35 +379,42 @@ void FinishRawLightmap( rawLightmap_t *lm ){ } /* allocate sampling lightmap storage */ - size = lm->sw * lm->sh * SUPER_LUXEL_SIZE * sizeof( float ); + size = lm->sw * lm->sh * sizeof( *lm->superLuxels[ 0 ] ); if ( lm->superLuxels[ 0 ] == NULL ) { lm->superLuxels[ 0 ] = safe_malloc( size ); } memset( lm->superLuxels[ 0 ], 0, size ); /* allocate origin map storage */ - size = lm->sw * lm->sh * SUPER_ORIGIN_SIZE * sizeof( float ); + size = lm->sw * lm->sh * sizeof( *lm->superOrigins ); if ( lm->superOrigins == NULL ) { lm->superOrigins = safe_malloc( size ); } memset( lm->superOrigins, 0, size ); /* allocate normal map storage */ - size = lm->sw * lm->sh * SUPER_NORMAL_SIZE * sizeof( float ); + size = lm->sw * lm->sh * sizeof( *lm->superNormals ); if ( lm->superNormals == NULL ) { lm->superNormals = safe_malloc( size ); } memset( lm->superNormals, 0, size ); + /* allocate dirt map storage */ + size = lm->sw * lm->sh * sizeof( *lm->superDirt ); + if ( lm->superDirt == NULL ) { + lm->superDirt = safe_malloc( size ); + } + memset( lm->superDirt, 0, size ); + /* allocate floodlight map storage */ - size = lm->sw * lm->sh * SUPER_FLOODLIGHT_SIZE * sizeof( float ); + size = lm->sw * lm->sh * sizeof( *lm->superFloodLight ); if ( lm->superFloodLight == NULL ) { lm->superFloodLight = safe_malloc( size ); } memset( lm->superFloodLight, 0, size ); /* allocate cluster map storage */ - size = lm->sw * lm->sh * sizeof( int ); + size = lm->sw * lm->sh * sizeof( *lm->superClusters ); if ( lm->superClusters == NULL ) { lm->superClusters = safe_malloc( size ); } @@ -422,14 +426,14 @@ void FinishRawLightmap( rawLightmap_t *lm ){ /* deluxemap allocation */ if ( deluxemap ) { /* allocate sampling deluxel storage */ - size = lm->sw * lm->sh * SUPER_DELUXEL_SIZE * sizeof( float ); + size = lm->sw * lm->sh * sizeof( *lm->superDeluxels ); if ( lm->superDeluxels == NULL ) { lm->superDeluxels = safe_malloc( size ); } memset( lm->superDeluxels, 0, size ); /* allocate bsp deluxel storage */ - size = lm->w * lm->h * BSP_DELUXEL_SIZE * sizeof( float ); + size = lm->w * lm->h * sizeof( *lm->bspDeluxels ); if ( lm->bspDeluxels == NULL ) { lm->bspDeluxels = safe_malloc( size ); } @@ -455,7 +459,6 @@ bool AddPatchToRawLightmap( int num, rawLightmap_t *lm ){ surfaceInfo_t *info; int x, y; bspDrawVert_t *verts, *a, *b; - vec3_t delta; mesh_t src, *subdivided, *mesh; float sBasis, tBasis, s, t; float length, widthTable[ MAX_EXPANDED_AXIS ] = {0}, heightTable[ MAX_EXPANDED_AXIS ] = {0}; @@ -490,8 +493,7 @@ bool AddPatchToRawLightmap( int num, rawLightmap_t *lm ){ if ( x + 1 < mesh->width ) { a = &verts[ ( y * mesh->width ) + x ]; b = &verts[ ( y * mesh->width ) + x + 1 ]; - VectorSubtract( a->xyz, b->xyz, delta ); - length = VectorLength( delta ); + length = vector3_length( a->xyz - b->xyz ); if ( length > widthTable[ x ] ) { widthTable[ x ] = length; } @@ -501,8 +503,7 @@ bool AddPatchToRawLightmap( int num, rawLightmap_t *lm ){ if ( y + 1 < mesh->height ) { a = &verts[ ( y * mesh->width ) + x ]; b = &verts[ ( ( y + 1 ) * mesh->width ) + x ]; - VectorSubtract( a->xyz, b->xyz, delta ); - length = VectorLength( delta ); + length = vector3_length( a->xyz - b->xyz ); if ( length > heightTable[ y ] ) { heightTable[ y ] = length; } @@ -588,9 +589,9 @@ bool AddSurfaceToRawLightmap( int num, rawLightmap_t *lm ){ bspDrawSurface_t *ds, *ds2; surfaceInfo_t *info; int num2, n, i, axisNum; - float s, t, d, len, sampleSize; - vec3_t mins, maxs, origin, faxis, size, delta, normalized, vecs[ 2 ]; - vec4_t plane; + float s, t, len, sampleSize; + Vector3 mins, maxs, origin, faxis, size, delta, normalized, vecs[ 2 ]; + Plane3f plane; bspDrawVert_t *verts; @@ -622,14 +623,8 @@ bool AddSurfaceToRawLightmap( int num, rawLightmap_t *lm ){ } /* surface bounds must intersect with raw lightmap bounds */ - for ( i = 0; i < 3; i++ ) - { - if ( info->mins[ i ] > lm->maxs[ i ] ) { - return false; - } - if ( info->maxs[ i ] < lm->mins[ i ] ) { - return false; - } + if( !info->minmax.test( lm->minmax ) ){ + return false; } /* plane check (fixme: allow merging of nonplanars) */ @@ -639,10 +634,10 @@ bool AddSurfaceToRawLightmap( int num, rawLightmap_t *lm ){ } /* compare planes */ - for ( i = 0; i < 4; i++ ) - if ( fabs( info->plane[ i ] - lm->plane[ i ] ) > EQUAL_EPSILON ) { - return false; - } + if( !vector3_equal_epsilon( info->plane->normal(), lm->plane->normal(), EQUAL_EPSILON ) + || !float_equal_epsilon( info->plane->dist(), lm->plane->dist(), EQUAL_EPSILON ) ){ + return false; + } } /* debug code hacking */ @@ -656,8 +651,7 @@ bool AddSurfaceToRawLightmap( int num, rawLightmap_t *lm ){ } /* add surface to lightmap bounds */ - AddPointToBounds( info->mins, lm->mins, lm->maxs ); - AddPointToBounds( info->maxs, lm->mins, lm->maxs ); + lm->minmax.extend( info->minmax ); /* check to see if this is a non-planar patch */ if ( ds->surfaceType == MST_PATCH && @@ -671,8 +665,8 @@ bool AddSurfaceToRawLightmap( int num, rawLightmap_t *lm ){ /* round to the lightmap resolution */ for ( i = 0; i < 3; i++ ) { - mins[ i ] = sampleSize * floor( lm->mins[ i ] / sampleSize ); - maxs[ i ] = sampleSize * ceil( lm->maxs[ i ] / sampleSize ); + mins[ i ] = sampleSize * floor( lm->minmax.mins[ i ] / sampleSize ); + maxs[ i ] = sampleSize * ceil( lm->minmax.maxs[ i ] / sampleSize ); size[ i ] = ( maxs[ i ] - mins[ i ] ) / sampleSize + 1.0f; /* hack (god this sucks) */ @@ -685,23 +679,23 @@ bool AddSurfaceToRawLightmap( int num, rawLightmap_t *lm ){ if ( sampleSize != lm->sampleSize && lmLimitSize == 0 ){ if ( debugSampleSize == 1 || lm->customWidth > 128 ){ Sys_FPrintf( SYS_WRN | SYS_VRBflag, "WARNING: surface at (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) too large for desired samplesize/lightmapsize/lightmapscale combination, increased samplesize from %d to %d\n", - info->mins[0], - info->mins[1], - info->mins[2], - info->maxs[0], - info->maxs[1], - info->maxs[2], + info->minmax.mins[0], + info->minmax.mins[1], + info->minmax.mins[2], + info->minmax.maxs[0], + info->minmax.maxs[1], + info->minmax.maxs[2], lm->sampleSize, (int) sampleSize ); } else if ( debugSampleSize == 0 ){ Sys_FPrintf( SYS_WRN | SYS_VRBflag, "WARNING: surface at (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) too large for desired samplesize/lightmapsize/lightmapscale combination, increased samplesize from %d to %d\n", - info->mins[0], - info->mins[1], - info->mins[2], - info->maxs[0], - info->maxs[1], - info->maxs[2], + info->minmax.mins[0], + info->minmax.mins[1], + info->minmax.mins[2], + info->minmax.maxs[0], + info->minmax.maxs[1], + info->minmax.maxs[2], lm->sampleSize, (int) sampleSize ); debugSampleSize--; @@ -716,13 +710,11 @@ bool AddSurfaceToRawLightmap( int num, rawLightmap_t *lm ){ /* fixme: copy rounded mins/maxes to lightmap record? */ if ( lm->plane == NULL ) { - VectorCopy( mins, lm->mins ); - VectorCopy( maxs, lm->maxs ); - VectorCopy( mins, origin ); + lm->minmax = { mins, maxs }; } /* set lightmap origin */ - VectorCopy( lm->mins, origin ); + origin = lm->minmax.mins; /* make absolute axis */ faxis[ 0 ] = fabs( lm->axis[ 0 ] ); @@ -777,9 +769,9 @@ bool AddSurfaceToRawLightmap( int num, rawLightmap_t *lm ){ /* set the lightmap texture coordinates in yDrawVerts in [0, superSample * lm->customWidth] space */ for ( i = 0; i < ds2->numVerts; i++ ) { - VectorSubtract( verts[ i ].xyz, origin, delta ); - s = DotProduct( delta, vecs[ 0 ] ) + 0.5f; - t = DotProduct( delta, vecs[ 1 ] ) + 0.5f; + delta = verts[ i ].xyz - origin; + s = vector3_dot( delta, vecs[ 0 ] ) + 0.5f; + t = vector3_dot( delta, vecs[ 1 ] ) + 0.5f; verts[ i ].lightmap[ 0 ][ 0 ] = s * superSample; verts[ i ].lightmap[ 0 ][ 1 ] = t * superSample; @@ -796,36 +788,33 @@ bool AddSurfaceToRawLightmap( int num, rawLightmap_t *lm ){ verts = &yDrawVerts[ ds2->firstVert ]; /* calculate lightmap origin */ - if ( VectorLength( ds2->lightmapVecs[ 2 ] ) ) { - VectorCopy( ds2->lightmapVecs[ 2 ], plane ); + if ( vector3_length( ds2->lightmapVecs[ 2 ] ) ) { + plane.normal() = ds2->lightmapVecs[ 2 ]; } else{ - VectorCopy( lm->axis, plane ); + plane.normal() = lm->axis; } - plane[ 3 ] = DotProduct( verts[ 0 ].xyz, plane ); + plane.dist() = vector3_dot( verts[ 0 ].xyz, plane.normal() ); - VectorCopy( origin, lm->origin ); - d = DotProduct( lm->origin, plane ) - plane[ 3 ]; - d /= plane[ axisNum ]; - lm->origin[ axisNum ] -= d; + lm->origin = origin; + lm->origin[ axisNum ] -= plane3_distance_to_point( plane, lm->origin ) / plane.normal()[ axisNum ]; /* legacy support */ - VectorCopy( lm->origin, ds->lightmapOrigin ); + ds->lightmapOrigin = lm->origin; /* for planar surfaces, create lightmap vectors for st->xyz conversion */ - if ( VectorLength( ds->lightmapVecs[ 2 ] ) || 1 ) { /* ydnar: can't remember what exactly i was thinking here... */ + if ( vector3_length( ds->lightmapVecs[ 2 ] ) || 1 ) { /* ydnar: can't remember what exactly i was thinking here... */ /* allocate space for the vectors */ - lm->vecs = safe_calloc( 3 * sizeof( vec3_t ) ); - VectorCopy( ds->lightmapVecs[ 2 ], lm->vecs[ 2 ] ); + lm->vecs = safe_calloc( 3 * sizeof( *lm->vecs ) ); + lm->vecs[ 2 ] = ds->lightmapVecs[ 2 ]; /* project stepped lightmap blocks and subtract to get planevecs */ for ( i = 0; i < 2; i++ ) { - len = VectorNormalize( vecs[ i ], normalized ); - VectorScale( normalized, ( 1.0 / len ), lm->vecs[ i ] ); - d = DotProduct( lm->vecs[ i ], plane ); - d /= plane[ axisNum ]; - lm->vecs[ i ][ axisNum ] -= d; + normalized = vecs[ i ]; + len = VectorNormalize( normalized ); + lm->vecs[ i ] = normalized * ( 1.0 / len ); + lm->vecs[ i ][ axisNum ] -= vector3_dot( lm->vecs[ i ], plane.normal() ) / plane.normal()[ axisNum ]; } } else @@ -923,24 +912,31 @@ static int CompareSurfaceInfo( const void *a, const void *b ){ return -1; } else if ( aInfo->plane != NULL && bInfo->plane != NULL ) { - for ( i = 0; i < 4; i++ ) + for ( i = 0; i < 3; i++ ) { - if ( aInfo->plane[ i ] < bInfo->plane[ i ] ) { + if ( aInfo->plane->normal()[ i ] < bInfo->plane->normal()[ i ] ) { return 1; } - else if ( aInfo->plane[ i ] > bInfo->plane[ i ] ) { + else if ( aInfo->plane->normal()[ i ] > bInfo->plane->normal()[ i ] ) { return -1; } } + if ( aInfo->plane->dist() < bInfo->plane->dist() ) { + return 1; + } + else if ( aInfo->plane->dist() > bInfo->plane->dist() ) { + return -1; + } + } /* then position in world */ for ( i = 0; i < 3; i++ ) { - if ( aInfo->mins[ i ] < bInfo->mins[ i ] ) { + if ( aInfo->minmax.mins[ i ] < bInfo->minmax.mins[ i ] ) { return 1; } - else if ( aInfo->mins[ i ] > bInfo->mins[ i ] ) { + else if ( aInfo->minmax.mins[ i ] > bInfo->minmax.mins[ i ] ) { return -1; } } @@ -965,7 +961,6 @@ void SetupSurfaceLightmaps( void ){ surfaceInfo_t *info, *info2; rawLightmap_t *lm; bool added; - vec3_t mapSize, entityOrigin; /* note it */ @@ -981,7 +976,7 @@ void SetupSurfaceLightmaps( void ){ } /* clear map bounds */ - ClearBounds( mapMins, mapMaxs ); + g_mapMinmax.clear(); /* allocate a list of surface clusters */ numSurfaceClusters = 0; @@ -1015,14 +1010,6 @@ void SetupSurfaceLightmaps( void ){ ds = &bspDrawSurfaces[ num ]; info = &surfaceInfos[ num ]; - /* set entity origin */ - if ( ds->numVerts > 0 ) { - VectorSubtract( yDrawVerts[ ds->firstVert ].xyz, bspDrawVerts[ ds->firstVert ].xyz, entityOrigin ); - } - else{ - VectorClear( entityOrigin ); - } - /* basic setup */ info->modelindex = i; info->lm = NULL; @@ -1049,11 +1036,11 @@ void SetupSurfaceLightmaps( void ){ } /* determine surface bounds */ - ClearBounds( info->mins, info->maxs ); + info->minmax.clear(); for ( k = 0; k < ds->numVerts; k++ ) { - AddPointToBounds( yDrawVerts[ ds->firstVert + k ].xyz, mapMins, mapMaxs ); - AddPointToBounds( yDrawVerts[ ds->firstVert + k ].xyz, info->mins, info->maxs ); + g_mapMinmax.extend( yDrawVerts[ ds->firstVert + k ].xyz ); + info->minmax.extend( yDrawVerts[ ds->firstVert + k ].xyz ); } /* find all the bsp clusters the surface falls into */ @@ -1063,9 +1050,7 @@ void SetupSurfaceLightmaps( void ){ leaf = &bspLeafs[ k ]; /* test bbox */ - if ( leaf->mins[ 0 ] > info->maxs[ 0 ] || leaf->maxs[ 0 ] < info->mins[ 0 ] || - leaf->mins[ 1 ] > info->maxs[ 1 ] || leaf->maxs[ 1 ] < info->mins[ 1 ] || - leaf->mins[ 2 ] > info->maxs[ 2 ] || leaf->maxs[ 2 ] < info->mins[ 2 ] ) { + if( !leaf->minmax.test( info->minmax ) ) { continue; } @@ -1084,11 +1069,11 @@ void SetupSurfaceLightmaps( void ){ } /* determine if surface is planar */ - if ( VectorLength( ds->lightmapVecs[ 2 ] ) > 0.0f ) { + if ( vector3_length( ds->lightmapVecs[ 2 ] ) != 0.0f ) { /* make a plane */ - info->plane = safe_malloc( 4 * sizeof( float ) ); - VectorCopy( ds->lightmapVecs[ 2 ], info->plane ); - info->plane[ 3 ] = DotProduct( yDrawVerts[ ds->firstVert ].xyz, info->plane ); + info->plane = safe_malloc( sizeof( *( info->plane ) ) ); + info->plane->normal() = ds->lightmapVecs[ 2 ]; + info->plane->dist() = vector3_dot( yDrawVerts[ ds->firstVert ].xyz, info->plane->normal() ); } /* determine if surface requires a lightmap */ @@ -1107,8 +1092,7 @@ void SetupSurfaceLightmaps( void ){ } /* find longest map distance */ - VectorSubtract( mapMaxs, mapMins, mapSize ); - maxMapDistance = VectorLength( mapSize ); + maxMapDistance = vector3_length( g_mapMinmax.maxs - g_mapMinmax.mins ); /* sort the surfaces info list */ qsort( sortSurfaces, numBSPDrawSurfaces, sizeof( int ), CompareSurfaceInfo ); @@ -1153,14 +1137,13 @@ void SetupSurfaceLightmaps( void ){ lm->recvShadows = info->recvShadows; lm->brightness = info->si->lmBrightness; lm->filterRadius = info->si->lmFilterRadius; - VectorCopy( info->si->floodlightRGB, lm->floodlightRGB ); + lm->floodlightRGB = info->si->floodlightRGB; lm->floodlightDistance = info->si->floodlightDistance; lm->floodlightIntensity = info->si->floodlightIntensity; lm->floodlightDirectionScale = info->si->floodlightDirectionScale; - VectorCopy( info->axis, lm->axis ); + lm->axis = info->axis; lm->plane = info->plane; - VectorCopy( info->mins, lm->mins ); - VectorCopy( info->maxs, lm->maxs ); + lm->minmax = info->minmax; lm->customWidth = info->si->lmCustomWidth; lm->customHeight = info->si->lmCustomHeight; @@ -1209,8 +1192,8 @@ void SetupSurfaceLightmaps( void ){ /* allocate vertex luxel storage */ for ( k = 0; k < MAX_LIGHTMAPS; k++ ) { - vertexLuxels[ k ] = safe_calloc( numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) ); - radVertexLuxels[ k ] = safe_calloc( numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) ); + vertexLuxels[ k ] = safe_calloc( numBSPDrawVerts * sizeof( *vertexLuxels[ 0 ] ) ); + radVertexLuxels[ k ] = safe_calloc( numBSPDrawVerts * sizeof( *radVertexLuxels[ 0 ] ) ); } /* emit some stats */ @@ -1236,11 +1219,10 @@ void SetupSurfaceLightmaps( void ){ #define MAX_STITCH_LUXELS 64 void StitchSurfaceLightmaps( void ){ - int i, j, x, y, x2, y2, *cluster, *cluster2, + int i, j, x, y, x2, y2, numStitched, numCandidates, numLuxels, f, fOld, start; rawLightmap_t *lm, *a, *b, *c[ MAX_STITCH_CANDIDATES ]; - float *luxel, *luxel2, *origin, *origin2, *normal, *normal2, - sampleSize, average[ 3 ], totalColor, ootc; + float sampleSize, totalColor; /* disabled for now */ @@ -1275,9 +1257,7 @@ void StitchSurfaceLightmaps( void ){ b = &rawLightmaps[ j ]; /* test bounding box */ - if ( a->mins[ 0 ] > b->maxs[ 0 ] || a->maxs[ 0 ] < b->mins[ 0 ] || - a->mins[ 1 ] > b->maxs[ 1 ] || a->maxs[ 1 ] < b->mins[ 1 ] || - a->mins[ 2 ] > b->maxs[ 2 ] || a->maxs[ 2 ] < b->mins[ 2 ] ) { + if ( !a->minmax.test( b->minmax ) ) { continue; } @@ -1292,18 +1272,17 @@ void StitchSurfaceLightmaps( void ){ { /* ignore unmapped/unlit luxels */ lm = a; - cluster = SUPER_CLUSTER( x, y ); - if ( *cluster == CLUSTER_UNMAPPED ) { + if ( lm->getSuperCluster( x, y ) == CLUSTER_UNMAPPED ) { continue; } - luxel = SUPER_LUXEL( 0, x, y ); - if ( luxel[ 3 ] <= 0.0f ) { + SuperLuxel& luxel = lm->getSuperLuxel( 0, x, y ); + if ( luxel.count <= 0.0f ) { continue; } /* get particulars */ - origin = SUPER_ORIGIN( x, y ); - normal = SUPER_NORMAL( x, y ); + const Vector3& origin = lm->getSuperOrigin( x, y ); + const Vector3& normal = lm->getSuperNormal( x, y ); /* walk candidate list */ for ( j = 0; j < numCandidates; j++ ) @@ -1313,17 +1292,17 @@ void StitchSurfaceLightmaps( void ){ lm = b; /* set samplesize to the smaller of the pair */ - sampleSize = 0.5f * ( a->actualSampleSize < b->actualSampleSize ? a->actualSampleSize : b->actualSampleSize ); + sampleSize = 0.5f * std::min( a->actualSampleSize, b->actualSampleSize ); /* test bounding box */ - if ( origin[ 0 ] < ( b->mins[ 0 ] - sampleSize ) || ( origin[ 0 ] > b->maxs[ 0 ] + sampleSize ) || - origin[ 1 ] < ( b->mins[ 1 ] - sampleSize ) || ( origin[ 1 ] > b->maxs[ 1 ] + sampleSize ) || - origin[ 2 ] < ( b->mins[ 2 ] - sampleSize ) || ( origin[ 2 ] > b->maxs[ 2 ] + sampleSize ) ) { + if ( origin[ 0 ] < ( b->minmax.mins[ 0 ] - sampleSize ) || ( origin[ 0 ] > b->minmax.maxs[ 0 ] + sampleSize ) || + origin[ 1 ] < ( b->minmax.mins[ 1 ] - sampleSize ) || ( origin[ 1 ] > b->minmax.maxs[ 1 ] + sampleSize ) || + origin[ 2 ] < ( b->minmax.mins[ 2 ] - sampleSize ) || ( origin[ 2 ] > b->minmax.maxs[ 2 ] + sampleSize ) ) { continue; } /* walk candidate luxels */ - VectorClear( average ); + Vector3 average( 0, 0, 0 ); numLuxels = 0; totalColor = 0.0f; for ( y2 = 0; y2 < b->sh && numLuxels < MAX_STITCH_LUXELS; y2++ ) @@ -1336,36 +1315,33 @@ void StitchSurfaceLightmaps( void ){ } /* ignore unmapped/unlit luxels */ - cluster2 = SUPER_CLUSTER( x2, y2 ); - if ( *cluster2 == CLUSTER_UNMAPPED ) { + if ( lm->getSuperCluster( x2, y2 ) == CLUSTER_UNMAPPED ) { continue; } - luxel2 = SUPER_LUXEL( 0, x2, y2 ); - if ( luxel2[ 3 ] <= 0.0f ) { + const SuperLuxel& luxel2 = lm->getSuperLuxel( 0, x2, y2 ); + if ( luxel2.count <= 0.0f ) { continue; } /* get particulars */ - origin2 = SUPER_ORIGIN( x2, y2 ); - normal2 = SUPER_NORMAL( x2, y2 ); + const Vector3& origin2 = lm->getSuperOrigin( x2, y2 ); + const Vector3& normal2 = lm->getSuperNormal( x2, y2 ); /* test normal */ - if ( DotProduct( normal, normal2 ) < 0.5f ) { + if ( vector3_dot( normal, normal2 ) < 0.5f ) { continue; } /* test bounds */ - if ( fabs( origin[ 0 ] - origin2[ 0 ] ) > sampleSize || - fabs( origin[ 1 ] - origin2[ 1 ] ) > sampleSize || - fabs( origin[ 2 ] - origin2[ 2 ] ) > sampleSize ) { + if ( !vector3_equal_epsilon( origin, origin2, sampleSize ) ) { continue; } /* add luxel */ - //% VectorSet( luxel2, 255, 0, 255 ); + //% luxel2.value = { 255, 0, 255 }; numLuxels++; - VectorAdd( average, luxel2, average ); - totalColor += luxel2[ 3 ]; + average += luxel2.value; + totalColor += luxel2.count; } } @@ -1375,9 +1351,8 @@ void StitchSurfaceLightmaps( void ){ } /* scale average */ - ootc = 1.0f / totalColor; - VectorScale( average, ootc, luxel ); - luxel[ 3 ] = 1.0f; + luxel.value = average * ( 1.0f / totalColor ); + luxel.count = 1.0f; numStitched++; } } @@ -1401,10 +1376,8 @@ void StitchSurfaceLightmaps( void ){ #define LUXEL_COLOR_FRAC 0.001302083 /* 1 / 3 / 256 */ static bool CompareBSPLuxels( rawLightmap_t *a, int aNum, rawLightmap_t *b, int bNum ){ - rawLightmap_t *lm; int x, y; double delta, total, rd, gd, bd; - float *aLuxel, *bLuxel; /* styled lightmaps will never be collapsed to non-styled lightmaps when there is _minlight */ @@ -1453,8 +1426,8 @@ static bool CompareBSPLuxels( rawLightmap_t *a, int aNum, rawLightmap_t *b, int total += 1.0; /* get luxels */ - lm = a; aLuxel = BSP_LUXEL( aNum, x, y ); - lm = b; bLuxel = BSP_LUXEL( bNum, x, y ); + const Vector3& aLuxel = a->getBspLuxel( aNum, x, y ); + const Vector3& bLuxel = b->getBspLuxel( bNum, x, y ); /* ignore unused luxels */ if ( aLuxel[ 0 ] < 0 || bLuxel[ 0 ] < 0 ) { @@ -1495,9 +1468,8 @@ static bool CompareBSPLuxels( rawLightmap_t *a, int aNum, rawLightmap_t *b, int */ static bool MergeBSPLuxels( rawLightmap_t *a, int aNum, rawLightmap_t *b, int bNum ){ - rawLightmap_t *lm; int x, y; - float luxel[ 3 ], *aLuxel, *bLuxel; + Vector3 luxel; /* basic tests */ @@ -1511,12 +1483,11 @@ static bool MergeBSPLuxels( rawLightmap_t *a, int aNum, rawLightmap_t *b, int bN /* compare solid lightmaps */ if ( a->solid[ aNum ] && b->solid[ bNum ] ) { /* average */ - VectorAdd( a->solidColor[ aNum ], b->solidColor[ bNum ], luxel ); - VectorScale( luxel, 0.5f, luxel ); + luxel = vector3_mid( a->solidColor[ aNum ], b->solidColor[ bNum ] ); /* copy to both */ - VectorCopy( luxel, a->solidColor[ aNum ] ); - VectorCopy( luxel, b->solidColor[ bNum ] ); + a->solidColor[ aNum ] = luxel; + b->solidColor[ bNum ] = luxel; /* return to sender */ return true; @@ -1533,28 +1504,27 @@ static bool MergeBSPLuxels( rawLightmap_t *a, int aNum, rawLightmap_t *b, int bN for ( x = 0; x < a->w; x++ ) { /* get luxels */ - lm = a; aLuxel = BSP_LUXEL( aNum, x, y ); - lm = b; bLuxel = BSP_LUXEL( bNum, x, y ); + Vector3& aLuxel = a->getBspLuxel( aNum, x, y ); + Vector3& bLuxel = b->getBspLuxel( bNum, x, y ); /* handle occlusion mismatch */ if ( aLuxel[ 0 ] < 0.0f ) { - VectorCopy( bLuxel, aLuxel ); + aLuxel = bLuxel; } else if ( bLuxel[ 0 ] < 0.0f ) { - VectorCopy( aLuxel, bLuxel ); + bLuxel = aLuxel; } else { /* average */ - VectorAdd( aLuxel, bLuxel, luxel ); - VectorScale( luxel, 0.5f, luxel ); + luxel = vector3_mid( aLuxel, bLuxel ); /* debugging code */ //% luxel[ 2 ] += 64.0f; /* copy to both */ - VectorCopy( luxel, aLuxel ); - VectorCopy( luxel, bLuxel ); + aLuxel = luxel; + bLuxel = luxel; } } } @@ -1572,9 +1542,6 @@ static bool MergeBSPLuxels( rawLightmap_t *a, int aNum, rawLightmap_t *b, int bN static bool ApproximateLuxel( rawLightmap_t *lm, bspDrawVert_t *dv ){ int i, x, y, d, lightmapNum; - float *luxel; - vec3_t color, vertexColor; - byte cb[ 4 ], vcb[ 4 ]; /* find luxel xy coords */ @@ -1602,7 +1569,7 @@ static bool ApproximateLuxel( rawLightmap_t *lm, bspDrawVert_t *dv ){ } /* get luxel */ - luxel = BSP_LUXEL( lightmapNum, x, y ); + const Vector3& luxel = lm->getBspLuxel( lightmapNum, x, y ); /* ignore occluded luxels */ if ( luxel[ 0 ] < 0.0f || luxel[ 1 ] < 0.0f || luxel[ 2 ] < 0.0f ) { @@ -1610,8 +1577,8 @@ static bool ApproximateLuxel( rawLightmap_t *lm, bspDrawVert_t *dv ){ } /* copy, set min color and compare */ - VectorCopy( luxel, color ); - VectorCopy( dv->color[ 0 ], vertexColor ); + Vector3 color = luxel; + Vector3 vertexColor = dv->color[ 0 ].rgb(); /* styles are not affected by minlight */ if ( lightmapNum == 0 ) { @@ -1628,8 +1595,9 @@ static bool ApproximateLuxel( rawLightmap_t *lm, bspDrawVert_t *dv ){ } /* set to bytes */ - ColorToBytes( color, cb, 1.0f ); - ColorToBytes( vertexColor, vcb, 1.0f ); + Color4b cb, vcb; + ColorToBytes( color, cb.rgb(), 1.0f ); + ColorToBytes( vertexColor, vcb.rgb(), 1.0f ); /* compare */ for ( i = 0; i < 3; i++ ) @@ -1674,17 +1642,13 @@ static bool ApproximateTriangle_r( rawLightmap_t *lm, bspDrawVert_t *dv[ 3 ] ){ /* subdivide calc */ { int i; - float dx, dy, dist, maxDist; - /* find the longest edge and split it */ max = -1; - maxDist = 0; + float maxDist = 0; for ( i = 0; i < 3; i++ ) { - dx = dv[ i ]->lightmap[ 0 ][ 0 ] - dv[ ( i + 1 ) % 3 ]->lightmap[ 0 ][ 0 ]; - dy = dv[ i ]->lightmap[ 0 ][ 1 ] - dv[ ( i + 1 ) % 3 ]->lightmap[ 0 ][ 1 ]; - dist = sqrt( ( dx * dx ) + ( dy * dy ) ); + const float dist = vector2_length( dv[ i ]->lightmap[ 0 ] - dv[ ( i + 1 ) % 3 ]->lightmap[ 0 ] ); if ( dist > maxDist ) { maxDist = dist; max = i; @@ -1778,9 +1742,9 @@ static bool ApproximateLightmap( rawLightmap_t *lm ){ } /* assume that surfaces whose bounding boxes is smaller than 2x samplesize will be forced to vertex */ - if ( ( info->maxs[ 0 ] - info->mins[ 0 ] ) <= ( 2.0f * info->sampleSize ) && - ( info->maxs[ 1 ] - info->mins[ 1 ] ) <= ( 2.0f * info->sampleSize ) && - ( info->maxs[ 2 ] - info->mins[ 2 ] ) <= ( 2.0f * info->sampleSize ) ) { + if ( ( info->minmax.maxs[ 0 ] - info->minmax.mins[ 0 ] ) <= ( 2.0f * info->sampleSize ) && + ( info->minmax.maxs[ 1 ] - info->minmax.mins[ 1 ] ) <= ( 2.0f * info->sampleSize ) && + ( info->minmax.maxs[ 2 ] - info->minmax.mins[ 2 ] ) <= ( 2.0f * info->sampleSize ) ) { info->approximated = true; numSurfsVertexForced++; continue; @@ -1882,7 +1846,6 @@ static bool ApproximateLightmap( rawLightmap_t *lm ){ static bool TestOutLightmapStamp( rawLightmap_t *lm, int lightmapNum, outLightmap_t *olm, int x, int y ){ int sx, sy, ox, oy, offset; - float *luxel; /* bounds check */ @@ -1905,8 +1868,7 @@ static bool TestOutLightmapStamp( rawLightmap_t *lm, int lightmapNum, outLightma for ( sx = 0; sx < lm->w; sx++ ) { /* get luxel */ - luxel = BSP_LUXEL( lightmapNum, sx, sy ); - if ( luxel[ 0 ] < 0.0f ) { + if ( lm->getBspLuxel( lightmapNum, sx, sy )[ 0 ] < 0.0f ) { continue; } @@ -1963,9 +1925,9 @@ static void SetupOutLightmap( rawLightmap_t *lm, outLightmap_t *olm ){ /* allocate buffers */ olm->lightBits = safe_calloc( ( olm->customWidth * olm->customHeight / 8 ) + 8 ); - olm->bspLightBytes = safe_calloc( olm->customWidth * olm->customHeight * 3 ); + olm->bspLightBytes = safe_calloc( olm->customWidth * olm->customHeight * sizeof( *olm->bspLightBytes ) ); if ( deluxemap ) { - olm->bspDirBytes = safe_calloc( olm->customWidth * olm->customHeight * 3 ); + olm->bspDirBytes = safe_calloc( olm->customWidth * olm->customHeight * sizeof( *olm->bspDirBytes ) ); } } @@ -1981,9 +1943,6 @@ static void FindOutLightmaps( rawLightmap_t *lm, bool fastAllocate ){ int i, j, k, lightmapNum, xMax, yMax, x = -1, y = -1, sx, sy, ox, oy, offset; outLightmap_t *olm; surfaceInfo_t *info; - float *luxel, *deluxel; - vec3_t color, direction; - byte *pixel; bool ok; int xIncrement, yIncrement; @@ -2235,23 +2194,23 @@ static void FindOutLightmaps( rawLightmap_t *lm, bool fastAllocate ){ for ( x = 0; x < xMax; x++ ) { /* get luxel */ - luxel = BSP_LUXEL( lightmapNum, x, y ); - deluxel = BSP_DELUXEL( x, y ); + const Vector3& luxel = lm->getBspLuxel( lightmapNum, x, y ); if ( luxel[ 0 ] < 0.0f && !lm->solid[ lightmapNum ] ) { continue; } - + Vector3 color; /* set minimum light */ if ( lm->solid[ lightmapNum ] ) { if ( debug ) { - VectorSet( color, 255.0f, 0.0f, 0.0f ); + color = { 255.0f, 0.0f, 0.0f }; } else{ - VectorCopy( lm->solidColor[ lightmapNum ], color ); + color = lm->solidColor[ lightmapNum ]; } } else{ - VectorCopy( luxel, color ); + + color = luxel; } /* styles are not affected by minlight */ @@ -2274,18 +2233,13 @@ static void FindOutLightmaps( rawLightmap_t *lm, bool fastAllocate ){ olm->freeLuxels--; /* store color */ - pixel = olm->bspLightBytes + ( ( ( oy * olm->customWidth ) + ox ) * 3 ); - ColorToBytes( color, pixel, lm->brightness ); + ColorToBytes( color, olm->bspLightBytes[ oy * olm->customWidth + ox], lm->brightness ); /* store direction */ if ( deluxemap ) { /* normalize average light direction */ - pixel = olm->bspDirBytes + ( ( ( oy * olm->customWidth ) + ox ) * 3 ); - VectorScale( deluxel, 1000.0f, direction ); - VectorNormalize( direction, direction ); - VectorScale( direction, 127.5f, direction ); - for ( i = 0; i < 3; i++ ) - pixel[ i ] = (byte)( 127.5f + direction[ i ] ); + const Vector3 direction = VectorNormalized( lm->getBspDeluxel( x, y ) * 1000.0f ) * 127.5f; + olm->bspDirBytes[ oy * olm->customWidth + ox ] = direction + Vector3().set( 127.5f ); } } } @@ -2357,16 +2311,16 @@ static int CompareRawLightmap( const void *a, const void *b ){ void FillOutLightmap( outLightmap_t *olm ){ int x, y; int ofs; - vec3_t dir_sum, light_sum; int cnt, filled; byte *lightBitsNew = NULL; - byte *lightBytesNew = NULL; - byte *dirBytesNew = NULL; + Vector3b *lightBytesNew = NULL; + Vector3b *dirBytesNew = NULL; + const size_t size = olm->customWidth * olm->customHeight * sizeof( Vector3b ); lightBitsNew = safe_malloc( ( olm->customWidth * olm->customHeight + 8 ) / 8 ); - lightBytesNew = safe_malloc( olm->customWidth * olm->customHeight * 3 ); + lightBytesNew = safe_malloc( size ); if ( deluxemap ) { - dirBytesNew = safe_malloc( olm->customWidth * olm->customHeight * 3 ); + dirBytesNew = safe_malloc( size ); } /* @@ -2379,9 +2333,9 @@ void FillOutLightmap( outLightmap_t *olm ){ */ memcpy( lightBitsNew, olm->lightBits, ( olm->customWidth * olm->customHeight + 8 ) / 8 ); - memcpy( lightBytesNew, olm->bspLightBytes, olm->customWidth * olm->customHeight * 3 ); + memcpy( lightBytesNew, olm->bspLightBytes, size ); if ( deluxemap ) { - memcpy( dirBytesNew, olm->bspDirBytes, olm->customWidth * olm->customHeight * 3 ); + memcpy( dirBytesNew, olm->bspDirBytes, size ); } for (;; ) @@ -2396,43 +2350,42 @@ void FillOutLightmap( outLightmap_t *olm ){ continue; } cnt = 0; - VectorClear( dir_sum ); - VectorClear( light_sum ); + Vector3 dir_sum( 0, 0, 0 ), light_sum( 0, 0, 0 ); /* try all four neighbors */ ofs = ( ( y + olm->customHeight - 1 ) % olm->customHeight ) * olm->customWidth + x; if ( olm->lightBits[ofs >> 3] & ( 1 << ( ofs & 7 ) ) ) { /* already filled */ ++cnt; - VectorAdd( light_sum, olm->bspLightBytes + ofs * 3, light_sum ); + light_sum += olm->bspLightBytes[ofs]; if ( deluxemap ) { - VectorAdd( dir_sum, olm->bspDirBytes + ofs * 3, dir_sum ); + dir_sum += olm->bspDirBytes[ofs]; } } ofs = ( ( y + 1 ) % olm->customHeight ) * olm->customWidth + x; if ( olm->lightBits[ofs >> 3] & ( 1 << ( ofs & 7 ) ) ) { /* already filled */ ++cnt; - VectorAdd( light_sum, olm->bspLightBytes + ofs * 3, light_sum ); + light_sum += olm->bspLightBytes[ofs]; if ( deluxemap ) { - VectorAdd( dir_sum, olm->bspDirBytes + ofs * 3, dir_sum ); + dir_sum += olm->bspDirBytes[ofs]; } } ofs = y * olm->customWidth + ( x + olm->customWidth - 1 ) % olm->customWidth; if ( olm->lightBits[ofs >> 3] & ( 1 << ( ofs & 7 ) ) ) { /* already filled */ ++cnt; - VectorAdd( light_sum, olm->bspLightBytes + ofs * 3, light_sum ); + light_sum += olm->bspLightBytes[ofs]; if ( deluxemap ) { - VectorAdd( dir_sum, olm->bspDirBytes + ofs * 3, dir_sum ); + dir_sum += olm->bspDirBytes[ofs]; } } ofs = y * olm->customWidth + ( x + 1 ) % olm->customWidth; if ( olm->lightBits[ofs >> 3] & ( 1 << ( ofs & 7 ) ) ) { /* already filled */ ++cnt; - VectorAdd( light_sum, olm->bspLightBytes + ofs * 3, light_sum ); + light_sum += olm->bspLightBytes[ofs]; if ( deluxemap ) { - VectorAdd( dir_sum, olm->bspDirBytes + ofs * 3, dir_sum ); + dir_sum += olm->bspDirBytes[ofs]; } } @@ -2440,9 +2393,9 @@ void FillOutLightmap( outLightmap_t *olm ){ ++filled; ofs = y * olm->customWidth + x; lightBitsNew[ofs >> 3] |= ( 1 << ( ofs & 7 ) ); - VectorScale( light_sum, 1.0 / cnt, lightBytesNew + ofs * 3 ); + lightBytesNew[ofs] = light_sum * ( 1.0 / cnt ); if ( deluxemap ) { - VectorScale( dir_sum, 1.0 / cnt, dirBytesNew + ofs * 3 ); + dirBytesNew[ofs] = dir_sum * ( 1.0 / cnt ); } } } @@ -2453,9 +2406,9 @@ void FillOutLightmap( outLightmap_t *olm ){ } memcpy( olm->lightBits, lightBitsNew, ( olm->customWidth * olm->customHeight + 8 ) / 8 ); - memcpy( olm->bspLightBytes, lightBytesNew, olm->customWidth * olm->customHeight * 3 ); + memcpy( olm->bspLightBytes, lightBytesNew, size ); if ( deluxemap ) { - memcpy( olm->bspDirBytes, dirBytesNew, olm->customWidth * olm->customHeight * 3 ); + memcpy( olm->bspDirBytes, dirBytesNew, size ); } } @@ -2472,15 +2425,14 @@ void FillOutLightmap( outLightmap_t *olm ){ */ void StoreSurfaceLightmaps( bool fastAllocate ){ - int i, j, k, x, y, lx, ly, sx, sy, *cluster, mappedSamples, timer_start; - int style, size, lightmapNum, lightmapNum2; - float *normal, *luxel, *bspLuxel, *bspLuxel2, *radLuxel, samples, occludedSamples; - vec3_t sample, occludedSample, dirSample, colorMins, colorMaxs; - float *deluxel, *bspDeluxel, *bspDeluxel2; + int i, j, k, x, y, lx, ly, sx, sy, mappedSamples, timer_start; + int style, lightmapNum, lightmapNum2; + float samples, occludedSamples; + Vector3 sample, occludedSample, dirSample; + MinMax colorMinmax; byte *lb; int numUsed, numTwins, numTwinLuxels, numStored; float lmx, lmy, efficiency; - vec3_t color; bspDrawSurface_t *ds, *parent, dsTemp; surfaceInfo_t *info; rawLightmap_t *lm, *lm2; @@ -2535,13 +2487,13 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ /* allocate bsp luxel storage */ if ( lm->bspLuxels[ lightmapNum ] == NULL ) { - size = lm->w * lm->h * BSP_LUXEL_SIZE * sizeof( float ); + const size_t size = lm->w * lm->h * sizeof( *( lm->bspLuxels[ 0 ] ) ); lm->bspLuxels[ lightmapNum ] = safe_calloc( size ); } /* allocate radiosity lightmap storage */ if ( bounce ) { - size = lm->w * lm->h * RAD_LUXEL_SIZE * sizeof( float ); + const size_t size = lm->w * lm->h * sizeof( *lm->radLuxels[ 0 ] ); if ( lm->radLuxels[ lightmapNum ] == NULL ) { lm->radLuxels[ lightmapNum ] = safe_malloc( size ); } @@ -2557,9 +2509,9 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ samples = 0.0f; occludedSamples = 0.0f; mappedSamples = 0; - VectorClear( sample ); - VectorClear( occludedSample ); - VectorClear( dirSample ); + sample.set( 0 ); + occludedSample.set( 0 ); + dirSample.set( 0 ); for ( ly = 0; ly < superSample; ly++ ) { for ( lx = 0; lx < superSample; lx++ ) @@ -2567,60 +2519,58 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ /* sample luxel */ sx = x * superSample + lx; sy = y * superSample + ly; - luxel = SUPER_LUXEL( lightmapNum, sx, sy ); - deluxel = SUPER_DELUXEL( sx, sy ); - normal = SUPER_NORMAL( sx, sy ); - cluster = SUPER_CLUSTER( sx, sy ); + SuperLuxel& luxel = lm->getSuperLuxel( lightmapNum, sx, sy ); + int& cluster = lm->getSuperCluster( sx, sy ); /* sample deluxemap */ if ( deluxemap && lightmapNum == 0 ) { - VectorAdd( dirSample, deluxel, dirSample ); + dirSample += lm->getSuperDeluxel( sx, sy ); } /* keep track of used/occluded samples */ - if ( *cluster != CLUSTER_UNMAPPED ) { + if ( cluster != CLUSTER_UNMAPPED ) { mappedSamples++; } /* handle lightmap border? */ - if ( lightmapBorder && ( sx == 0 || sx == ( lm->sw - 1 ) || sy == 0 || sy == ( lm->sh - 1 ) ) && luxel[ 3 ] > 0.0f ) { - VectorSet( sample, 255.0f, 0.0f, 0.0f ); + if ( lightmapBorder && ( sx == 0 || sx == ( lm->sw - 1 ) || sy == 0 || sy == ( lm->sh - 1 ) ) && luxel.count > 0.0f ) { + sample = { 255, 0, 0 }; samples += 1.0f; } /* handle debug */ - else if ( debug && *cluster < 0 ) { - if ( *cluster == CLUSTER_UNMAPPED ) { - VectorSet( luxel, 255, 204, 0 ); + else if ( debug && cluster < 0 ) { + if ( cluster == CLUSTER_UNMAPPED ) { + luxel.value = { 255, 204, 0 }; } - else if ( *cluster == CLUSTER_OCCLUDED ) { - VectorSet( luxel, 255, 0, 255 ); + else if ( cluster == CLUSTER_OCCLUDED ) { + luxel.value = { 255, 0, 255 }; } - else if ( *cluster == CLUSTER_FLOODED ) { - VectorSet( luxel, 0, 32, 255 ); + else if ( cluster == CLUSTER_FLOODED ) { + luxel.value = { 0, 32, 255 }; } - VectorAdd( occludedSample, luxel, occludedSample ); + occludedSample += luxel.value; occludedSamples += 1.0f; } /* normal luxel handling */ - else if ( luxel[ 3 ] > 0.0f ) { + else if ( luxel.count > 0.0f ) { /* handle lit or flooded luxels */ - if ( *cluster > 0 || *cluster == CLUSTER_FLOODED ) { - VectorAdd( sample, luxel, sample ); - samples += luxel[ 3 ]; + if ( cluster > 0 || cluster == CLUSTER_FLOODED ) { + sample += luxel.value; + samples += luxel.count; } /* handle occluded or unmapped luxels */ else { - VectorAdd( occludedSample, luxel, occludedSample ); - occludedSamples += luxel[ 3 ]; + occludedSample += luxel.value; + occludedSamples += luxel.count; } /* handle style debugging */ if ( debug && lightmapNum > 0 && x < 2 && y < 2 ) { - VectorCopy( debugColors[ 0 ], sample ); + sample = debugColors[ 0 ]; samples = 1; } } @@ -2629,48 +2579,47 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ /* only use occluded samples if necessary */ if ( samples <= 0.0f ) { - VectorCopy( occludedSample, sample ); + sample = occludedSample; samples = occludedSamples; } /* get luxels */ - luxel = SUPER_LUXEL( lightmapNum, x, y ); - deluxel = SUPER_DELUXEL( x, y ); + SuperLuxel& luxel = lm->getSuperLuxel( lightmapNum, x, y ); /* store light direction */ if ( deluxemap && lightmapNum == 0 ) { - VectorCopy( dirSample, deluxel ); + lm->getSuperDeluxel( x, y ) = dirSample; } /* store the sample back in super luxels */ if ( samples > 0.01f ) { - VectorScale( sample, ( 1.0f / samples ), luxel ); - luxel[ 3 ] = 1.0f; + luxel.value = sample * ( 1.0f / samples ); + luxel.count = 1.0f; } /* if any samples were mapped in any way, store ambient color */ else if ( mappedSamples > 0 ) { if ( lightmapNum == 0 ) { - VectorCopy( ambientColor, luxel ); + luxel.value = ambientColor; } else{ - VectorClear( luxel ); + luxel.value.set( 0 ); } - luxel[ 3 ] = 1.0f; + luxel.count = 1.0f; } /* store a bogus value to be fixed later */ else { - VectorClear( luxel ); - luxel[ 3 ] = -1.0f; + luxel.value.set( 0 ); + luxel.count = -1.0f; } } } /* setup */ lm->used = 0; - ClearBounds( colorMins, colorMaxs ); + colorMinmax.clear(); /* clean up and store into bsp luxels */ for ( y = 0; y < lm->h; y++ ) @@ -2678,18 +2627,17 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ for ( x = 0; x < lm->w; x++ ) { /* get luxels */ - luxel = SUPER_LUXEL( lightmapNum, x, y ); - deluxel = SUPER_DELUXEL( x, y ); + const SuperLuxel& luxel = lm->getSuperLuxel( lightmapNum, x, y ); /* copy light direction */ if ( deluxemap && lightmapNum == 0 ) { - VectorCopy( deluxel, dirSample ); + dirSample = lm->getSuperDeluxel( x, y ); } /* is this a valid sample? */ - if ( luxel[ 3 ] > 0.0f ) { - VectorCopy( luxel, sample ); - samples = luxel[ 3 ]; + if ( luxel.count > 0.0f ) { + sample = luxel.value; + samples = luxel.count; numUsed++; lm->used++; @@ -2704,8 +2652,8 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ else { /* nick an average value from the neighbors */ - VectorClear( sample ); - VectorClear( dirSample ); + sample.set( 0 ); + dirSample.set( 0 ); samples = 0.0f; /* fixme: why is this disabled?? */ @@ -2722,18 +2670,18 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ } /* get neighbor's particulars */ - luxel = SUPER_LUXEL( lightmapNum, sx, sy ); - if ( luxel[ 3 ] < 0.0f ) { + const SuperLuxel& luxel = lm->getSuperLuxel( lightmapNum, sx, sy ); + if ( luxel.count < 0.0f ) { continue; } - VectorAdd( sample, luxel, sample ); - samples += luxel[ 3 ]; + sample += luxel.value; + samples += luxel.count; } } /* no samples? */ if ( samples == 0.0f ) { - VectorSet( sample, -1.0f, -1.0f, -1.0f ); + sample.set( -1 ); samples = 1.0f; } else @@ -2752,12 +2700,11 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ } /* scale the sample */ - VectorScale( sample, ( 1.0f / samples ), sample ); + sample *= ( 1.0f / samples ); /* store the sample in the radiosity luxels */ if ( bounce > 0 ) { - radLuxel = RAD_LUXEL( lightmapNum, x, y ); - VectorCopy( sample, radLuxel ); + lm->getRadLuxel( lightmapNum, x, y ) = sample; /* if only storing bounced light, early out here */ if ( bounceOnly && !bouncing ) { @@ -2766,34 +2713,32 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ } /* store the sample in the bsp luxels */ - bspLuxel = BSP_LUXEL( lightmapNum, x, y ); - bspDeluxel = BSP_DELUXEL( x, y ); + Vector3& bspLuxel = lm->getBspLuxel( lightmapNum, x, y ); - VectorAdd( bspLuxel, sample, bspLuxel ); + bspLuxel += sample; if ( deluxemap && lightmapNum == 0 ) { - VectorAdd( bspDeluxel, dirSample, bspDeluxel ); + lm->getBspDeluxel( x, y ) += dirSample; } /* add color to bounds for solid checking */ if ( samples > 0.0f ) { - AddPointToBounds( bspLuxel, colorMins, colorMaxs ); + colorMinmax.extend( bspLuxel ); } } } /* set solid color */ lm->solid[ lightmapNum ] = false; - VectorAdd( colorMins, colorMaxs, lm->solidColor[ lightmapNum ] ); - VectorScale( lm->solidColor[ lightmapNum ], 0.5f, lm->solidColor[ lightmapNum ] ); + lm->solidColor[ lightmapNum ] = colorMinmax.origin(); /* nocollapse prevents solid lightmaps */ if ( !noCollapse ) { /* check solid color */ - VectorSubtract( colorMaxs, colorMins, sample ); + sample = colorMinmax.maxs - colorMinmax.mins; if ( ( sample[ 0 ] <= SOLID_EPSILON && sample[ 1 ] <= SOLID_EPSILON && sample[ 2 ] <= SOLID_EPSILON ) || ( lm->w <= 2 && lm->h <= 2 ) ) { /* small lightmaps get forced to solid color */ /* set to solid */ - VectorCopy( colorMins, lm->solidColor[ lightmapNum ] ); + lm->solidColor[ lightmapNum ] = colorMinmax.mins; lm->solid[ lightmapNum ] = true; numSolidLightmaps++; } @@ -2814,34 +2759,27 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ if ( lm->wrap[ 0 ] ) { for ( y = 0; y < lm->h; y++ ) { - bspLuxel = BSP_LUXEL( lightmapNum, 0, y ); - bspLuxel2 = BSP_LUXEL( lightmapNum, lm->w - 1, y ); - VectorAdd( bspLuxel, bspLuxel2, bspLuxel ); - VectorScale( bspLuxel, 0.5f, bspLuxel ); - VectorCopy( bspLuxel, bspLuxel2 ); + Vector3& bspLuxel = lm->getBspLuxel( lightmapNum, 0, y ); + Vector3& bspLuxel2 = lm->getBspLuxel( lightmapNum, lm->w - 1, y ); + bspLuxel = bspLuxel2 = vector3_mid( bspLuxel, bspLuxel2 ); if ( deluxemap && lightmapNum == 0 ) { - bspDeluxel = BSP_DELUXEL( 0, y ); - bspDeluxel2 = BSP_DELUXEL( lm->w - 1, y ); - VectorAdd( bspDeluxel, bspDeluxel2, bspDeluxel ); - VectorScale( bspDeluxel, 0.5f, bspDeluxel ); - VectorCopy( bspDeluxel, bspDeluxel2 ); + Vector3& bspDeluxel = lm->getBspDeluxel( 0, y ); + Vector3& bspDeluxel2 = lm->getBspDeluxel( lm->w - 1, y ); + bspDeluxel = bspDeluxel2 = vector3_mid( bspDeluxel, bspDeluxel2 ); } } } if ( lm->wrap[ 1 ] ) { for ( x = 0; x < lm->w; x++ ) { - bspLuxel = BSP_LUXEL( lightmapNum, x, 0 ); - bspLuxel2 = BSP_LUXEL( lightmapNum, x, lm->h - 1 ); - VectorAdd( bspLuxel, bspLuxel2, bspLuxel ); - VectorScale( bspLuxel, 0.5f, bspLuxel ); - VectorCopy( bspLuxel, bspLuxel2 ); + Vector3& bspLuxel = lm->getBspLuxel( lightmapNum, x, 0 ); + Vector3& bspLuxel2 = lm->getBspLuxel( lightmapNum, x, lm->h - 1 ); + bspLuxel = vector3_mid( bspLuxel, bspLuxel2 ); + bspLuxel2 = bspLuxel; if ( deluxemap && lightmapNum == 0 ) { - bspDeluxel = BSP_DELUXEL( x, 0 ); - bspDeluxel2 = BSP_DELUXEL( x, lm->h - 1 ); - VectorAdd( bspDeluxel, bspDeluxel2, bspDeluxel ); - VectorScale( bspDeluxel, 0.5f, bspDeluxel ); - VectorCopy( bspDeluxel, bspDeluxel2 ); + Vector3& bspDeluxel = lm->getBspDeluxel( x, 0 ); + Vector3& bspDeluxel2 = lm->getBspDeluxel( x, lm->h - 1 ); + bspDeluxel = bspDeluxel2 = vector3_mid( bspDeluxel, bspDeluxel2 ); } } } @@ -2856,9 +2794,6 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ /* note it */ if ( !bouncing ) { if ( deluxemap && deluxemode == 1 ) { - vec3_t worldUp, myNormal, myTangent, myBinormal; - float dist; - timer_start = I_FloatTime(); Sys_Printf( "converting..." ); @@ -2874,59 +2809,49 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ for ( x = 0; x < lm->sw; x++ ) { /* get normal and deluxel */ - normal = SUPER_NORMAL( x, y ); - cluster = SUPER_CLUSTER( x, y ); - bspDeluxel = BSP_DELUXEL( x, y ); - deluxel = SUPER_DELUXEL( x, y ); + Vector3& bspDeluxel = lm->getBspDeluxel( x, y ); /* get normal */ - VectorSet( myNormal, normal[0], normal[1], normal[2] ); + const Vector3 myNormal = lm->getSuperNormal( x, y ); /* get tangent vectors */ + Vector3 myTangent, myBinormal; if ( myNormal[ 0 ] == 0.0f && myNormal[ 1 ] == 0.0f ) { - if ( myNormal[ 2 ] == 1.0f ) { - VectorSet( myTangent, 1.0f, 0.0f, 0.0f ); - VectorSet( myBinormal, 0.0f, 1.0f, 0.0f ); + if ( myNormal.z() == 1.0f ) { + myTangent = g_vector3_axis_x; + myBinormal = g_vector3_axis_y; } - else if ( myNormal[ 2 ] == -1.0f ) { - VectorSet( myTangent, -1.0f, 0.0f, 0.0f ); - VectorSet( myBinormal, 0.0f, 1.0f, 0.0f ); + else if ( myNormal.z() == -1.0f ) { + myTangent = -g_vector3_axis_x; + myBinormal = g_vector3_axis_y; } } else { - VectorSet( worldUp, 0.0f, 0.0f, 1.0f ); - CrossProduct( myNormal, worldUp, myTangent ); - VectorNormalize( myTangent, myTangent ); - CrossProduct( myTangent, myNormal, myBinormal ); - VectorNormalize( myBinormal, myBinormal ); + myTangent = VectorNormalized( vector3_cross( myNormal, g_vector3_axis_z ) ); + myBinormal = VectorNormalized( vector3_cross( myTangent, myNormal ) ); } /* project onto plane */ - dist = -DotProduct( myTangent, myNormal ); - VectorMA( myTangent, dist, myNormal, myTangent ); - dist = -DotProduct( myBinormal, myNormal ); - VectorMA( myBinormal, dist, myNormal, myBinormal ); + myTangent -= myNormal * vector3_dot( myTangent, myNormal ); + myBinormal -= myNormal * vector3_dot( myBinormal, myNormal ); /* renormalize */ - VectorNormalize( myTangent, myTangent ); - VectorNormalize( myBinormal, myBinormal ); + VectorNormalize( myTangent ); + VectorNormalize( myBinormal ); /* convert modelspace deluxel to tangentspace */ - dirSample[0] = bspDeluxel[0]; - dirSample[1] = bspDeluxel[1]; - dirSample[2] = bspDeluxel[2]; - VectorNormalize( dirSample, dirSample ); + dirSample = VectorNormalized( bspDeluxel ); /* fix tangents to world matrix */ - if ( myNormal[0] > 0 || myNormal[1] < 0 || myNormal[2] < 0 ) { - VectorNegate( myTangent, myTangent ); + if ( myNormal.x() > 0 || myNormal.y() < 0 || myNormal.z() < 0 ) { + vector3_negate( myTangent ); } /* build tangentspace vectors */ - bspDeluxel[0] = DotProduct( dirSample, myTangent ); - bspDeluxel[1] = DotProduct( dirSample, myBinormal ); - bspDeluxel[2] = DotProduct( dirSample, myNormal ); + bspDeluxel[0] = vector3_dot( dirSample, myTangent ); + bspDeluxel[1] = vector3_dot( dirSample, myBinormal ); + bspDeluxel[2] = vector3_dot( dirSample, myNormal ); } } } @@ -2945,7 +2870,7 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ for ( i = 0; i < numRawLightmaps; i++ ) { - vec3_t myColor; + Vector3 myColor; float myBrightness; /* get lightmap */ @@ -2965,15 +2890,15 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ for ( x = 0; x < lm->sw; x++ ) { /* get luxel */ - bspLuxel = BSP_LUXEL( lightmapNum, x, y ); + Vector3& bspLuxel = lm->getBspLuxel( lightmapNum, x, y ); /* get color */ - VectorNormalize( bspLuxel, myColor ); - myBrightness = VectorLength( bspLuxel ); + myColor = VectorNormalized( bspLuxel ); + myBrightness = vector3_length( bspLuxel ); myBrightness *= ( 1 / 127.0f ); myBrightness = myBrightness * myBrightness; myBrightness *= 127.0f; - VectorScale( myColor, myBrightness, bspLuxel ); + bspLuxel = myColor * myBrightness; } } } @@ -3143,13 +3068,14 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ /* count the bsp lightmaps and allocate space */ free( bspLightBytes ); + const size_t gameLmSize = game->lightmapSize * game->lightmapSize * sizeof( Vector3b ); if ( numBSPLightmaps == 0 || externalLightmaps ) { numBSPLightBytes = 0; bspLightBytes = NULL; } else { - numBSPLightBytes = ( numBSPLightmaps * game->lightmapSize * game->lightmapSize * 3 ); + numBSPLightBytes = numBSPLightmaps * gameLmSize; bspLightBytes = safe_calloc( numBSPLightBytes ); } @@ -3166,7 +3092,7 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ else if( lightmapPink ){ for ( x = 0; x < olm->customHeight * olm->customWidth; ++x ){ if ( ( olm->lightBits[x >> 3] & ( 1 << ( x & 7 ) ) ) == 0 ) { /* not filled */ - VectorSet( olm->bspLightBytes + x * 3, 255, 0, 255 ); + olm->bspLightBytes[x] = { 255, 0, 255 }; } } } @@ -3174,13 +3100,13 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ /* is this a valid bsp lightmap? */ if ( olm->lightmapNum >= 0 && !externalLightmaps ) { /* copy lighting data */ - lb = bspLightBytes + ( olm->lightmapNum * game->lightmapSize * game->lightmapSize * 3 ); - memcpy( lb, olm->bspLightBytes, game->lightmapSize * game->lightmapSize * 3 ); + lb = bspLightBytes + ( olm->lightmapNum * gameLmSize ); + memcpy( lb, olm->bspLightBytes, gameLmSize ); /* copy direction data */ if ( deluxemap ) { - lb = bspLightBytes + ( ( olm->lightmapNum + 1 ) * game->lightmapSize * game->lightmapSize * 3 ); - memcpy( lb, olm->bspDirBytes, game->lightmapSize * game->lightmapSize * 3 ); + lb = bspLightBytes + ( ( olm->lightmapNum + 1 ) * gameLmSize ); + memcpy( lb, olm->bspDirBytes, gameLmSize ); } } @@ -3195,14 +3121,14 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ /* write lightmap */ sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, numExtLightmaps ); Sys_FPrintf( SYS_VRB, "\nwriting %s", filename ); - WriteTGA24( filename, olm->bspLightBytes, olm->customWidth, olm->customHeight, true ); + WriteTGA24( filename, olm->bspLightBytes->data(), olm->customWidth, olm->customHeight, true ); numExtLightmaps++; /* write deluxemap */ if ( deluxemap ) { sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, numExtLightmaps ); Sys_FPrintf( SYS_VRB, "\nwriting %s", filename ); - WriteTGA24( filename, olm->bspDirBytes, olm->customWidth, olm->customHeight, true ); + WriteTGA24( filename, olm->bspDirBytes->data(), olm->customWidth, olm->customHeight, true ); numExtLightmaps++; if ( debugDeluxemap ) { @@ -3341,15 +3267,15 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ /* walk lightmaps */ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) { + Vector3 color; /* handle unused style */ if ( ds->vertexStyles[ lightmapNum ] == LS_NONE ) { - VectorClear( color ); + color.set( 0 ); } else { /* get vertex color */ - luxel = VERTEX_LUXEL( lightmapNum, ds->firstVert + j ); - VectorCopy( luxel, color ); + color = getVertexLuxel( lightmapNum, ds->firstVert + j ); /* set minimum light */ if ( lightmapNum == 0 ) { @@ -3362,7 +3288,7 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ /* store to bytes */ if ( !info->si->noVertexLight ) { - ColorToBytes( color, dv[ j ].color[ lightmapNum ], info->si->vertexScale ); + ColorToBytes( color, dv[ j ].color[ lightmapNum ].rgb(), info->si->vertexScale ); } } } @@ -3428,11 +3354,10 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ } /* calculate st offset */ - lmx = dv[ 0 ].lightmap[ lightmapNum ][ 0 ] - dv[ 0 ].lightmap[ 0 ][ 0 ]; - lmy = dv[ 0 ].lightmap[ lightmapNum ][ 1 ] - dv[ 0 ].lightmap[ 0 ][ 1 ]; + const Vector2 lmxy = dv[ 0 ].lightmap[ lightmapNum ] - dv[ 0 ].lightmap[ 0 ]; /* create additional stage */ - if ( lmx == 0.0f && lmy == 0.0f ) { + if ( lmxy.x() == 0.0f && lmxy.y() == 0.0f ) { sprintf( styleStage, "\t{\n" "\t\tmap %s\n" /* lightmap */ "\t\tblendFunc GL_SRC_ALPHA GL_ONE\n" @@ -3461,7 +3386,7 @@ void StoreSurfaceLightmaps( bool fastAllocate ){ ( dfEqual ? "\t\tdepthFunc equal\n" : "" ), rgbGen, alphaGen, - lmx, lmy ); + lmxy.x(), lmxy.y() ); } diff --git a/tools/quake3/q3map2/map.cpp b/tools/quake3/q3map2/map.cpp index 4016b16a..53da1bb5 100644 --- a/tools/quake3/q3map2/map.cpp +++ b/tools/quake3/q3map2/map.cpp @@ -54,23 +54,20 @@ int c_structural; ydnar: replaced with variable epsilon for djbob */ -bool PlaneEqual( plane_t *p, vec3_t normal, vec_t dist ){ - float ne, de; - - +bool PlaneEqual( const plane_t *p, const Plane3f& plane ){ /* get local copies */ - ne = normalEpsilon; - de = distanceEpsilon; + const float ne = normalEpsilon; + const float de = distanceEpsilon; /* compare */ // We check equality of each component since we're using '<', not '<=' // (the epsilons may be zero). We want to use '<' instead of '<=' to be // consistent with the true meaning of "epsilon", and also because other // parts of the code uses this inequality. - if ( ( p->dist == dist || fabs( p->dist - dist ) < de ) && - ( p->normal[0] == normal[0] || fabs( p->normal[0] - normal[0] ) < ne ) && - ( p->normal[1] == normal[1] || fabs( p->normal[1] - normal[1] ) < ne ) && - ( p->normal[2] == normal[2] || fabs( p->normal[2] - normal[2] ) < ne ) ) { + if ( ( p->dist() == plane.dist() || fabs( p->dist() - plane.dist() ) < de ) && + ( p->normal()[0] == plane.normal()[0] || fabs( p->normal()[0] - plane.normal()[0] ) < ne ) && + ( p->normal()[1] == plane.normal()[1] || fabs( p->normal()[1] - plane.normal()[1] ) < ne ) && + ( p->normal()[2] == plane.normal()[2] || fabs( p->normal()[2] - plane.normal()[2] ) < ne ) ) { return true; } @@ -88,7 +85,7 @@ void AddPlaneToHash( plane_t *p ){ int hash; - hash = ( PLANE_HASHES - 1 ) & (int) fabs( p->dist ); + hash = ( PLANE_HASHES - 1 ) & (int) fabs( p->dist() ); p->hash_chain = planehash[hash]; planehash[hash] = p - mapplanes + 1; @@ -99,10 +96,9 @@ void AddPlaneToHash( plane_t *p ){ CreateNewFloatPlane ================ */ -int CreateNewFloatPlane( vec3_t normal, vec_t dist ){ - plane_t *p, temp; +int CreateNewFloatPlane( const Plane3f& plane ){ - if ( VectorLength( normal ) < 0.5 ) { + if ( vector3_length( plane.normal() ) < 0.5 ) { Sys_Printf( "FloatPlane: bad normal\n" ); return -1; } @@ -110,23 +106,18 @@ int CreateNewFloatPlane( vec3_t normal, vec_t dist ){ // create a new plane AUTOEXPAND_BY_REALLOC( mapplanes, nummapplanes + 1, allocatedmapplanes, 1024 ); - p = &mapplanes[nummapplanes]; - VectorCopy( normal, p->normal ); - p->dist = dist; - p->type = ( p + 1 )->type = PlaneTypeForNormal( p->normal ); - - VectorSubtract( vec3_origin, normal, ( p + 1 )->normal ); - ( p + 1 )->dist = -dist; + plane_t *p = &mapplanes[nummapplanes]; + p->plane = plane; + ( p + 1 )->plane = plane3_flipped( plane ); + p->type = ( p + 1 )->type = PlaneTypeForNormal( p->normal() ); nummapplanes += 2; // always put axial planes facing positive first - if ( p->type < 3 ) { - if ( p->normal[0] < 0 || p->normal[1] < 0 || p->normal[2] < 0 ) { + if ( p->type < ePlaneNonAxial ) { + if ( p->normal()[0] < 0 || p->normal()[1] < 0 || p->normal()[2] < 0 ) { // flip order - temp = *p; - *p = *( p + 1 ); - *( p + 1 ) = temp; + std::swap( *p, *( p + 1 ) ); AddPlaneToHash( p ); AddPlaneToHash( p + 1 ); @@ -147,7 +138,7 @@ int CreateNewFloatPlane( vec3_t normal, vec_t dist ){ Returns true if and only if the normal was adjusted. */ -bool SnapNormal( vec3_t normal ){ +bool SnapNormal( Vector3& normal ){ #if Q3MAP2_EXPERIMENTAL_SNAP_NORMAL_FIX int i; bool adjusted = false; @@ -163,15 +154,15 @@ bool SnapNormal( vec3_t normal ){ //they cause precision errors - if ( ( normal[0] != 0.0 || normal[1] != 0.0 ) && fabs(normal[0]) < 0.00025 && fabs(normal[1]) < 0.00025){ + if ( ( normal[0] != 0.0 || normal[1] != 0.0 ) && fabs( normal[0] ) < 0.00025 && fabs( normal[1] ) < 0.00025){ normal[0] = normal[1] = 0.0; adjusted = true; } - else if ( ( normal[0] != 0.0 || normal[2] != 0.0 ) && fabs(normal[0]) < 0.00025 && fabs(normal[2]) < 0.00025){ + else if ( ( normal[0] != 0.0 || normal[2] != 0.0 ) && fabs( normal[0] ) < 0.00025 && fabs( normal[2] ) < 0.00025){ normal[0] = normal[2] = 0.0; adjusted = true; } - else if ( ( normal[2] != 0.0 || normal[1] != 0.0 ) && fabs(normal[2]) < 0.00025 && fabs(normal[1]) < 0.00025){ + else if ( ( normal[2] != 0.0 || normal[1] != 0.0 ) && fabs( normal[2] ) < 0.00025 && fabs( normal[1] ) < 0.00025){ normal[2] = normal[1] = 0.0; adjusted = true; } @@ -206,7 +197,7 @@ bool SnapNormal( vec3_t normal ){ } if ( adjusted ) { - VectorNormalize( normal, normal ); + VectorNormalize( normal ); return true; } return false; @@ -249,12 +240,12 @@ bool SnapNormal( vec3_t normal ){ for ( i = 0; i < 3; i++ ) { if ( fabs( normal[ i ] - 1 ) < normalEpsilon ) { - VectorClear( normal ); + normal.set( 0 ); normal[ i ] = 1; return true; } if ( fabs( normal[ i ] - -1 ) < normalEpsilon ) { - VectorClear( normal ); + normal.set( 0 ); normal[ i ] = -1; return true; } @@ -270,7 +261,7 @@ bool SnapNormal( vec3_t normal ){ snaps a plane to normal/distance epsilons */ -void SnapPlane( vec3_t normal, vec_t *dist ){ +void SnapPlane( Plane3f& plane ){ // SnapPlane disabled by LordHavoc because it often messes up collision // brushes made from triangles of embedded models, and it has little effect // on anything else (axial planes are usually derived from snapped points) @@ -278,7 +269,7 @@ void SnapPlane( vec3_t normal, vec_t *dist ){ SnapPlane reenabled by namespace because of multiple reports of q3map2-crashes which were triggered by this patch. */ - SnapNormal( normal ); + SnapNormal( plane.normal() ); // TODO: Rambetter has some serious comments here as well. First off, // in the case where a normal is non-axial, there is nothing special @@ -301,8 +292,8 @@ void SnapPlane( vec3_t normal, vec_t *dist ){ // solve so that we can better engineer it (I'm not saying that SnapPlane() // should be removed altogether). Fix all this snapping code at some point! - if ( fabs( *dist - Q_rint( *dist ) ) < distanceEpsilon ) { - *dist = Q_rint( *dist ); + if ( fabs( plane.dist() - std::rint( plane.dist() ) ) < distanceEpsilon ) { + plane.dist() = std::rint( plane.dist() ); } } @@ -310,30 +301,26 @@ void SnapPlane( vec3_t normal, vec_t *dist ){ SnapPlaneImproved() snaps a plane to normal/distance epsilons, improved code */ -void SnapPlaneImproved( vec3_t normal, vec_t *dist, int numPoints, const vec3_t *points ){ - int i; - vec3_t center; - vec_t distNearestInt; - - if ( SnapNormal( normal ) ) { +void SnapPlaneImproved( Plane3f& plane, int numPoints, const Vector3 *points ){ + if ( SnapNormal( plane.normal() ) ) { if ( numPoints > 0 ) { // Adjust the dist so that the provided points don't drift away. - VectorClear( center ); - for ( i = 0; i < numPoints; i++ ) + Vector3 center( 0, 0, 0 ); + for ( int i = 0; i < numPoints; i++ ) { - VectorAdd( center, points[i], center ); + center += points[i]; } - for ( i = 0; i < 3; i++ ) { center[i] = center[i] / numPoints; } - *dist = DotProduct( normal, center ); + center /= numPoints; + plane.dist() = vector3_dot( plane.normal(), center ); } } - if ( VectorIsOnAxis( normal ) ) { + if ( VectorIsOnAxis( plane.normal() ) ) { // Only snap distance if the normal is an axis. Otherwise there // is nothing "natural" about snapping the distance to an integer. - distNearestInt = Q_rint( *dist ); - if ( -distanceEpsilon < *dist - distNearestInt && *dist - distNearestInt < distanceEpsilon ) { - *dist = distNearestInt; + const float distNearestInt = std::rint( plane.dist() ); + if ( -distanceEpsilon < plane.dist() - distNearestInt && plane.dist() - distNearestInt < distanceEpsilon ) { + plane.dist() = distNearestInt; } } } @@ -346,25 +333,22 @@ void SnapPlaneImproved( vec3_t normal, vec_t *dist, int numPoints, const vec3_t must be within an epsilon distance of the plane */ -int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points ) // NOTE: this has a side effect on the normal. Good or bad? +int FindFloatPlane( const Plane3f& inplane, int numPoints, const Vector3 *points ) // NOTE: this has a side effect on the normal. Good or bad? #ifdef USE_HASHING { int i, j, hash, h; int pidx; - plane_t *p; - vec_t d; - vec3_t normal; + Plane3f plane( inplane ); - VectorCopy( innormal, normal ); #if Q3MAP2_EXPERIMENTAL_SNAP_PLANE_FIX - SnapPlaneImproved( normal, &dist, numPoints, (const vec3_t *) points ); + SnapPlaneImproved( plane, numPoints, points ); #else - SnapPlane( normal, &dist ); + SnapPlane( plane ); #endif /* hash the plane */ - hash = ( PLANE_HASHES - 1 ) & (int) fabs( dist ); + hash = ( PLANE_HASHES - 1 ) & (int) fabs( plane.dist() ); /* search the border bins as well */ for ( i = -1; i <= 1; i++ ) @@ -372,10 +356,10 @@ int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points ) h = ( hash + i ) & ( PLANE_HASHES - 1 ); for ( pidx = planehash[ h ] - 1; pidx != -1; pidx = mapplanes[pidx].hash_chain - 1 ) { - p = &mapplanes[pidx]; + plane_t *p = &mapplanes[pidx]; /* do standard plane compare */ - if ( !PlaneEqual( p, normal, dist ) ) { + if ( !PlaneEqual( p, plane ) ) { continue; } @@ -390,8 +374,7 @@ int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points ) // very small when world coordinates extend to 2^16. Making the // dot product here in 64 bit land will not really help the situation // because the error will already be carried in dist. - d = DotProduct( points[ j ], p->normal ) - p->dist; - d = fabs( d ); + const double d = fabs( plane3_distance_to_point( p->plane, points[ j ] ) ); if ( d != 0.0 && d >= distanceEpsilon ) { break; // Point is too far from plane. } @@ -405,25 +388,24 @@ int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points ) } /* none found, so create a new one */ - return CreateNewFloatPlane( normal, dist ); + return CreateNewFloatPlane( plane ); } #else { - int i; + int i, j; plane_t *p; - vec3_t normal; + Plane3f plane( innormal, dist ); - VectorCopy( innormal, normal ); #if Q3MAP2_EXPERIMENTAL_SNAP_PLANE_FIX - SnapPlaneImproved( normal, &dist, numPoints, (const vec3_t *) points ); + SnapPlaneImproved( plane, numPoints, points ); #else - SnapPlane( normal, &dist ); + SnapPlane( plane ); #endif for ( i = 0, p = mapplanes; i < nummapplanes; i++, p++ ) { - if ( !PlaneEqual( p, normal, dist ) ) { + if ( !PlaneEqual( p, plane ) ) { continue; } @@ -433,8 +415,7 @@ int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points ) /* ydnar: test supplied points against this plane */ for ( j = 0; j < numPoints; j++ ) { - d = DotProduct( points[ j ], p->normal ) - p->dist; - if ( fabs( d ) > distanceEpsilon ) { + if ( fabs( plane3_distance_to_point( p->plane, points[ j ] ) ) > distanceEpsilon ) { break; } } @@ -448,7 +429,7 @@ int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points ) // is unmaintained because nobody sets USE_HASHING to off. } - return CreateNewFloatPlane( normal, dist ); + return CreateNewFloatPlane( plane ); } #endif @@ -460,44 +441,18 @@ int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points ) takes 3 points and finds the plane they lie in */ -int MapPlaneFromPoints( vec3_t *p ){ +int MapPlaneFromPoints( Vector3 p[3] ){ #if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES - vec3_accu_t paccu[3]; - vec3_accu_t t1, t2, normalAccu; - vec3_t normal; - vec_t dist; - - VectorCopyRegularToAccu( p[0], paccu[0] ); - VectorCopyRegularToAccu( p[1], paccu[1] ); - VectorCopyRegularToAccu( p[2], paccu[2] ); - - VectorSubtractAccu( paccu[0], paccu[1], t1 ); - VectorSubtractAccu( paccu[2], paccu[1], t2 ); - CrossProductAccu( t1, t2, normalAccu ); - VectorNormalizeAccu( normalAccu, normalAccu ); + Plane3 plane; + PlaneFromPoints( plane, DoubleVector3( p[0] ), DoubleVector3( p[1] ), DoubleVector3( p[2] ) ); // TODO: A 32 bit float for the plane distance isn't enough resolution // if the plane is 2^16 units away from the origin (the "epsilon" approaches // 0.01 in that case). - dist = (vec_t) DotProductAccu( paccu[0], normalAccu ); - VectorCopyAccuToRegular( normalAccu, normal ); - - return FindFloatPlane( normal, dist, 3, p ); + return FindFloatPlane( Plane3f( plane.normal(), plane.dist() ), 3, p ); #else - vec3_t t1, t2, normal; - vec_t dist; - - - /* calc plane normal */ - VectorSubtract( p[ 0 ], p[ 1 ], t1 ); - VectorSubtract( p[ 2 ], p[ 1 ], t2 ); - CrossProduct( t1, t2, normal ); - VectorNormalize( normal, normal ); - - /* calc plane distance */ - dist = DotProduct( p[ 0 ], normal ); - - /* store the plane */ - return FindFloatPlane( normal, dist, 3, p ); + Plane3f plane; + PlaneFromPoints( plane, p ); + return FindFloatPlane( plane, 3, p ); #endif } @@ -628,9 +583,8 @@ void AddBrushBevels( void ){ side_t sidetemp; side_t *s, *s2; winding_t *w, *w2; - vec3_t normal; - float dist; - vec3_t vec, vec2; + Plane3f plane; + Vector3 vec, vec2; float d, minBack; int surfaceFlagsMask = game->brushBevelsSurfaceFlagsMask; @@ -646,18 +600,18 @@ void AddBrushBevels( void ){ /* ydnar: testing disabling of mre code */ #if 0 if ( dir > 0 ) { - if ( mapplanes[s->planenum].normal[axis] >= 0.9999f ) { + if ( mapplanes[s->planenum].normal()[axis] >= 0.9999f ) { break; } } else { - if ( mapplanes[s->planenum].normal[axis] <= -0.9999f ) { + if ( mapplanes[s->planenum].normal()[axis] <= -0.9999f ) { break; } } #else - if ( ( dir > 0 && mapplanes[ s->planenum ].normal[ axis ] == 1.0f ) || - ( dir < 0 && mapplanes[ s->planenum ].normal[ axis ] == -1.0f ) ) { + if ( ( dir > 0 && mapplanes[ s->planenum ].normal()[ axis ] == 1.0f ) || + ( dir < 0 && mapplanes[ s->planenum ].normal()[ axis ] == -1.0f ) ) { break; } #endif @@ -670,30 +624,30 @@ void AddBrushBevels( void ){ } memset( s, 0, sizeof( *s ) ); buildBrush->numsides++; - VectorClear( normal ); - normal[axis] = dir; + plane.normal().set( 0 ); + plane.normal()[axis] = dir; if ( dir == 1 ) { /* ydnar: adding bevel plane snapping for fewer bsp planes */ if ( bevelSnap > 0 ) { - dist = floor( buildBrush->maxs[ axis ] / bevelSnap ) * bevelSnap; + plane.dist() = floor( buildBrush->minmax.maxs[ axis ] / bevelSnap ) * bevelSnap; } else{ - dist = buildBrush->maxs[ axis ]; + plane.dist() = buildBrush->minmax.maxs[ axis ]; } } else { /* ydnar: adding bevel plane snapping for fewer bsp planes */ if ( bevelSnap > 0 ) { - dist = -ceil( buildBrush->mins[ axis ] / bevelSnap ) * bevelSnap; + plane.dist() = -ceil( buildBrush->minmax.mins[ axis ] / bevelSnap ) * bevelSnap; } else{ - dist = -buildBrush->mins[ axis ]; + plane.dist() = -buildBrush->minmax.mins[ axis ]; } } - s->planenum = FindFloatPlane( normal, dist, 0, NULL ); + s->planenum = FindFloatPlane( plane, 0, NULL ); s->contentFlags = buildBrush->sides[ 0 ].contentFlags; /* handle bevel surfaceflags for topmost one only: assuming that only walkable ones are meaningful */ if( axis == 2 && dir == 1 ){ @@ -704,7 +658,7 @@ void AddBrushBevels( void ){ continue; } for ( k = 0; k < w->numpoints; k++ ) { - if ( fabs( dist - w->p[k][axis] ) < .1f ) { + if ( fabs( plane.dist() - w->p[k][axis] ) < .1f ) { s->surfaceFlags |= ( s2->surfaceFlags & surfaceFlagsMask ); break; } @@ -740,8 +694,8 @@ void AddBrushBevels( void ){ } for ( j = 0; j < w->numpoints; j++ ) { k = ( j + 1 ) % w->numpoints; - VectorSubtract( w->p[j], w->p[k], vec ); - if ( VectorNormalize( vec, vec ) < 0.5f ) { + vec = w->p[j] - w->p[k]; + if ( VectorNormalize( vec ) < 0.5f ) { continue; } SnapNormal( vec ); @@ -761,20 +715,20 @@ void AddBrushBevels( void ){ for ( axis = 0; axis < 3; axis++ ) { for ( dir = -1; dir <= 1; dir += 2 ) { // construct a plane - VectorClear( vec2 ); + vec2.set( 0 ); vec2[axis] = dir; - CrossProduct( vec, vec2, normal ); - if ( VectorNormalize( normal, normal ) < 0.5f ) { + plane.normal() = vector3_cross( vec, vec2 ); + if ( VectorNormalize( plane.normal() ) < 0.5f ) { continue; } - dist = DotProduct( w->p[j], normal ); + plane.dist() = vector3_dot( w->p[j], plane.normal() ); // if all the points on all the sides are // behind this plane, it is a proper edge bevel for ( k = 0; k < buildBrush->numsides; k++ ) { // if this plane has allready been used, skip it - if ( PlaneEqual( &mapplanes[buildBrush->sides[k].planenum], normal, dist ) ) { + if ( PlaneEqual( &mapplanes[buildBrush->sides[k].planenum], plane ) ) { if( buildBrush->sides[k].bevel ){ /* handle bevel surfaceflags */ buildBrush->sides[k].surfaceFlags |= ( s->surfaceFlags & surfaceFlagsMask ); } @@ -787,7 +741,7 @@ void AddBrushBevels( void ){ } minBack = 0.0f; for ( l = 0; l < w2->numpoints; l++ ) { - d = DotProduct( w2->p[l], normal ) - dist; + d = plane3_distance_to_point( plane, w2->p[l] ); if ( d > 0.1f ) { break; // point in front } @@ -822,7 +776,7 @@ void AddBrushBevels( void ){ buildBrush->numsides++; memset( s2, 0, sizeof( *s2 ) ); - s2->planenum = FindFloatPlane( normal, dist, 1, &w->p[ j ] ); + s2->planenum = FindFloatPlane( plane, 1, &w->p[ j ] ); s2->contentFlags = buildBrush->sides[0].contentFlags; s2->surfaceFlags = ( s->surfaceFlags & surfaceFlagsMask ); /* handle bevel surfaceflags */ s2->bevel = true; @@ -841,16 +795,14 @@ void AddBrushBevels( void ){ and links it to the current entity */ -static void MergeOrigin( entity_t *ent, vec3_t origin ){ - vec3_t adjustment; +static void MergeOrigin( entity_t *ent, const Vector3& origin ){ char string[128]; /* we have not parsed the brush completely yet... */ ent->vectorForKey( "origin", ent->origin ); - VectorMA( origin, -1, ent->originbrush_origin, adjustment ); - VectorAdd( adjustment, ent->origin, ent->origin ); - VectorCopy( origin, ent->originbrush_origin ); + ent->origin += origin - ent->originbrush_origin; + ent->originbrush_origin = origin; sprintf( string, "%f %f %f", ent->origin[0], ent->origin[1], ent->origin[2] ); ent->setKeyValue( "origin", string ); @@ -868,8 +820,6 @@ brush_t *FinishBrush( bool noCollapseGroups ){ /* origin brushes are removed, but they set the rotation origin for the rest of the brushes in the entity. after the entire entity is parsed, the planenums and texinfos will be adjusted for the origin brush */ if ( buildBrush->compileFlags & C_ORIGIN ) { - vec3_t origin; - Sys_Printf( "Entity %i (%s), Brush %i: origin brush detected\n", mapEnt->mapEntityNum, mapEnt->classname(), entitySourceBrushes ); @@ -879,10 +829,7 @@ brush_t *FinishBrush( bool noCollapseGroups ){ return NULL; } - VectorAdd( buildBrush->mins, buildBrush->maxs, origin ); - VectorScale( origin, 0.5, origin ); - - MergeOrigin( &entities.back(), origin ); + MergeOrigin( &entities.back(), buildBrush->minmax.origin() ); /* don't keep this brush */ return NULL; @@ -946,7 +893,7 @@ brush_t *FinishBrush( bool noCollapseGroups ){ (must be identical in radiant!) */ -vec3_t baseaxis[18] = +Vector3 baseaxis[18] = { {0,0,1}, {1,0,0}, {0,-1,0}, // floor {0,0,-1}, {1,0,0}, {0,-1,0}, // ceiling @@ -956,25 +903,21 @@ vec3_t baseaxis[18] = {0,-1,0}, {1,0,0}, {0,0,-1} // north wall }; -void TextureAxisFromPlane( plane_t *pln, vec3_t xv, vec3_t yv ){ - int bestaxis; - vec_t dot,best; - int i; +void TextureAxisFromPlane( const plane_t *pln, Vector3& xv, Vector3& yv ){ + float best = 0; + int bestaxis = 0; - best = 0; - bestaxis = 0; - - for ( i = 0 ; i < 6 ; i++ ) + for ( int i = 0 ; i < 6 ; i++ ) { - dot = DotProduct( pln->normal, baseaxis[i * 3] ); + const float dot = vector3_dot( pln->normal(), baseaxis[i * 3] ); if ( dot > best + 0.0001f ) { /* ydnar: bug 637 fix, suggested by jmonroe */ best = dot; bestaxis = i; } } - VectorCopy( baseaxis[bestaxis * 3 + 1], xv ); - VectorCopy( baseaxis[bestaxis * 3 + 2], yv ); + xv = baseaxis[bestaxis * 3 + 1]; + yv = baseaxis[bestaxis * 3 + 2]; } @@ -984,12 +927,12 @@ void TextureAxisFromPlane( plane_t *pln, vec3_t xv, vec3_t yv ){ creates world-to-texture mapping vecs for crappy quake plane arrangements */ -void QuakeTextureVecs( plane_t *plane, vec_t shift[ 2 ], vec_t rotate, vec_t scale[ 2 ], vec_t mappingVecs[ 2 ][ 4 ] ){ - vec3_t vecs[2]; +void QuakeTextureVecs( const plane_t *plane, float shift[ 2 ], float rotate, float scale[ 2 ], Vector4 mappingVecs[ 2 ] ){ + Vector3 vecs[2]; int sv, tv; - vec_t ang, sinv, cosv; - vec_t ns, nt; - int i, j; + float ang, sinv, cosv; + float ns, nt; + int i; TextureAxisFromPlane( plane, vecs[0], vecs[1] ); @@ -1016,7 +959,7 @@ void QuakeTextureVecs( plane_t *plane, vec_t shift[ 2 ], vec_t rotate, vec_t sca } else { - ang = rotate / 180 * Q_PI; + ang = degrees_to_radians( rotate ); sinv = sin( ang ); cosv = cos( ang ); } @@ -1049,8 +992,7 @@ void QuakeTextureVecs( plane_t *plane, vec_t shift[ 2 ], vec_t rotate, vec_t sca } for ( i = 0 ; i < 2 ; i++ ) - for ( j = 0 ; j < 3 ; j++ ) - mappingVecs[i][j] = vecs[i][j] / scale[i]; + mappingVecs[i].vec3() = vecs[i] / scale[i]; mappingVecs[0][3] = shift[0]; mappingVecs[1][3] = shift[1]; @@ -1074,12 +1016,12 @@ void QuakeTextureVecs( plane_t *plane, vec_t shift[ 2 ], vec_t rotate, vec_t sca static void ParseRawBrush( bool onlyLights ){ side_t *side; - vec3_t planePoints[ 3 ]; + Vector3 planePoints[ 3 ]; int planenum; shaderInfo_t *si; - vec_t shift[ 2 ]; - vec_t rotate = 0; - vec_t scale[ 2 ]; + float shift[ 2 ]; + float rotate = 0; + float scale[ 2 ]; int flags; @@ -1128,13 +1070,13 @@ static void ParseRawBrush( bool onlyLights ){ buildBrush->numsides++; /* read the three point plane definition */ - Parse1DMatrix( 3, planePoints[ 0 ] ); - Parse1DMatrix( 3, planePoints[ 1 ] ); - Parse1DMatrix( 3, planePoints[ 2 ] ); + Parse1DMatrix( 3, planePoints[ 0 ].data() ); + Parse1DMatrix( 3, planePoints[ 1 ].data() ); + Parse1DMatrix( 3, planePoints[ 2 ].data() ); /* bp: read the texture matrix */ if ( g_brushType == EBrushType::Bp ) { - Parse2DMatrix( 2, 3, (float*) side->texMat ); + Parse2DMatrix( 2, 3, side->texMat->data() ); } /* read shader name */ @@ -1187,8 +1129,7 @@ static void ParseRawBrush( bool onlyLights ){ if ( !scale[0] ) scale[0] = 1.f; if ( !scale[1] ) scale[1] = 1.f; for ( axis = 0; axis < 2; ++axis ) - for ( comp = 0; comp < 3; ++comp ) - side->vecs[axis][comp] /= scale[axis]; + side->vecs[axis].vec3() /= scale[axis]; } /* set default flags and values */ @@ -1373,9 +1314,9 @@ void MoveBrushesToWorld( entity_t *ent ){ parseMesh_t *pm; /* we need to undo the common/origin adjustment, and instead shift them by the entity key origin */ - VectorScale( ent->origin, -1, ent->originbrush_origin ); + ent->originbrush_origin = -ent->origin; AdjustBrushesForOrigin( ent ); - VectorClear( ent->originbrush_origin ); + ent->originbrush_origin.set( 0 ); /* move brushes */ for ( b = ent->brushes; b != NULL; b = next ) @@ -1431,7 +1372,7 @@ void AdjustBrushesForOrigin( entity_t *ent ){ int i; side_t *s; - vec_t newdist; + float newdist; brush_t *b; parseMesh_t *p; @@ -1445,10 +1386,10 @@ void AdjustBrushesForOrigin( entity_t *ent ){ s = &b->sides[ i ]; /* offset side plane */ - newdist = mapplanes[ s->planenum ].dist - DotProduct( mapplanes[ s->planenum ].normal, ent->originbrush_origin ); + newdist = -plane3_distance_to_point( mapplanes[ s->planenum ].plane, ent->originbrush_origin ); /* find a new plane */ - s->planenum = FindFloatPlane( mapplanes[ s->planenum ].normal, newdist, 0, NULL ); + s->planenum = FindFloatPlane( mapplanes[ s->planenum ].normal(), newdist, 0, NULL ); } /* rebuild brush windings (ydnar: just offsetting the winding above should be fine) */ @@ -1459,7 +1400,7 @@ void AdjustBrushesForOrigin( entity_t *ent ){ for ( p = ent->patches; p != NULL; p = p->next ) { for ( i = 0; i < ( p->mesh.width * p->mesh.height ); i++ ) - VectorSubtract( p->mesh.verts[ i ].xyz, ent->originbrush_origin, p->mesh.verts[ i ].xyz ); + p->mesh.verts[ i ].xyz -= ent->originbrush_origin; } } @@ -1474,36 +1415,32 @@ void SetEntityBounds( entity_t *e ){ int i; brush_t *b; parseMesh_t *p; - vec3_t mins, maxs; + MinMax minmax; /* walk the entity's brushes/patches and determine bounds */ - ClearBounds( mins, maxs ); for ( b = e->brushes; b; b = b->next ) { - AddPointToBounds( b->mins, mins, maxs ); - AddPointToBounds( b->maxs, mins, maxs ); + minmax.extend( b->minmax ); } for ( p = e->patches; p; p = p->next ) { for ( i = 0; i < ( p->mesh.width * p->mesh.height ); i++ ) - AddPointToBounds( p->mesh.verts[ i ].xyz, mins, maxs ); + minmax.extend( p->mesh.verts[ i ].xyz ); } /* try to find explicit min/max key */ - e->read_keyvalue( mins, "min" ); - e->read_keyvalue( maxs, "max" ); + e->read_keyvalue( minmax.mins, "min" ); + e->read_keyvalue( minmax.maxs, "max" ); /* store the bounds */ for ( b = e->brushes; b; b = b->next ) { - VectorCopy( mins, b->eMins ); - VectorCopy( maxs, b->eMaxs ); + b->eMinmax = minmax; } for ( p = e->patches; p; p = p->next ) { - VectorCopy( mins, p->eMins ); - VectorCopy( maxs, p->eMaxs ); + p->eMinmax = minmax; } } @@ -1897,11 +1834,10 @@ void LoadMapFile( char *filename, bool onlyLights, bool noCollapseGroups ){ else { /* set map bounds */ - ClearBounds( mapMins, mapMaxs ); + g_mapMinmax.clear(); for ( b = entities[ 0 ].brushes; b; b = b->next ) { - AddPointToBounds( b->mins, mapMins, mapMaxs ); - AddPointToBounds( b->maxs, mapMins, mapMaxs ); + g_mapMinmax.extend( b->minmax ); } /* get brush counts */ @@ -1920,8 +1856,8 @@ void LoadMapFile( char *filename, bool onlyLights, bool noCollapseGroups ){ Sys_FPrintf( SYS_VRB, "%9d planes\n", nummapplanes ); Sys_Printf( "%9d areaportals\n", c_areaportals ); Sys_Printf( "Size: %5.0f, %5.0f, %5.0f to %5.0f, %5.0f, %5.0f\n", - mapMins[ 0 ], mapMins[ 1 ], mapMins[ 2 ], - mapMaxs[ 0 ], mapMaxs[ 1 ], mapMaxs[ 2 ] ); + g_mapMinmax.mins[0], g_mapMinmax.mins[1], g_mapMinmax.mins[2], + g_mapMinmax.maxs[0], g_mapMinmax.maxs[1], g_mapMinmax.maxs[2] ); /* write bogus map */ if ( fakemap ) { diff --git a/tools/quake3/q3map2/mesh.cpp b/tools/quake3/q3map2/mesh.cpp index 40c92aa1..d1c94536 100644 --- a/tools/quake3/q3map2/mesh.cpp +++ b/tools/quake3/q3map2/mesh.cpp @@ -38,35 +38,24 @@ returns an 50/50 interpolated vert */ -void LerpDrawVert( bspDrawVert_t *a, bspDrawVert_t *b, bspDrawVert_t *out ){ - int k; +void LerpDrawVert( const bspDrawVert_t *a, const bspDrawVert_t *b, bspDrawVert_t *out ){ + out->xyz = vector3_mid( a->xyz, b->xyz ); + out->st = vector2_mid( a->st, b->st ); - out->xyz[ 0 ] = 0.5 * ( a->xyz[ 0 ] + b->xyz[ 0 ] ); - out->xyz[ 1 ] = 0.5 * ( a->xyz[ 1 ] + b->xyz[ 1 ] ); - out->xyz[ 2 ] = 0.5 * ( a->xyz[ 2 ] + b->xyz[ 2 ] ); - - out->st[ 0 ] = 0.5 * ( a->st[ 0 ] + b->st[ 0 ] ); - out->st[ 1 ] = 0.5 * ( a->st[ 1 ] + b->st[ 1 ] ); - - for ( k = 0; k < MAX_LIGHTMAPS; k++ ) + for ( int k = 0; k < MAX_LIGHTMAPS; k++ ) { - out->lightmap[ k ][ 0 ] = 0.5f * ( a->lightmap[ k ][ 0 ] + b->lightmap[ k ][ 0 ] ); - out->lightmap[ k ][ 1 ] = 0.5f * ( a->lightmap[ k ][ 1 ] + b->lightmap[ k ][ 1 ] ); - out->color[ k ][ 0 ] = ( a->color[ k ][ 0 ] + b->color[ k ][ 0 ] ) >> 1; - out->color[ k ][ 1 ] = ( a->color[ k ][ 1 ] + b->color[ k ][ 1 ] ) >> 1; - out->color[ k ][ 2 ] = ( a->color[ k ][ 2 ] + b->color[ k ][ 2 ] ) >> 1; - out->color[ k ][ 3 ] = ( a->color[ k ][ 3 ] + b->color[ k ][ 3 ] ) >> 1; + out->lightmap[ k ] = vector2_mid( a->lightmap[ k ], b->lightmap[ k ] ); + for( int i = 0; i < 4; ++i ) + out->color[ k ][ i ] = ( a->color[ k ][ i ] + b->color[ k ][ i ] ) >> 1; } /* ydnar: added normal interpolation */ - out->normal[ 0 ] = 0.5f * ( a->normal[ 0 ] + b->normal[ 0 ] ); - out->normal[ 1 ] = 0.5f * ( a->normal[ 1 ] + b->normal[ 1 ] ); - out->normal[ 2 ] = 0.5f * ( a->normal[ 2 ] + b->normal[ 2 ] ); + out->normal = vector3_mid( a->normal, b->normal ); /* if the interpolant created a bogus normal, just copy the normal from a */ - if ( VectorNormalize( out->normal, out->normal ) == 0 ) { - VectorCopy( a->normal, out->normal ); + if ( VectorNormalize( out->normal ) == 0 ) { + out->normal = a->normal; } } @@ -78,33 +67,23 @@ void LerpDrawVert( bspDrawVert_t *a, bspDrawVert_t *b, bspDrawVert_t *out ){ */ void LerpDrawVertAmount( bspDrawVert_t *a, bspDrawVert_t *b, float amount, bspDrawVert_t *out ){ - int k; + out->xyz = a->xyz + ( b->xyz - a->xyz ) * amount; - out->xyz[ 0 ] = a->xyz[ 0 ] + amount * ( b->xyz[ 0 ] - a->xyz[ 0 ] ); - out->xyz[ 1 ] = a->xyz[ 1 ] + amount * ( b->xyz[ 1 ] - a->xyz[ 1 ] ); - out->xyz[ 2 ] = a->xyz[ 2 ] + amount * ( b->xyz[ 2 ] - a->xyz[ 2 ] ); + out->st = a->st + ( b->st - a->st ) * amount; - out->st[ 0 ] = a->st[ 0 ] + amount * ( b->st[ 0 ] - a->st[ 0 ] ); - out->st[ 1 ] = a->st[ 1 ] + amount * ( b->st[ 1 ] - a->st[ 1 ] ); - - for ( k = 0; k < MAX_LIGHTMAPS; k++ ) + for ( int k = 0; k < MAX_LIGHTMAPS; k++ ) { - out->lightmap[ k ][ 0 ] = a->lightmap[ k ][ 0 ] + amount * ( b->lightmap[ k ][ 0 ] - a->lightmap[ k ][ 0 ] ); - out->lightmap[ k ][ 1 ] = a->lightmap[ k ][ 1 ] + amount * ( b->lightmap[ k ][ 1 ] - a->lightmap[ k ][ 1 ] ); - out->color[ k ][ 0 ] = a->color[ k ][ 0 ] + amount * ( b->color[ k ][ 0 ] - a->color[ k ][ 0 ] ); - out->color[ k ][ 1 ] = a->color[ k ][ 1 ] + amount * ( b->color[ k ][ 1 ] - a->color[ k ][ 1 ] ); - out->color[ k ][ 2 ] = a->color[ k ][ 2 ] + amount * ( b->color[ k ][ 2 ] - a->color[ k ][ 2 ] ); - out->color[ k ][ 3 ] = a->color[ k ][ 3 ] + amount * ( b->color[ k ][ 3 ] - a->color[ k ][ 3 ] ); + out->lightmap[ k ] = a->lightmap[ k ] + ( b->lightmap[ k ] - a->lightmap[ k ] ) * amount; + for( int i = 0; i < 4; ++i ) + out->color[ k ][ i ] = a->color[ k ][ i ] + amount * ( b->color[ k ][ i ] - a->color[ k ][ i ] ); } - out->normal[ 0 ] = a->normal[ 0 ] + amount * ( b->normal[ 0 ] - a->normal[ 0 ] ); - out->normal[ 1 ] = a->normal[ 1 ] + amount * ( b->normal[ 1 ] - a->normal[ 1 ] ); - out->normal[ 2 ] = a->normal[ 2 ] + amount * ( b->normal[ 2 ] - a->normal[ 2 ] ); + out->normal = a->normal + ( b->normal - a->normal ) * amount; /* if the interpolant created a bogus normal, just copy the normal from a */ - if ( VectorNormalize( out->normal, out->normal ) == 0 ) { - VectorCopy( a->normal, out->normal ); + if ( VectorNormalize( out->normal ) == 0 ) { + out->normal = a->normal; } } @@ -191,17 +170,12 @@ void InvertMesh( mesh_t *in ) { */ void MakeMeshNormals( mesh_t in ){ int i, j, k, dist; - vec3_t normal; - vec3_t sum; int count; - vec3_t base; - vec3_t delta; int x, y; bspDrawVert_t *dv; - vec3_t around[8], temp; + Vector3 around[8]; bool good[8]; bool wrapWidth, wrapHeight; - float len; int neighbors[8][2] = { {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1}, {-1,-1}, {-1,0}, {-1,1} @@ -210,10 +184,7 @@ void MakeMeshNormals( mesh_t in ){ wrapWidth = false; for ( i = 0 ; i < in.height ; i++ ) { - VectorSubtract( in.verts[i * in.width].xyz, - in.verts[i * in.width + in.width - 1].xyz, delta ); - len = VectorLength( delta ); - if ( len > 1.0 ) { + if ( vector3_length( in.verts[i * in.width].xyz - in.verts[i * in.width + in.width - 1].xyz ) > 1.0 ) { break; } } @@ -223,10 +194,7 @@ void MakeMeshNormals( mesh_t in ){ wrapHeight = false; for ( i = 0 ; i < in.width ; i++ ) { - VectorSubtract( in.verts[i].xyz, - in.verts[i + ( in.height - 1 ) * in.width].xyz, delta ); - len = VectorLength( delta ); - if ( len > 1.0 ) { + if ( vector3_length( in.verts[i].xyz - in.verts[i + ( in.height - 1 ) * in.width].xyz ) > 1.0 ) { break; } } @@ -239,9 +207,9 @@ void MakeMeshNormals( mesh_t in ){ for ( j = 0 ; j < in.height ; j++ ) { count = 0; dv = &in.verts[j * in.width + i]; - VectorCopy( dv->xyz, base ); + const Vector3 base( dv->xyz ); for ( k = 0 ; k < 8 ; k++ ) { - VectorClear( around[k] ); + around[k].set( 0 ); good[k] = false; for ( dist = 1 ; dist <= 3 ; dist++ ) { @@ -267,35 +235,35 @@ void MakeMeshNormals( mesh_t in ){ if ( x < 0 || x >= in.width || y < 0 || y >= in.height ) { break; // edge of patch } - VectorSubtract( in.verts[y * in.width + x].xyz, base, temp ); - if ( VectorNormalize( temp, temp ) == 0 ) { + Vector3 temp = in.verts[y * in.width + x].xyz - base; + if ( VectorNormalize( temp ) == 0 ) { continue; // degenerate edge, get more dist } else { good[k] = true; - VectorCopy( temp, around[k] ); + around[k] = temp; break; // good edge } } } - VectorClear( sum ); + Vector3 sum( 0, 0, 0 ); for ( k = 0 ; k < 8 ; k++ ) { if ( !good[k] || !good[( k + 1 ) & 7] ) { continue; // didn't get two points } - CrossProduct( around[( k + 1 ) & 7], around[k], normal ); - if ( VectorNormalize( normal, normal ) == 0 ) { + Vector3 normal = vector3_cross( around[( k + 1 ) & 7], around[k] ); + if ( VectorNormalize( normal ) == 0 ) { continue; } - VectorAdd( normal, sum, sum ); + sum += normal; count++; } if ( count == 0 ) { //Sys_Printf("bad normal\n"); count = 1; } - VectorNormalize( sum, dv->normal ); + dv->normal = VectorNormalized( sum ); } } } @@ -307,55 +275,40 @@ void MakeMeshNormals( mesh_t in ){ */ void PutMeshOnCurve( mesh_t in ) { - int i, j, l, m; - float prev, next; + int i, j, m; // put all the aproximating points on the curve for ( i = 0 ; i < in.width ; i++ ) { for ( j = 1 ; j < in.height ; j += 2 ) { - for ( l = 0 ; l < 3 ; l++ ) { - prev = ( in.verts[j * in.width + i].xyz[l] + in.verts[( j + 1 ) * in.width + i].xyz[l] ) * 0.5; - next = ( in.verts[j * in.width + i].xyz[l] + in.verts[( j - 1 ) * in.width + i].xyz[l] ) * 0.5; - in.verts[j * in.width + i].xyz[l] = ( prev + next ) * 0.5; - - /* ydnar: interpolating st coords */ - if ( l < 2 ) { - prev = ( in.verts[j * in.width + i].st[l] + in.verts[( j + 1 ) * in.width + i].st[l] ) * 0.5; - next = ( in.verts[j * in.width + i].st[l] + in.verts[( j - 1 ) * in.width + i].st[l] ) * 0.5; - in.verts[j * in.width + i].st[l] = ( prev + next ) * 0.5; - - for ( m = 0; m < MAX_LIGHTMAPS; m++ ) - { - prev = ( in.verts[j * in.width + i].lightmap[ m ][l] + in.verts[( j + 1 ) * in.width + i].lightmap[ m ][l] ) * 0.5; - next = ( in.verts[j * in.width + i].lightmap[ m ][l] + in.verts[( j - 1 ) * in.width + i].lightmap[ m ][l] ) * 0.5; - in.verts[j * in.width + i].lightmap[ m ][l] = ( prev + next ) * 0.5; - } - } + const int idx = j * in.width + i; + const int idprev = ( j + 1 ) * in.width + i; + const int idnext = ( j - 1 ) * in.width + i; + in.verts[idx].xyz = vector3_mid( vector3_mid( in.verts[idx].xyz, in.verts[idprev].xyz ), + vector3_mid( in.verts[idx].xyz, in.verts[idnext].xyz ) ); + /* ydnar: interpolating st coords */ + in.verts[idx].st = vector2_mid( vector2_mid( in.verts[idx].st, in.verts[idprev].st ), + vector2_mid( in.verts[idx].st, in.verts[idnext].st ) ); + for ( m = 0; m < MAX_LIGHTMAPS; m++ ) + { + in.verts[idx].lightmap[ m ] = vector2_mid( vector2_mid( in.verts[idx].lightmap[ m ], in.verts[idprev].lightmap[ m ] ), + vector2_mid( in.verts[idx].lightmap[ m ], in.verts[idnext].lightmap[ m ] ) ); } } } for ( j = 0 ; j < in.height ; j++ ) { for ( i = 1 ; i < in.width ; i += 2 ) { - for ( l = 0 ; l < 3 ; l++ ) { - prev = ( in.verts[j * in.width + i].xyz[l] + in.verts[j * in.width + i + 1].xyz[l] ) * 0.5; - next = ( in.verts[j * in.width + i].xyz[l] + in.verts[j * in.width + i - 1].xyz[l] ) * 0.5; - in.verts[j * in.width + i].xyz[l] = ( prev + next ) * 0.5; - - /* ydnar: interpolating st coords */ - if ( l < 2 ) { - prev = ( in.verts[j * in.width + i].st[l] + in.verts[j * in.width + i + 1].st[l] ) * 0.5; - next = ( in.verts[j * in.width + i].st[l] + in.verts[j * in.width + i - 1].st[l] ) * 0.5; - in.verts[j * in.width + i].st[l] = ( prev + next ) * 0.5; - - for ( m = 0; m < MAX_LIGHTMAPS; m++ ) - { - prev = ( in.verts[j * in.width + i].lightmap[ m ][l] + in.verts[j * in.width + i + 1].lightmap[ m ][l] ) * 0.5; - next = ( in.verts[j * in.width + i].lightmap[ m ][l] + in.verts[j * in.width + i - 1].lightmap[ m ][l] ) * 0.5; - in.verts[j * in.width + i].lightmap[ m ][l] = ( prev + next ) * 0.5; - } - } + const int idx = j * in.width + i; + in.verts[idx].xyz = vector3_mid( vector3_mid( in.verts[idx].xyz, in.verts[idx + 1].xyz ), + vector3_mid( in.verts[idx].xyz, in.verts[idx - 1].xyz ) ); + /* ydnar: interpolating st coords */ + in.verts[idx].st = vector2_mid( vector2_mid( in.verts[idx].st, in.verts[idx + 1].st ), + vector2_mid( in.verts[idx].st, in.verts[idx - 1].st ) ); + for ( m = 0; m < MAX_LIGHTMAPS; m++ ) + { + in.verts[idx].lightmap[ m ] = vector2_mid( vector2_mid( in.verts[idx].lightmap[ m ], in.verts[idx + 1].lightmap[ m ] ), + vector2_mid( in.verts[idx].lightmap[ m ], in.verts[idx - 1].lightmap[ m ] ) ); } } } @@ -369,11 +322,9 @@ void PutMeshOnCurve( mesh_t in ) { ================= */ mesh_t *SubdivideMesh( mesh_t in, float maxError, float minLength ){ - int i, j, k, l; + int i, j, k; bspDrawVert_t prev, next, mid; - vec3_t prevxyz, nextxyz, midxyz; - vec3_t delta; - float len; + Vector3 prevxyz, nextxyz, midxyz; mesh_t out; bspDrawVert_t expand[MAX_EXPANDED_AXIS][MAX_EXPANDED_AXIS]; @@ -392,23 +343,18 @@ mesh_t *SubdivideMesh( mesh_t in, float maxError, float minLength ){ for ( j = 0 ; j + 2 < out.width ; j += 2 ) { // check subdivided midpoints against control points for ( i = 0 ; i < out.height ; i++ ) { - for ( l = 0 ; l < 3 ; l++ ) { - prevxyz[l] = expand[i][j + 1].xyz[l] - expand[i][j].xyz[l]; - nextxyz[l] = expand[i][j + 2].xyz[l] - expand[i][j + 1].xyz[l]; - midxyz[l] = ( expand[i][j].xyz[l] + expand[i][j + 1].xyz[l] * 2 - + expand[i][j + 2].xyz[l] ) * 0.25; - } + prevxyz = expand[i][j + 1].xyz - expand[i][j].xyz; + nextxyz = expand[i][j + 2].xyz - expand[i][j + 1].xyz; + midxyz = ( expand[i][j].xyz + expand[i][j + 1].xyz * 2 + expand[i][j + 2].xyz ) * 0.25; // if the span length is too long, force a subdivision - if ( VectorLength( prevxyz ) > minLength - || VectorLength( nextxyz ) > minLength ) { + if ( vector3_length( prevxyz ) > minLength + || vector3_length( nextxyz ) > minLength ) { break; } // see if this midpoint is off far enough to subdivide - VectorSubtract( expand[i][j + 1].xyz, midxyz, delta ); - len = VectorLength( delta ); - if ( len > maxError ) { + if ( vector3_length( expand[i][j + 1].xyz - midxyz ) > maxError ) { break; } } @@ -446,22 +392,17 @@ mesh_t *SubdivideMesh( mesh_t in, float maxError, float minLength ){ for ( j = 0 ; j + 2 < out.height ; j += 2 ) { // check subdivided midpoints against control points for ( i = 0 ; i < out.width ; i++ ) { - for ( l = 0 ; l < 3 ; l++ ) { - prevxyz[l] = expand[j + 1][i].xyz[l] - expand[j][i].xyz[l]; - nextxyz[l] = expand[j + 2][i].xyz[l] - expand[j + 1][i].xyz[l]; - midxyz[l] = ( expand[j][i].xyz[l] + expand[j + 1][i].xyz[l] * 2 - + expand[j + 2][i].xyz[l] ) * 0.25; - } + prevxyz = expand[j + 1][i].xyz - expand[j][i].xyz; + nextxyz = expand[j + 2][i].xyz - expand[j + 1][i].xyz; + midxyz = ( expand[j][i].xyz + expand[j + 1][i].xyz * 2 + expand[j + 2][i].xyz ) * 0.25; // if the span length is too long, force a subdivision - if ( VectorLength( prevxyz ) > minLength - || VectorLength( nextxyz ) > minLength ) { + if ( vector3_length( prevxyz ) > minLength + || vector3_length( nextxyz ) > minLength ) { break; } // see if this midpoint is off far enough to subdivide - VectorSubtract( expand[j + 1][i].xyz, midxyz, delta ); - len = VectorLength( delta ); - if ( len > maxError ) { + if ( vector3_length( expand[j + 1][i].xyz - midxyz ) > maxError ) { break; } } @@ -626,14 +567,11 @@ mesh_t *SubdivideMesh2( mesh_t in, int iterations ){ ProjectPointOntoVector ================ */ -void ProjectPointOntoVector( vec3_t point, vec3_t vStart, vec3_t vEnd, vec3_t vProj ){ - vec3_t pVec, vec; - - VectorSubtract( point, vStart, pVec ); - VectorSubtract( vEnd, vStart, vec ); - VectorNormalize( vec, vec ); +Vector3 ProjectPointOntoVector( const Vector3& point, const Vector3& vStart, const Vector3& vEnd ){ + const Vector3 pVec = point - vStart; + const Vector3 vec = VectorNormalized( vEnd - vStart ); // project onto the directional vector for this segment - VectorMA( vStart, DotProduct( pVec, vec ), vec, vProj ); + return ( vStart + vec * vector3_dot( pVec, vec ) ); } /* @@ -644,7 +582,6 @@ void ProjectPointOntoVector( vec3_t point, vec3_t vStart, vec3_t vEnd, vec3_t vP mesh_t *RemoveLinearMeshColumnsRows( mesh_t *in ) { int i, j, k; float len, maxLength; - vec3_t proj, dir; mesh_t out; bspDrawVert_t expand[MAX_EXPANDED_AXIS][MAX_EXPANDED_AXIS]; @@ -662,9 +599,7 @@ mesh_t *RemoveLinearMeshColumnsRows( mesh_t *in ) { for ( j = 1 ; j < out.width - 1; j++ ) { maxLength = 0; for ( i = 0 ; i < out.height ; i++ ) { - ProjectPointOntoVector( expand[i][j].xyz, expand[i][j - 1].xyz, expand[i][j + 1].xyz, proj ); - VectorSubtract( expand[i][j].xyz, proj, dir ); - len = VectorLength( dir ); + len = vector3_length( expand[i][j].xyz - ProjectPointOntoVector( expand[i][j].xyz, expand[i][j - 1].xyz, expand[i][j + 1].xyz ) ); if ( len > maxLength ) { maxLength = len; } @@ -682,9 +617,7 @@ mesh_t *RemoveLinearMeshColumnsRows( mesh_t *in ) { for ( j = 1 ; j < out.height - 1; j++ ) { maxLength = 0; for ( i = 0 ; i < out.width ; i++ ) { - ProjectPointOntoVector( expand[j][i].xyz, expand[j - 1][i].xyz, expand[j + 1][i].xyz, proj ); - VectorSubtract( expand[j][i].xyz, proj, dir ); - len = VectorLength( dir ); + len = vector3_length( expand[j][i].xyz - ProjectPointOntoVector( expand[j][i].xyz, expand[j - 1][i].xyz, expand[j + 1][i].xyz ) ); if ( len > maxLength ) { maxLength = len; } @@ -717,7 +650,6 @@ mesh_t *RemoveLinearMeshColumnsRows( mesh_t *in ) { */ mesh_t *SubdivideMeshQuads( mesh_t *in, float minLength, int maxsize, int *widthtable, int *heighttable ){ int i, j, k, w, h, maxsubdivisions, subdivisions; - vec3_t dir; float length, maxLength, amount; mesh_t out; bspDrawVert_t expand[MAX_EXPANDED_AXIS][MAX_EXPANDED_AXIS]; @@ -742,8 +674,7 @@ mesh_t *SubdivideMeshQuads( mesh_t *in, float minLength, int maxsize, int *width for ( w = 0, j = 0 ; w < in->width - 1; w++, j += subdivisions + 1 ) { maxLength = 0; for ( i = 0 ; i < out.height ; i++ ) { - VectorSubtract( expand[i][j + 1].xyz, expand[i][j].xyz, dir ); - length = VectorLength( dir ); + length = vector3_length( expand[i][j + 1].xyz - expand[i][j].xyz ); if ( length > maxLength ) { maxLength = length; } @@ -778,9 +709,8 @@ mesh_t *SubdivideMeshQuads( mesh_t *in, float minLength, int maxsize, int *width for ( h = 0, j = 0 ; h < in->height - 1; h++, j += subdivisions + 1 ) { maxLength = 0; for ( i = 0 ; i < out.width ; i++ ) { - VectorSubtract( expand[j + 1][i].xyz, expand[j][i].xyz, dir ); - length = VectorLength( dir ); - if ( length > maxLength ) { + length = vector3_length( expand[j + 1][i].xyz - expand[j][i].xyz ); + if ( length > maxLength ) { maxLength = length; } } diff --git a/tools/quake3/q3map2/minimap.cpp b/tools/quake3/q3map2/minimap.cpp index 09627ae3..cb6b6e99 100644 --- a/tools/quake3/q3map2/minimap.cpp +++ b/tools/quake3/q3map2/minimap.cpp @@ -45,29 +45,29 @@ struct minimap_t float boost, brightness, contrast; float *data1f; float *sharpendata1f; - vec3_t mins, size; + Vector3 mins, size; }; static minimap_t minimap; -bool BrushIntersectionWithLine( bspBrush_t *brush, vec3_t start, vec3_t dir, float *t_in, float *t_out ){ +bool BrushIntersectionWithLine( bspBrush_t *brush, const Vector3& start, const Vector3& dir, float *t_in, float *t_out ){ int i; bool in = false, out = false; bspBrushSide_t *sides = &bspBrushSides[brush->firstSide]; for ( i = 0; i < brush->numSides; ++i ) { - bspPlane_t *p = &bspPlanes[sides[i].planeNum]; - float sn = DotProduct( start, p->normal ); - float dn = DotProduct( dir, p->normal ); + const bspPlane_t& p = bspPlanes[sides[i].planeNum]; + float sn = vector3_dot( start, p.normal() ); + float dn = vector3_dot( dir, p.normal() ); if ( dn == 0 ) { - if ( sn > p->dist ) { + if ( sn > p.dist() ) { return false; // outside! } } else { - float t = ( p->dist - sn ) / dn; + float t = ( p.dist() - sn ) / dn; if ( dn < 0 ) { if ( !in || t > *t_in ) { *t_in = t; @@ -95,7 +95,6 @@ bool BrushIntersectionWithLine( bspBrush_t *brush, vec3_t start, vec3_t dir, flo } static float MiniMapSample( float x, float y ){ - vec3_t org, dir; int i, bi; float t0, t1; float samp; @@ -103,12 +102,8 @@ static float MiniMapSample( float x, float y ){ bspBrushSide_t *s; int cnt; - org[0] = x; - org[1] = y; - org[2] = 0; - dir[0] = 0; - dir[1] = 0; - dir[2] = 1; + const Vector3 org( x, y, 0 ); + const Vector3 dir( g_vector3_axis_z ); cnt = 0; samp = 0; @@ -120,16 +115,16 @@ static float MiniMapSample( float x, float y ){ // sort out mins/maxs of the brush s = &bspBrushSides[b->firstSide]; - if ( x < -bspPlanes[s[0].planeNum].dist ) { + if ( x < -bspPlanes[s[0].planeNum].dist() ) { continue; } - if ( x > +bspPlanes[s[1].planeNum].dist ) { + if ( x > +bspPlanes[s[1].planeNum].dist() ) { continue; } - if ( y < -bspPlanes[s[2].planeNum].dist ) { + if ( y < -bspPlanes[s[2].planeNum].dist() ) { continue; } - if ( y > +bspPlanes[s[3].planeNum].dist ) { + if ( y > +bspPlanes[s[3].planeNum].dist() ) { continue; } @@ -281,16 +276,16 @@ static void MiniMapBrightnessContrast( int y ){ } } -void MiniMapMakeMinsMaxs( vec3_t mins_in, vec3_t maxs_in, float border, bool keepaspect ){ - vec3_t mins, maxs, extend; - VectorCopy( mins_in, mins ); - VectorCopy( maxs_in, maxs ); +void MiniMapMakeMinsMaxs( const Vector3& mins_in, const Vector3& maxs_in, float border, bool keepaspect ){ + Vector3 mins = mins_in; + Vector3 maxs = maxs_in; + Vector3 extend; // line compatible to nexuiz mapinfo Sys_Printf( "size %f %f %f %f %f %f\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2] ); if ( keepaspect ) { - VectorSubtract( maxs, mins, extend ); + extend = maxs - mins; if ( extend[1] > extend[0] ) { mins[0] -= ( extend[1] - extend[0] ) * 0.5; maxs[0] += ( extend[1] - extend[0] ) * 0.5; @@ -305,14 +300,13 @@ void MiniMapMakeMinsMaxs( vec3_t mins_in, vec3_t maxs_in, float border, bool kee /* border: amount of black area around the image */ /* input: border, 1-2*border, border but we need border/(1-2*border) */ - VectorSubtract( maxs, mins, extend ); - VectorScale( extend, border / ( 1 - 2 * border ), extend ); + extend = ( maxs - mins ) * ( border / ( 1 - 2 * border ) ); - VectorSubtract( mins, extend, mins ); - VectorAdd( maxs, extend, maxs ); + mins -= extend; + maxs += extend; - VectorCopy( mins, minimap.mins ); - VectorSubtract( maxs, mins, minimap.size ); + minimap.mins = mins; + minimap.size = maxs - mins; // line compatible to nexuiz mapinfo Sys_Printf( "size_texcoords %f %f %f %f %f %f\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2] ); @@ -468,7 +462,6 @@ int MiniMapBSPMain( int argc, char **argv ){ int x, y; int i; EMiniMapMode mode; - vec3_t mins, maxs; bool keepaspect; /* arg checking */ @@ -486,10 +479,10 @@ int MiniMapBSPMain( int argc, char **argv ){ LoadBSPFile( source ); minimap.model = &bspModels[0]; - VectorCopy( minimap.model->mins, mins ); - VectorCopy( minimap.model->maxs, maxs ); + Vector3 mins = minimap.model->minmax.mins; + Vector3 maxs = minimap.model->minmax.maxs; - *minimapFilename = 0; + strClear( minimapFilename ); minimapSharpen = game->miniMapSharpen; minimap.width = minimap.height = game->miniMapSize; border = game->miniMapBorder; @@ -598,7 +591,7 @@ int MiniMapBSPMain( int argc, char **argv ){ MiniMapMakeMinsMaxs( mins, maxs, border, keepaspect ); - if ( !*minimapFilename ) { + if ( strEmpty( minimapFilename ) ) { ExtractFileBase( source, basename ); ExtractFilePath( source, path ); sprintf( relativeMinimapFilename, game->miniMapNameFormat, basename ); diff --git a/tools/quake3/q3map2/model.cpp b/tools/quake3/q3map2/model.cpp index e2ff7815..67082eb2 100644 --- a/tools/quake3/q3map2/model.cpp +++ b/tools/quake3/q3map2/model.cpp @@ -205,9 +205,9 @@ picoModel_t *LoadModel( const char *name, int frame ){ adds a picomodel into the bsp */ -void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const std::list *remaps, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle, float clipDepth ){ +void InsertModel( const char *name, int skin, int frame, const Matrix4& transform, const std::list *remaps, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle, float clipDepth ){ int i, j, s, k, numSurfaces; - m4x4_t identity, nTransform; + const Matrix4 nTransform( matrix4_for_normal_transform( transform ) ); picoModel_t *model; picoSurface_t *surface; shaderInfo_t *si; @@ -291,24 +291,11 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const free( skinfilecontent ); } - /* handle null matrix */ - if ( transform == NULL ) { - m4x4_identity( identity ); - transform = identity; - } - /* hack: Stable-1_2 and trunk have differing row/column major matrix order this transpose is necessary with Stable-1_2 uncomment the following line with old m4x4_t (non 1.3/spog_branch) code */ //% m4x4_transpose( transform ); - /* create transform matrix for normals */ - memcpy( nTransform, transform, sizeof( m4x4_t ) ); - if ( m4x4_invert( nTransform ) ) { - Sys_FPrintf( SYS_WRN | SYS_VRBflag, "WARNING: Can't invert model transform matrix, using transpose instead\n" ); - } - m4x4_transpose( nTransform ); - /* fix bogus lightmap scale */ if ( lightmapScale <= 0.0f ) { lightmapScale = 1.0f; @@ -442,24 +429,23 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const /* xyz and normal */ xyz = PicoGetSurfaceXYZ( surface, i ); VectorCopy( xyz, dv->xyz ); - m4x4_transform_point( transform, dv->xyz ); + matrix4_transform_point( transform, dv->xyz ); normal = PicoGetSurfaceNormal( surface, i ); VectorCopy( normal, dv->normal ); - m4x4_transform_normal( nTransform, dv->normal ); - VectorNormalize( dv->normal, dv->normal ); + matrix4_transform_direction( nTransform, dv->normal ); + VectorNormalize( dv->normal ); /* ydnar: tek-fu celshading support for flat shaded shit */ if ( flat ) { - dv->st[ 0 ] = si->stFlat[ 0 ]; - dv->st[ 1 ] = si->stFlat[ 1 ]; + dv->st = si->stFlat; } /* ydnar: gs mods: added support for explicit shader texcoord generation */ else if ( si->tcGen ) { /* project the texture */ - dv->st[ 0 ] = DotProduct( si->vecs[ 0 ], dv->xyz ); - dv->st[ 1 ] = DotProduct( si->vecs[ 1 ], dv->xyz ); + dv->st[ 0 ] = vector3_dot( si->vecs[ 0 ], dv->xyz ); + dv->st[ 1 ] = vector3_dot( si->vecs[ 1 ], dv->xyz ); } /* normal texture coordinates */ @@ -477,17 +463,11 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const dv->lightmap[ j ][ 0 ] = 0.0f; dv->lightmap[ j ][ 1 ] = 0.0f; if ( spawnFlags & 32 ) { // spawnflag 32: model color -> alpha hack - dv->color[ j ][ 0 ] = 255.0f; - dv->color[ j ][ 1 ] = 255.0f; - dv->color[ j ][ 2 ] = 255.0f; - dv->color[ j ][ 3 ] = RGBTOGRAY( color ); + dv->color[ j ] = { 255, 255, 255, RGBTOGRAY( color ) }; } else { - dv->color[ j ][ 0 ] = color[ 0 ]; - dv->color[ j ][ 1 ] = color[ 1 ]; - dv->color[ j ][ 2 ] = color[ 2 ]; - dv->color[ j ][ 3 ] = color[ 3 ]; + dv->color[ j ] = { color[0], color[1], color[2], color[3] }; } } } @@ -522,12 +502,12 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const ( spf == 5632 ) || //EXTRUDE_DOWNWARDS+EXTRUDE_UPWARDS+AXIAL_BACKPLANE ( spf == 3072 ) || //EXTRUDE_UPWARDS+MAX_EXTRUDE ( spf == 5120 ) ){ //EXTRUDE_UPWARDS+AXIAL_BACKPLANE - vec3_t points[ 4 ], cnt, bestNormal, nrm, Vnorm[3], Enorm[3]; - vec4_t plane, reverse, p[3]; + Vector3 points[ 4 ], cnt, bestNormal, nrm, Vnorm[3], Enorm[3]; + Plane3f plane, reverse, p[3]; double normalEpsilon_save; bool snpd; - vec3_t min = { 999999, 999999, 999999 }, max = { -999999, -999999, -999999 }; - vec3_t avgDirection = { 0, 0, 0 }; + MinMax minmax; + Vector3 avgDirection( 0, 0, 0 ); int axis; #define nonax_clip_dbg 0 @@ -549,41 +529,27 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const for ( j = 0; j < 3; j++ ) { dv = &ds->verts[ ds->indexes[ i + j ] ]; - VectorCopy( dv->xyz, points[ j ] ); + points[ j ] = dv->xyz; } - if ( PlaneFromPoints( plane, points[ 0 ], points[ 1 ], points[ 2 ] ) ){ - if ( spawnFlags & 16 ) VectorAdd( avgDirection, plane, avgDirection ); //calculate average mesh facing direction + if ( PlaneFromPoints( plane, points ) ){ + if ( spawnFlags & 16 ) + avgDirection += plane.normal(); //calculate average mesh facing direction //get min/max - for ( k = 2; k > -1; k-- ){ - if ( plane[k] > 0 ){ - for ( j = 0; j < 3; j++ ){ if ( points[j][k] < min[k] ) min[k] = points[j][k]; } - } - else if ( plane[k] < 0 ){ - for ( j = 0; j < 3; j++ ){ if ( points[j][k] > max[k] ) max[k] = points[j][k]; } - } - //if EXTRUDE_DOWNWARDS or EXTRUDE_UPWARDS - if ( ( spawnFlags & 512 ) || ( spawnFlags & 1024 ) ){ - break; - } + for ( j = 0; j < 3; ++j ){ + minmax.extend( points[j] ); } } } //unify avg direction if ( spawnFlags & 16 ){ - for ( j = 0; j < 3; j++ ){ - if ( fabs(avgDirection[j]) > fabs(avgDirection[(j+1)%3]) ){ - avgDirection[(j+1)%3] = 0.0; - axis = j; - } - else { - avgDirection[j] = 0.0; - } + if ( vector3_length( avgDirection ) != 0 ){ + axis = vector3_max_abs_component_index( avgDirection ); } - if ( VectorNormalize( avgDirection, avgDirection ) == 0 ){ + else{ axis = 2; - VectorSet( avgDirection, 0, 0, 1 ); } + avgDirection = avgDirection[axis] >= 0? g_vector3_axes[axis] : -g_vector3_axes[axis]; } } @@ -600,11 +566,11 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const dv = &ds->verts[ ds->indexes[ i + j ] ]; /* copy xyz */ - VectorCopy( dv->xyz, points[ j ] ); + points[ j ] = dv->xyz; } /* make plane for triangle */ - if ( PlaneFromPoints( plane, points[ 0 ], points[ 1 ], points[ 2 ] ) ) { + if ( PlaneFromPoints( plane, points ) ) { /* build a brush */ buildBrush = AllocBrush( 48 ); @@ -621,11 +587,10 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const snpd = false; for ( j=0; j<3; j++ ) { - if ( fabs(plane[j]) < 0.00025 && fabs(plane[(j+1)%3]) < 0.00025 && ( plane[j] != 0.0 || plane[(j+1)%3] != 0.0 ) ){ - VectorAdd( points[ 0 ], points[ 1 ], cnt ); - VectorAdd( cnt, points[ 2 ], cnt ); - VectorScale( cnt, 0.3333333333333f, cnt ); - points[0][(j+2)%3]=points[1][(j+2)%3]=points[2][(j+2)%3]=cnt[(j+2)%3]; + if ( fabs( plane.normal()[j] ) < 0.00025 && fabs( plane.normal()[(j+1)%3] ) < 0.00025 + && ( plane.normal()[j] != 0.0 || plane.normal()[(j+1)%3] != 0.0 ) ){ + cnt = ( points[0] + points[1] + points[2] ) / 3.0; + points[0][(j+2)%3] = points[1][(j+2)%3] = points[2][(j+2)%3] = cnt[(j+2)%3]; snpd = true; break; } @@ -634,8 +599,7 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const //snap pairs of points to prevent bad side planes for ( j=0; j<3; j++ ) { - VectorSubtract( points[j], points[(j+1)%3], nrm ); - VectorNormalize( nrm, nrm ); + nrm = VectorNormalized( points[j] - points[(j+1)%3] ); for ( k=0; k<3; k++ ) { if ( nrm[k] != 0.0 && fabs(nrm[k]) < 0.00025 ){ @@ -648,19 +612,18 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const } if ( snpd ) { - PlaneFromPoints( plane, points[ 0 ], points[ 1 ], points[ 2 ] ); + PlaneFromPoints( plane, points ); snpd = false; } //vector-is-close-to-be-on-axis check again, happens after previous code sometimes for ( j=0; j<3; j++ ) { - if ( fabs(plane[j]) < 0.00025 && fabs(plane[(j+1)%3]) < 0.00025 && ( plane[j] != 0.0 || plane[(j+1)%3] != 0.0 ) ){ - VectorAdd( points[ 0 ], points[ 1 ], cnt ); - VectorAdd( cnt, points[ 2 ], cnt ); - VectorScale( cnt, 0.3333333333333f, cnt ); - points[0][(j+2)%3]=points[1][(j+2)%3]=points[2][(j+2)%3]=cnt[(j+2)%3]; - PlaneFromPoints( plane, points[ 0 ], points[ 1 ], points[ 2 ] ); + if ( fabs( plane.normal()[j] ) < 0.00025 && fabs( plane.normal()[(j+1)%3] ) < 0.00025 + && ( plane.normal()[j] != 0.0 || plane.normal()[(j+1)%3] != 0.0 ) ){ + cnt = ( points[0] + points[1] + points[2] ) / 3.0; + points[0][(j+2)%3] = points[1][(j+2)%3] = points[2][(j+2)%3] = cnt[(j+2)%3]; + PlaneFromPoints( plane, points ); break; } } @@ -668,25 +631,23 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const //snap single snappable normal components for ( j=0; j<3; j++ ) { - if ( plane[j] != 0.0 && fabs(plane[j]) < 0.00005 ){ - plane[j]=0.0; + if ( plane.normal()[j] != 0.0 && fabs( plane.normal()[j] ) < 0.00005 ){ + plane.normal()[j]=0.0; snpd = true; } } //adjust plane dist if ( snpd ) { - VectorAdd( points[ 0 ], points[ 1 ], cnt ); - VectorAdd( cnt, points[ 2 ], cnt ); - VectorScale( cnt, 0.3333333333333f, cnt ); - VectorNormalize( plane, plane ); - plane[3] = DotProduct( plane, cnt ); + cnt = ( points[0] + points[1] + points[2] ) / 3.0; + VectorNormalize( plane.normal() ); + plane.dist() = vector3_dot( plane.normal(), cnt ); //project points to resulting plane to keep intersections precision for ( j=0; j<3; j++ ) { //Sys_Printf( "b4 %i (%6.7f %6.7f %6.7f)\n", j, points[j][0], points[j][1], points[j][2] ); - VectorMA( points[j], plane[3] - DotProduct( plane, points[j]), plane, points[j] ); + points[j] = plane3_project_point( plane, points[j] ); //Sys_Printf( "sn %i (%6.7f %6.7f %6.7f)\n", j, points[j][0], points[j][1], points[j][2] ); } //Sys_Printf( "sn pln (%6.7f %6.7f %6.7f %6.7f)\n", plane[0], plane[1], plane[2], plane[3] ); @@ -696,15 +657,15 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const /* sanity check */ { - vec3_t d1, d2, normaL; - VectorSubtract( points[1], points[0], d1 ); - VectorSubtract( points[2], points[0], d2 ); - CrossProduct( d2, d1, normaL ); + const Vector3 d1 = points[1] - points[0]; + const Vector3 d2 = points[2] - points[0]; + const Vector3 normaL = vector3_cross( d2, d1 ); /* https://en.wikipedia.org/wiki/Cross_product#Geometric_meaning cross( a, b ).length = a.length b.length sin( angle ) */ - const double lengthsSquared = ( d1[0] * d1[0] + d1[1] * d1[1] + d1[2] * d1[2] ) * ( d2[0] * d2[0] + d2[1] * d2[1] + d2[2] * d2[2] ); - if ( lengthsSquared == 0 || fabs( ( normaL[0] * normaL[0] + normaL[1] * normaL[1] + normaL[2] * normaL[2] ) / lengthsSquared ) < 1e-8 ) { - Sys_Warning( "triangle (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) of %s was not autoclipped: points on line\n", points[0][0], points[0][1], points[0][2], points[1][0], points[1][1], points[1][2], points[2][0], points[2][1], points[2][2], name ); + const double lengthsSquared = vector3_length_squared( d1 ) * vector3_length_squared( d2 ); + if ( lengthsSquared == 0 || fabs( vector3_length_squared( normaL ) / lengthsSquared ) < 1e-8 ) { + Sys_Warning( "triangle (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) of %s was not autoclipped: points on line\n", + points[0][0], points[0][1], points[0][2], points[1][0], points[1][1], points[1][2], points[2][0], points[2][1], points[2][2], name ); continue; } } @@ -714,13 +675,13 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const for ( j=0; j<3; j++ ) { - if ( fabs(plane[j]) < 0.05 && fabs(plane[(j+1)%3]) < 0.05 ){ //no way, close to lay on two axises + if ( fabs( plane.normal()[j] ) < 0.05 && fabs( plane.normal()[(j+1)%3] ) < 0.05 ){ //no way, close to lay on two axes goto default_CLIPMODEL; } } // best axial normal - VectorCopy( plane, bestNormal ); + bestNormal = plane.normal(); for ( j = 0; j < 3; j++ ){ if ( fabs(bestNormal[j]) > fabs(bestNormal[(j+1)%3]) ){ bestNormal[(j+1)%3] = 0.0; @@ -730,7 +691,7 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const bestNormal[j] = 0.0; } } - VectorNormalize( bestNormal, bestNormal ); + VectorNormalize( bestNormal ); float bestdist, currdist, bestangle, currangle, mindist = 999999; @@ -738,13 +699,13 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const for ( j = 0; j < 3; j++ ){//planes bestdist = 999999; bestangle = 1; - for ( k = 0; k < 3; k++ ){//axises - VectorSubtract( points[ (j+1)%3 ], points[ j ], nrm ); + for ( k = 0; k < 3; k++ ){//axes + nrm = points[(j+1)%3] - points[j]; if ( k == axis ){ - CrossProduct( bestNormal, nrm, reverse ); + reverse.normal() = vector3_cross( bestNormal, nrm ); } else{ - VectorClear( Vnorm[0] ); + Vnorm[0].set( 0 ); if ( (k+1)%3 == axis ){ if ( nrm[ (k+2)%3 ] == 0 ) continue; Vnorm[0][ (k+2)%3 ] = nrm[ (k+2)%3 ]; @@ -753,20 +714,19 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const if ( nrm[ (k+1)%3 ] == 0 ) continue; Vnorm[0][ (k+1)%3 ] = nrm[ (k+1)%3 ]; } - CrossProduct( bestNormal, Vnorm[0], Enorm[0] ); - CrossProduct( Enorm[0], nrm, reverse ); + Enorm[0] = vector3_cross( bestNormal, Vnorm[0] ); + reverse.normal() = vector3_cross( Enorm[0], nrm ); } - VectorNormalize( reverse, reverse ); - reverse[3] = DotProduct( points[ j ], reverse ); + VectorNormalize( reverse.normal() ); + reverse.dist() = vector3_dot( points[ j ], reverse.normal() ); //check facing, thickness - currdist = reverse[3] - DotProduct( reverse, points[ (j+2)%3 ] ); - currangle = DotProduct( reverse, plane ); + currdist = reverse.dist() - vector3_dot( reverse.normal(), points[ (j+2)%3 ] ); + currangle = vector3_dot( reverse.normal(), plane.normal() ); if ( ( ( currdist > 0.1 ) && ( currdist < bestdist ) && ( currangle < 0 ) ) || ( ( currangle >= 0 ) && ( currangle <= bestangle ) ) ){ bestangle = currangle; if ( currangle < 0 ) bestdist = currdist; - VectorCopy( reverse, p[j] ); - p[j][3] = reverse[3]; + p[j] = reverse; } } //if ( bestdist == 999999 && bestangle == 1 ) Sys_Printf("default_CLIPMODEL\n"); @@ -800,12 +760,12 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works } } - VectorCopy( points[0], points[3] ); // for cyclic usage + points[3] = points[0]; // for cyclic usage - buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points ); - buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1] - buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2] - buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3] + buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points ); + buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1] + buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2] + buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3] } @@ -824,22 +784,21 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const ( spf == 5120 ) ){ //EXTRUDE_UPWARDS+AXIAL_BACKPLANE if ( spawnFlags & 16 ){ //autodirection - VectorCopy( avgDirection, bestNormal ); + bestNormal = avgDirection; } else{ axis = 2; if ( ( spawnFlags & 1536 ) == 1536 ){ //up+down - VectorSet( bestNormal, 0, 0, ( plane[2] >= 0 ? 1 : -1 ) ); + bestNormal = plane.normal()[2] >= 0? g_vector3_axis_z : -g_vector3_axis_z; } else if ( spawnFlags & 512 ){ //down - VectorSet( bestNormal, 0, 0, 1 ); - + bestNormal = g_vector3_axis_z; } else if ( spawnFlags & 1024 ){ //up - VectorSet( bestNormal, 0, 0, -1 ); + bestNormal = -g_vector3_axis_z; } else{ // best axial normal - VectorCopy( plane, bestNormal ); + bestNormal = plane.normal(); for ( j = 0; j < 3; j++ ){ if ( fabs(bestNormal[j]) > fabs(bestNormal[(j+1)%3]) ){ bestNormal[(j+1)%3] = 0.0; @@ -849,11 +808,11 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const bestNormal[j] = 0.0; } } - VectorNormalize( bestNormal, bestNormal ); + VectorNormalize( bestNormal ); } } - if ( DotProduct( plane, bestNormal ) < 0.05 ){ + if ( vector3_dot( plane.normal(), bestNormal ) < 0.05 ){ goto default_CLIPMODEL; } @@ -861,69 +820,65 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const /* make side planes */ for ( j = 0; j < 3; j++ ) { - VectorSubtract( points[(j+1)%3], points[ j ], nrm ); - CrossProduct( bestNormal, nrm, p[ j ] ); - VectorNormalize( p[ j ], p[ j ] ); - p[j][3] = DotProduct( points[j], p[j] ); + p[j].normal() = VectorNormalized( vector3_cross( bestNormal, points[(j+1)%3] - points[j] ) ); + p[j].dist() = vector3_dot( points[j], p[j].normal() ); } /* make back plane */ if ( spawnFlags & 2048 ){ //max extrude - VectorScale( bestNormal, -1.0f, reverse ); + reverse.normal() = -bestNormal; if ( bestNormal[axis] > 0 ){ - reverse[3] = -min[axis] + clipDepth; + reverse.dist() = -minmax.mins[axis] + clipDepth; } else{ - reverse[3] = max[axis] + clipDepth; + reverse.dist() = minmax.maxs[axis] + clipDepth; } } else if ( spawnFlags & 4096 ){ //axial backplane - VectorScale( bestNormal, -1.0f, reverse ); - reverse[3] = points[0][axis]; + reverse.normal() = -bestNormal; + reverse.dist() = points[0][axis]; if ( bestNormal[axis] > 0 ){ for ( j = 1; j < 3; j++ ){ - if ( points[j][axis] < reverse[3] ){ - reverse[3] = points[j][axis]; + if ( points[j][axis] < reverse.dist() ){ + reverse.dist() = points[j][axis]; } } - reverse[3] = -reverse[3] + clipDepth; + reverse.dist() = -reverse.dist() + clipDepth; } else{ for ( j = 1; j < 3; j++ ){ - if ( points[j][axis] > reverse[3] ){ - reverse[3] = points[j][axis]; + if ( points[j][axis] > reverse.dist() ){ + reverse.dist() = points[j][axis]; } } - reverse[3] += clipDepth; + reverse.dist() += clipDepth; } - if (limDepth != 0.0){ - VectorCopy( points[0], cnt ); + if ( limDepth != 0.0 ){ + cnt = points[0]; if ( bestNormal[axis] > 0 ){ for ( j = 1; j < 3; j++ ){ if ( points[j][axis] > cnt[axis] ){ - VectorCopy( points[j], cnt ); + cnt = points[j]; } } } else { for ( j = 1; j < 3; j++ ){ if ( points[j][axis] < cnt[axis] ){ - VectorCopy( points[j], cnt ); + cnt = points[j]; } } } - VectorMA( cnt, reverse[3] - DotProduct( reverse, cnt ), reverse, cnt ); - if ( ( plane[3] - DotProduct( plane, cnt ) ) > limDepth ){ - VectorScale( plane, -1.0f, reverse ); - reverse[ 3 ] = -plane[ 3 ]; - reverse[3] += clipDepth; + cnt = plane3_project_point( reverse, cnt ); + if ( -plane3_distance_to_point( plane, cnt ) > limDepth ){ + reverse = plane3_flipped( plane ); + reverse.dist() += clipDepth; } } } else{ //normal backplane - VectorScale( plane, -1.0f, reverse ); - reverse[ 3 ] = -plane[ 3 ]; - reverse[3] += clipDepth; + reverse = plane3_flipped( plane ); + reverse.dist() += clipDepth; } #if nonax_clip_dbg for ( j = 0; j < 3; j++ ) @@ -949,13 +904,13 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works } } - VectorCopy( points[0], points[3] ); // for cyclic usage + points[3] = points[0]; // for cyclic usage - buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points ); - buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1] - buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2] - buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3] - buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, reverse[ 3 ], 0, NULL ); + buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points ); + buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1] + buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2] + buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3] + buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL ); } @@ -964,36 +919,31 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const //45 degrees normals for side planes for ( j = 0; j < 3; j++ ) { - VectorSubtract( points[(j+1)%3], points[ j ], nrm ); - CrossProduct( plane, nrm, Enorm[ j ] ); - VectorNormalize( Enorm[ j ], Enorm[ j ] ); - VectorAdd( plane, Enorm[ j ], Enorm[ j ] ); - VectorNormalize( Enorm[ j ], Enorm[ j ] ); + nrm = points[(j+1)%3] - points[ j ]; + Enorm[ j ] = VectorNormalized( vector3_cross( plane.normal(), nrm ) ); + Enorm[ j ] += plane.normal(); + VectorNormalize( Enorm[ j ] ); /* make side planes */ - CrossProduct( Enorm[ j ], nrm, p[ j ] ); - VectorNormalize( p[ j ], p[ j ] ); - p[j][3] = DotProduct( points[j], p[j] ); + p[j].normal() = VectorNormalized( vector3_cross( Enorm[ j ], nrm ) ); + p[j].dist() = vector3_dot( points[j], p[j].normal() ); //snap nearly axial side planes snpd = false; for ( k = 0; k < 3; k++ ) { - if ( fabs(p[j][k]) < 0.00025 && p[j][k] != 0.0 ){ - p[j][k] = 0.0; + if ( fabs( p[j].normal()[k] ) < 0.00025 && p[j].normal()[k] != 0.0 ){ + p[j].normal()[k] = 0.0; snpd = true; } } if ( snpd ){ - VectorNormalize( p[j], p[j] ); - VectorAdd( points[j], points[(j+1)%3], cnt ); - VectorScale( cnt, 0.5f, cnt ); - p[j][3] = DotProduct( cnt, p[j] ); + VectorNormalize( p[j].normal() ); + p[j].dist() = vector3_dot( ( points[j] + points[(j+1)%3] ) / 2.0, p[j].normal() ); } } /* make back plane */ - VectorScale( plane, -1.0f, reverse ); - reverse[ 3 ] = -plane[ 3 ]; - reverse[3] += clipDepth; + reverse = plane3_flipped( plane ); + reverse.dist() += clipDepth; /* set up brush sides */ buildBrush->numsides = 5; @@ -1008,13 +958,13 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works } } - VectorCopy( points[0], points[3] ); // for cyclic usage + points[3] = points[0]; // for cyclic usage - buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points ); - buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1] - buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2] - buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3] - buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, reverse[ 3 ], 0, NULL ); + buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points ); + buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1] + buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2] + buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3] + buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL ); } @@ -1026,21 +976,18 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const /* get vertex */ dv = &ds->verts[ ds->indexes[ i + j ] ]; /* copy normal */ - VectorCopy( dv->normal, Vnorm[ j ] ); + Vnorm[ j ] = dv->normal; } //avg normals for side planes for ( j = 0; j < 3; j++ ) { - VectorAdd( Vnorm[ j ], Vnorm[ (j+1)%3 ], Enorm[ j ] ); - VectorNormalize( Enorm[ j ], Enorm[ j ] ); + Enorm[ j ] = VectorNormalized( Vnorm[ j ] + Vnorm[ (j+1)%3 ] ); //check fuer bad ones - VectorSubtract( points[(j+1)%3], points[ j ], cnt ); - CrossProduct( plane, cnt, nrm ); - VectorNormalize( nrm, nrm ); + nrm = VectorNormalized( vector3_cross( plane.normal(), points[(j+1)%3] - points[ j ] ) ); //check for negative or outside direction - if ( DotProduct( Enorm[ j ], plane ) > 0.1 ){ - if ( ( DotProduct( Enorm[ j ], nrm ) > -0.2 ) || ( spawnFlags & 256 ) ){ + if ( vector3_dot( Enorm[ j ], plane.normal() ) > 0.1 ){ + if ( ( vector3_dot( Enorm[ j ], nrm ) > -0.2 ) || ( spawnFlags & 256 ) ){ //ok++; continue; } @@ -1048,41 +995,36 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const //notok++; //Sys_Printf( "faulty Enormal %i/%i\n", notok, ok ); //use 45 normal - VectorAdd( plane, nrm, Enorm[ j ] ); - VectorNormalize( Enorm[ j ], Enorm[ j ] ); + Enorm[ j ] = plane.normal() + nrm; + VectorNormalize( Enorm[ j ] ); } /* make side planes */ for ( j = 0; j < 3; j++ ) { - VectorSubtract( points[(j+1)%3], points[ j ], nrm ); - CrossProduct( Enorm[ j ], nrm, p[ j ] ); - VectorNormalize( p[ j ], p[ j ] ); - p[j][3] = DotProduct( points[j], p[j] ); + p[j].normal() = VectorNormalized( vector3_cross( Enorm[ j ], points[(j+1)%3] - points[j] ) ); + p[j].dist() = vector3_dot( points[j], p[j].normal() ); //snap nearly axial side planes snpd = false; for ( k = 0; k < 3; k++ ) { - if ( fabs(p[j][k]) < 0.00025 && p[j][k] != 0.0 ){ + if ( fabs( p[j].normal()[k] ) < 0.00025 && p[j].normal()[k] != 0.0 ){ //Sys_Printf( "init plane %6.8f %6.8f %6.8f %6.8f\n", p[j][0], p[j][1], p[j][2], p[j][3]); - p[j][k] = 0.0; + p[j].normal()[k] = 0.0; snpd = true; } } if ( snpd ){ - VectorNormalize( p[j], p[j] ); + VectorNormalize( p[j].normal() ); //Sys_Printf( "nrm plane %6.8f %6.8f %6.8f %6.8f\n", p[j][0], p[j][1], p[j][2], p[j][3]); - VectorAdd( points[j], points[(j+1)%3], cnt ); - VectorScale( cnt, 0.5f, cnt ); - p[j][3] = DotProduct( cnt, p[j] ); + p[j].dist() = vector3_dot( ( points[j] + points[(j+1)%3] ) / 2.0, p[j].normal() ); //Sys_Printf( "dst plane %6.8f %6.8f %6.8f %6.8f\n", p[j][0], p[j][1], p[j][2], p[j][3]); } } /* make back plane */ - VectorScale( plane, -1.0f, reverse ); - reverse[ 3 ] = -plane[ 3 ]; - reverse[3] += clipDepth; + reverse = plane3_flipped( plane ); + reverse.dist() += clipDepth; /* set up brush sides */ buildBrush->numsides = 5; @@ -1097,13 +1039,13 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works } } - VectorCopy( points[0], points[3] ); // for cyclic usage + points[3] = points[0]; // for cyclic usage - buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points ); - buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1] - buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2] - buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3] - buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, reverse[ 3 ], 0, NULL ); + buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points ); + buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1] + buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2] + buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3] + buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL ); } @@ -1112,34 +1054,30 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const /* make side planes */ for ( j = 0; j < 3; j++ ) { - VectorSubtract( points[(j+1)%3], points[ j ], nrm ); - CrossProduct( plane, nrm, p[ j ] ); - VectorNormalize( p[ j ], p[ j ] ); - p[j][3] = DotProduct( points[j], p[j] ); + p[j].normal() = VectorNormalized( vector3_cross( plane.normal(), points[(j+1)%3] - points[j] ) ); + p[j].dist() = vector3_dot( points[j], p[j].normal() ); //snap nearly axial side planes snpd = false; for ( k = 0; k < 3; k++ ) { - if ( fabs(p[j][k]) < 0.00025 && p[j][k] != 0.0 ){ + if ( fabs( p[j].normal()[k] ) < 0.00025 && p[j].normal()[k] != 0.0 ){ //Sys_Printf( "init plane %6.8f %6.8f %6.8f %6.8f\n", p[j][0], p[j][1], p[j][2], p[j][3]); - p[j][k] = 0.0; + p[j].normal()[k] = 0.0; snpd = true; } } if ( snpd ){ - VectorNormalize( p[j], p[j] ); + VectorNormalize( p[j].normal() ); //Sys_Printf( "nrm plane %6.8f %6.8f %6.8f %6.8f\n", p[j][0], p[j][1], p[j][2], p[j][3]); - VectorAdd( points[j], points[(j+1)%3], cnt ); - VectorScale( cnt, 0.5f, cnt ); - p[j][3] = DotProduct( cnt, p[j] ); + cnt = ( points[j] + points[(j+1)%3] ) / 2.0; + p[j].dist() = vector3_dot( cnt, p[j].normal() ); //Sys_Printf( "dst plane %6.8f %6.8f %6.8f %6.8f\n", p[j][0], p[j][1], p[j][2], p[j][3]); } } /* make back plane */ - VectorScale( plane, -1.0f, reverse ); - reverse[ 3 ] = -plane[ 3 ]; - reverse[3] += clipDepth; + reverse = plane3_flipped( plane ); + reverse.dist() += clipDepth; #if nonax_clip_dbg for ( j = 0; j < 3; j++ ) { @@ -1165,25 +1103,23 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works } } - VectorCopy( points[0], points[3] ); // for cyclic usage + points[3] = points[0]; // for cyclic usage - buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points ); - buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1] - buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2] - buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3] - buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, reverse[ 3 ], 0, NULL ); + buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points ); + buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1] + buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2] + buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3] + buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL ); } else if ( spf == 256 ){ //PYRAMIDAL_CLIP /* calculate center */ - VectorAdd( points[ 0 ], points[ 1 ], cnt ); - VectorAdd( cnt, points[ 2 ], cnt ); - VectorScale( cnt, 0.3333333333333f, cnt ); + cnt = ( points[0] + points[1] + points[2] ) / 3.0; /* make back pyramid point */ - VectorMA( cnt, -clipDepth, plane, cnt ); + cnt -= plane.normal() * clipDepth; /* make 3 more planes */ if( PlaneFromPoints( p[0], points[ 2 ], points[ 1 ], cnt ) && @@ -1191,16 +1127,16 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const PlaneFromPoints( p[2], points[ 0 ], points[ 2 ], cnt ) ) { //check for dangerous planes - while( (( p[0][0] != 0.0 || p[0][1] != 0.0 ) && fabs(p[0][0]) < 0.00025 && fabs(p[0][1]) < 0.00025) || - (( p[0][0] != 0.0 || p[0][2] != 0.0 ) && fabs(p[0][0]) < 0.00025 && fabs(p[0][2]) < 0.00025) || - (( p[0][2] != 0.0 || p[0][1] != 0.0 ) && fabs(p[0][2]) < 0.00025 && fabs(p[0][1]) < 0.00025) || - (( p[1][0] != 0.0 || p[1][1] != 0.0 ) && fabs(p[1][0]) < 0.00025 && fabs(p[1][1]) < 0.00025) || - (( p[1][0] != 0.0 || p[1][2] != 0.0 ) && fabs(p[1][0]) < 0.00025 && fabs(p[1][2]) < 0.00025) || - (( p[1][2] != 0.0 || p[1][1] != 0.0 ) && fabs(p[1][2]) < 0.00025 && fabs(p[1][1]) < 0.00025) || - (( p[2][0] != 0.0 || p[2][1] != 0.0 ) && fabs(p[2][0]) < 0.00025 && fabs(p[2][1]) < 0.00025) || - (( p[2][0] != 0.0 || p[2][2] != 0.0 ) && fabs(p[2][0]) < 0.00025 && fabs(p[2][2]) < 0.00025) || - (( p[2][2] != 0.0 || p[2][1] != 0.0 ) && fabs(p[2][2]) < 0.00025 && fabs(p[2][1]) < 0.00025) ) { - VectorMA( cnt, -0.1f, plane, cnt ); + while( (( p[0].a != 0.0 || p[0].b != 0.0 ) && fabs( p[0].a ) < 0.00025 && fabs( p[0].b ) < 0.00025) || + (( p[0].a != 0.0 || p[0].c != 0.0 ) && fabs( p[0].a ) < 0.00025 && fabs( p[0].c ) < 0.00025) || + (( p[0].c != 0.0 || p[0].b != 0.0 ) && fabs( p[0].c ) < 0.00025 && fabs( p[0].b ) < 0.00025) || + (( p[1].a != 0.0 || p[1].b != 0.0 ) && fabs( p[1].a ) < 0.00025 && fabs( p[1].b ) < 0.00025) || + (( p[1].a != 0.0 || p[1].c != 0.0 ) && fabs( p[1].a ) < 0.00025 && fabs( p[1].c ) < 0.00025) || + (( p[1].c != 0.0 || p[1].b != 0.0 ) && fabs( p[1].c ) < 0.00025 && fabs( p[1].b ) < 0.00025) || + (( p[2].a != 0.0 || p[2].b != 0.0 ) && fabs( p[2].a ) < 0.00025 && fabs( p[2].b ) < 0.00025) || + (( p[2].a != 0.0 || p[2].c != 0.0 ) && fabs( p[2].a ) < 0.00025 && fabs( p[2].c ) < 0.00025) || + (( p[2].c != 0.0 || p[2].b != 0.0 ) && fabs( p[2].c ) < 0.00025 && fabs( p[2].b ) < 0.00025) ) { + cnt -= plane.normal() * 0.1f; // Sys_Printf( "shifting pyramid point\n" ); PlaneFromPoints( p[0], points[ 2 ], points[ 1 ], cnt ); PlaneFromPoints( p[1], points[ 1 ], points[ 0 ], cnt ); @@ -1230,16 +1166,17 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works } } - VectorCopy( points[0], points[3] ); // for cyclic usage + points[3] = points[0]; // for cyclic usage - buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points ); - buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 1 ] ); // p[0] contains points[1] and points[2] - buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 0 ] ); // p[1] contains points[0] and points[1] - buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3] + buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points ); + buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 1 ] ); // p[0] contains points[1] and points[2] + buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 0 ] ); // p[1] contains points[0] and points[1] + buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3] } else { - Sys_Warning( "triangle (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) of %s was not autoclipped\n", points[0][0], points[0][1], points[0][2], points[1][0], points[1][1], points[1][2], points[2][0], points[2][1], points[2][2], name ); + Sys_Warning( "triangle (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) of %s was not autoclipped\n", + points[0][0], points[0][1], points[0][2], points[1][0], points[1][1], points[1][2], points[2][0], points[2][1], points[2][2], name ); free( buildBrush ); continue; } @@ -1250,7 +1187,7 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const default_CLIPMODEL: // axial normal - VectorCopy( plane, bestNormal ); + bestNormal = plane.normal(); for ( j = 0; j < 3; j++ ){ if ( fabs(bestNormal[j]) > fabs(bestNormal[(j+1)%3]) ){ bestNormal[(j+1)%3] = 0.0; @@ -1259,21 +1196,18 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const bestNormal[j] = 0.0; } } - VectorNormalize( bestNormal, bestNormal ); + VectorNormalize( bestNormal ); /* make side planes */ for ( j = 0; j < 3; j++ ) { - VectorSubtract( points[(j+1)%3], points[ j ], nrm ); - CrossProduct( bestNormal, nrm, p[ j ] ); - VectorNormalize( p[ j ], p[ j ] ); - p[j][3] = DotProduct( points[j], p[j] ); + p[j].normal() = VectorNormalized( vector3_cross( bestNormal, points[(j+1)%3] - points[j] ) ); + p[j].dist() = vector3_dot( points[j], p[j].normal() ); } /* make back plane */ - VectorScale( plane, -1.0f, reverse ); - reverse[ 3 ] = -plane[ 3 ]; - reverse[3] += DotProduct( bestNormal, plane ) * clipDepth; + reverse = plane3_flipped( plane ); + reverse.dist() += vector3_dot( bestNormal, plane.normal() ) * clipDepth; #if nonax_clip_dbg for ( j = 0; j < 3; j++ ) { @@ -1298,13 +1232,13 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works } } - VectorCopy( points[0], points[3] ); // for cyclic usage + points[3] = points[0]; // for cyclic usage - buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points ); - buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1] - buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2] - buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3] - buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, reverse[ 3 ], 0, NULL ); + buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points ); + buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1] + buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2] + buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3] + buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL ); } @@ -1317,7 +1251,8 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const entities[ mapEntityNum ].numBrushes++; } else{ - Sys_Warning( "triangle (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) of %s was not autoclipped\n", points[0][0], points[0][1], points[0][2], points[1][0], points[1][1], points[1][2], points[2][0], points[2][1], points[2][2], name ); + Sys_Warning( "triangle (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) of %s was not autoclipped\n", + points[0][0], points[0][1], points[0][2], points[1][0], points[1][1], points[1][2], points[2][0], points[2][1], points[2][2], name ); free( buildBrush ); } } @@ -1395,27 +1330,26 @@ void AddTriangleModels( entity_t *eparent ){ const int spawnFlags = e->intForKey( "spawnflags" ); /* get origin */ - vec3_t origin; + Vector3 origin; e->vectorForKey( "origin", origin ); - VectorSubtract( origin, eparent->origin, origin ); /* offset by parent */ + origin -= eparent->origin; /* offset by parent */ /* get scale */ - vec3_t scale = { 1.f, 1.f, 1.f }; + Vector3 scale( 1, 1, 1 ); if( !e->read_keyvalue( scale, "modelscale_vec" ) ) if( e->read_keyvalue( scale[0], "modelscale" ) ) scale[1] = scale[2] = scale[0]; /* get "angle" (yaw) or "angles" (pitch yaw roll), store as (roll pitch yaw) */ const char *value; - vec3_t angles = { 0.f, 0.f, 0.f }; + Vector3 angles( 0, 0, 0 ); if ( !e->read_keyvalue( value, "angles" ) || 3 != sscanf( value, "%f %f %f", &angles[ 1 ], &angles[ 2 ], &angles[ 0 ] ) ) e->read_keyvalue( angles[ 2 ], "angle" ); /* set transform matrix (thanks spog) */ - m4x4_t transform; - m4x4_identity( transform ); - m4x4_pivoted_transform_by_vec3( transform, origin, angles, eXYZ, scale, vec3_origin ); + Matrix4 transform( g_matrix4_identity ); + matrix4_transform_by_euler_xyz_degrees( transform, origin, angles, scale ); /* get shader remappings */ std::list remaps; diff --git a/tools/quake3/q3map2/patch.cpp b/tools/quake3/q3map2/patch.cpp index 96f14910..9070a189 100644 --- a/tools/quake3/q3map2/patch.cpp +++ b/tools/quake3/q3map2/patch.cpp @@ -40,51 +40,49 @@ #define APPROX_SUBDIVISION 8 -static void ExpandLongestCurve( float *longestCurve, vec3_t a, vec3_t b, vec3_t c ){ +static void ExpandLongestCurve( float *longestCurve, const Vector3& a, const Vector3& b, const Vector3& c ){ int i; float t, len; - vec3_t ab, bc, ac, pt, last, delta; + Vector3 ab, bc, ac, pt, last, delta; /* calc vectors */ - VectorSubtract( b, a, ab ); - if ( VectorNormalize( ab, ab ) < 0.125f ) { + ab = b - a; + if ( VectorNormalize( ab ) < 0.125f ) { return; } - VectorSubtract( c, b, bc ); - if ( VectorNormalize( bc, bc ) < 0.125f ) { + bc = c - b; + if ( VectorNormalize( bc ) < 0.125f ) { return; } - VectorSubtract( c, a, ac ); - if ( VectorNormalize( ac, ac ) < 0.125f ) { + ac = c - a; + if ( VectorNormalize( ac ) < 0.125f ) { return; } /* if all 3 vectors are the same direction, then this edge is linear, so we ignore it */ - if ( DotProduct( ab, bc ) > 0.99f && DotProduct( ab, ac ) > 0.99f ) { + if ( vector3_dot( ab, bc ) > 0.99f && vector3_dot( ab, ac ) > 0.99f ) { return; } /* recalculate vectors */ - VectorSubtract( b, a, ab ); - VectorSubtract( c, b, bc ); + ab = b - a; + bc = c - b; /* determine length */ - VectorCopy( a, last ); + last = a; for ( i = 0, len = 0.0f, t = 0.0f; i < APPROX_SUBDIVISION; i++, t += ( 1.0f / APPROX_SUBDIVISION ) ) { /* calculate delta */ - delta[ 0 ] = ( ( 1.0f - t ) * ab[ 0 ] ) + ( t * bc[ 0 ] ); - delta[ 1 ] = ( ( 1.0f - t ) * ab[ 1 ] ) + ( t * bc[ 1 ] ); - delta[ 2 ] = ( ( 1.0f - t ) * ab[ 2 ] ) + ( t * bc[ 2 ] ); + delta = ab * ( 1.0f - t ) + bc * t; /* add to first point and calculate pt-pt delta */ - VectorAdd( a, delta, pt ); - VectorSubtract( pt, last, delta ); + pt = a + delta; + delta = pt - last; /* add it to length and store last point */ - len += VectorLength( delta ); - VectorCopy( pt, last ); + len += vector3_length( delta ); + last = pt; } /* longer? */ @@ -100,19 +98,18 @@ static void ExpandLongestCurve( float *longestCurve, vec3_t a, vec3_t b, vec3_t determines how many iterations a quadratic curve needs to be subdivided with to fit the specified error */ -static void ExpandMaxIterations( int *maxIterations, int maxError, vec3_t a, vec3_t b, vec3_t c ){ +static void ExpandMaxIterations( int *maxIterations, int maxError, const Vector3& a, const Vector3& b, const Vector3& c ){ int i, j; - vec3_t prev, next, mid, delta, delta2; - float len, len2; + Vector3 prev, next, mid; int numPoints, iterations; - vec3_t points[ MAX_EXPANDED_AXIS ]; + Vector3 points[ MAX_EXPANDED_AXIS ]; /* initial setup */ numPoints = 3; - VectorCopy( a, points[ 0 ] ); - VectorCopy( b, points[ 1 ] ); - VectorCopy( c, points[ 2 ] ); + points[ 0 ] = a; + points[ 1 ] = b; + points[ 2 ] = c; /* subdivide */ for ( i = 0; i + 2 < numPoints; i += 2 ) @@ -123,17 +120,12 @@ static void ExpandMaxIterations( int *maxIterations, int maxError, vec3_t a, vec } /* calculate new curve deltas */ - for ( j = 0; j < 3; j++ ) - { - prev[ j ] = points[ i + 1 ][ j ] - points[ i ][ j ]; - next[ j ] = points[ i + 2 ][ j ] - points[ i + 1 ][ j ]; - mid[ j ] = ( points[ i ][ j ] + points[ i + 1 ][ j ] * 2.0f + points[ i + 2 ][ j ] ) * 0.25f; - } + prev = points[ i + 1 ] - points[ i ]; + next = points[ i + 2 ] - points[ i + 1 ]; + mid = ( points[ i ] + points[ i + 1 ] * 2.0f + points[ i + 2 ] ) * 0.25f; /* see if this midpoint is off far enough to subdivide */ - VectorSubtract( points[ i + 1 ], mid, delta ); - len = VectorLength( delta ); - if ( len < maxError ) { + if ( vector3_length( points[ i + 1 ] - mid ) < maxError ) { continue; } @@ -141,21 +133,18 @@ static void ExpandMaxIterations( int *maxIterations, int maxError, vec3_t a, vec numPoints += 2; /* create new points */ - for ( j = 0; j < 3; j++ ) - { - prev[ j ] = 0.5f * ( points[ i ][ j ] + points[ i + 1 ][ j ] ); - next[ j ] = 0.5f * ( points[ i + 1 ][ j ] + points[ i + 2 ][ j ] ); - mid[ j ] = 0.5f * ( prev[ j ] + next[ j ] ); - } + prev = ( points[ i ] + points[ i + 1 ] ) * 0.5f; + next = ( points[ i + 1 ] + points[ i + 2 ] ) * 0.5f; + mid = ( prev + next ) * 0.5f; /* push points out */ for ( j = numPoints - 1; j > i + 3; j-- ) - VectorCopy( points[ j - 2 ], points[ j ] ); + points[ j ] = points[ j - 2 ]; /* insert new points */ - VectorCopy( prev, points[ i + 1 ] ); - VectorCopy( mid, points[ i + 2 ] ); - VectorCopy( next, points[ i + 3 ] ); + points[ i + 1 ] = prev; + points[ i + 2 ] = mid; + points[ i + 3 ] = next; /* back up and recheck this set again, it may need more subdivision */ i -= 2; @@ -164,27 +153,24 @@ static void ExpandMaxIterations( int *maxIterations, int maxError, vec3_t a, vec /* put the line on the curve */ for ( i = 1; i < numPoints; i += 2 ) { - for ( j = 0; j < 3; j++ ) - { - prev[ j ] = 0.5f * ( points[ i ][ j ] + points[ i + 1 ][ j ] ); - next[ j ] = 0.5f * ( points[ i ][ j ] + points[ i - 1 ][ j ] ); - points[ i ][ j ] = 0.5f * ( prev[ j ] + next[ j ] ); - } + prev = ( points[ i ] + points[ i + 1 ] ) * 0.5f; + next = ( points[ i ] + points[ i - 1 ] ) * 0.5f; + points[ i ] = ( prev + next ) * 0.5f; } /* eliminate linear sections */ for ( i = 0; i + 2 < numPoints; i++ ) { /* create vectors */ - VectorSubtract( points[ i + 1 ], points[ i ], delta ); - len = VectorNormalize( delta, delta ); - VectorSubtract( points[ i + 2 ], points[ i + 1 ], delta2 ); - len2 = VectorNormalize( delta2, delta2 ); + Vector3 delta = points[ i + 1 ] - points[ i ]; + const float len = VectorNormalize( delta ); + Vector3 delta2 = points[ i + 2 ] - points[ i + 1 ]; + const float len2 = VectorNormalize( delta2 ); /* if either edge is degenerate, then eliminate it */ - if ( len < 0.0625f || len2 < 0.0625f || DotProduct( delta, delta2 ) >= 1.0f ) { + if ( len < 0.0625f || len2 < 0.0625f || vector3_dot( delta, delta2 ) >= 1.0f ) { for ( j = i + 1; j + 1 < numPoints; j++ ) - VectorCopy( points[ j + 1 ], points[ j ] ); + points[ j ] = points[ j + 1 ]; numPoints--; continue; } @@ -213,12 +199,11 @@ static void ExpandMaxIterations( int *maxIterations, int maxError, vec3_t a, vec */ void ParsePatch( bool onlyLights ){ - vec_t info[ 5 ]; + float info[ 5 ]; int i, j, k; parseMesh_t *pm; mesh_t m; bspDrawVert_t *verts; - vec4_t delta, delta2, delta3; bool degenerate; float longestCurve; int maxIterations; @@ -244,15 +229,12 @@ void ParsePatch( bool onlyLights ){ MatchToken( "(" ); for ( i = 0; i < m.height ; i++ ) { - Parse1DMatrix( 5, verts[ i * m.width + j ].xyz ); + Parse1DMatrix( 5, verts[ i * m.width + j ].xyz.data() ); /* ydnar: fix colors */ for ( k = 0; k < MAX_LIGHTMAPS; k++ ) { - verts[ i * m.width + j ].color[ k ][ 0 ] = 255; - verts[ i * m.width + j ].color[ k ][ 1 ] = 255; - verts[ i * m.width + j ].color[ k ][ 2 ] = 255; - verts[ i * m.width + j ].color[ k ][ 3 ] = 255; + verts[ i * m.width + j ].color[ k ].set( 255 ); } } MatchToken( ")" ); @@ -280,15 +262,14 @@ void ParsePatch( bool onlyLights ){ /* ydnar: delete and warn about degenerate patches */ j = ( m.width * m.height ); - VectorClear( delta ); - delta[ 3 ] = 0; + Vector4 delta( 0, 0, 0, 0 ); degenerate = true; /* find first valid vector */ for ( i = 1; i < j && delta[ 3 ] == 0; i++ ) { - VectorSubtract( m.verts[ 0 ].xyz, m.verts[ i ].xyz, delta ); - delta[ 3 ] = VectorNormalize( delta, delta ); + delta.vec3() = m.verts[ 0 ].xyz - m.verts[ i ].xyz; + delta[ 3 ] = VectorNormalize( delta.vec3() ); } /* secondary degenerate test */ @@ -300,16 +281,15 @@ void ParsePatch( bool onlyLights ){ /* if all vectors match this or are zero, then this is a degenerate patch */ for ( i = 1; i < j && degenerate; i++ ) { - VectorSubtract( m.verts[ 0 ].xyz, m.verts[ i ].xyz, delta2 ); - delta2[ 3 ] = VectorNormalize( delta2, delta2 ); + Vector4 delta2( m.verts[ 0 ].xyz - m.verts[ i ].xyz, 0 ); + delta2[ 3 ] = VectorNormalize( delta2.vec3() ); if ( delta2[ 3 ] != 0 ) { /* create inverse vector */ - VectorCopy( delta2, delta3 ); - delta3[ 3 ] = delta2[ 3 ]; - VectorInverse( delta3 ); + Vector4 delta3( delta2 ); + vector3_negate( delta3.vec3() ); /* compare */ - if ( !VectorCompare( delta, delta2 ) && !VectorCompare( delta, delta3 ) ) { + if ( !VectorCompare( delta.vec3(), delta2.vec3() ) && !VectorCompare( delta.vec3(), delta3.vec3() ) ) { degenerate = false; } } @@ -413,7 +393,7 @@ void PatchMapDrawSurfs( entity_t *e ){ mapDrawSurface_t *ds; int patchCount, groupCount; bspDrawVert_t *v1, *v2; - vec3_t bounds[ 2 ]; + MinMax bounds; byte *bordering; parseMesh_t *meshes[ MAX_MAP_DRAW_SURFS ]; @@ -491,7 +471,8 @@ void PatchMapDrawSurfs( entity_t *e ){ GrowGroup_r( scan, i, patchCount, meshes, bordering, group ); /* bound them */ - ClearBounds( bounds[ 0 ], bounds[ 1 ] ); + + bounds.clear(); for ( j = 0; j < patchCount; j++ ) { if ( group[ j ] ) { @@ -500,7 +481,7 @@ void PatchMapDrawSurfs( entity_t *e ){ c1 = check->mesh.width * check->mesh.height; v1 = check->mesh.verts; for ( k = 0; k < c1; k++, v1++ ) - AddPointToBounds( v1->xyz, bounds[ 0 ], bounds[ 1 ] ); + bounds.extend( v1->xyz ); } } @@ -510,8 +491,7 @@ void PatchMapDrawSurfs( entity_t *e ){ /* create drawsurf */ scan->grouped = true; ds = DrawSurfaceForMesh( e, scan, NULL ); /* ydnar */ - VectorCopy( bounds[ 0 ], ds->bounds[ 0 ] ); - VectorCopy( bounds[ 1 ], ds->bounds[ 1 ] ); + ds->bounds = bounds; } /* emit some statistics */ diff --git a/tools/quake3/q3map2/portals.cpp b/tools/quake3/q3map2/portals.cpp index b031b7a1..f2edb85e 100644 --- a/tools/quake3/q3map2/portals.cpp +++ b/tools/quake3/q3map2/portals.cpp @@ -175,10 +175,10 @@ void PrintPortal( portal_t *p ){ */ #define SIDESPACE 8 void MakeHeadnodePortals( tree_t *tree ){ - vec3_t bounds[2]; + Vector3 bounds[2]; int i, j, n; portal_t *p, *portals[6]; - plane_t bplanes[6], *pl; + plane_t bplanes[6]; node_t *node; node = tree->headnode; @@ -186,8 +186,8 @@ void MakeHeadnodePortals( tree_t *tree ){ // pad with some space so there will never be null volume leafs for ( i = 0 ; i < 3 ; i++ ) { - bounds[0][i] = tree->mins[i] - SIDESPACE; - bounds[1][i] = tree->maxs[i] + SIDESPACE; + bounds[0][i] = tree->minmax.mins[i] - SIDESPACE; + bounds[1][i] = tree->minmax.maxs[i] + SIDESPACE; if ( bounds[0][i] >= bounds[1][i] ) { Error( "Backwards tree volume" ); } @@ -206,19 +206,19 @@ void MakeHeadnodePortals( tree_t *tree ){ p = AllocPortal(); portals[n] = p; - pl = &bplanes[n]; + plane_t *pl = &bplanes[n]; memset( pl, 0, sizeof( *pl ) ); if ( j ) { - pl->normal[i] = -1; - pl->dist = -bounds[j][i]; + pl->normal()[i] = -1; + pl->dist() = -bounds[j][i]; } else { - pl->normal[i] = 1; - pl->dist = bounds[j][i]; + pl->normal()[i] = 1; + pl->dist() = bounds[j][i]; } p->plane = *pl; - p->winding = BaseWindingForPlane( pl->normal, pl->dist ); + p->winding = BaseWindingForPlane( pl->plane ); AddPortalToNodes( p, node, &tree->outside_node ); } @@ -230,7 +230,7 @@ void MakeHeadnodePortals( tree_t *tree ){ if ( j == i ) { continue; } - ChopWindingInPlace( &portals[i]->winding, bplanes[j].normal, bplanes[j].dist, ON_EPSILON ); + ChopWindingInPlace( &portals[i]->winding, bplanes[j].plane, ON_EPSILON ); } } } @@ -249,26 +249,20 @@ void MakeHeadnodePortals( tree_t *tree ){ winding_t *BaseWindingForNode( node_t *node ){ winding_t *w; node_t *n; - plane_t *plane; - vec3_t normal; - vec_t dist; - w = BaseWindingForPlane( mapplanes[node->planenum].normal - , mapplanes[node->planenum].dist ); + w = BaseWindingForPlane( mapplanes[node->planenum].plane ); // clip by all the parents for ( n = node->parent ; n && w ; ) { - plane = &mapplanes[n->planenum]; + const plane_t& plane = mapplanes[n->planenum]; if ( n->children[0] == node ) { // take front - ChopWindingInPlace( &w, plane->normal, plane->dist, BASE_WINDING_EPSILON ); + ChopWindingInPlace( &w, plane.plane, BASE_WINDING_EPSILON ); } else { // take back - VectorSubtract( vec3_origin, plane->normal, normal ); - dist = -plane->dist; - ChopWindingInPlace( &w, normal, dist, BASE_WINDING_EPSILON ); + ChopWindingInPlace( &w, plane3_flipped( plane.plane ), BASE_WINDING_EPSILON ); } node = n; n = n->parent; @@ -290,8 +284,6 @@ winding_t *BaseWindingForNode( node_t *node ){ void MakeNodePortal( node_t *node ){ portal_t *new_portal, *p; winding_t *w; - vec3_t normal; - float dist; int side; w = BaseWindingForNode( node ); @@ -301,19 +293,16 @@ void MakeNodePortal( node_t *node ){ { if ( p->nodes[0] == node ) { side = 0; - VectorCopy( p->plane.normal, normal ); - dist = p->plane.dist; + ChopWindingInPlace( &w, p->plane.plane, CLIP_EPSILON ); } else if ( p->nodes[1] == node ) { side = 1; - VectorSubtract( vec3_origin, p->plane.normal, normal ); - dist = -p->plane.dist; + ChopWindingInPlace( &w, plane3_flipped( p->plane.plane ), CLIP_EPSILON ); } else{ Error( "CutNodePortals_r: mislinked portal" ); } - ChopWindingInPlace( &w, normal, dist, CLIP_EPSILON ); } if ( !w ) { @@ -357,10 +346,9 @@ void SplitNodePortals( node_t *node ){ portal_t *p, *next_portal, *new_portal; node_t *f, *b, *other_node; int side; - plane_t *plane; winding_t *frontwinding, *backwinding; - plane = &mapplanes[node->planenum]; + const plane_t& plane = mapplanes[node->planenum]; f = node->children[0]; b = node->children[1]; @@ -384,16 +372,16 @@ void SplitNodePortals( node_t *node ){ // // cut the portal into two portals, one on each side of the cut plane // - ClipWindingEpsilon( p->winding, plane->normal, plane->dist, + ClipWindingEpsilon( p->winding, plane.plane, SPLIT_WINDING_EPSILON, &frontwinding, &backwinding ); /* not strict, we want to always keep one of them even if coplanar */ if ( frontwinding && WindingIsTiny( frontwinding ) ) { if ( !f->tinyportals ) { - VectorCopy( frontwinding->p[0], f->referencepoint ); + f->referencepoint = frontwinding->p[0]; } f->tinyportals++; if ( !other_node->tinyportals ) { - VectorCopy( frontwinding->p[0], other_node->referencepoint ); + other_node->referencepoint = frontwinding->p[0]; } other_node->tinyportals++; @@ -404,11 +392,11 @@ void SplitNodePortals( node_t *node ){ if ( backwinding && WindingIsTiny( backwinding ) ) { if ( !b->tinyportals ) { - VectorCopy( backwinding->p[0], b->referencepoint ); + b->referencepoint = backwinding->p[0]; } b->tinyportals++; if ( !other_node->tinyportals ) { - VectorCopy( backwinding->p[0], other_node->referencepoint ); + other_node->referencepoint = backwinding->p[0]; } other_node->tinyportals++; @@ -475,12 +463,12 @@ void CalcNodeBounds( node_t *node ){ int i; // calc mins/maxs for both leafs and nodes - ClearBounds( node->mins, node->maxs ); + node->minmax.clear(); for ( p = node->portals ; p ; p = p->next[s] ) { s = ( p->nodes[1] == node ); for ( i = 0 ; i < p->winding->numpoints ; i++ ) - AddPointToBounds( p->winding->p[i], node->mins, node->maxs ); + node->minmax.extend( p->winding->p[i] ); } } @@ -493,7 +481,7 @@ void MakeTreePortals_r( node_t *node ){ int i; CalcNodeBounds( node ); - if ( node->mins[0] >= node->maxs[0] ) { + if ( node->minmax.mins[0] >= node->minmax.maxs[0] ) { Sys_Warning( "node without a volume\n" "node has %d tiny portals\n" "node reference point %1.2f %1.2f %1.2f\n", @@ -505,7 +493,7 @@ void MakeTreePortals_r( node_t *node ){ for ( i = 0 ; i < 3 ; i++ ) { - if ( node->mins[i] < MIN_WORLD_COORD || node->maxs[i] > MAX_WORLD_COORD ) { + if ( node->minmax.mins[i] < MIN_WORLD_COORD || node->minmax.maxs[i] > MAX_WORLD_COORD ) { if ( node->portals && node->portals->winding ) { xml_Winding( "WARNING: Node With Unbounded Volume", node->portals->winding->p, node->portals->winding->numpoints, false ); } @@ -587,19 +575,14 @@ void FloodPortals( node_t *node, bool skybox ){ ============= */ -bool PlaceOccupant( node_t *headnode, vec3_t origin, const entity_t *occupant, bool skybox ){ - vec_t d; +bool PlaceOccupant( node_t *headnode, const Vector3& origin, const entity_t *occupant, bool skybox ){ node_t *node; - plane_t *plane; - // find the leaf to start in node = headnode; while ( node->planenum != PLANENUM_LEAF ) { - plane = &mapplanes[ node->planenum ]; - d = DotProduct( origin, plane->normal ) - plane->dist; - if ( d >= 0 ) { + if ( plane3_distance_to_point( mapplanes[ node->planenum ].plane, origin ) >= 0 ) { node = node->children[ 0 ]; } else{ @@ -644,11 +627,11 @@ EFloodEntities FloodEntities( tree_t *tree ){ const entity_t& e = entities[ i ]; /* get origin */ - vec3_t origin; + Vector3 origin; e.vectorForKey( "origin", origin ); #if 0 // 0 = allow maps with only point entity@( 0, 0, 0 ); assuming that entities, containing no primitives are point ones /* as a special case, allow origin-less entities */ - if ( VectorCompare( origin, vec3_origin ) ) { + if ( VectorCompare( origin, g_vector3_identity ) ) { continue; } #endif @@ -661,25 +644,21 @@ EFloodEntities FloodEntities( tree_t *tree ){ if ( e.classname_is( "_skybox" ) ) { skybox = true; - /* invert origin */ - vec3_t offset; - VectorScale( origin, -1.0f, offset ); - /* get scale */ - vec3_t scale = { 64.0f, 64.0f, 64.0f }; + Vector3 scale( 64, 64, 64 ); if( !e.read_keyvalue( scale, "_scale" ) ) if( e.read_keyvalue( scale[0], "_scale" ) ) scale[1] = scale[2] = scale[0]; /* get "angle" (yaw) or "angles" (pitch yaw roll), store as (roll pitch yaw) */ - vec3_t angles = { 0.f, 0.f, 0.f }; + Vector3 angles( 0, 0, 0 ); if ( !e.read_keyvalue( value, "angles" ) || 3 != sscanf( value, "%f %f %f", &angles[ 1 ], &angles[ 2 ], &angles[ 0 ] ) ) e.read_keyvalue( angles[ 2 ], "angle" ); /* set transform matrix (thanks spog) */ - m4x4_identity( skyboxTransform ); - m4x4_pivoted_transform_by_vec3( skyboxTransform, offset, angles, eXYZ, scale, origin ); + skyboxTransform = g_matrix4_identity; + matrix4_pivoted_transform_by_euler_xyz_degrees( skyboxTransform, -origin, angles, scale, origin ); } else{ skybox = false; diff --git a/tools/quake3/q3map2/prtfile.cpp b/tools/quake3/q3map2/prtfile.cpp index dde87aba..bddc899a 100644 --- a/tools/quake3/q3map2/prtfile.cpp +++ b/tools/quake3/q3map2/prtfile.cpp @@ -50,9 +50,9 @@ int num_visclusters; // clusters the player can be in int num_visportals; int num_solidfaces; -void WriteFloat( FILE *f, vec_t v ){ - if ( fabs( v - Q_rint( v ) ) < 0.001 ) { - fprintf( f, "%i ", (int)Q_rint( v ) ); +void WriteFloat( FILE *f, float v ){ + if ( fabs( v - std::rint( v ) ) < 0.001 ) { + fprintf( f, "%li ", std::lrint( v ) ); } else{ fprintf( f, "%f ", v ); @@ -100,8 +100,6 @@ void WritePortalFile_r( node_t *node ){ int i, s, flags; portal_t *p; winding_t *w; - vec3_t normal; - vec_t dist; // decision node if ( node->planenum != PLANENUM_LEAF ) { @@ -132,9 +130,7 @@ void WritePortalFile_r( node_t *node ){ // the changeover point between different axis. interpret the // plane the same way vis will, and flip the side orders if needed // FIXME: is this still relevent? - WindingPlane( w, normal, &dist ); - - if ( DotProduct( p->plane.normal, normal ) < 0.99 ) { // backwards... + if ( vector3_dot( p->plane.normal(), WindingPlane( w ).normal() ) < 0.99 ) { // backwards... fprintf( pf, "%i %i %i ", w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster ); } else{ diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index d02eb93a..420c1819 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -69,7 +69,6 @@ #include "version.h" /* ttimo: might want to guard that if built outside of the GtkRadiant tree */ #include "cmdlib.h" -#include "mathlib.h" #include "md5lib.h" #include "ddslib.h" @@ -88,20 +87,12 @@ #include "stream/stringstream.h" #include "bitflags.h" #include +#include "qmath.h" #include #include - -/* ------------------------------------------------------------------------------- - - port-related hacks - - ------------------------------------------------------------------------------- */ - -/* macro version */ -#define VectorMA( a, s, b, c ) ( ( c )[ 0 ] = ( a )[ 0 ] + ( s ) * ( b )[ 0 ], ( c )[ 1 ] = ( a )[ 1 ] + ( s ) * ( b )[ 1 ], ( c )[ 2 ] = ( a )[ 2 ] + ( s ) * ( b )[ 2 ] ) - +#include "maxworld.h" /* ------------------------------------------------------------------------------- @@ -241,33 +232,8 @@ enum class EBrushType #define CLUSTER_OCCLUDED -2 #define CLUSTER_FLOODED -3 -#define VERTEX_LUXEL_SIZE 3 -#define BSP_LUXEL_SIZE 3 -#define RAD_LUXEL_SIZE 3 -#define SUPER_LUXEL_SIZE 4 -#define SUPER_FLAG_SIZE 4 #define FLAG_FORCE_SUBSAMPLING 1 #define FLAG_ALREADY_SUBSAMPLED 2 -#define SUPER_ORIGIN_SIZE 3 -#define SUPER_NORMAL_SIZE 4 -#define SUPER_DELUXEL_SIZE 3 -#define BSP_DELUXEL_SIZE 3 -#define SUPER_FLOODLIGHT_SIZE 4 - -#define VERTEX_LUXEL( s, v ) ( vertexLuxels[ s ] + ( ( v ) * VERTEX_LUXEL_SIZE ) ) -#define RAD_VERTEX_LUXEL( s, v )( radVertexLuxels[ s ] + ( ( v ) * VERTEX_LUXEL_SIZE ) ) -#define BSP_LUXEL( s, x, y ) ( lm->bspLuxels[ s ] + ( ( ( ( y ) * lm->w ) + ( x ) ) * BSP_LUXEL_SIZE ) ) -#define RAD_LUXEL( s, x, y ) ( lm->radLuxels[ s ] + ( ( ( ( y ) * lm->w ) + ( x ) ) * RAD_LUXEL_SIZE ) ) -#define SUPER_LUXEL( s, x, y ) ( lm->superLuxels[ s ] + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_LUXEL_SIZE ) ) -#define SUPER_FLAG( x, y ) ( lm->superFlags + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_FLAG_SIZE ) ) -#define SUPER_DELUXEL( x, y ) ( lm->superDeluxels + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_DELUXEL_SIZE ) ) -#define BSP_DELUXEL( x, y ) ( lm->bspDeluxels + ( ( ( ( y ) * lm->w ) + ( x ) ) * BSP_DELUXEL_SIZE ) ) -#define SUPER_CLUSTER( x, y ) ( lm->superClusters + ( ( ( y ) * lm->sw ) + ( x ) ) ) -#define SUPER_ORIGIN( x, y ) ( lm->superOrigins + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_ORIGIN_SIZE ) ) -#define SUPER_NORMAL( x, y ) ( lm->superNormals + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_NORMAL_SIZE ) ) -#define SUPER_DIRT( x, y ) ( lm->superNormals + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_NORMAL_SIZE ) + 3 ) /* stash dirtyness in normal[ 3 ] */ -#define SUPER_FLOODLIGHT( x, y ) ( lm->superFloodLight + ( ( ( ( y ) * lm->sw ) + ( x ) ) * SUPER_FLOODLIGHT_SIZE ) ) - /* ------------------------------------------------------------------------------- @@ -308,9 +274,8 @@ enum class EBrushType #define LIGHTMAP_WIDTH 128 #define LIGHTMAP_HEIGHT 128 -#define MIN_WORLD_COORD ( -65536 ) -#define MAX_WORLD_COORD ( 65536 ) -#define WORLD_SIZE ( MAX_WORLD_COORD - MIN_WORLD_COORD ) + +using Vector3b = BasicVector3; typedef void ( *bspFunc )( const char * ); @@ -333,7 +298,7 @@ struct bspHeader_t struct bspModel_t { - float mins[ 3 ], maxs[ 3 ]; + MinMax minmax; int firstBSPSurface, numBSPSurfaces; int firstBSPBrush, numBSPBrushes; }; @@ -349,19 +314,14 @@ struct bspShader_t /* planes x^1 is always the opposite of plane x */ -struct bspPlane_t -{ - float normal[ 3 ]; - float dist; -}; +using bspPlane_t = Plane3f; struct bspNode_t { int planeNum; int children[ 2 ]; /* negative numbers are -(leafs+1), not nodes */ - int mins[ 3 ]; /* for frustum culling */ - int maxs[ 3 ]; + MinMax___ minmax; /* for frustum culling */ }; @@ -370,8 +330,7 @@ struct bspLeaf_t int cluster; /* -1 = opaque cluster (do I still store these?) */ int area; - int mins[ 3 ]; /* for frustum culling */ - int maxs[ 3 ]; + MinMax___ minmax; /* for frustum culling */ int firstBSPLeafSurface; int numBSPLeafSurfaces; @@ -407,11 +366,11 @@ struct bspFog_t struct bspDrawVert_t { - vec3_t xyz; - float st[ 2 ]; - float lightmap[ MAX_LIGHTMAPS ][ 2 ]; /* RBSP */ - vec3_t normal; - byte color[ MAX_LIGHTMAPS ][ 4 ]; /* RBSP */ + Vector3 xyz; + Vector2 st; + Vector2 lightmap[ MAX_LIGHTMAPS ]; /* RBSP */ + Vector3 normal; + Color4b color[ MAX_LIGHTMAPS ]; /* RBSP */ }; @@ -428,8 +387,8 @@ enum bspSurfaceType_t struct bspGridPoint_t { - byte ambient[ MAX_LIGHTMAPS ][ 3 ]; - byte directed[ MAX_LIGHTMAPS ][ 3 ]; + Vector3b ambient[ MAX_LIGHTMAPS ]; + Vector3b directed[ MAX_LIGHTMAPS ]; byte styles[ MAX_LIGHTMAPS ]; byte latLong[ 2 ]; }; @@ -453,8 +412,8 @@ struct bspDrawSurface_t int lightmapX[ MAX_LIGHTMAPS ], lightmapY[ MAX_LIGHTMAPS ]; /* RBSP */ int lightmapWidth, lightmapHeight; - vec3_t lightmapOrigin; - vec3_t lightmapVecs[ 3 ]; /* on patches, [ 0 ] and [ 1 ] are lodbounds */ + Vector3 lightmapOrigin; + Vector3 lightmapVecs[ 3 ]; /* on patches, [ 0 ] and [ 1 ] are lodbounds */ int patchWidth; int patchHeight; @@ -465,8 +424,8 @@ struct bspDrawSurface_t struct bspAdvertisement_t { int cellId; - vec3_t normal; - vec3_t rect[4]; + Vector3 normal; + Vector3 rect[4]; char model[ MAX_QPATH ]; }; @@ -553,7 +512,7 @@ struct image_t struct sun_t { sun_t *next; - vec3_t direction, color; + Vector3 direction, color; float photons, deviance, filterRadius; int numSamples, style; }; @@ -579,7 +538,7 @@ struct foliage_t struct foliageInstance_t { - vec3_t xyz, normal; + Vector3 xyz, normal; }; @@ -613,7 +572,7 @@ struct colorMod_t { colorMod_t *next; EColorMod type; - vec_t data[ 16 ]; + float data[ 16 ]; }; @@ -657,7 +616,7 @@ struct shaderInfo_t float offset; /* ydnar: offset in units */ float shadeAngleDegrees; /* ydnar: breaking angle for smooth shading (degrees) */ - vec3_t mins, maxs; /* ydnar: for particle studio vertexDeform move support */ + MinMax minmax; /* ydnar: for particle studio vertexDeform move support */ bool legacyTerrain; /* ydnar: enable legacy terrain crutches */ bool indexed; /* ydnar: attempt to use indexmap (terrain alphamap style) */ @@ -667,9 +626,9 @@ struct shaderInfo_t bool invert; /* ydnar: reverse facing */ bool nonplanar; /* ydnar: for nonplanar meta surface merging */ bool tcGen; /* ydnar: has explicit texcoord generation */ - vec3_t vecs[ 2 ]; /* ydnar: explicit texture vectors for [0,1] texture space */ + Vector3 vecs[ 2 ]; /* ydnar: explicit texture vectors for [0,1] texture space */ tcMod_t mod; /* ydnar: q3map_tcMod matrix for djbob :) */ - vec3_t lightmapAxis; /* ydnar: explicit lightmap axis projection */ + Vector3 lightmapAxis; /* ydnar: explicit lightmap axis projection */ colorMod_t *colorMod; /* ydnar: q3map_rgb/color/alpha/Set/Mod support */ int furNumLayers; /* ydnar: number of fur layers */ @@ -714,13 +673,13 @@ struct shaderInfo_t int skyLightIterations; /* ydnar */ sun_t *sun; /* ydnar */ - vec3_t color; /* normalized color */ - vec4_t averageColor; + Vector3 color; /* normalized color */ + Color4f averageColor; byte lightStyle; /* vortex: per-surface floodlight */ float floodlightDirectionScale; - vec3_t floodlightRGB; + Vector3 floodlightRGB; float floodlightIntensity; float floodlightDistance; @@ -730,9 +689,9 @@ struct shaderInfo_t float lmFilterRadius; /* ydnar: lightmap filtering/blurring radius for this shader (default: 0) */ int shaderWidth, shaderHeight; /* ydnar */ - float stFlat[ 2 ]; + Vector2 stFlat; - vec3_t fogDir; /* ydnar */ + Vector3 fogDir; /* ydnar */ char *shaderText; /* ydnar */ bool custom; @@ -760,9 +719,20 @@ struct face_t struct plane_t { - vec3_t normal; - vec_t dist; - int type; + Plane3f plane; + Vector3& normal(){ + return plane.normal(); + } + const Vector3& normal() const { + return plane.normal(); + } + float& dist(){ + return plane.dist(); + } + const float& dist() const { + return plane.dist(); + } + EPlaneType type; int counter; int hash_chain; }; @@ -774,8 +744,8 @@ struct side_t int outputNum; /* set when the side is written to the file list */ - float texMat[ 2 ][ 3 ]; /* brush primitive texture matrix */ - float vecs[ 2 ][ 4 ]; /* old-style texture coordinate mapping */ + Vector3 texMat[ 2 ]; /* brush primitive texture matrix */ + Vector4 vecs[ 2 ]; /* old-style texture coordinate mapping */ winding_t *winding; winding_t *visibleHull; /* convex hull of all visible fragments */ @@ -830,7 +800,7 @@ struct brush_t int lightmapSampleSize; /* jal : entity based _lightmapsamplesize */ float lightmapScale; float shadeAngleDegrees; /* jal : entity based _shadeangle */ - vec3_t eMins, eMaxs; + MinMax eMinmax; indexMap_t *im; int contentFlags; @@ -840,7 +810,7 @@ struct brush_t int portalareas[ 2 ]; - vec3_t mins, maxs; + MinMax minmax; int numsides; side_t sides[]; /* variably sized */ @@ -879,7 +849,7 @@ struct parseMesh_t /* ydnar: gs mods */ int lightmapSampleSize; /* jal : entity based _lightmapsamplesize */ float lightmapScale; - vec3_t eMins, eMaxs; + MinMax eMinmax; indexMap_t *im; /* grouping */ @@ -963,8 +933,8 @@ struct mapDrawSurface_t int *indexes; int planeNum; - vec3_t lightmapOrigin; /* also used for flares */ - vec3_t lightmapVecs[ 3 ]; /* also used for flares */ + Vector3 lightmapOrigin; /* also used for flares */ + Vector3 lightmapVecs[ 3 ]; /* also used for flares */ int lightStyle; /* used for flares */ /* ydnar: per-surface (per-entity, actually) lightmap sample size scaling */ @@ -974,8 +944,8 @@ struct mapDrawSurface_t float shadeAngleDegrees; /* ydnar: surface classification */ - vec3_t mins, maxs; - vec3_t lightmapAxis; + MinMax minmax; + Vector3 lightmapAxis; int sampleSize; /* ydnar: shadow group support */ @@ -989,7 +959,7 @@ struct mapDrawSurface_t float longestCurve; int maxIterations; int patchWidth, patchHeight; - vec3_t bounds[ 2 ]; + MinMax bounds; /* ydnar/sd: for foliage */ int numFoliageInstances; @@ -1014,8 +984,8 @@ struct metaTriangle_t side_t *side; int entityNum, surfaceNum, planeNum, fogNum, sampleSize, castShadows, recvShadows; float shadeAngleDegrees; - vec4_t plane; - vec3_t lightmapAxis; + Plane3f plane; + Vector3 lightmapAxis; int indexes[ 3 ]; }; @@ -1028,13 +998,13 @@ struct epair_t struct entity_t { - vec3_t origin; + Vector3 origin; brush_t *brushes, *lastBrush, *colorModBrushes; parseMesh_t *patches; int mapEntityNum, firstDrawSurf; int firstBrush, numBrushes; /* only valid during BSP compile */ std::list epairs; - vec3_t originbrush_origin; + Vector3 originbrush_origin; void setKeyValue( const char *key, const char *value ); const char *valueForKey( const char *key ) const; @@ -1057,9 +1027,9 @@ struct entity_t read_keyvalue_( float_value, { keys ... } ); return float_value; } - void vectorForKey( const char *key, vec3_t& vec ) const { + void vectorForKey( const char *key, Vector3& vec ) const { if( !read_keyvalue_( vec, { key } ) ) - VectorClear( vec ); + vec.set( 0 ); } const char *classname() const { @@ -1083,7 +1053,7 @@ private: bool read_keyvalue_( bool &bool_value, std::initializer_list&& keys ) const; bool read_keyvalue_( int &int_value, std::initializer_list&& keys ) const; bool read_keyvalue_( float &float_value, std::initializer_list&& keys ) const; - bool read_keyvalue_( float (&vector3_value)[3], std::initializer_list&& keys ) const; + bool read_keyvalue_( Vector3& vector3_value, std::initializer_list&& keys ) const; bool read_keyvalue_( char (&string_value)[1024], std::initializer_list&& keys ) const; bool read_keyvalue_( const char *&string_ptr_value, std::initializer_list&& keys ) const; }; @@ -1094,7 +1064,7 @@ struct node_t /* both leafs and nodes */ int planenum; /* -1 = leaf node */ node_t *parent; - vec3_t mins, maxs; /* valid after portalization */ + MinMax minmax; /* valid after portalization */ brush_t *volume; /* one for each leaf/node */ /* nodes only */ @@ -1102,7 +1072,7 @@ struct node_t node_t *children[ 2 ]; int compileFlags; /* ydnar: hint, antiportal */ int tinyportals; - vec3_t referencepoint; + Vector3 referencepoint; /* leafs only */ bool opaque; /* view can never be inside */ @@ -1141,7 +1111,7 @@ struct tree_t { node_t *headnode; node_t outside_node; - vec3_t mins, maxs; + MinMax minmax; }; @@ -1152,17 +1122,13 @@ struct tree_t ------------------------------------------------------------------------------- */ -struct visPlane_t -{ - vec3_t normal; - float dist; -}; +using visPlane_t = Plane3f; struct fixedWinding_t { int numpoints; - vec3_t points[ MAX_POINTS_ON_FIXED_WINDING ]; /* variable sized */ + Vector3 points[ MAX_POINTS_ON_FIXED_WINDING ]; /* variable sized */ }; @@ -1190,7 +1156,7 @@ struct vportal_t visPlane_t plane; /* normal pointing into neighbor */ int leaf; /* neighbor */ - vec3_t origin; /* for fast clip testing */ + Vector3 origin; /* for fast clip testing */ float radius; fixedWinding_t *winding; @@ -1287,13 +1253,13 @@ struct light_t LightFlags flags; /* ydnar: condensed all the booleans into one flags int */ shaderInfo_t *si; - vec3_t origin; - vec3_t normal; /* for surfaces, spotlights, and suns */ + Vector3 origin; + Vector3 normal; /* for surfaces, spotlights, and suns */ float dist; /* plane location along normal */ float photons; int style; - vec3_t color; + Vector3 color; float radiusByDist; /* for spotlights */ float fade; /* ydnar: from wolf, for linear lights */ float angleScale; /* ydnar: stolen from vlight for K */ @@ -1302,11 +1268,11 @@ struct light_t float add; /* ydnar: used for area lights */ float envelope; /* ydnar: units until falloff < tolerance */ float envelope2; /* ydnar: envelope squared (tiny optimization) */ - vec3_t mins, maxs; /* ydnar: pvs envelope */ + MinMax minmax; /* ydnar: pvs envelope */ int cluster; /* ydnar: cluster light falls into */ winding_t *w; - vec3_t emitColor; /* full out-of-gamut value */ + Vector3 emitColor; /* full out-of-gamut value */ float falloffTolerance; /* ydnar: minimum attenuation threshold */ float filterRadius; /* ydnar: lightmap filter radius in world units, 0 == default */ @@ -1329,28 +1295,28 @@ struct trace_t /* per-sample input */ int cluster; - vec3_t origin, normal; - vec_t inhibitRadius; /* sphere in which occluding geometry is ignored */ + Vector3 origin, normal; + float inhibitRadius; /* sphere in which occluding geometry is ignored */ /* per-light input */ light_t *light; - vec3_t end; + Vector3 end; /* calculated input */ - vec3_t displacement, direction; - vec_t distance; + Vector3 displacement, direction; + float distance; /* input and output */ - vec3_t color; /* starts out at full color, may be reduced if transparent surfaces are crossed */ - vec3_t colorNoShadow; /* result color with no shadow casting */ - vec3_t directionContribution; /* result contribution to the deluxe map */ + Vector3 color; /* starts out at full color, may be reduced if transparent surfaces are crossed */ + Vector3 colorNoShadow; /* result color with no shadow casting */ + Vector3 directionContribution; /* result contribution to the deluxe map */ /* output */ - vec3_t hit; + Vector3 hit; int compileFlags; /* for determining surface compile flags traced through */ bool passSolid; bool opaque; - vec_t forceSubsampling; /* needs subsampling (alphashadow), value = max color contribution possible from it */ + float forceSubsampling; /* needs subsampling (alphashadow), value = max color contribution possible from it */ /* working data */ int numTestNodes; @@ -1358,15 +1324,14 @@ struct trace_t }; - /* must be identical to bspDrawVert_t except for float color! */ struct radVert_t { - vec3_t xyz; - float st[ 2 ]; - float lightmap[ MAX_LIGHTMAPS ][ 2 ]; - vec3_t normal; - float color[ MAX_LIGHTMAPS ][ 4 ]; + Vector3 xyz; + Vector2 st; + Vector2 lightmap[ MAX_LIGHTMAPS ]; + Vector3 normal; + Color4f color[ MAX_LIGHTMAPS ]; }; @@ -1380,8 +1345,8 @@ struct radWinding_t /* crutch for poor local allocations in win32 smp */ struct clipWork_t { - vec_t dists[ MAX_POINTS_ON_WINDING + 4 ]; - int sides[ MAX_POINTS_ON_WINDING + 4 ]; + float dists[ MAX_POINTS_ON_WINDING + 4 ]; + EPlaneSide sides[ MAX_POINTS_ON_WINDING + 4 ]; }; @@ -1395,10 +1360,19 @@ struct outLightmap_t int numShaders; shaderInfo_t *shaders[ MAX_LIGHTMAP_SHADERS ]; byte *lightBits; - byte *bspLightBytes; - byte *bspDirBytes; + Vector3b *bspLightBytes; + Vector3b *bspDirBytes; }; +struct SuperLuxel{ + Vector3 value; + float count; +}; + +struct SuperFloodLight{ + Vector3 value; + float scale; +}; struct rawLightmap_t { @@ -1414,18 +1388,19 @@ struct rawLightmap_t /* vortex: per-surface floodlight */ float floodlightDirectionScale; - vec3_t floodlightRGB; + Vector3 floodlightRGB; float floodlightIntensity; float floodlightDistance; int entityNum; int recvShadows; - vec3_t mins, maxs, axis, origin, *vecs; - float *plane; + MinMax minmax; + Vector3 axis, origin, *vecs; + Plane3f *plane; int w, h, sw, sh, used; bool solid[ MAX_LIGHTMAPS ]; - vec3_t solidColor[ MAX_LIGHTMAPS ]; + Vector3 solidColor[ MAX_LIGHTMAPS ]; int numStyledTwins; rawLightmap_t *twins[ MAX_LIGHTMAPS ]; @@ -1434,25 +1409,92 @@ struct rawLightmap_t int twinNums[ MAX_LIGHTMAPS ]; int lightmapX[ MAX_LIGHTMAPS ], lightmapY[ MAX_LIGHTMAPS ]; byte styles[ MAX_LIGHTMAPS ]; - float *bspLuxels[ MAX_LIGHTMAPS ]; - float *radLuxels[ MAX_LIGHTMAPS ]; - float *superLuxels[ MAX_LIGHTMAPS ]; - unsigned char *superFlags; - float *superOrigins; - float *superNormals; + Vector3 *bspLuxels[ MAX_LIGHTMAPS ]; + Vector3 *radLuxels[ MAX_LIGHTMAPS ]; + SuperLuxel *superLuxels[ MAX_LIGHTMAPS ]; + byte *superFlags; + Vector3 *superOrigins; + Vector3 *superNormals; + float *superDirt; int *superClusters; - float *superDeluxels; /* average light direction */ - float *bspDeluxels; - float *superFloodLight; + Vector3 *superDeluxels; /* average light direction */ + Vector3 *bspDeluxels; + SuperFloodLight *superFloodLight; + Vector3& getBspLuxel( int lightmapNum, int x, int y ){ + return bspLuxels[ lightmapNum ][y * w + x]; + } + const Vector3& getBspLuxel( int lightmapNum, int x, int y ) const { + return bspLuxels[ lightmapNum ][y * w + x]; + } + Vector3& getRadLuxel( int lightmapNum, int x, int y ){ + return radLuxels[ lightmapNum ][y * w + x]; + } + const Vector3& getRadLuxel( int lightmapNum, int x, int y ) const { + return radLuxels[ lightmapNum ][y * w + x]; + } + SuperLuxel& getSuperLuxel( int lightmapNum, int x, int y ){ + return superLuxels[ lightmapNum ][y * sw + x]; + } + const SuperLuxel& getSuperLuxel( int lightmapNum, int x, int y ) const { + return superLuxels[ lightmapNum ][y * sw + x]; + } + const byte& getSuperFlag( int x, int y ) const { + return superFlags[y * sw + x]; + } + byte& getSuperFlag( int x, int y ){ + return superFlags[y * sw + x]; + } + Vector3& getSuperOrigin( int x, int y ){ + return superOrigins[y * sw + x]; + } + const Vector3& getSuperOrigin( int x, int y ) const { + return superOrigins[y * sw + x]; + } + Vector3& getSuperNormal( int x, int y ){ + return superNormals[y * sw + x]; + } + const Vector3& getSuperNormal( int x, int y ) const { + return superNormals[y * sw + x]; + } + float& getSuperDirt( int x, int y ){ + return superDirt[y * sw + x]; + } + const float& getSuperDirt( int x, int y ) const { + return superDirt[y * sw + x]; + } + int& getSuperCluster( int x, int y ){ + return superClusters[y * sw + x]; + } + const int& getSuperCluster( int x, int y ) const { + return superClusters[y * sw + x]; + } + Vector3& getSuperDeluxel( int x, int y ){ + return superDeluxels[y * sw + x]; + } + const Vector3& getSuperDeluxel( int x, int y ) const { + return superDeluxels[y * sw + x]; + } + Vector3& getBspDeluxel( int x, int y ){ + return bspDeluxels[y * w + x]; + } + const Vector3& getBspDeluxel( int x, int y ) const { + return bspDeluxels[y * w + x]; + } + SuperFloodLight& getSuperFloodLight( int x, int y ){ + return superFloodLight[y * sw + x]; + } + const SuperFloodLight& getSuperFloodLight( int x, int y ) const { + return superFloodLight[y * sw + x]; + } }; struct rawGridPoint_t { - vec3_t ambient[ MAX_LIGHTMAPS ]; - vec3_t directed[ MAX_LIGHTMAPS ]; - vec3_t dir; + Vector3 ambient[ MAX_LIGHTMAPS ]; + Vector3 directed[ MAX_LIGHTMAPS ]; + Vector3 dir; byte styles[ MAX_LIGHTMAPS ]; }; @@ -1465,8 +1507,9 @@ struct surfaceInfo_t int parentSurfaceNum, childSurfaceNum; int entityNum, castShadows, recvShadows, sampleSize, patchIterations; float longestCurve; - float *plane; - vec3_t axis, mins, maxs; + Plane3f *plane; + Vector3 axis; + MinMax minmax; bool hasLightmap, approximated; int firstSurfaceCluster, numSurfaceClusters; }; @@ -1477,8 +1520,8 @@ struct surfaceInfo_t ------------------------------------------------------------------------------- */ -static inline vec_t Random( void ){ /* returns a pseudorandom number between 0 and 1 */ - return (vec_t) rand() / RAND_MAX; +inline float Random( void ){ /* returns a pseudorandom number between 0 and 1 */ + return (float) rand() / RAND_MAX; } /* help.c */ @@ -1524,15 +1567,15 @@ void FreeBrush( brush_t *brushes ); void FreeBrushList( brush_t *brushes ); brush_t *CopyBrush( const brush_t *brush ); bool BoundBrush( brush_t *brush ); +void SnapWeldVector( const Vector3& a, const Vector3& b, Vector3& out ); bool CreateBrushWindings( brush_t *brush ); -brush_t *BrushFromBounds( vec3_t mins, vec3_t maxs ); -vec_t BrushVolume( brush_t *brush ); +brush_t *BrushFromBounds( const Vector3& mins, const Vector3& maxs ); +float BrushVolume( brush_t *brush ); void WriteBSPBrushMap( const char *name, brush_t *list ); void FilterDetailBrushesIntoTree( entity_t *e, tree_t *tree ); void FilterStructuralBrushesIntoTree( entity_t *e, tree_t *tree ); -int BoxOnPlaneSide( vec3_t mins, vec3_t maxs, plane_t *plane ); bool WindingIsTiny( winding_t *w ); void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back ); @@ -1542,7 +1585,7 @@ node_t *AllocNode( void ); /* mesh.c */ -void LerpDrawVert( bspDrawVert_t *a, bspDrawVert_t *b, bspDrawVert_t *out ); +void LerpDrawVert( const bspDrawVert_t *a, const bspDrawVert_t *b, bspDrawVert_t *out ); void LerpDrawVertAmount( bspDrawVert_t *a, bspDrawVert_t *b, float amount, bspDrawVert_t *out ); void FreeMesh( mesh_t *m ); mesh_t *CopyMesh( mesh_t *mesh ); @@ -1560,9 +1603,11 @@ void PutMeshOnCurve( mesh_t in ); /* map.c */ void LoadMapFile( char *filename, bool onlyLights, bool noCollapseGroups ); -int FindFloatPlane( vec3_t normal, vec_t dist, int numPoints, vec3_t *points ); -bool PlaneEqual( plane_t *p, vec3_t normal, vec_t dist ); -int PlaneTypeForNormal( vec3_t normal ); +int FindFloatPlane( const Plane3f& plane, int numPoints, const Vector3 *points ); +inline int FindFloatPlane( const Vector3& normal, float dist, int numPoints, const Vector3 *points ){ + return FindFloatPlane( Plane3f( normal, dist ), numPoints, points ); +} +bool PlaneEqual( const plane_t *p, const Plane3f& plane ); void AddBrushBevels( void ); brush_t *FinishBrush( bool noCollapseGroups ); @@ -1634,8 +1679,8 @@ void FixTJunctions( entity_t *e ); /* fog.c */ winding_t *WindingFromDrawSurf( mapDrawSurface_t *ds ); void FogDrawSurfaces( entity_t *e ); -int FogForPoint( vec3_t point, float epsilon ); -int FogForBounds( vec3_t mins, vec3_t maxs, float epsilon ); +int FogForPoint( const Vector3& point, float epsilon ); +int FogForBounds( const MinMax& minmax, float epsilon ); void CreateMapFogs( void ); @@ -1650,7 +1695,7 @@ void PicoPrintFunc( int level, const char *str ); void PicoLoadFileFunc( const char *name, byte **buffer, int *bufSize ); picoModel_t *FindModel( const char *name, int frame ); picoModel_t *LoadModel( const char *name, int frame ); -void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const std::list *remaps, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle, float clipDepth ); +void InsertModel( const char *name, int skin, int frame, const Matrix4& transform, const std::list *remaps, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle, float clipDepth ); void AddTriangleModels( entity_t *e ); @@ -1660,7 +1705,7 @@ void FinishSurface( mapDrawSurface_t *ds ); void StripFaceSurface( mapDrawSurface_t *ds ); void MaxAreaFaceSurface( mapDrawSurface_t *ds ); bool CalcSurfaceTextureRange( mapDrawSurface_t *ds ); -bool CalcLightmapAxis( vec3_t normal, vec3_t axis ); +bool CalcLightmapAxis( const Vector3& normal, Vector3& axis ); void ClassifySurfaces( int numSurfs, mapDrawSurface_t *ds ); void ClassifyEntitySurfaces( entity_t *e ); void TidyEntitySurfaces( entity_t *e ); @@ -1671,7 +1716,7 @@ void ClearSurface( mapDrawSurface_t *ds ); void AddEntitySurfaceModels( entity_t *e ); mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, winding_t *w ); mapDrawSurface_t *DrawSurfaceForMesh( entity_t *e, parseMesh_t *p, mesh_t *mesh ); -mapDrawSurface_t *DrawSurfaceForFlare( int entNum, vec3_t origin, vec3_t normal, vec3_t color, const char *flareShader, int lightStyle ); +mapDrawSurface_t *DrawSurfaceForFlare( int entNum, const Vector3& origin, const Vector3& normal, const Vector3& color, const char *flareShader, int lightStyle ); mapDrawSurface_t *DrawSurfaceForShader( const char *shader ); void ClipSidesIntoTree( entity_t *e, tree_t *tree ); void MakeDebugPortalSurfs( tree_t *tree ); @@ -1715,7 +1760,7 @@ int GetSurfaceExtraRecvShadows( int num ); int GetSurfaceExtraSampleSize( int num ); int GetSurfaceExtraMinSampleSize( int num ); float GetSurfaceExtraLongestCurve( int num ); -void GetSurfaceExtraLightmapAxis( int num, vec3_t lightmapAxis ); +void GetSurfaceExtraLightmapAxis( int num, Vector3& lightmapAxis ); void WriteSurfaceExtraFile( const char *path ); void LoadSurfaceExtraFile( const char *path ); @@ -1726,11 +1771,7 @@ void ProcessDecals( void ); void MakeEntityDecals( entity_t *e ); /* map.c */ -void TextureAxisFromPlane( plane_t *pln, vec3_t xv, vec3_t yv ); - -/* brush_primit.c */ -void ComputeAxisBase( vec3_t normal, vec3_t texX, vec3_t texY ); - +void TextureAxisFromPlane( const plane_t *pln, Vector3& xv, Vector3& yv ); /* vis.c */ fixedWinding_t *NewFixedWinding( int points ); @@ -1749,9 +1790,9 @@ void PassagePortalFlow( int portalnum ); /* light.c */ -float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const winding_t *w ); +float PointToPolygonFormFactor( const Vector3& point, const Vector3& normal, const winding_t *w ); int LightContributionToSample( trace_t *trace ); -void LightingAtSample( trace_t * trace, byte styles[ MAX_LIGHTMAPS ], vec3_t colors[ MAX_LIGHTMAPS ] ); +void LightingAtSample( trace_t * trace, byte styles[ MAX_LIGHTMAPS ], Vector3 (&colors)[ MAX_LIGHTMAPS ] ); bool LightContributionToPoint( trace_t *trace ); int LightMain( int argc, char **argv ); @@ -1763,7 +1804,7 @@ float SetupTrace( trace_t *trace ); /* light_bounce.c */ -bool RadSampleImage( byte * pixels, int width, int height, float st[ 2 ], float color[ 4 ] ); +bool RadSampleImage( byte * pixels, int width, int height, const Vector2& st, Color4f& color ); void RadLightForTriangles( int num, int lightmapNum, rawLightmap_t *lm, shaderInfo_t *si, float scale, float subdivide, clipWork_t *cw ); void RadLightForPatch( int num, int lightmapNum, rawLightmap_t *lm, shaderInfo_t *si, float scale, float subdivide, clipWork_t *cw ); void RadCreateDiffuseLights( void ); @@ -1771,7 +1812,7 @@ void RadFreeLights(); /* light_ydnar.c */ -void ColorToBytes( const float *color, byte *colorBytes, float scale ); +void ColorToBytes( const Vector3& color, Vector3b& colorBytes, float scale ); void SmoothNormals( void ); void MapRawLightmap( int num ); @@ -1793,14 +1834,14 @@ void SetupBrushesFlags( int mask_any, int test_any, int m void SetupBrushes( void ); void SetupClusters( void ); bool ClusterVisible( int a, int b ); -bool ClusterVisibleToPoint( vec3_t point, int cluster ); -int ClusterForPoint( vec3_t point ); -int ClusterForPointExt( vec3_t point, float epsilon ); -int ClusterForPointExtFilter( vec3_t point, float epsilon, int numClusters, int *clusters ); -int ShaderForPointInLeaf( vec3_t point, int leafNum, float epsilon, int wantContentFlags, int wantSurfaceFlags, int *contentFlags, int *surfaceFlags ); +bool ClusterVisibleToPoint( const Vector3& point, int cluster ); +int ClusterForPoint( const Vector3& point ); +int ClusterForPointExt( const Vector3& point, float epsilon ); +int ClusterForPointExtFilter( const Vector3& point, float epsilon, int numClusters, int *clusters ); +int ShaderForPointInLeaf( const Vector3& point, int leafNum, float epsilon, int wantContentFlags, int wantSurfaceFlags, int *contentFlags, int *surfaceFlags ); void SetupEnvelopes( bool forGrid, bool fastFlag ); void FreeTraceLights( trace_t *trace ); -void CreateTraceLightsForBounds( vec3_t mins, vec3_t maxs, vec3_t normal, int numClusters, int *clusters, LightFlags flags, trace_t *trace ); +void CreateTraceLightsForBounds( const MinMax& minmax, const Vector3 *normal, int numClusters, int *clusters, LightFlags flags, trace_t *trace ); void CreateTraceLightsForSurface( int num, trace_t *trace ); @@ -1829,7 +1870,7 @@ image_t *ImageLoad( const char *filename ); /* shaders.c */ void ColorMod( colorMod_t *am, int numVerts, bspDrawVert_t *drawVerts ); -void TCMod( tcMod_t mod, float st[ 2 ] ); +void TCMod( tcMod_t mod, Vector2& st ); void TCModIdentity( tcMod_t mod ); void TCModMultiply( tcMod_t a, tcMod_t b, tcMod_t out ); void TCModTranslate( tcMod_t mod, float s, float t ); @@ -2085,7 +2126,7 @@ Q_EXTERN plane_t *mapplanes Q_ASSIGN( NULL ); /* mapplanes[ num ^ 1 Q_EXTERN int nummapplanes Q_ASSIGN( 0 ); /* nummapplanes will always be even */ Q_EXTERN int allocatedmapplanes Q_ASSIGN( 0 ); Q_EXTERN int numMapPatches; -Q_EXTERN vec3_t mapMins, mapMaxs; +Q_EXTERN MinMax g_mapMinmax; Q_EXTERN int defaultFogNum Q_ASSIGN( -1 ); /* ydnar: cleaner fog handling */ Q_EXTERN int numMapFogs Q_ASSIGN( 0 ); @@ -2114,7 +2155,7 @@ Q_EXTERN int numRedundantIndexes; Q_EXTERN int numSurfaceModels Q_ASSIGN( 0 ); -Q_EXTERN byte debugColors[ 12 ][ 3 ] +Q_EXTERN Vector3b debugColors[ 12 ] #ifndef MAIN_C ; #else @@ -2136,7 +2177,7 @@ Q_EXTERN byte debugColors[ 12 ][ 3 ] #endif Q_EXTERN int skyboxArea Q_ASSIGN( -1 ); -Q_EXTERN m4x4_t skyboxTransform; +Q_EXTERN Matrix4 skyboxTransform; @@ -2255,7 +2296,7 @@ Q_EXTERN float dirtGain Q_ASSIGN( 1.0f ); Q_EXTERN bool debugnormals Q_ASSIGN( false ); Q_EXTERN bool floodlighty Q_ASSIGN( false ); Q_EXTERN bool floodlight_lowquality Q_ASSIGN( false ); -Q_EXTERN vec3_t floodlightRGB; +Q_EXTERN Vector3 floodlightRGB; Q_EXTERN float floodlightIntensity Q_ASSIGN( 512.0f ); Q_EXTERN float floodlightDistance Q_ASSIGN( 1024.0f ); Q_EXTERN float floodlightDirectionScale Q_ASSIGN( 1.0f ); @@ -2343,15 +2384,15 @@ Q_EXTERN FILE *dumpFile; Q_EXTERN int defaultLightSubdivide Q_ASSIGN( 999 ); -Q_EXTERN vec3_t ambientColor; -Q_EXTERN vec3_t minLight, minVertexLight, minGridLight; +Q_EXTERN Vector3 ambientColor; +Q_EXTERN Vector3 minLight, minVertexLight, minGridLight; Q_EXTERN float maxLight Q_ASSIGN( 255.f ); Q_EXTERN int *entitySurface; -Q_EXTERN vec3_t *surfaceOrigin; +Q_EXTERN Vector3 *surfaceOrigin; -Q_EXTERN vec3_t sunDirection; -Q_EXTERN vec3_t sunLight; +Q_EXTERN Vector3 sunDirection; +Q_EXTERN Vector3 sunLight; /* ydnar: light optimization */ Q_EXTERN float subdivideThreshold Q_ASSIGN( DEFAULT_SUBDIVIDE_THRESHOLD ); @@ -2392,8 +2433,15 @@ Q_EXTERN rawLightmap_t *rawLightmaps Q_ASSIGN( NULL ); Q_EXTERN int *sortLightmaps Q_ASSIGN( NULL ); /* vertex luxels */ -Q_EXTERN float *vertexLuxels[ MAX_LIGHTMAPS ]; -Q_EXTERN float *radVertexLuxels[ MAX_LIGHTMAPS ]; +Q_EXTERN Vector3 *vertexLuxels[ MAX_LIGHTMAPS ]; +Q_EXTERN Vector3 *radVertexLuxels[ MAX_LIGHTMAPS ]; + +inline Vector3& getVertexLuxel( int lightmapNum, int vertexNum ){ + return vertexLuxels[lightmapNum][vertexNum]; +} +inline Vector3& getRadVertexLuxel( int lightmapNum, int vertexNum ){ + return radVertexLuxels[lightmapNum][vertexNum]; +} /* bsp lightmaps */ Q_EXTERN int numLightmapShaders Q_ASSIGN( 0 ); @@ -2426,9 +2474,9 @@ Q_EXTERN int numLuxelsIlluminated Q_ASSIGN( 0 ); Q_EXTERN int numVertsIlluminated Q_ASSIGN( 0 ); /* lightgrid */ -Q_EXTERN vec3_t gridMins; +Q_EXTERN Vector3 gridMins; Q_EXTERN int gridBounds[ 3 ]; -Q_EXTERN vec3_t gridSize +Q_EXTERN Vector3 gridSize #ifndef MAIN_C ; #else diff --git a/tools/quake3/q3map2/shaders.cpp b/tools/quake3/q3map2/shaders.cpp index d2538270..334bd01f 100644 --- a/tools/quake3/q3map2/shaders.cpp +++ b/tools/quake3/q3map2/shaders.cpp @@ -41,7 +41,7 @@ void ColorMod( colorMod_t *cm, int numVerts, bspDrawVert_t *drawVerts ){ int i, j, k; float c; - vec4_t mult, add; + Vector4 mult, add; bspDrawVert_t *dv; colorMod_t *cm2; @@ -62,17 +62,16 @@ void ColorMod( colorMod_t *cm, int numVerts, bspDrawVert_t *drawVerts ){ for ( cm2 = cm; cm2 != NULL; cm2 = cm2->next ) { /* default */ - VectorSet( mult, 1.0f, 1.0f, 1.0f ); - mult[ 3 ] = 1.0f; - VectorSet( add, 0.0f, 0.0f, 0.0f ); - add[ 3 ] = 0.0f; + mult.set( 1 ); + add.set( 0 ); + const Vector3 cm2_data = vector3_from_array( cm2->data ); /* switch on type */ switch ( cm2->type ) { case EColorMod::ColorSet: - VectorClear( mult ); - VectorScale( cm2->data, 255.0f, add ); + mult.vec3().set( 0 ); + add.vec3() = cm2_data * 255.0f; break; case EColorMod::AlphaSet: @@ -81,7 +80,7 @@ void ColorMod( colorMod_t *cm, int numVerts, bspDrawVert_t *drawVerts ){ break; case EColorMod::ColorScale: - VectorCopy( cm2->data, mult ); + mult.vec3() = cm2_data; break; case EColorMod::AlphaScale: @@ -89,46 +88,46 @@ void ColorMod( colorMod_t *cm, int numVerts, bspDrawVert_t *drawVerts ){ break; case EColorMod::ColorDotProduct: - c = DotProduct( dv->normal, cm2->data ); - VectorSet( mult, c, c, c ); + c = vector3_dot( dv->normal, cm2_data ); + mult.vec3().set( c ); break; case EColorMod::ColorDotProductScale: - c = DotProduct( dv->normal, cm2->data ); + c = vector3_dot( dv->normal, cm2_data ); c = ( c - cm2->data[3] ) / ( cm2->data[4] - cm2->data[3] ); - VectorSet( mult, c, c, c ); + mult.vec3().set( c ); break; case EColorMod::AlphaDotProduct: - mult[ 3 ] = DotProduct( dv->normal, cm2->data ); + mult[ 3 ] = vector3_dot( dv->normal, cm2_data ); break; case EColorMod::AlphaDotProductScale: - c = DotProduct( dv->normal, cm2->data ); + c = vector3_dot( dv->normal, cm2_data ); c = ( c - cm2->data[3] ) / ( cm2->data[4] - cm2->data[3] ); mult[ 3 ] = c; break; case EColorMod::ColorDotProduct2: - c = DotProduct( dv->normal, cm2->data ); + c = vector3_dot( dv->normal, cm2_data ); c *= c; - VectorSet( mult, c, c, c ); + mult.vec3().set( c ); break; case EColorMod::ColorDotProduct2Scale: - c = DotProduct( dv->normal, cm2->data ); + c = vector3_dot( dv->normal, cm2_data ); c *= c; c = ( c - cm2->data[3] ) / ( cm2->data[4] - cm2->data[3] ); - VectorSet( mult, c, c, c ); + mult.vec3().set( c ); break; case EColorMod::AlphaDotProduct2: - mult[ 3 ] = DotProduct( dv->normal, cm2->data ); + mult[ 3 ] = vector3_dot( dv->normal, cm2_data ); mult[ 3 ] *= mult[ 3 ]; break; case EColorMod::AlphaDotProduct2Scale: - c = DotProduct( dv->normal, cm2->data ); + c = vector3_dot( dv->normal, cm2_data ); c *= c; c = ( c - cm2->data[3] ) / ( cm2->data[4] - cm2->data[3] ); mult[ 3 ] = c; @@ -164,7 +163,7 @@ void ColorMod( colorMod_t *cm, int numVerts, bspDrawVert_t *drawVerts ){ routines for dealing with a 3x3 texture mod matrix */ -void TCMod( tcMod_t mod, float st[ 2 ] ){ +void TCMod( tcMod_t mod, Vector2& st ){ float old[ 2 ]; @@ -215,7 +214,7 @@ void TCModRotate( tcMod_t mod, float euler ){ memcpy( old, mod, sizeof( tcMod_t ) ); TCModIdentity( temp ); - radians = euler / 180 * Q_PI; + radians = degrees_to_radians( euler ); sinv = sin( radians ); cosv = cos( radians ); @@ -663,8 +662,7 @@ static shaderInfo_t *AllocShaderInfo( void ){ void FinishShader( shaderInfo_t *si ){ int x, y; - float st[ 2 ], o[ 2 ], dist, bestDist; - vec4_t color, delta; + Vector2 st; /* don't double-dip */ @@ -682,28 +680,26 @@ void FinishShader( shaderInfo_t *si ){ if ( si->legacyTerrain && !si->tcGen ) { /* set xy texture projection */ si->tcGen = true; - VectorSet( si->vecs[ 0 ], ( 1.0f / ( si->shaderWidth * 0.5f ) ), 0, 0 ); - VectorSet( si->vecs[ 1 ], 0, ( 1.0f / ( si->shaderHeight * 0.5f ) ), 0 ); + si->vecs[ 0 ] = { ( 1.0f / ( si->shaderWidth * 0.5f ) ), 0, 0 }; + si->vecs[ 1 ] = { 0, ( 1.0f / ( si->shaderHeight * 0.5f ) ), 0 }; } /* find pixel coordinates best matching the average color of the image */ - bestDist = 99999999; - o[ 0 ] = 1.0f / si->shaderImage->width; - o[ 1 ] = 1.0f / si->shaderImage->height; + float bestDist = 99999999; + const Vector2 o( 1.0f / si->shaderImage->width, 1.0f / si->shaderImage->height ); for ( y = 0, st[ 1 ] = 0.0f; y < si->shaderImage->height; y++, st[ 1 ] += o[ 1 ] ) { for ( x = 0, st[ 0 ] = 0.0f; x < si->shaderImage->width; x++, st[ 0 ] += o[ 0 ] ) { /* sample the shader image */ + Color4f color; RadSampleImage( si->shaderImage->pixels, si->shaderImage->width, si->shaderImage->height, st, color ); /* determine error squared */ - VectorSubtract( color, si->averageColor, delta ); - delta[ 3 ] = color[ 3 ] - si->averageColor[ 3 ]; - dist = delta[ 0 ] * delta[ 0 ] + delta[ 1 ] * delta[ 1 ] + delta[ 2 ] * delta[ 2 ] + delta[ 3 ] * delta[ 3 ]; + const Color4f delta = color - si->averageColor; + const float dist = vector4_dot( delta, delta ); if ( dist < bestDist ) { - si->stFlat[ 0 ] = st[ 0 ]; - si->stFlat[ 1 ] = st[ 1 ]; + si->stFlat = st; } } } @@ -725,9 +721,6 @@ void FinishShader( shaderInfo_t *si ){ */ static void LoadShaderImages( shaderInfo_t *si ){ - int i, count; - float color[ 4 ]; - /* nodraw shaders don't need images */ if ( si->compileFlags & C_NODRAW ) { @@ -779,10 +772,9 @@ static void LoadShaderImages( shaderInfo_t *si ){ } /* create default and average colors */ - count = si->lightImage->width * si->lightImage->height; - VectorClear( color ); - color[ 3 ] = 0.0f; - for ( i = 0; i < count; i++ ) + const int count = si->lightImage->width * si->lightImage->height; + Color4f color( 0, 0, 0, 0 ); + for ( int i = 0; i < count; i++ ) { color[ 0 ] += si->lightImage->pixels[ i * 4 + 0 ]; color[ 1 ] += si->lightImage->pixels[ i * 4 + 1 ]; @@ -790,15 +782,15 @@ static void LoadShaderImages( shaderInfo_t *si ){ color[ 3 ] += si->lightImage->pixels[ i * 4 + 3 ]; } - if ( VectorLength( si->color ) <= 0.0f ) { - ColorNormalize( color, si->color ); - VectorScale( color, ( 1.0f / count ), si->averageColor ); - si->averageColor[ 3 ] = color[ 3 ] / count; + if ( vector3_length( si->color ) == 0.0f ) { + si->color = color.rgb(); + ColorNormalize( si->color ); + si->averageColor = color / count; } else { - VectorCopy( si->color, si->averageColor ); - si->averageColor[ 3 ] = 1.0f; + si->averageColor.rgb() = si->color; + si->averageColor.alpha() = 1.0f; } } @@ -921,14 +913,12 @@ bool GetTokenAppend( char *buffer, bool crossline ){ } -void Parse1DMatrixAppend( char *buffer, int x, vec_t *m ){ - int i; - +void Parse1DMatrixAppend( char *buffer, int x, float *m ){ if ( !GetTokenAppend( buffer, true ) || !strEqual( token, "(" ) ) { Error( "Parse1DMatrixAppend(): line %d: ( not found!\nFile location be: %s\n", scriptline, g_strLoadedFileLocation ); } - for ( i = 0; i < x; i++ ) + for ( int i = 0; i < x; i++ ) { if ( !GetTokenAppend( buffer, false ) ) { Error( "Parse1DMatrixAppend(): line %d: Number not found!\nFile location be: %s\n", scriptline, g_strLoadedFileLocation ); @@ -968,7 +958,7 @@ static void ParseShaderFile( const char *filename ){ if ( si != NULL && !strEmpty( shaderText ) ) { strcat( shaderText, "\n" ); si->shaderText = copystring( shaderText ); - //% if( VectorLength( si->vecs[ 0 ] ) ) + //% if( vector3_length( si->vecs[ 0 ] ) ) //% Sys_Printf( "%s\n", shaderText ); } @@ -1119,7 +1109,7 @@ static void ParseShaderFile( const char *filename ){ /* deformVertexes move (ydnar: for particle studio support) */ if ( striEqual( token, "move" ) ) { - vec3_t amt, mins, maxs; + Vector3 amt; float base, amp; @@ -1136,10 +1126,10 @@ static void ParseShaderFile( const char *filename ){ GetTokenAppend( shaderText, false ); amp = atof( token ); /* calculate */ - VectorScale( amt, base, mins ); - VectorMA( mins, amp, amt, maxs ); - VectorAdd( si->mins, mins, si->mins ); - VectorAdd( si->maxs, maxs, si->maxs ); + const Vector3 mins = amt * base; + const Vector3 maxs = amt * amp + mins; + si->minmax.mins += mins; + si->minmax.maxs += maxs; } } @@ -1271,7 +1261,7 @@ static void ParseShaderFile( const char *filename ){ } /* normalize it */ - ColorNormalize( sun->color, sun->color ); + ColorNormalize( sun->color ); /* scale color by brightness */ GetTokenAppend( shaderText, false ); @@ -1279,12 +1269,10 @@ static void ParseShaderFile( const char *filename ){ /* get sun angle/elevation */ GetTokenAppend( shaderText, false ); - a = atof( token ); - a = a / 180.0f * Q_PI; + a = degrees_to_radians( atof( token ) ); GetTokenAppend( shaderText, false ); - b = atof( token ); - b = b / 180.0f * Q_PI; + b = degrees_to_radians( atof( token ) ); sun->direction[ 0 ] = cos( a ) * cos( b ); sun->direction[ 1 ] = sin( a ) * cos( b ); @@ -1296,8 +1284,7 @@ static void ParseShaderFile( const char *filename ){ /* ydnar: get sun angular deviance/samples */ if ( ext && TokenAvailable() ) { GetTokenAppend( shaderText, false ); - sun->deviance = atof( token ); - sun->deviance = sun->deviance / 180.0f * Q_PI; + sun->deviance = degrees_to_radians( atof( token ) ); GetTokenAppend( shaderText, false ); sun->numSamples = atoi( token ); @@ -1436,7 +1423,7 @@ static void ParseShaderFile( const char *filename ){ /* wolf: q3map_lightRGB */ else if ( striEqual( token, "q3map_lightRGB" ) ) { - VectorClear( si->color ); + si->color.set( 0 ); GetTokenAppend( shaderText, false ); si->color[ 0 ] = atof( token ); GetTokenAppend( shaderText, false ); @@ -1448,7 +1435,7 @@ static void ParseShaderFile( const char *filename ){ si->color[1] = Image_LinearFloatFromsRGBFloat( si->color[1] ); si->color[2] = Image_LinearFloatFromsRGBFloat( si->color[2] ); } - ColorNormalize( si->color, si->color ); + ColorNormalize( si->color ); } /* q3map_lightSubdivide */ @@ -1485,7 +1472,7 @@ static void ParseShaderFile( const char *filename ){ si->floodlightRGB[1] = Image_LinearFloatFromsRGBFloat( si->floodlightRGB[1] ); si->floodlightRGB[2] = Image_LinearFloatFromsRGBFloat( si->floodlightRGB[2] ); } - ColorNormalize( si->floodlightRGB, si->floodlightRGB ); + ColorNormalize( si->floodlightRGB ); } /* jal: q3map_nodirty : skip dirty */ @@ -1517,18 +1504,18 @@ static void ParseShaderFile( const char *filename ){ else if ( striEqual( token, "q3map_lightmapAxis" ) ) { GetTokenAppend( shaderText, false ); if ( striEqual( token, "x" ) ) { - VectorSet( si->lightmapAxis, 1, 0, 0 ); + si->lightmapAxis = g_vector3_axis_x; } else if ( striEqual( token, "y" ) ) { - VectorSet( si->lightmapAxis, 0, 1, 0 ); + si->lightmapAxis = g_vector3_axis_y; } else if ( striEqual( token, "z" ) ) { - VectorSet( si->lightmapAxis, 0, 0, 1 ); + si->lightmapAxis = g_vector3_axis_z; } else { Sys_Warning( "Unknown value for lightmap axis: %s\n", token ); - VectorClear( si->lightmapAxis ); + si->lightmapAxis.set( 0 ); } } @@ -1636,7 +1623,7 @@ static void ParseShaderFile( const char *filename ){ si->nonplanar = true; si->forceMeta = true; si->shadeAngleDegrees = 179.0f; - //% VectorSet( si->lightmapAxis, 0, 0, 1 ); /* ydnar 2002-09-21: turning this off for better lightmapping of cliff faces */ + //% si->lightmapAxis = g_vector3_axis_z; /* ydnar 2002-09-21: turning this off for better lightmapping of cliff faces */ } /* ydnar: picomodel: q3map_forceMeta (forces brush faces and/or triangle models to go through the metasurface pipeline) */ @@ -1665,14 +1652,14 @@ static void ParseShaderFile( const char *filename ){ /* q3map_tcGen vector */ if ( striEqual( token, "vector" ) ) { - Parse1DMatrixAppend( shaderText, 3, si->vecs[ 0 ] ); - Parse1DMatrixAppend( shaderText, 3, si->vecs[ 1 ] ); + Parse1DMatrixAppend( shaderText, 3, si->vecs[ 0 ].data() ); + Parse1DMatrixAppend( shaderText, 3, si->vecs[ 1 ].data() ); } /* q3map_tcGen ivector <1.0/s vector> <1.0/t vector> (inverse vector, easier for mappers to understand) */ else if ( striEqual( token, "ivector" ) ) { - Parse1DMatrixAppend( shaderText, 3, si->vecs[ 0 ] ); - Parse1DMatrixAppend( shaderText, 3, si->vecs[ 1 ] ); + Parse1DMatrixAppend( shaderText, 3, si->vecs[ 0 ].data() ); + Parse1DMatrixAppend( shaderText, 3, si->vecs[ 1 ].data() ); for ( i = 0; i < 3; i++ ) { si->vecs[ 0 ][ i ] = si->vecs[ 0 ][ i ] ? 1.0 / si->vecs[ 0 ][ i ] : 0; @@ -1682,8 +1669,8 @@ static void ParseShaderFile( const char *filename ){ else { Sys_Warning( "Unknown q3map_tcGen method: %s\n", token ); - VectorClear( si->vecs[ 0 ] ); - VectorClear( si->vecs[ 1 ] ); + si->vecs[ 0 ].set( 0 ); + si->vecs[ 1 ].set( 0 ); } } @@ -1825,8 +1812,8 @@ static void ParseShaderFile( const char *filename ){ /* q3map_fogDir (direction a fog shader fades from transparent to opaque) */ else if ( striEqual( token, "q3map_fogDir" ) ) { - Parse1DMatrixAppend( shaderText, 3, si->fogDir ); - VectorNormalize( si->fogDir, si->fogDir ); + Parse1DMatrixAppend( shaderText, 3, si->fogDir.data() ); + VectorNormalize( si->fogDir ); } /* q3map_globaltexture */ diff --git a/tools/quake3/q3map2/surface.cpp b/tools/quake3/q3map2/surface.cpp index a63dbbee..1fa8a23c 100644 --- a/tools/quake3/q3map2/surface.cpp +++ b/tools/quake3/q3map2/surface.cpp @@ -209,7 +209,7 @@ mapDrawSurface_t *MakeSkyboxSurface( mapDrawSurface_t *src ){ /* scale the surface vertexes */ for ( i = 0; i < ds->numVerts; i++ ) { - m4x4_transform_point( skyboxTransform, ds->verts[ i ].xyz ); + matrix4_transform_point( skyboxTransform, ds->verts[ i ].xyz ); /* debug code */ //% bspDrawVerts[ bspDrawSurfaces[ ds->outputNum ].firstVert + i ].color[ 0 ][ 1 ] = 0; @@ -217,7 +217,7 @@ mapDrawSurface_t *MakeSkyboxSurface( mapDrawSurface_t *src ){ } /* so backface culling creep doesn't bork the surface */ - VectorClear( ds->lightmapVecs[ 2 ] ); + ds->lightmapVecs[ 2 ].set( 0 ); /* return the surface */ return ds; @@ -233,18 +233,9 @@ mapDrawSurface_t *MakeSkyboxSurface( mapDrawSurface_t *src ){ #define TINY_AREA 1.0f bool IsTriangleDegenerate( bspDrawVert_t *points, int a, int b, int c ){ - vec3_t v1, v2, v3; - float d; - - /* calcuate the area of the triangle */ - VectorSubtract( points[ b ].xyz, points[ a ].xyz, v1 ); - VectorSubtract( points[ c ].xyz, points[ a ].xyz, v2 ); - CrossProduct( v1, v2, v3 ); - d = VectorLength( v3 ); - /* assume all very small or backwards triangles will cause problems */ - if ( d < TINY_AREA ) { + if ( vector3_length( vector3_cross( points[ b ].xyz - points[ a ].xyz, points[ c ].xyz - points[ a ].xyz ) ) < TINY_AREA ) { return true; } @@ -374,7 +365,7 @@ bool CalcSurfaceTextureRange( mapDrawSurface_t *ds ){ { for ( j = 0; j < 2; j++ ) { - v = ( (float) ds->verts[ i ].st[ j ] + ds->bias[ j ] ) * size[ j ]; + v = ( ds->verts[ i ].st[ j ] + ds->bias[ j ] ) * size[ j ]; if ( v < ds->texMins[ j ] ) { ds->texMins[ j ] = v; } @@ -412,13 +403,13 @@ bool CalcSurfaceTextureRange( mapDrawSurface_t *ds ){ gives closed lightmap axis for a plane normal */ -bool CalcLightmapAxis( vec3_t normal, vec3_t axis ){ - vec3_t absolute; +bool CalcLightmapAxis( const Vector3& normal, Vector3& axis ){ + Vector3 absolute; /* test */ - if ( normal[ 0 ] == 0.0f && normal[ 1 ] == 0.0f && normal[ 2 ] == 0.0f ) { - VectorClear( axis ); + if ( normal == g_vector3_identity ) { + axis.set( 0 ); return false; } @@ -430,27 +421,27 @@ bool CalcLightmapAxis( vec3_t normal, vec3_t axis ){ /* test and set */ if ( absolute[ 2 ] > absolute[ 0 ] - 0.0001f && absolute[ 2 ] > absolute[ 1 ] - 0.0001f ) { if ( normal[ 2 ] > 0.0f ) { - VectorSet( axis, 0.0f, 0.0f, 1.0f ); + axis = g_vector3_axis_z; } else{ - VectorSet( axis, 0.0f, 0.0f, -1.0f ); + axis = -g_vector3_axis_z; } } else if ( absolute[ 0 ] > absolute[ 1 ] - 0.0001f && absolute[ 0 ] > absolute[ 2 ] - 0.0001f ) { if ( normal[ 0 ] > 0.0f ) { - VectorSet( axis, 1.0f, 0.0f, 0.0f ); + axis = g_vector3_axis_x; } else{ - VectorSet( axis, -1.0f, 0.0f, 0.0f ); + axis = -g_vector3_axis_x; } } else { if ( normal[ 1 ] > 0.0f ) { - VectorSet( axis, 0.0f, 1.0f, 0.0f ); + axis = g_vector3_axis_y; } else{ - VectorSet( axis, 0.0f, -1.0f, 0.0f ); + axis = -g_vector3_axis_y; } } @@ -469,10 +460,9 @@ bool CalcLightmapAxis( vec3_t normal, vec3_t axis ){ void ClassifySurfaces( int numSurfs, mapDrawSurface_t *ds ){ int i, bestAxis; - float dist; - vec4_t plane; + Plane3f plane; shaderInfo_t *si; - static vec3_t axii[ 6 ] = + static Vector3 axii[ 6 ] = { { 0, 0, -1 }, { 0, 0, 1 }, @@ -509,33 +499,31 @@ void ClassifySurfaces( int numSurfs, mapDrawSurface_t *ds ){ ----------------------------------------------------------------- */ /* set surface bounding box */ - ClearBounds( ds->mins, ds->maxs ); + ds->minmax.clear(); for ( i = 0; i < ds->numVerts; i++ ) - AddPointToBounds( ds->verts[ i ].xyz, ds->mins, ds->maxs ); + ds->minmax.extend( ds->verts[ i ].xyz ); /* try to get an existing plane */ if ( ds->planeNum >= 0 ) { - VectorCopy( mapplanes[ ds->planeNum ].normal, plane ); - plane[ 3 ] = mapplanes[ ds->planeNum ].dist; + plane = mapplanes[ ds->planeNum ].plane; } /* construct one from the first vert with a valid normal */ else { - VectorClear( plane ); - plane[ 3 ] = 0.0f; + plane = { 0, 0, 0, 0 }; for ( i = 0; i < ds->numVerts; i++ ) { if ( ds->verts[ i ].normal[ 0 ] != 0.0f && ds->verts[ i ].normal[ 1 ] != 0.0f && ds->verts[ i ].normal[ 2 ] != 0.0f ) { - VectorCopy( ds->verts[ i ].normal, plane ); - plane[ 3 ] = DotProduct( ds->verts[ i ].xyz, plane ); + plane.normal() = ds->verts[ i ].normal; + plane.dist() = vector3_dot( ds->verts[ i ].xyz, plane.normal() ); break; } } } /* test for bogus plane */ - if ( VectorLength( plane ) <= 0.0f ) { + if ( vector3_length( plane.normal() ) == 0.0f ) { ds->planar = false; ds->planeNum = -1; } @@ -548,8 +536,7 @@ void ClassifySurfaces( int numSurfs, mapDrawSurface_t *ds ){ for ( i = 0; i < ds->numVerts; i++ ) { /* point-plane test */ - dist = DotProduct( ds->verts[ i ].xyz, plane ) - plane[ 3 ]; - if ( fabs( dist ) > PLANAR_EPSILON ) { + if ( fabs( plane3_distance_to_point( plane, ds->verts[ i ].xyz ) ) > PLANAR_EPSILON ) { //% if( ds->planeNum >= 0 ) //% { //% Sys_Warning( "Planar surface marked unplanar (%f > %f)\n", fabs( dist ), PLANAR_EPSILON ); @@ -564,14 +551,14 @@ void ClassifySurfaces( int numSurfs, mapDrawSurface_t *ds ){ /* find map plane if necessary */ if ( ds->planar ) { if ( ds->planeNum < 0 ) { - ds->planeNum = FindFloatPlane( plane, plane[ 3 ], 1, &ds->verts[ 0 ].xyz ); + ds->planeNum = FindFloatPlane( plane, 1, &ds->verts[ 0 ].xyz ); } - VectorCopy( plane, ds->lightmapVecs[ 2 ] ); + ds->lightmapVecs[ 2 ] = plane.normal(); } else { ds->planeNum = -1; - VectorClear( ds->lightmapVecs[ 2 ] ); + ds->lightmapVecs[ 2 ].set( 0 ); //% if( ds->type == SURF_META || ds->type == SURF_FACE ) //% Sys_Warning( "Non-planar face (%d): %s\n", ds->planeNum, ds->shaderInfo->shader ); } @@ -582,33 +569,33 @@ void ClassifySurfaces( int numSurfs, mapDrawSurface_t *ds ){ /* vertex lit surfaces don't need this information */ if ( si->compileFlags & C_VERTEXLIT || ds->type == ESurfaceType::Triangles || nolm ) { - VectorClear( ds->lightmapAxis ); - //% VectorClear( ds->lightmapVecs[ 2 ] ); + ds->lightmapAxis.set( 0 ); + //% ds->lightmapVecs[ 2 ].set( 0 ); ds->sampleSize = 0; continue; } /* the shader can specify an explicit lightmap axis */ if ( si->lightmapAxis[ 0 ] || si->lightmapAxis[ 1 ] || si->lightmapAxis[ 2 ] ) { - VectorCopy( si->lightmapAxis, ds->lightmapAxis ); + ds->lightmapAxis = si->lightmapAxis; } else if ( ds->type == ESurfaceType::ForcedMeta ) { - VectorClear( ds->lightmapAxis ); + ds->lightmapAxis.set( 0 ); } else if ( ds->planar ) { - CalcLightmapAxis( plane, ds->lightmapAxis ); + CalcLightmapAxis( plane.normal(), ds->lightmapAxis ); } else { /* find best lightmap axis */ for ( bestAxis = 0; bestAxis < 6; bestAxis++ ) { - for ( i = 0; i < ds->numVerts && bestAxis < 6; i++ ) + for ( i = 0; i < ds->numVerts; i++ ) { //% Sys_Printf( "Comparing %1.3f %1.3f %1.3f to %1.3f %1.3f %1.3f\n", //% ds->verts[ i ].normal[ 0 ], ds->verts[ i ].normal[ 1 ], ds->verts[ i ].normal[ 2 ], //% axii[ bestAxis ][ 0 ], axii[ bestAxis ][ 1 ], axii[ bestAxis ][ 2 ] ); - if ( DotProduct( ds->verts[ i ].normal, axii[ bestAxis ] ) < 0.25f ) { /* fixme: adjust this tolerance to taste */ + if ( vector3_dot( ds->verts[ i ].normal, axii[ bestAxis ] ) < 0.25f ) { /* fixme: adjust this tolerance to taste */ break; } } @@ -622,7 +609,7 @@ void ClassifySurfaces( int numSurfs, mapDrawSurface_t *ds ){ if ( bestAxis < 6 ) { //% if( ds->type == ESurfaceType::Patch ) //% Sys_Printf( "Mapped axis %d onto patch\n", bestAxis ); - VectorCopy( axii[ bestAxis ], ds->lightmapAxis ); + ds->lightmapAxis = axii[ bestAxis ]; } /* debug code */ @@ -689,10 +676,8 @@ void ClassifyEntitySurfaces( entity_t *e ){ for shader-indexed surfaces (terrain), find a matching index from the indexmap */ -byte GetShaderIndexForPoint( const indexMap_t *im, const vec3_t eMins, const vec3_t eMaxs, const vec3_t point ){ - int i, x, y; - float s, t; - vec3_t mins, maxs, size; +byte GetShaderIndexForPoint( const indexMap_t *im, const MinMax& eMinmax, const Vector3& point ){ + int x, y; /* early out if no indexmap */ @@ -703,16 +688,17 @@ byte GetShaderIndexForPoint( const indexMap_t *im, const vec3_t eMins, const vec /* this code is really broken */ #if 0 /* legacy precision fudges for terrain */ - for ( i = 0; i < 3; i++ ) + Vector3 mins, maxs; + for ( int i = 0; i < 3; i++ ) { - mins[ i ] = floor( eMins[ i ] + 0.1 ); - maxs[ i ] = floor( eMaxs[ i ] + 0.1 ); - size[ i ] = maxs[ i ] - mins[ i ]; + mins[ i ] = floor( eMinmax.mins[ i ] + 0.1 ); + maxs[ i ] = floor( eMinmax.maxs[ i ] + 0.1 ); } + const Vector3 size = maxs - mins; /* find st (fixme: support more than just z-axis projection) */ - s = floor( point[ 0 ] + 0.1f - mins[ 0 ] ) / size[ 0 ]; - t = floor( maxs[ 1 ] - point[ 1 ] + 0.1f ) / size[ 1 ]; + float s = floor( point[ 0 ] + 0.1f - mins[ 0 ] ) / size[ 0 ]; + float t = floor( maxs[ 1 ] - point[ 1 ] + 0.1f ) / size[ 1 ]; if ( s < 0.0f ) { s = 0.0f; } @@ -731,16 +717,11 @@ byte GetShaderIndexForPoint( const indexMap_t *im, const vec3_t eMins, const vec y = ( im->h - 1 ) * t; #else /* get size */ - for ( i = 0; i < 3; i++ ) - { - mins[ i ] = eMins[ i ]; - maxs[ i ] = eMaxs[ i ]; - size[ i ] = maxs[ i ] - mins[ i ]; - } + const Vector3 size = eMinmax.maxs - eMinmax.mins; /* calc st */ - s = ( point[ 0 ] - mins[ 0 ] ) / size[ 0 ]; - t = ( maxs[ 1 ] - point[ 1 ] ) / size[ 1 ]; + const float s = ( point[ 0 ] - eMinmax.mins[ 0 ] ) / size[ 0 ]; + const float t = ( eMinmax.maxs[ 1 ] - point[ 1 ] ) / size[ 1 ]; /* calc xy */ x = s * im->w; @@ -828,12 +809,12 @@ shaderInfo_t *GetIndexedShader( const shaderInfo_t *parent, const indexMap_t *im if ( parent->tcGen && !si->tcGen ) { /* set xy texture projection */ si->tcGen = true; - VectorCopy( parent->vecs[ 0 ], si->vecs[ 0 ] ); - VectorCopy( parent->vecs[ 1 ], si->vecs[ 1 ] ); + si->vecs[ 0 ] = parent->vecs[ 0 ]; + si->vecs[ 1 ] = parent->vecs[ 1 ]; } - if ( VectorLength( parent->lightmapAxis ) > 0.0f && VectorLength( si->lightmapAxis ) <= 0.0f ) { + if ( vector3_length( parent->lightmapAxis ) != 0.0f && vector3_length( si->lightmapAxis ) == 0.0f ) { /* set lightmap projection axis */ - VectorCopy( parent->lightmapAxis, si->lightmapAxis ); + si->lightmapAxis = parent->lightmapAxis; } /* return the shader */ @@ -856,9 +837,9 @@ mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, windin mapDrawSurface_t *ds; shaderInfo_t *si, *parent; bspDrawVert_t *dv; - vec3_t texX, texY; - vec_t x, y; - vec3_t vTranslated; + Vector3 texX, texY; + float x, y; + Vector3 vTranslated; bool indexed; byte shaderIndexes[ 256 ]; float offsets[ 256 ]; @@ -885,7 +866,7 @@ mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, windin /* get shader indexes for each point */ for ( i = 0; i < w->numpoints; i++ ) { - shaderIndexes[ i ] = GetShaderIndexForPoint( b->im, b->eMins, b->eMaxs, w->p[ i ] ); + shaderIndexes[ i ] = GetShaderIndexForPoint( b->im, b->eMinmax, w->p[ i ] ); offsets[ i ] = b->im->offsets[ shaderIndexes[ i ] ]; //% Sys_Printf( "%f ", offsets[ i ] ); } @@ -913,7 +894,7 @@ mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, windin ds->planar = true; ds->planeNum = s->planenum; - VectorCopy( mapplanes[ s->planenum ].normal, ds->lightmapVecs[ 2 ] ); + ds->lightmapVecs[ 2 ] = mapplanes[ s->planenum ].normal(); ds->shaderInfo = si; ds->mapBrush = b; @@ -925,7 +906,7 @@ mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, windin ds->verts = safe_calloc( ds->numVerts * sizeof( *ds->verts ) ); /* compute s/t coordinates from brush primitive texture matrix (compute axis base) */ - ComputeAxisBase( mapplanes[ s->planenum ].normal, texX, texY ); + ComputeAxisBase( mapplanes[ s->planenum ].normal(), texX, texY ); /* create the vertexes */ for ( j = 0; j < w->numpoints; j++ ) @@ -934,7 +915,7 @@ mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, windin dv = ds->verts + j; /* copy xyz and do potential z offset */ - VectorCopy( w->p[ j ], dv->xyz ); + dv->xyz = w->p[ j ]; if ( indexed ) { dv->xyz[ 2 ] += offsets[ j ]; } @@ -942,25 +923,24 @@ mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, windin /* round the xyz to a given precision and translate by origin */ for ( i = 0 ; i < 3 ; i++ ) dv->xyz[ i ] = SNAP_INT_TO_FLOAT * floor( dv->xyz[ i ] * SNAP_FLOAT_TO_INT + 0.5f ); - VectorAdd( dv->xyz, e->origin, vTranslated ); + vTranslated = dv->xyz + e->origin; /* ydnar: tek-fu celshading support for flat shaded shit */ if ( flat ) { - dv->st[ 0 ] = si->stFlat[ 0 ]; - dv->st[ 1 ] = si->stFlat[ 1 ]; + dv->st = si->stFlat; } /* ydnar: gs mods: added support for explicit shader texcoord generation */ else if ( si->tcGen ) { - dv->st[ 0 ] = DotProduct( si->vecs[ 0 ], vTranslated ); - dv->st[ 1 ] = DotProduct( si->vecs[ 1 ], vTranslated ); + dv->st[ 0 ] = vector3_dot( si->vecs[ 0 ], vTranslated ); + dv->st[ 1 ] = vector3_dot( si->vecs[ 1 ], vTranslated ); } /* brush primitive texturing */ else if ( g_brushType == EBrushType::Bp ) { /* calculate texture s/t from brush primitive texture matrix */ - x = DotProduct( vTranslated, texX ); - y = DotProduct( vTranslated, texY ); + x = vector3_dot( vTranslated, texX ); + y = vector3_dot( vTranslated, texY ); dv->st[ 0 ] = s->texMat[ 0 ][ 0 ] * x + s->texMat[ 0 ][ 1 ] * y + s->texMat[ 0 ][ 2 ]; dv->st[ 1 ] = s->texMat[ 1 ][ 0 ] * x + s->texMat[ 1 ][ 1 ] * y + s->texMat[ 1 ][ 2 ]; } @@ -968,24 +948,23 @@ mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, windin /* old quake-style or valve 220 texturing */ else { /* nearest-axial projection */ - dv->st[ 0 ] = s->vecs[ 0 ][ 3 ] + DotProduct( s->vecs[ 0 ], vTranslated ); - dv->st[ 1 ] = s->vecs[ 1 ][ 3 ] + DotProduct( s->vecs[ 1 ], vTranslated ); + dv->st[ 0 ] = s->vecs[ 0 ][ 3 ] + vector3_dot( s->vecs[ 0 ].vec3(), vTranslated ); + dv->st[ 1 ] = s->vecs[ 1 ][ 3 ] + vector3_dot( s->vecs[ 1 ].vec3(), vTranslated ); dv->st[ 0 ] /= si->shaderWidth; dv->st[ 1 ] /= si->shaderHeight; } /* copy normal */ - VectorCopy( mapplanes[ s->planenum ].normal, dv->normal ); + dv->normal = mapplanes[ s->planenum ].normal(); /* ydnar: set color */ for ( k = 0; k < MAX_LIGHTMAPS; k++ ) { - dv->color[ k ][ 0 ] = 255; - dv->color[ k ][ 1 ] = 255; - dv->color[ k ][ 2 ] = 255; + dv->color[ k ].set( 255 ); /* ydnar: gs mods: handle indexed shader blending */ - dv->color[ k ][ 3 ] = ( indexed ? shaderIndexes[ j ] : 255 ); + if( indexed ) + dv->color[ k ].alpha() = shaderIndexes[ j ]; } } @@ -1008,26 +987,13 @@ mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, windin moved here from patch.c */ -#define YDNAR_NORMAL_EPSILON 0.50f - -bool VectorCompareExt( vec3_t n1, vec3_t n2, float epsilon ){ - /* test */ - for ( int i = 0; i < 3; i++ ) - if ( fabs( n1[ i ] - n2[ i ] ) > epsilon ) { - return false; - } - return true; -} - mapDrawSurface_t *DrawSurfaceForMesh( entity_t *e, parseMesh_t *p, mesh_t *mesh ){ int i, k, numVerts; - vec4_t plane; + Plane3f plane; bool planar; - float dist; mapDrawSurface_t *ds; shaderInfo_t *si, *parent; bspDrawVert_t *dv; - vec3_t vTranslated; mesh_t *copy; bool indexed; byte shaderIndexes[ MAX_EXPANDED_AXIS * MAX_EXPANDED_AXIS ]; @@ -1056,7 +1022,7 @@ mapDrawSurface_t *DrawSurfaceForMesh( entity_t *e, parseMesh_t *p, mesh_t *mesh /* store off the original (potentially bad) normals */ MakeMeshNormals( *copy ); for ( i = 0; i < numVerts; i++ ) - VectorCopy( copy->verts[ i ].normal, mesh->verts[ i ].normal ); + mesh->verts[ i ].normal = copy->verts[ i ].normal; /* put the mesh on the curve */ PutMeshOnCurve( *copy ); @@ -1066,8 +1032,8 @@ mapDrawSurface_t *DrawSurfaceForMesh( entity_t *e, parseMesh_t *p, mesh_t *mesh for ( i = 0; i < numVerts; i++ ) { /* ydnar: only copy normals that are significantly different from the originals */ - if ( DotProduct( copy->verts[ i ].normal, mesh->verts[ i ].normal ) < 0.75f ) { - VectorCopy( copy->verts[ i ].normal, mesh->verts[ i ].normal ); + if ( vector3_dot( copy->verts[ i ].normal, mesh->verts[ i ].normal ) < 0.75f ) { + mesh->verts[ i ].normal = copy->verts[ i ].normal; } } @@ -1082,7 +1048,7 @@ mapDrawSurface_t *DrawSurfaceForMesh( entity_t *e, parseMesh_t *p, mesh_t *mesh /* get shader indexes for each point */ for ( i = 0; i < numVerts; i++ ) { - shaderIndexes[ i ] = GetShaderIndexForPoint( p->im, p->eMins, p->eMaxs, mesh->verts[ i ].xyz ); + shaderIndexes[ i ] = GetShaderIndexForPoint( p->im, p->eMinmax, mesh->verts[ i ].xyz ); offsets[ i ] = p->im->offsets[ shaderIndexes[ i ] ]; } @@ -1118,12 +1084,12 @@ mapDrawSurface_t *DrawSurfaceForMesh( entity_t *e, parseMesh_t *p, mesh_t *mesh ds->maxIterations = p->maxIterations; /* construct a plane from the first vert */ - VectorCopy( mesh->verts[ 0 ].normal, plane ); - plane[ 3 ] = DotProduct( mesh->verts[ 0 ].xyz, plane ); + plane.normal() = mesh->verts[ 0 ].normal; + plane.dist() = vector3_dot( mesh->verts[ 0 ].xyz, plane.normal() ); planar = true; /* spew forth errors */ - if ( VectorLength( plane ) < 0.001f ) { + if ( vector3_length( plane.normal() ) < 0.001f ) { Sys_Printf( "DrawSurfaceForMesh: bogus plane\n" ); } @@ -1131,13 +1097,12 @@ mapDrawSurface_t *DrawSurfaceForMesh( entity_t *e, parseMesh_t *p, mesh_t *mesh for ( i = 1; i < ds->numVerts && planar; i++ ) { /* normal test */ - if ( !VectorCompare( plane, mesh->verts[ i ].normal ) ) { + if ( !VectorCompare( plane.normal(), mesh->verts[ i ].normal ) ) { planar = false; } /* point-plane test */ - dist = DotProduct( mesh->verts[ i ].xyz, plane ) - plane[ 3 ]; - if ( fabs( dist ) > EQUAL_EPSILON ) { + if ( fabs( plane3_distance_to_point( plane, mesh->verts[ i ].xyz ) ) > EQUAL_EPSILON ) { planar = false; } } @@ -1145,12 +1110,12 @@ mapDrawSurface_t *DrawSurfaceForMesh( entity_t *e, parseMesh_t *p, mesh_t *mesh /* add a map plane */ if ( planar ) { /* make a map plane */ - ds->planeNum = FindFloatPlane( plane, plane[ 3 ], 1, &mesh->verts[ 0 ].xyz ); - VectorCopy( plane, ds->lightmapVecs[ 2 ] ); + ds->planeNum = FindFloatPlane( plane, 1, &mesh->verts[ 0 ].xyz ); + ds->lightmapVecs[ 2 ] = plane.normal(); /* push this normal to all verts (ydnar 2003-02-14: bad idea, small patches get screwed up) */ for ( i = 0; i < ds->numVerts; i++ ) - VectorCopy( plane, ds->verts[ i ].normal ); + ds->verts[ i ].normal = plane.normal(); } /* walk the verts to do special stuff */ @@ -1161,27 +1126,25 @@ mapDrawSurface_t *DrawSurfaceForMesh( entity_t *e, parseMesh_t *p, mesh_t *mesh /* ydnar: tek-fu celshading support for flat shaded shit */ if ( flat ) { - dv->st[ 0 ] = si->stFlat[ 0 ]; - dv->st[ 1 ] = si->stFlat[ 1 ]; + dv->st = si->stFlat; } /* ydnar: gs mods: added support for explicit shader texcoord generation */ else if ( si->tcGen ) { /* translate by origin and project the texture */ - VectorAdd( dv->xyz, e->origin, vTranslated ); - dv->st[ 0 ] = DotProduct( si->vecs[ 0 ], vTranslated ); - dv->st[ 1 ] = DotProduct( si->vecs[ 1 ], vTranslated ); + const Vector3 vTranslated = dv->xyz + e->origin; + dv->st[ 0 ] = vector3_dot( si->vecs[ 0 ], vTranslated ); + dv->st[ 1 ] = vector3_dot( si->vecs[ 1 ], vTranslated ); } /* ydnar: set color */ for ( k = 0; k < MAX_LIGHTMAPS; k++ ) { - dv->color[ k ][ 0 ] = 255; - dv->color[ k ][ 1 ] = 255; - dv->color[ k ][ 2 ] = 255; + dv->color[ k ].set( 255 ); /* ydnar: gs mods: handle indexed shader blending */ - dv->color[ k ][ 3 ] = ( indexed ? shaderIndexes[ i ] : 255 ); + if( indexed ) + dv->color[ k ].alpha() = shaderIndexes[ i ]; } /* ydnar: offset */ @@ -1204,7 +1167,7 @@ mapDrawSurface_t *DrawSurfaceForMesh( entity_t *e, parseMesh_t *p, mesh_t *mesh creates a flare draw surface */ -mapDrawSurface_t *DrawSurfaceForFlare( int entNum, vec3_t origin, vec3_t normal, vec3_t color, const char *flareShader, int lightStyle ){ +mapDrawSurface_t *DrawSurfaceForFlare( int entNum, const Vector3& origin, const Vector3& normal, const Vector3& color, const char *flareShader, int lightStyle ){ mapDrawSurface_t *ds; @@ -1224,15 +1187,9 @@ mapDrawSurface_t *DrawSurfaceForFlare( int entNum, vec3_t origin, vec3_t normal, else{ ds->shaderInfo = ShaderInfoForShader( game->flareShader ); } - if ( origin != NULL ) { - VectorCopy( origin, ds->lightmapOrigin ); - } - if ( normal != NULL ) { - VectorCopy( normal, ds->lightmapVecs[ 2 ] ); - } - if ( color != NULL ) { - VectorCopy( color, ds->lightmapVecs[ 0 ] ); - } + ds->lightmapOrigin = origin; + ds->lightmapVecs[ 2 ] = normal; + ds->lightmapVecs[ 0 ] = color; /* store light style */ ds->lightStyle = lightStyle; @@ -1290,22 +1247,19 @@ mapDrawSurface_t *DrawSurfaceForShader( const char *shader ){ creates flares (coronas) centered on surfaces */ -static void AddSurfaceFlare( mapDrawSurface_t *ds, vec3_t entityOrigin ){ - vec3_t origin; +static void AddSurfaceFlare( mapDrawSurface_t *ds, const Vector3& entityOrigin ){ + Vector3 origin( 0, 0, 0 ); int i; /* find centroid */ - VectorClear( origin ); for ( i = 0; i < ds->numVerts; i++ ) - VectorAdd( origin, ds->verts[ i ].xyz, origin ); - VectorScale( origin, ( 1.0f / ds->numVerts ), origin ); - if ( entityOrigin != NULL ) { - VectorAdd( origin, entityOrigin, origin ); - } + origin += ds->verts[ i ].xyz; + origin /= ds->numVerts; + origin += entityOrigin; /* push origin off surface a bit */ - VectorMA( origin, 2.0f, ds->lightmapVecs[ 2 ], origin ); + origin += ds->lightmapVecs[ 2 ] * 2; /* create the drawsurface */ DrawSurfaceForFlare( ds->entityNum, origin, ds->lightmapVecs[ 2 ], ds->shaderInfo->color, ds->shaderInfo->flareShader, ds->shaderInfo->lightStyle ); @@ -1321,7 +1275,7 @@ static void AddSurfaceFlare( mapDrawSurface_t *ds, vec3_t entityOrigin ){ static void SubdivideFace_r( entity_t *e, brush_t *brush, side_t *side, winding_t *w, int fogNum, float subdivisions ){ int i; int axis; - vec3_t bounds[ 2 ]; + MinMax bounds; const float epsilon = 0.1; int subFloor, subCeil; winding_t *frontWinding, *backWinding; @@ -1337,29 +1291,27 @@ static void SubdivideFace_r( entity_t *e, brush_t *brush, side_t *side, winding_ } /* determine surface bounds */ - ClearBounds( bounds[ 0 ], bounds[ 1 ] ); for ( i = 0; i < w->numpoints; i++ ) - AddPointToBounds( w->p[ i ], bounds[ 0 ], bounds[ 1 ] ); + bounds.extend( w->p[ i ] ); /* split the face */ for ( axis = 0; axis < 3; axis++ ) { - vec3_t planePoint = { 0, 0, 0 }; - vec3_t planeNormal = { 0, 0, 0 }; - float d; + Vector3 planePoint( 0, 0, 0 ); + Plane3f plane( 0, 0, 0, 0 ); /* create an axial clipping plane */ - subFloor = floor( bounds[ 0 ][ axis ] / subdivisions ) * subdivisions; - subCeil = ceil( bounds[ 1 ][ axis ] / subdivisions ) * subdivisions; + subFloor = floor( bounds.mins[ axis ] / subdivisions ) * subdivisions; + subCeil = ceil( bounds.maxs[ axis ] / subdivisions ) * subdivisions; planePoint[ axis ] = subFloor + subdivisions; - planeNormal[ axis ] = -1; - d = DotProduct( planePoint, planeNormal ); + plane.normal()[ axis ] = -1; + plane.dist() = vector3_dot( planePoint, plane.normal() ); /* subdivide if necessary */ if ( ( subCeil - subFloor ) > subdivisions ) { /* clip the winding */ - ClipWindingEpsilon( w, planeNormal, d, epsilon, &frontWinding, &backWinding ); /* not strict; we assume we always keep a winding */ + ClipWindingEpsilon( w, plane, epsilon, &frontWinding, &backWinding ); /* not strict; we assume we always keep a winding */ /* the clip may not produce two polygons if it was epsilon close */ if ( frontWinding == NULL ) { @@ -1436,12 +1388,10 @@ void SubdivideFaceSurfaces( entity_t *e, tree_t *tree ){ ClassifySurfaces( 1, ds ); if ( !CalcSurfaceTextureRange( ds ) ) { /* calculate subdivisions texture range (this code is shit) */ - range = ( ds->texRange[ 0 ] > ds->texRange[ 1 ] ? ds->texRange[ 0 ] : ds->texRange[ 1 ] ); - size = ds->maxs[ 0 ] - ds->mins[ 0 ]; + range = std::max( ds->texRange[ 0 ], ds->texRange[ 1 ] ); + size = ds->minmax.maxs[ 0 ] - ds->minmax.mins[ 0 ]; for ( j = 1; j < 3; j++ ) - if ( ( ds->maxs[ j ] - ds->mins[ j ] ) > size ) { - size = ds->maxs[ j ] - ds->mins[ j ]; - } + size = std::max( size, ds->minmax.maxs[ j ] - ds->minmax.mins[ j ] ); subdivisions = ( size / range ) * texRange; subdivisions = ceil( subdivisions / 2 ) * 2; for ( j = 1; j < 8; j++ ) @@ -1488,7 +1438,6 @@ void SubdivideFaceSurfaces( entity_t *e, tree_t *tree ){ */ void ClipSideIntoTree_r( winding_t *w, side_t *side, node_t *node ){ - plane_t *plane; winding_t *front, *back; if ( !w ) { @@ -1505,8 +1454,8 @@ void ClipSideIntoTree_r( winding_t *w, side_t *side, node_t *node ){ return; } - plane = &mapplanes[ node->planenum ]; - ClipWindingEpsilonStrict( w, plane->normal, plane->dist, + const Plane3f& plane = mapplanes[ node->planenum ].plane; + ClipWindingEpsilonStrict( w, plane, ON_EPSILON, &front, &back ); /* strict, we handle the "winding disappeared" case */ if ( !front && !back ) { /* in doubt, register it in both nodes */ @@ -1523,7 +1472,7 @@ void ClipSideIntoTree_r( winding_t *w, side_t *side, node_t *node ){ // if opaque leaf, don't add if ( !node->opaque ) { - AddWindingToConvexHull( w, &side->visibleHull, mapplanes[ side->planenum ].normal ); + AddWindingToConvexHull( w, &side->visibleHull, mapplanes[ side->planenum ].normal() ); } FreeWinding( w ); @@ -1538,36 +1487,14 @@ static int g_numHiddenFaces, g_numCoinFaces; -/* - CullVectorCompare() - ydnar - compares two vectors with an epsilon - */ - #define CULL_EPSILON 0.1f -bool CullVectorCompare( const vec3_t v1, const vec3_t v2 ){ - int i; - - - for ( i = 0; i < 3; i++ ) - if ( fabs( v1[ i ] - v2[ i ] ) > CULL_EPSILON ) { - return false; - } - return true; -} - - - /* SideInBrush() - ydnar determines if a brushside lies inside another brush */ bool SideInBrush( side_t *side, brush_t *b ){ - int i, s; - plane_t *plane; - - /* ignore sides w/o windings or shaders */ if ( side->winding == NULL || side->shaderInfo == NULL ) { return true; @@ -1579,7 +1506,7 @@ bool SideInBrush( side_t *side, brush_t *b ){ } /* side iterator */ - for ( i = 0; i < b->numsides; i++ ) + for ( int i = 0; i < b->numsides; i++ ) { /* fail if any sides are caulk */ if ( b->sides[ i ].compileFlags & C_NODRAW ) { @@ -1587,12 +1514,12 @@ bool SideInBrush( side_t *side, brush_t *b ){ } /* check if side's winding is on or behind the plane */ - plane = &mapplanes[ b->sides[ i ].planenum ]; - s = WindingOnPlaneSide( side->winding, plane->normal, plane->dist ); - if ( s == SIDE_FRONT || s == SIDE_CROSS ) { + const Plane3f& plane = mapplanes[ b->sides[ i ].planenum ].plane; + const EPlaneSide s = WindingOnPlaneSide( side->winding, plane ); + if ( s == eSideFront || s == eSideCross ) { return false; } - if( s == SIDE_ON && b->sides[ i ].culled && DotProduct( ( mapplanes[ side->planenum ].normal ), ( plane->normal ) ) > 0 ) /* don't cull by freshly culled with matching plane */ + if( s == eSideOn && b->sides[ i ].culled && vector3_dot( mapplanes[ side->planenum ].normal(), plane.normal() ) > 0 ) /* don't cull by freshly culled with matching plane */ return false; } @@ -1651,12 +1578,7 @@ void CullSides( entity_t *e ){ } /* bbox check */ - j = 0; - for ( i = 0; i < 3; i++ ) - if ( b1->mins[ i ] > b2->maxs[ i ] || b1->maxs[ i ] < b2->mins[ i ] ) { - j++; - } - if ( j ) { + if ( !b1->minmax.test( b2->minmax ) ) { continue; } @@ -1736,7 +1658,7 @@ void CullSides( entity_t *e ){ else{ second = 0; } - if ( CullVectorCompare( w1->p[ 1 ], w2->p[ second ] ) ) { + if ( vector3_equal_epsilon( w1->p[ 1 ], w2->p[ second ], CULL_EPSILON ) ) { dir = 1; } else @@ -1747,7 +1669,7 @@ void CullSides( entity_t *e ){ else{ second = numPoints - 1; } - if ( CullVectorCompare( w1->p[ 1 ], w2->p[ second ] ) ) { + if ( vector3_equal_epsilon( w1->p[ 1 ], w2->p[ second ], CULL_EPSILON ) ) { dir = -1; } } @@ -1759,7 +1681,7 @@ void CullSides( entity_t *e ){ l = first; for ( k = 0; k < numPoints; k++ ) { - if ( !CullVectorCompare( w1->p[ k ], w2->p[ l ] ) ) { + if ( !vector3_equal_epsilon( w1->p[ k ], w2->p[ l ], CULL_EPSILON ) ) { k = 100000; } @@ -1972,7 +1894,7 @@ int AddReferenceToTree_r( mapDrawSurface_t *ds, node_t *node, bool skybox ){ /* increase the leaf bounds */ for ( i = 0; i < ds->numVerts; i++ ) - AddPointToBounds( ds->verts[ i ].xyz, node->mins, node->maxs ); + node->minmax.extend( ds->verts[ i ].xyz ); } /* add a reference */ @@ -1986,17 +1908,15 @@ int AddReferenceToTree_r( mapDrawSurface_t *ds, node_t *node, bool skybox ){ filters a single point from a surface into the tree */ -int FilterPointIntoTree_r( vec3_t point, mapDrawSurface_t *ds, node_t *node ){ +int FilterPointIntoTree_r( const Vector3& point, mapDrawSurface_t *ds, node_t *node ){ float d; - plane_t *plane; int refs = 0; /* is this a decision node? */ if ( node->planenum != PLANENUM_LEAF ) { /* classify the point in relation to the plane */ - plane = &mapplanes[ node->planenum ]; - d = DotProduct( point, plane->normal ) - plane->dist; + d = plane3_distance_to_point( mapplanes[ node->planenum ].plane, point ); /* filter by this plane */ refs = 0; @@ -2020,9 +1940,8 @@ int FilterPointIntoTree_r( vec3_t point, mapDrawSurface_t *ds, node_t *node ){ filters the convex hull of multiple points from a surface into the tree */ -int FilterPointConvexHullIntoTree_r( vec3_t **points, int npoints, mapDrawSurface_t *ds, node_t *node ){ +int FilterPointConvexHullIntoTree_r( Vector3 *points[], const int npoints, mapDrawSurface_t *ds, node_t *node ){ float d, dmin, dmax; - plane_t *plane; int refs = 0; int i; @@ -2033,12 +1952,12 @@ int FilterPointConvexHullIntoTree_r( vec3_t **points, int npoints, mapDrawSurfac /* is this a decision node? */ if ( node->planenum != PLANENUM_LEAF ) { /* classify the point in relation to the plane */ - plane = &mapplanes[ node->planenum ]; + const Plane3f& plane = mapplanes[ node->planenum ].plane; - dmin = dmax = DotProduct( *( points[0] ), plane->normal ) - plane->dist; + dmin = dmax = plane3_distance_to_point( plane, *points[0] ); for ( i = 1; i < npoints; ++i ) { - d = DotProduct( *( points[i] ), plane->normal ) - plane->dist; + d = plane3_distance_to_point( plane, *points[i] ); if ( d > dmax ) { dmax = d; } @@ -2072,8 +1991,6 @@ int FilterPointConvexHullIntoTree_r( vec3_t **points, int npoints, mapDrawSurfac int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ){ int i, refs = 0; - plane_t *p1; - vec4_t plane1; winding_t *fat, *front, *back; shaderInfo_t *si; @@ -2083,9 +2000,9 @@ int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ){ /* ydnar: is this the head node? */ if ( node->parent == NULL && si != NULL && - ( si->mins[ 0 ] != 0.0f || si->maxs[ 0 ] != 0.0f || - si->mins[ 1 ] != 0.0f || si->maxs[ 1 ] != 0.0f || - si->mins[ 2 ] != 0.0f || si->maxs[ 2 ] != 0.0f ) ) { + ( si->minmax.mins[ 0 ] != 0.0f || si->minmax.maxs[ 0 ] != 0.0f || + si->minmax.mins[ 1 ] != 0.0f || si->minmax.maxs[ 1 ] != 0.0f || + si->minmax.mins[ 2 ] != 0.0f || si->minmax.maxs[ 2 ] != 0.0f ) ) { static bool warned = false; if ( !warned ) { Sys_Warning( "this map uses the deformVertexes move hack\n" ); @@ -2098,13 +2015,13 @@ int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ){ fat->numpoints = w->numpoints * 3 + 3; for ( i = 0; i < w->numpoints; i++ ) { - VectorCopy( w->p[ i ], fat->p[ i ] ); - VectorAdd( w->p[ i ], si->mins, fat->p[ i + ( w->numpoints + 1 ) ] ); - VectorAdd( w->p[ i ], si->maxs, fat->p[ i + ( w->numpoints + 1 ) * 2 ] ); + fat->p[ i ] = w->p[ i ]; + fat->p[ i + ( w->numpoints + 1 ) ] = w->p[ i ] + si->minmax.mins; + fat->p[ i + ( w->numpoints + 1 ) * 2 ] = w->p[ i ] + si->minmax.maxs; } - VectorCopy( w->p[ 0 ], fat->p[ i ] ); - VectorAdd( w->p[ 0 ], si->mins, fat->p[ i + w->numpoints ] ); - VectorAdd( w->p[ 0 ], si->maxs, fat->p[ i + w->numpoints * 2 ] ); + fat->p[ i ] = w->p[ 0 ]; + fat->p[ i + w->numpoints ] = w->p[ 0 ] + si->minmax.mins; + fat->p[ i + w->numpoints * 2 ] = w->p[ 0 ] + si->minmax.maxs; /* * note: this winding is STILL not suitable for ClipWindingEpsilon, and @@ -2121,33 +2038,23 @@ int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ){ /* is this a decision node? */ if ( node->planenum != PLANENUM_LEAF ) { /* get node plane */ - p1 = &mapplanes[ node->planenum ]; - VectorCopy( p1->normal, plane1 ); - plane1[ 3 ] = p1->dist; + const Plane3f plane1 = mapplanes[ node->planenum ].plane; /* check if surface is planar */ if ( ds->planeNum >= 0 ) { #if 0 - plane_t *p2; - vec4_t plane2; - /* get surface plane */ - p2 = &mapplanes[ ds->planeNum ]; - VectorCopy( p2->normal, plane2 ); - plane2[ 3 ] = p2->dist; + const Plane3f plane2 = mapplanes[ ds->planeNum ].plane; /* div0: this is the plague (inaccurate) */ - vec4_t reverse; - /* invert surface plane */ - VectorSubtract( vec3_origin, plane2, reverse ); - reverse[ 3 ] = -plane2[ 3 ]; + const Plane3f reverse = plane3_flipped( plane2 ); /* compare planes */ - if ( DotProduct( plane1, plane2 ) > 0.999f && fabs( plane1[ 3 ] - plane2[ 3 ] ) < 0.001f ) { + if ( vector3_dot( plane1.normal(), plane2.normal() ) > 0.999f && fabs( plane1.dist() - plane2.dist() ) < 0.001f ) { return FilterWindingIntoTree_r( w, ds, node->children[ 0 ] ); } - if ( DotProduct( plane1, reverse ) > 0.999f && fabs( plane1[ 3 ] - reverse[ 3 ] ) < 0.001f ) { + if ( vector3_dot( plane1.normal(), reverse.normal() ) > 0.999f && fabs( plane1.dist() - reverse.dist() ) < 0.001f ) { return FilterWindingIntoTree_r( w, ds, node->children[ 1 ] ); } #else @@ -2164,7 +2071,7 @@ int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ){ } /* clip the winding by this plane */ - ClipWindingEpsilonStrict( w, plane1, plane1[ 3 ], ON_EPSILON, &front, &back ); /* strict; we handle the "winding disappeared" case */ + ClipWindingEpsilonStrict( w, plane1, ON_EPSILON, &front, &back ); /* strict; we handle the "winding disappeared" case */ /* filter by this plane */ refs = 0; @@ -2225,7 +2132,7 @@ static int FilterPatchIntoTree( mapDrawSurface_t *ds, tree_t *tree ){ for ( y = 0; y + 2 < ds->patchHeight; y += 2 ) for ( x = 0; x + 2 < ds->patchWidth; x += 2 ) { - vec3_t *points[9]; + Vector3 *points[9]; points[0] = &ds->verts[( y + 0 ) * ds->patchWidth + ( x + 0 )].xyz; points[1] = &ds->verts[( y + 0 ) * ds->patchWidth + ( x + 1 )].xyz; points[2] = &ds->verts[( y + 0 ) * ds->patchWidth + ( x + 2 )].xyz; @@ -2267,9 +2174,9 @@ static int FilterTrianglesIntoTree( mapDrawSurface_t *ds, tree_t *tree ){ /* make a triangle winding and filter it into the tree */ w = AllocWinding( 3 ); w->numpoints = 3; - VectorCopy( ds->verts[ ds->indexes[ i ] ].xyz, w->p[ 0 ] ); - VectorCopy( ds->verts[ ds->indexes[ i + 1 ] ].xyz, w->p[ 1 ] ); - VectorCopy( ds->verts[ ds->indexes[ i + 2 ] ].xyz, w->p[ 2 ] ); + w->p[ 0 ] = ds->verts[ ds->indexes[ i ] ].xyz; + w->p[ 1 ] = ds->verts[ ds->indexes[ i + 1 ] ].xyz; + w->p[ 2 ] = ds->verts[ ds->indexes[ i + 2 ] ].xyz; refs += FilterWindingIntoTree_r( w, ds, tree->headnode ); } @@ -2290,7 +2197,6 @@ static int FilterTrianglesIntoTree( mapDrawSurface_t *ds, tree_t *tree ){ static int FilterFoliageIntoTree( mapDrawSurface_t *ds, tree_t *tree ){ int f, i, refs; bspDrawVert_t *instance; - vec3_t xyz; winding_t *w; @@ -2314,17 +2220,16 @@ static int FilterFoliageIntoTree( mapDrawSurface_t *ds, tree_t *tree ){ /* make a triangle winding and filter it into the tree */ w = AllocWinding( 3 ); w->numpoints = 3; - VectorAdd( instance->xyz, ds->verts[ ds->indexes[ i ] ].xyz, w->p[ 0 ] ); - VectorAdd( instance->xyz, ds->verts[ ds->indexes[ i + 1 ] ].xyz, w->p[ 1 ] ); - VectorAdd( instance->xyz, ds->verts[ ds->indexes[ i + 2 ] ].xyz, w->p[ 2 ] ); + w->p[ 0 ] = instance->xyz + ds->verts[ ds->indexes[ i ] ].xyz; + w->p[ 1 ] = instance->xyz + ds->verts[ ds->indexes[ i + 1 ] ].xyz; + w->p[ 2 ] = instance->xyz + ds->verts[ ds->indexes[ i + 2 ] ].xyz; refs += FilterWindingIntoTree_r( w, ds, tree->headnode ); } /* use point filtering as well */ for ( i = 0; i < ( ds->numVerts - ds->numFoliageInstances ); i++ ) { - VectorAdd( instance->xyz, ds->verts[ i ].xyz, xyz ); - refs += FilterPointIntoTree_r( xyz, ds, tree->headnode ); + refs += FilterPointIntoTree_r( instance->xyz + ds->verts[ i ].xyz, ds, tree->headnode ); } } @@ -2373,20 +2278,20 @@ void EmitDrawVerts( mapDrawSurface_t *ds, bspDrawSurface_t *out ){ /* offset? */ if ( offset != 0.0f ) { - VectorMA( dv->xyz, offset, dv->normal, dv->xyz ); + dv->xyz += dv->normal * offset; } /* expand model bounds necessary because of misc_model surfaces on entities note: does not happen on worldspawn as its bounds is only used for determining lightgrid bounds */ if ( numBSPModels > 0 ) { - AddPointToBounds( dv->xyz, bspModels[ numBSPModels ].mins, bspModels[ numBSPModels ].maxs ); + bspModels[ numBSPModels ].minmax.extend( dv->xyz ); } /* debug color? */ if ( debugSurfaces ) { for ( k = 0; k < MAX_LIGHTMAPS; k++ ) - VectorCopy( debugColors[ ( ds - mapDrawSurfs ) % 12 ], dv->color[ k ] ); + dv->color[ k ].rgb() = debugColors[ ( ds - mapDrawSurfs ) % 12 ]; } } } @@ -2544,10 +2449,10 @@ void EmitFlareSurface( mapDrawSurface_t *ds ){ out->lightmapStyles[ 0 ] = ds->lightStyle; out->vertexStyles[ 0 ] = ds->lightStyle; - VectorCopy( ds->lightmapOrigin, out->lightmapOrigin ); /* origin */ - VectorCopy( ds->lightmapVecs[ 0 ], out->lightmapVecs[ 0 ] ); /* color */ - VectorCopy( ds->lightmapVecs[ 1 ], out->lightmapVecs[ 1 ] ); - VectorCopy( ds->lightmapVecs[ 2 ], out->lightmapVecs[ 2 ] ); /* normal */ + out->lightmapOrigin = ds->lightmapOrigin; /* origin */ + out->lightmapVecs[ 0 ] = ds->lightmapVecs[ 0 ]; /* color */ + out->lightmapVecs[ 1 ] = ds->lightmapVecs[ 1 ]; + out->lightmapVecs[ 2 ] = ds->lightmapVecs[ 2 ]; /* normal */ /* add to count */ numSurfacesByType[ static_cast( ds->type ) ]++; @@ -2572,7 +2477,7 @@ void EmitPatchSurface( entity_t *e, mapDrawSurface_t *ds ){ /* walk the verts, flip the normal */ for ( i = 0; i < ds->numVerts; i++ ) - VectorScale( ds->verts[ i ].normal, -1.0f, ds->verts[ i ].normal ); + vector3_negate( ds->verts[ i ].normal ); /* walk the verts again, but this time reverse their order */ for ( j = 0; j < ds->patchHeight; j++ ) @@ -2588,7 +2493,7 @@ void EmitPatchSurface( entity_t *e, mapDrawSurface_t *ds ){ } /* invert facing */ - VectorScale( ds->lightmapVecs[ 2 ], -1.0f, ds->lightmapVecs[ 2 ] ); + vector3_negate( ds->lightmapVecs[ 2 ] ); } /* allocate a new surface */ @@ -2613,8 +2518,8 @@ void EmitPatchSurface( entity_t *e, mapDrawSurface_t *ds ){ ApplySurfaceParm( "pointlight", &contentFlags, &surfaceFlags, NULL ); /* we don't want this patch getting lightmapped */ - VectorClear( ds->lightmapVecs[ 2 ] ); - VectorClear( ds->lightmapAxis ); + ds->lightmapVecs[ 2 ].set( 0 ); + ds->lightmapAxis.set( 0 ); ds->sampleSize = 0; /* emit the new fake shader */ @@ -2638,14 +2543,14 @@ void EmitPatchSurface( entity_t *e, mapDrawSurface_t *ds ){ out->vertexStyles[ 0 ] = LS_NORMAL; /* ydnar: gs mods: previously, the lod bounds were stored in lightmapVecs[ 0 ] and [ 1 ], moved to bounds[ 0 ] and [ 1 ] */ - VectorCopy( ds->lightmapOrigin, out->lightmapOrigin ); - VectorCopy( ds->bounds[ 0 ], out->lightmapVecs[ 0 ] ); - VectorCopy( ds->bounds[ 1 ], out->lightmapVecs[ 1 ] ); - VectorCopy( ds->lightmapVecs[ 2 ], out->lightmapVecs[ 2 ] ); + out->lightmapOrigin = ds->lightmapOrigin; + out->lightmapVecs[ 0 ] = ds->bounds.mins; + out->lightmapVecs[ 1 ] = ds->bounds.maxs; + out->lightmapVecs[ 2 ] = ds->lightmapVecs[ 2 ]; /* ydnar: gs mods: clear out the plane normal */ if ( !ds->planar ) { - VectorClear( out->lightmapVecs[ 2 ] ); + out->lightmapVecs[ 2 ].set( 0 ); } /* emit the verts and indexes */ @@ -2796,10 +2701,10 @@ void EmitTriangleSurface( mapDrawSurface_t *ds ){ /* walk the verts, flip the normal */ for ( i = 0; i < ds->numVerts; i++ ) - VectorScale( ds->verts[ i ].normal, -1.0f, ds->verts[ i ].normal ); + vector3_negate( ds->verts[ i ].normal ); /* invert facing */ - VectorScale( ds->lightmapVecs[ 2 ], -1.0f, ds->lightmapVecs[ 2 ] ); + vector3_negate( ds->lightmapVecs[ 2 ] ); } /* allocate a new surface */ @@ -2817,8 +2722,8 @@ void EmitTriangleSurface( mapDrawSurface_t *ds ){ } /* ydnar: gs mods: handle lightmapped terrain (force to planar type) */ - //% else if( VectorLength( ds->lightmapAxis ) <= 0.0f || ds->type == ESurfaceType::Triangles || ds->type == ESurfaceType::Foghull || debugSurfaces ) - else if ( ( VectorLength( ds->lightmapAxis ) <= 0.0f && !ds->planar ) || + //% else if( vector3_length( ds->lightmapAxis ) <= 0.0f || ds->type == ESurfaceType::Triangles || ds->type == ESurfaceType::Foghull || debugSurfaces ) + else if ( ( vector3_length( ds->lightmapAxis ) <= 0.0f && !ds->planar ) || ds->type == ESurfaceType::Triangles || ds->type == ESurfaceType::Foghull || ds->numVerts > maxLMSurfaceVerts || @@ -2845,8 +2750,6 @@ void EmitTriangleSurface( mapDrawSurface_t *ds ){ /* debug inset (push each triangle vertex towards the center of each triangle it is on */ if ( debugInset ) { bspDrawVert_t *a, *b, *c; - vec3_t cent, dir; - /* walk triangle list */ for ( i = 0; i < ds->numIndexes; i += 3 ) @@ -2857,21 +2760,12 @@ void EmitTriangleSurface( mapDrawSurface_t *ds ){ c = &ds->verts[ ds->indexes[ i + 2 ] ]; /* calculate centroid */ - VectorCopy( a->xyz, cent ); - VectorAdd( cent, b->xyz, cent ); - VectorAdd( cent, c->xyz, cent ); - VectorScale( cent, 1.0f / 3.0f, cent ); + const Vector3 cent = ( a->xyz + b->xyz + c->xyz ) / 3; /* offset each vertex */ - VectorSubtract( cent, a->xyz, dir ); - VectorNormalize( dir, dir ); - VectorAdd( a->xyz, dir, a->xyz ); - VectorSubtract( cent, b->xyz, dir ); - VectorNormalize( dir, dir ); - VectorAdd( b->xyz, dir, b->xyz ); - VectorSubtract( cent, c->xyz, dir ); - VectorNormalize( dir, dir ); - VectorAdd( c->xyz, dir, c->xyz ); + a->xyz += VectorNormalized( cent - a->xyz ); + b->xyz += VectorNormalized( cent - b->xyz ); + c->xyz += VectorNormalized( cent - c->xyz ); } } @@ -2886,14 +2780,14 @@ void EmitTriangleSurface( mapDrawSurface_t *ds ){ out->vertexStyles[ 0 ] = LS_NORMAL; /* lightmap vectors (lod bounds for patches */ - VectorCopy( ds->lightmapOrigin, out->lightmapOrigin ); - VectorCopy( ds->lightmapVecs[ 0 ], out->lightmapVecs[ 0 ] ); - VectorCopy( ds->lightmapVecs[ 1 ], out->lightmapVecs[ 1 ] ); - VectorCopy( ds->lightmapVecs[ 2 ], out->lightmapVecs[ 2 ] ); + out->lightmapOrigin = ds->lightmapOrigin; + out->lightmapVecs[ 0 ] = ds->lightmapVecs[ 0 ]; + out->lightmapVecs[ 1 ] = ds->lightmapVecs[ 1 ]; + out->lightmapVecs[ 2 ] = ds->lightmapVecs[ 2 ]; /* ydnar: gs mods: clear out the plane normal */ if ( !ds->planar ) { - VectorClear( out->lightmapVecs[ 2 ] ); + out->lightmapVecs[ 2 ].set( 0 ); } /* optimize the surface's triangles */ @@ -2975,8 +2869,8 @@ static void MakeDebugPortalSurfs_r( node_t *node, shaderInfo_t *si ){ ds->shaderInfo = si; ds->planar = true; ds->sideRef = AllocSideRef( p->side, NULL ); - ds->planeNum = FindFloatPlane( p->plane.normal, p->plane.dist, 0, NULL ); - VectorCopy( p->plane.normal, ds->lightmapVecs[ 2 ] ); + ds->planeNum = FindFloatPlane( p->plane.plane, 0, NULL ); + ds->lightmapVecs[ 2 ] = p->plane.normal(); ds->fogNum = -1; ds->numVerts = w->numpoints; ds->verts = safe_calloc( ds->numVerts * sizeof( *ds->verts ) ); @@ -2988,14 +2882,14 @@ static void MakeDebugPortalSurfs_r( node_t *node, shaderInfo_t *si ){ dv = ds->verts + i; /* set it */ - VectorCopy( w->p[ i ], dv->xyz ); - VectorCopy( p->plane.normal, dv->normal ); + dv->xyz = w->p[ i ]; + dv->normal = p->plane.normal(); dv->st[ 0 ] = 0; dv->st[ 1 ] = 0; for ( k = 0; k < MAX_LIGHTMAPS; k++ ) { - VectorCopy( debugColors[ c % 12 ], dv->color[ k ] ); - dv->color[ k ][ 3 ] = 32; + dv->color[ k ].rgb() = debugColors[ c % 12 ]; + dv->color[ k ].alpha() = 32; } } } @@ -3033,8 +2927,7 @@ void MakeDebugPortalSurfs( tree_t *tree ){ void MakeFogHullSurfs( entity_t *e, tree_t *tree, const char *shader ){ shaderInfo_t *si; mapDrawSurface_t *ds; - vec3_t fogMins, fogMaxs; - int i, indexes[] = + int indexes[] = { 0, 1, 2, 0, 2, 3, 4, 7, 5, 5, 7, 6, @@ -3054,13 +2947,8 @@ void MakeFogHullSurfs( entity_t *e, tree_t *tree, const char *shader ){ Sys_FPrintf( SYS_VRB, "--- MakeFogHullSurfs ---\n" ); /* get hull bounds */ - VectorCopy( mapMins, fogMins ); - VectorCopy( mapMaxs, fogMaxs ); - for ( i = 0; i < 3; i++ ) - { - fogMins[ i ] -= 128; - fogMaxs[ i ] += 128; - } + const Vector3 fogMins = g_mapMinmax.mins - Vector3( 128, 128, 128 ); + const Vector3 fogMaxs = g_mapMinmax.maxs + Vector3( 128, 128, 128 ); /* get foghull shader */ si = ShaderInfoForShader( shader ); @@ -3075,15 +2963,15 @@ void MakeFogHullSurfs( entity_t *e, tree_t *tree, const char *shader ){ ds->indexes = safe_calloc( ds->numIndexes * sizeof( *ds->indexes ) ); /* set verts */ - VectorSet( ds->verts[ 0 ].xyz, fogMins[ 0 ], fogMins[ 1 ], fogMins[ 2 ] ); - VectorSet( ds->verts[ 1 ].xyz, fogMins[ 0 ], fogMaxs[ 1 ], fogMins[ 2 ] ); - VectorSet( ds->verts[ 2 ].xyz, fogMaxs[ 0 ], fogMaxs[ 1 ], fogMins[ 2 ] ); - VectorSet( ds->verts[ 3 ].xyz, fogMaxs[ 0 ], fogMins[ 1 ], fogMins[ 2 ] ); + ds->verts[ 0 ].xyz = { fogMins[ 0 ], fogMins[ 1 ], fogMins[ 2 ] }; + ds->verts[ 1 ].xyz = { fogMins[ 0 ], fogMaxs[ 1 ], fogMins[ 2 ] }; + ds->verts[ 2 ].xyz = { fogMaxs[ 0 ], fogMaxs[ 1 ], fogMins[ 2 ] }; + ds->verts[ 3 ].xyz = { fogMaxs[ 0 ], fogMins[ 1 ], fogMins[ 2 ] }; - VectorSet( ds->verts[ 4 ].xyz, fogMins[ 0 ], fogMins[ 1 ], fogMaxs[ 2 ] ); - VectorSet( ds->verts[ 5 ].xyz, fogMins[ 0 ], fogMaxs[ 1 ], fogMaxs[ 2 ] ); - VectorSet( ds->verts[ 6 ].xyz, fogMaxs[ 0 ], fogMaxs[ 1 ], fogMaxs[ 2 ] ); - VectorSet( ds->verts[ 7 ].xyz, fogMaxs[ 0 ], fogMins[ 1 ], fogMaxs[ 2 ] ); + ds->verts[ 4 ].xyz = { fogMins[ 0 ], fogMins[ 1 ], fogMaxs[ 2 ] }; + ds->verts[ 5 ].xyz = { fogMins[ 0 ], fogMaxs[ 1 ], fogMaxs[ 2 ] }; + ds->verts[ 6 ].xyz = { fogMaxs[ 0 ], fogMaxs[ 1 ], fogMaxs[ 2 ] }; + ds->verts[ 7 ].xyz = { fogMaxs[ 0 ], fogMins[ 1 ], fogMaxs[ 2 ] }; /* set indexes */ memcpy( ds->indexes, indexes, ds->numIndexes * sizeof( *ds->indexes ) ); @@ -3134,23 +3022,15 @@ int AddSurfaceModelsToTriangle_r( mapDrawSurface_t *ds, const surfaceModel_t& mo /* subdivide calc */ { int i; - float *a, *b, dx, dy, dz, dist, maxDist; /* find the longest edge and split it */ max = -1; - maxDist = 0.0f; + float maxDist = 0.0f; for ( i = 0; i < 3; i++ ) { - /* get verts */ - a = tri[ i ]->xyz; - b = tri[ ( i + 1 ) % 3 ]->xyz; - - /* get dists */ - dx = a[ 0 ] - b[ 0 ]; - dy = a[ 1 ] - b[ 1 ]; - dz = a[ 2 ] - b[ 2 ]; - dist = ( dx * dx ) + ( dy * dy ) + ( dz * dz ); + /* get dist */ + const float dist = vector3_length_squared( tri[ i ]->xyz - tri[ ( i + 1 ) % 3 ]->xyz ); /* longer? */ if ( dist > maxDist ) { @@ -3162,12 +3042,11 @@ int AddSurfaceModelsToTriangle_r( mapDrawSurface_t *ds, const surfaceModel_t& mo /* is the triangle small enough? */ if ( max < 0 || maxDist <= ( model.density * model.density ) ) { float odds, r, angle; - vec3_t origin, normal, scale, axis[ 3 ], angles; - m4x4_t transform, temp; + Vector3 axis[ 3 ]; /* roll the dice (model's odds scaled by vertex alpha) */ - odds = model.odds * ( tri[ 0 ]->color[ 0 ][ 3 ] + tri[ 0 ]->color[ 0 ][ 3 ] + tri[ 0 ]->color[ 0 ][ 3 ] ) / 765.0f; + odds = model.odds * ( tri[ 0 ]->color[ 0 ].alpha() + tri[ 0 ]->color[ 0 ].alpha() + tri[ 0 ]->color[ 0 ].alpha() ) / 765.0f; r = Random(); if ( r > odds ) { return 0; @@ -3175,63 +3054,55 @@ int AddSurfaceModelsToTriangle_r( mapDrawSurface_t *ds, const surfaceModel_t& mo /* calculate scale */ r = model.minScale + Random() * ( model.maxScale - model.minScale ); - VectorSet( scale, r, r, r ); + const Vector3 scale( r, r, r ); /* calculate angle */ angle = model.minAngle + Random() * ( model.maxAngle - model.minAngle ); + /* set angles */ + const Vector3 angles( 0, 0, angle ); + /* calculate average origin */ - VectorCopy( tri[ 0 ]->xyz, origin ); - VectorAdd( origin, tri[ 1 ]->xyz, origin ); - VectorAdd( origin, tri[ 2 ]->xyz, origin ); - VectorScale( origin, ( 1.0f / 3.0f ), origin ); + const Vector3 origin = ( tri[ 0 ]->xyz + tri[ 1 ]->xyz + tri[ 2 ]->xyz ) / 3; /* clear transform matrix */ - m4x4_identity( transform ); + Matrix4 transform( g_matrix4_identity ); /* handle oriented models */ if ( model.oriented ) { - /* set angles */ - VectorSet( angles, 0.0f, 0.0f, angle ); - /* calculate average normal */ - VectorCopy( tri[ 0 ]->normal, normal ); - VectorAdd( normal, tri[ 1 ]->normal, normal ); - VectorAdd( normal, tri[ 2 ]->normal, normal ); - if ( VectorNormalize( normal, axis[ 2 ] ) == 0.0f ) { - VectorCopy( tri[ 0 ]->normal, axis[ 2 ] ); + axis[ 2 ] = tri[ 0 ]->normal + tri[ 1 ]->normal + tri[ 2 ]->normal; + if ( VectorNormalize( axis[ 2 ] ) == 0.0f ) { + axis[ 2 ] = tri[ 0 ]->normal; } /* make perpendicular vectors */ MakeNormalVectors( axis[ 2 ], axis[ 1 ], axis[ 0 ] ); /* copy to matrix */ - m4x4_identity( temp ); - temp[ 0 ] = axis[ 0 ][ 0 ]; temp[ 1 ] = axis[ 0 ][ 1 ]; temp[ 2 ] = axis[ 0 ][ 2 ]; - temp[ 4 ] = axis[ 1 ][ 0 ]; temp[ 5 ] = axis[ 1 ][ 1 ]; temp[ 6 ] = axis[ 1 ][ 2 ]; - temp[ 8 ] = axis[ 2 ][ 0 ]; temp[ 9 ] = axis[ 2 ][ 1 ]; temp[ 10 ] = axis[ 2 ][ 2 ]; + Matrix4 temp( g_matrix4_identity ); + temp.x().vec3() = axis[0]; + temp.y().vec3() = axis[1]; + temp.z().vec3() = axis[2]; /* scale */ - m4x4_scale_by_vec3( temp, scale ); + matrix4_scale_by_vec3( temp, scale ); /* rotate around z axis */ - m4x4_rotate_by_vec3( temp, angles, eXYZ ); + matrix4_rotate_by_euler_xyz_degrees( temp, angles ); /* translate */ - m4x4_translate_by_vec3( transform, origin ); + matrix4_translate_by_vec3( transform, origin ); /* tranform into axis space */ - m4x4_multiply_by_m4x4( transform, temp ); + matrix4_multiply_by_matrix4( transform, temp ); } /* handle z-up models */ else { - /* set angles */ - VectorSet( angles, 0.0f, 0.0f, angle ); - /* set matrix */ - m4x4_pivoted_transform_by_vec3( transform, origin, angles, eXYZ, scale, vec3_origin ); + matrix4_transform_by_euler_xyz_degrees( transform, origin, angles, scale ); } /* insert the model */ @@ -3305,22 +3176,18 @@ int AddSurfaceModels( mapDrawSurface_t *ds ){ /* walk verts */ for ( i = 0; i < ds->numVerts; i++ ) { - VectorAdd( centroid.xyz, ds->verts[ i ].xyz, centroid.xyz ); - VectorAdd( centroid.normal, ds->verts[ i ].normal, centroid.normal ); - centroid.st[ 0 ] += ds->verts[ i ].st[ 0 ]; - centroid.st[ 1 ] += ds->verts[ i ].st[ 1 ]; - alpha += ds->verts[ i ].color[ 0 ][ 3 ]; + centroid.xyz += ds->verts[ i ].xyz; + centroid.normal += ds->verts[ i ].normal; + centroid.st += ds->verts[ i ].st; + alpha += ds->verts[ i ].color[ 0 ].alpha(); } /* average */ - centroid.xyz[ 0 ] /= ds->numVerts; - centroid.xyz[ 1 ] /= ds->numVerts; - centroid.xyz[ 2 ] /= ds->numVerts; - if ( VectorNormalize( centroid.normal, centroid.normal ) == 0.0f ) { - VectorCopy( ds->verts[ 0 ].normal, centroid.normal ); + centroid.xyz /= ds->numVerts; + if ( VectorNormalize( centroid.normal ) == 0.0f ) { + centroid.normal = ds->verts[ 0 ].normal; } - centroid.st[ 0 ] /= ds->numVerts; - centroid.st[ 1 ] /= ds->numVerts; + centroid.st /= ds->numVerts; alpha /= ds->numVerts; centroid.color[ 0 ][ 0 ] = 0xFF; centroid.color[ 0 ][ 1 ] = 0xFF; @@ -3458,9 +3325,7 @@ void AddEntitySurfaceModels( entity_t *e ){ static void VolumeColorMods( entity_t *e, mapDrawSurface_t *ds ){ int i, j; - float d; brush_t *b; - plane_t *plane; /* early out */ @@ -3477,9 +3342,7 @@ static void VolumeColorMods( entity_t *e, mapDrawSurface_t *ds ){ } /* test bbox */ - if ( b->mins[ 0 ] > ds->maxs[ 0 ] || b->maxs[ 0 ] < ds->mins[ 0 ] || - b->mins[ 1 ] > ds->maxs[ 1 ] || b->maxs[ 1 ] < ds->mins[ 1 ] || - b->mins[ 2 ] > ds->maxs[ 2 ] || b->maxs[ 2 ] < ds->mins[ 2 ] ) { + if ( !b->minmax.test( ds->minmax ) ) { continue; } @@ -3490,9 +3353,7 @@ static void VolumeColorMods( entity_t *e, mapDrawSurface_t *ds ){ for ( j = 0; j < b->numsides; j++ ) { /* point-plane test */ - plane = &mapplanes[ b->sides[ j ].planenum ]; - d = DotProduct( ds->verts[ i ].xyz, plane->normal ) - plane->dist; - if ( d > 1.0f ) { + if ( plane3_distance_to_point( mapplanes[ b->sides[ j ].planenum ].plane, ds->verts[ i ].xyz ) > 1.0f ) { break; } } @@ -3518,7 +3379,6 @@ void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree ){ int i, j; mapDrawSurface_t *ds; shaderInfo_t *si; - vec3_t origin, mins, maxs; int refs; int numSurfs, numRefs, numSkyboxSurfaces; bool sb; @@ -3590,16 +3450,11 @@ void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree ){ /* ydnar: globalizing of fog volume handling (eek a hack) */ if ( e != &entities[0] && !si->noFog ) { - /* find surface origin and offset by entity origin */ - VectorAdd( ds->mins, ds->maxs, origin ); - VectorScale( origin, 0.5f, origin ); - VectorAdd( origin, e->origin, origin ); - - VectorAdd( ds->mins, e->origin, mins ); - VectorAdd( ds->maxs, e->origin, maxs ); + /* offset surface by entity origin */ + const MinMax minmax( ds->minmax.mins + e->origin, ds->minmax.maxs + e->origin ); /* set the fog number for this surface */ - ds->fogNum = FogForBounds( mins, maxs, 1.0f ); //% FogForPoint( origin, 0.0f ); + ds->fogNum = FogForBounds( minmax, 1.0f ); //% FogForPoint( origin, 0.0f ); } } diff --git a/tools/quake3/q3map2/surface_extra.cpp b/tools/quake3/q3map2/surface_extra.cpp index 7bdfa3f1..beedeb6e 100644 --- a/tools/quake3/q3map2/surface_extra.cpp +++ b/tools/quake3/q3map2/surface_extra.cpp @@ -48,7 +48,7 @@ struct surfaceExtra_t int castShadows, recvShadows; int sampleSize; float longestCurve; - vec3_t lightmapAxis; + Vector3 lightmapAxis; }; #define GROW_SURFACE_EXTRAS 1024 @@ -117,7 +117,7 @@ void SetSurfaceExtra( mapDrawSurface_t *ds, int num ){ se->recvShadows = ds->recvShadows; se->sampleSize = ds->sampleSize; se->longestCurve = ds->longestCurve; - VectorCopy( ds->lightmapAxis, se->lightmapAxis ); + se->lightmapAxis = ds->lightmapAxis; /* debug code */ //% Sys_FPrintf( SYS_VRB, "SetSurfaceExtra(): entityNum = %d\n", ds->entityNum ); @@ -180,9 +180,9 @@ float GetSurfaceExtraLongestCurve( int num ){ } -void GetSurfaceExtraLightmapAxis( int num, vec3_t lightmapAxis ){ +void GetSurfaceExtraLightmapAxis( int num, Vector3& lightmapAxis ){ surfaceExtra_t *se = GetSurfaceExtra( num ); - VectorCopy( se->lightmapAxis, lightmapAxis ); + lightmapAxis = se->lightmapAxis; } @@ -402,7 +402,7 @@ void LoadSurfaceExtraFile( const char *path ){ /* lightmap axis vector */ else if ( striEqual( token, "lightmapAxis" ) ) { - Parse1DMatrix( 3, se->lightmapAxis ); + Parse1DMatrix( 3, se->lightmapAxis.data() ); } /* ignore all other tokens on the line */ diff --git a/tools/quake3/q3map2/surface_foliage.cpp b/tools/quake3/q3map2/surface_foliage.cpp index cf04765d..e8bb10cb 100644 --- a/tools/quake3/q3map2/surface_foliage.cpp +++ b/tools/quake3/q3map2/surface_foliage.cpp @@ -57,8 +57,7 @@ static void SubdivideFoliageTriangle_r( mapDrawSurface_t *ds, const foliage_t& f /* plane test */ { - vec4_t plane; - + Plane3f plane; /* make a plane */ if ( !PlaneFromPoints( plane, tri[ 0 ]->xyz, tri[ 1 ]->xyz, tri[ 2 ]->xyz ) ) { @@ -66,7 +65,7 @@ static void SubdivideFoliageTriangle_r( mapDrawSurface_t *ds, const foliage_t& f } /* if normal is too far off vertical, then don't place an instance */ - if ( plane[ 2 ] < 0.5f ) { + if ( plane.normal().z() < 0.5f ) { return; } } @@ -74,7 +73,7 @@ static void SubdivideFoliageTriangle_r( mapDrawSurface_t *ds, const foliage_t& f /* subdivide calc */ { int i; - float *a, *b, dx, dy, dz, dist, maxDist; + float dx, dy, dz, dist, maxDist; foliageInstance_t *fi; @@ -84,13 +83,13 @@ static void SubdivideFoliageTriangle_r( mapDrawSurface_t *ds, const foliage_t& f /* find the longest edge and split it */ max = -1; maxDist = 0.0f; - VectorClear( fi->xyz ); - VectorClear( fi->normal ); + fi->xyz.set( 0 ); + fi->normal.set( 0 ); for ( i = 0; i < 3; i++ ) { /* get verts */ - a = tri[ i ]->xyz; - b = tri[ ( i + 1 ) % 3 ]->xyz; + const Vector3& a = tri[ i ]->xyz; + const Vector3& b = tri[ ( i + 1 ) % 3 ]->xyz; /* get dists */ dx = a[ 0 ] - b[ 0 ]; @@ -105,8 +104,8 @@ static void SubdivideFoliageTriangle_r( mapDrawSurface_t *ds, const foliage_t& f } /* add to centroid */ - VectorAdd( fi->xyz, tri[ i ]->xyz, fi->xyz ); - VectorAdd( fi->normal, tri[ i ]->normal, fi->normal ); + fi->xyz += tri[ i ]->xyz; + fi->normal += tri[ i ]->normal; } /* is the triangle small enough? */ @@ -120,7 +119,7 @@ static void SubdivideFoliageTriangle_r( mapDrawSurface_t *ds, const foliage_t& f } else { - alpha = ( (float) tri[ 0 ]->color[ 0 ][ 3 ] + (float) tri[ 1 ]->color[ 0 ][ 3 ] + (float) tri[ 2 ]->color[ 0 ][ 3 ] ) / 765.0f; + alpha = ( (float) tri[ 0 ]->color[ 0 ].alpha() + (float) tri[ 1 ]->color[ 0 ].alpha() + (float) tri[ 2 ]->color[ 0 ].alpha() ) / 765.0f; if ( foliage.inverseAlpha == 1 ) { alpha = 1.0f - alpha; } @@ -137,8 +136,8 @@ static void SubdivideFoliageTriangle_r( mapDrawSurface_t *ds, const foliage_t& f } /* scale centroid */ - VectorScale( fi->xyz, 0.33333333f, fi->xyz ); - if ( VectorNormalize( fi->normal, fi->normal ) == 0.0f ) { + fi->xyz *= 0.33333333f; + if ( VectorNormalize( fi->normal ) == 0.0f ) { return; } @@ -175,8 +174,6 @@ void Foliage( mapDrawSurface_t *src ){ shaderInfo_t *si; mesh_t srcMesh, *subdivided, *mesh; bspDrawVert_t *verts, *dv[ 3 ], *fi; - vec3_t scale; - m4x4_t transform; /* get shader */ @@ -270,12 +267,8 @@ void Foliage( mapDrawSurface_t *src ){ /* remember surface count */ oldNumMapDrawSurfs = numMapDrawSurfs; - /* set transform matrix */ - VectorSet( scale, foliage.scale, foliage.scale, foliage.scale ); - m4x4_scale_for_vec3( transform, scale ); - /* add the model to the bsp */ - InsertModel( foliage.model.c_str(), 0, 0, transform, NULL, NULL, src->entityNum, src->castShadows, src->recvShadows, 0, src->lightmapScale, 0, 0, clipDepthGlobal ); + InsertModel( foliage.model.c_str(), 0, 0, matrix4_scale_for_vec3( Vector3().set( foliage.scale ) ), NULL, NULL, src->entityNum, src->castShadows, src->recvShadows, 0, src->lightmapScale, 0, 0, clipDepthGlobal ); /* walk each new surface */ for ( i = oldNumMapDrawSurfs; i < numMapDrawSurfs; i++ ) @@ -307,16 +300,13 @@ void Foliage( mapDrawSurface_t *src ){ fi = &ds->verts[ ds->numVerts + j ]; /* copy xyz and normal */ - VectorCopy( foliageInstances[ j ].xyz, fi->xyz ); - VectorCopy( foliageInstances[ j ].normal, fi->normal ); + fi->xyz = foliageInstances[ j ].xyz; + fi->normal = foliageInstances[ j ].normal; /* ydnar: set color */ for ( k = 0; k < MAX_LIGHTMAPS; k++ ) { - fi->color[ k ][ 0 ] = 255; - fi->color[ k ][ 1 ] = 255; - fi->color[ k ][ 2 ] = 255; - fi->color[ k ][ 3 ] = 255; + fi->color[ k ].set( 255 ); } } diff --git a/tools/quake3/q3map2/surface_fur.cpp b/tools/quake3/q3map2/surface_fur.cpp index b706e714..13b38715 100644 --- a/tools/quake3/q3map2/surface_fur.cpp +++ b/tools/quake3/q3map2/surface_fur.cpp @@ -73,10 +73,10 @@ void Fur( mapDrawSurface_t *ds ){ dv = &ds->verts[ j ]; /* offset is scaled by original vertex alpha */ - a = (float) dv->color[ 0 ][ 3 ] / 255.0; + a = (float) dv->color[ 0 ].alpha() / 255.0; /* offset it */ - VectorMA( dv->xyz, ( offset * a ), dv->normal, dv->xyz ); + dv->xyz += dv->normal * ( offset * a ); } /* wash, rinse, repeat */ @@ -98,27 +98,19 @@ void Fur( mapDrawSurface_t *ds ){ dv = &ds->verts[ j ]; /* offset is scaled by original vertex alpha */ - a = (float) dv->color[ 0 ][ 3 ] / 255.0; + a = (float) dv->color[ 0 ].alpha() / 255.0; /* get fur vert */ dv = &fur->verts[ j ]; /* offset it */ - VectorMA( dv->xyz, ( offset * a * i ), dv->normal, dv->xyz ); + dv->xyz += dv->normal * ( offset * a * i ); /* fade alpha */ for ( k = 0; k < MAX_LIGHTMAPS; k++ ) { - a = (float) dv->color[ k ][ 3 ] - fade; - if ( a > 255.0f ) { - dv->color[ k ][ 3 ] = 255; - } - else if ( a < 0 ) { - dv->color[ k ][ 3 ] = 0; - } - else{ - dv->color[ k ][ 3 ] = a; - } + a = (float) dv->color[ k ].alpha() - fade; + dv->color[ k ].alpha() = ( a > 255.0f )? 255 : ( a < 0 )? 0 : a; } } } diff --git a/tools/quake3/q3map2/surface_meta.cpp b/tools/quake3/q3map2/surface_meta.cpp index 99b6332a..308ff124 100644 --- a/tools/quake3/q3map2/surface_meta.cpp +++ b/tools/quake3/q3map2/surface_meta.cpp @@ -123,21 +123,15 @@ static int AddMetaTriangle( void ){ int FindMetaTriangle( metaTriangle_t *src, bspDrawVert_t *a, bspDrawVert_t *b, bspDrawVert_t *c, int planeNum ){ int triIndex; - vec3_t dir; - - /* detect degenerate triangles fixme: do something proper here */ - VectorSubtract( a->xyz, b->xyz, dir ); - if ( VectorLength( dir ) < 0.125f ) { + if ( vector3_length( a->xyz - b->xyz ) < 0.125f ) { return -1; } - VectorSubtract( b->xyz, c->xyz, dir ); - if ( VectorLength( dir ) < 0.125f ) { + if ( vector3_length( b->xyz - c->xyz ) < 0.125f ) { return -1; } - VectorSubtract( c->xyz, a->xyz, dir ); - if ( VectorLength( dir ) < 0.125f ) { + if ( vector3_length( c->xyz - a->xyz ) < 0.125f ) { return -1; } @@ -145,8 +139,7 @@ int FindMetaTriangle( metaTriangle_t *src, bspDrawVert_t *a, bspDrawVert_t *b, b if ( planeNum >= 0 ) { /* because of precision issues with small triangles, try to use the specified plane */ src->planeNum = planeNum; - VectorCopy( mapplanes[ planeNum ].normal, src->plane ); - src->plane[ 3 ] = mapplanes[ planeNum ].dist; + src->plane = mapplanes[ planeNum ].plane; } else { @@ -158,14 +151,14 @@ int FindMetaTriangle( metaTriangle_t *src, bspDrawVert_t *a, bspDrawVert_t *b, b } /* ydnar 2002-10-03: repair any bogus normals (busted ase import kludge) */ - if ( VectorLength( a->normal ) <= 0.0f ) { - VectorCopy( src->plane, a->normal ); + if ( vector3_length( a->normal ) == 0.0f ) { + a->normal = src->plane.normal(); } - if ( VectorLength( b->normal ) <= 0.0f ) { - VectorCopy( src->plane, b->normal ); + if ( vector3_length( b->normal ) == 0.0f ) { + b->normal = src->plane.normal(); } - if ( VectorLength( c->normal ) <= 0.0f ) { - VectorCopy( src->plane, c->normal ); + if ( vector3_length( c->normal ) == 0.0f ) { + c->normal = src->plane.normal(); } /* ydnar 2002-10-04: set lightmap axis if not already set */ @@ -173,12 +166,12 @@ int FindMetaTriangle( metaTriangle_t *src, bspDrawVert_t *a, bspDrawVert_t *b, b src->lightmapAxis[ 0 ] == 0.0f && src->lightmapAxis[ 1 ] == 0.0f && src->lightmapAxis[ 2 ] == 0.0f ) { /* the shader can specify an explicit lightmap axis */ if ( src->si->lightmapAxis[ 0 ] || src->si->lightmapAxis[ 1 ] || src->si->lightmapAxis[ 2 ] ) { - VectorCopy( src->si->lightmapAxis, src->lightmapAxis ); + src->lightmapAxis = src->si->lightmapAxis; } /* new axis-finding code */ else{ - CalcLightmapAxis( src->plane, src->lightmapAxis ); + CalcLightmapAxis( src->plane.normal(), src->lightmapAxis ); } } @@ -261,7 +254,7 @@ static void SurfaceToMetaTriangles( mapDrawSurface_t *ds ){ src.fogNum = ds->fogNum; src.sampleSize = ds->sampleSize; src.shadeAngleDegrees = ds->shadeAngleDegrees; - VectorCopy( ds->lightmapAxis, src.lightmapAxis ); + src.lightmapAxis = ds->lightmapAxis; /* copy drawverts */ memcpy( &a, &ds->verts[ ds->indexes[ i ] ], sizeof( a ) ); @@ -385,7 +378,6 @@ int MaxAreaIndexes( bspDrawVert_t *vert, int cnt, int *indexes ){ int r, s, t, bestR = 0, bestS = 1, bestT = 2; int i, j; double A, bestA = -1, V, bestV = -1; - vec3_t ab, ac, bc, cross; bspDrawVert_t *buf; double shiftWidth; @@ -397,16 +389,12 @@ int MaxAreaIndexes( bspDrawVert_t *vert, int cnt, int *indexes ){ A = 0; for ( i = 1; i + 1 < cnt; ++i ) { - VectorSubtract( vert[i].xyz, vert[0].xyz, ab ); - VectorSubtract( vert[i + 1].xyz, vert[0].xyz, ac ); - CrossProduct( ab, ac, cross ); - A += VectorLength( cross ); + A += vector3_length( vector3_cross( vert[i].xyz - vert[0].xyz, vert[i + 1].xyz - vert[0].xyz ) ); } V = 0; for ( i = 0; i < cnt; ++i ) { - VectorSubtract( vert[( i + 1 ) % cnt].xyz, vert[i].xyz, ab ); - V += VectorLength( ab ); + V += vector3_length( vert[( i + 1 ) % cnt].xyz - vert[i].xyz ); } /* calculate shift width from the area sensibly, assuming the polygon @@ -429,13 +417,12 @@ int MaxAreaIndexes( bspDrawVert_t *vert, int cnt, int *indexes ){ for ( s = r + 1; s + 1 < cnt; ++s ) for ( t = s + 1; t < cnt; ++t ) { - VectorSubtract( vert[s].xyz, vert[r].xyz, ab ); - VectorSubtract( vert[t].xyz, vert[r].xyz, ac ); - VectorSubtract( vert[t].xyz, vert[s].xyz, bc ); - CrossProduct( ab, ac, cross ); - A = VectorLength( cross ); + const Vector3 ab = vert[s].xyz - vert[r].xyz; + const Vector3 ac = vert[t].xyz - vert[r].xyz; + const Vector3 bc = vert[t].xyz - vert[s].xyz; + A = vector3_length( vector3_cross( ab, ac ) ); - V = A - ( VectorLength( ab ) - VectorLength( ac ) - VectorLength( bc ) ) * shiftWidth; + V = A - ( vector3_length( ab ) - vector3_length( ac ) - vector3_length( bc ) ) * shiftWidth; /* value = A - circumference * shiftWidth, i.e. we back out by shiftWidth units from each side, to prevent too acute triangles */ /* this kind of simulates "number of shiftWidth*shiftWidth fragments in the triangle not touched by an edge" */ @@ -483,10 +470,7 @@ int MaxAreaIndexes( bspDrawVert_t *vert, int cnt, int *indexes ){ } // abc abc abc abc abc abc - VectorSubtract( vert[bestS].xyz, vert[bestR].xyz, ab ); - VectorSubtract( vert[bestT].xyz, vert[bestR].xyz, ac ); - CrossProduct( ab, ac, cross ); - bestA = VectorLength( cross ); + bestA = vector3_length( vector3_cross( vert[bestS].xyz - vert[bestR].xyz, vert[bestT].xyz - vert[bestR].xyz ) ); } if ( bestA < TINY_AREA ) { @@ -599,7 +583,9 @@ void MaxAreaFaceSurface( mapDrawSurface_t *ds ){ void FanFaceSurface( mapDrawSurface_t *ds ){ int i, j, k, a, b, c; - int color[ MAX_LIGHTMAPS ][ 4 ] = {{0}}; + BasicVector4 color[ MAX_LIGHTMAPS ]; + for ( k = 0; k < MAX_LIGHTMAPS; k++ ) + color[k].set( 0 ); bspDrawVert_t *verts, *centroid, *dv; double iv; @@ -620,37 +606,28 @@ void FanFaceSurface( mapDrawSurface_t *ds ){ centroid = &verts[ 0 ]; for ( i = 1, dv = &verts[ 1 ]; i < ( ds->numVerts + 1 ); i++, dv++ ) { - VectorAdd( centroid->xyz, dv->xyz, centroid->xyz ); - VectorAdd( centroid->normal, dv->normal, centroid->normal ); - for ( j = 0; j < 4; j++ ) - { - for ( k = 0; k < MAX_LIGHTMAPS; k++ ) - color[ k ][ j ] += dv->color[ k ][ j ]; - if ( j < 2 ) { - centroid->st[ j ] += dv->st[ j ]; - for ( k = 0; k < MAX_LIGHTMAPS; k++ ) - centroid->lightmap[ k ][ j ] += dv->lightmap[ k ][ j ]; - } + centroid->xyz += dv->xyz; + centroid->normal += dv->normal; + centroid->st += dv->st; + for ( k = 0; k < MAX_LIGHTMAPS; k++ ){ + color[ k ] += dv->color[ k ]; + centroid->lightmap[ k ] += dv->lightmap[ k ]; } } /* average the centroid */ iv = 1.0f / ds->numVerts; - VectorScale( centroid->xyz, iv, centroid->xyz ); - if ( VectorNormalize( centroid->normal, centroid->normal ) <= 0 ) { - VectorCopy( verts[ 1 ].normal, centroid->normal ); + centroid->xyz *= iv; + if ( VectorNormalize( centroid->normal ) == 0 ) { + centroid->normal = verts[ 1 ].normal; } - for ( j = 0; j < 4; j++ ) - { - for ( k = 0; k < MAX_LIGHTMAPS; k++ ) + centroid->st *= iv; + for ( k = 0; k < MAX_LIGHTMAPS; k++ ){ + centroid->lightmap[ k ] *= iv; + for ( j = 0; j < 4; j++ ) { color[ k ][ j ] /= ds->numVerts; - centroid->color[ k ][ j ] = ( color[ k ][ j ] < 255.0f ? color[ k ][ j ] : 255 ); - } - if ( j < 2 ) { - centroid->st[ j ] *= iv; - for ( k = 0; k < MAX_LIGHTMAPS; k++ ) - centroid->lightmap[ k ][ j ] *= iv; + centroid->color[ k ][ j ] = ( color[ k ][ j ] < 255 ? color[ k ][ j ] : 255 ); } } @@ -690,7 +667,6 @@ void FanFaceSurface( mapDrawSurface_t *ds ){ void StripFaceSurface( mapDrawSurface_t *ds ){ int i, r, least, rotate, numIndexes, ni, a, b, c, indexes[ MAX_INDEXES ]; - vec_t *v1, *v2; /* try to early out */ @@ -711,8 +687,8 @@ void StripFaceSurface( mapDrawSurface_t *ds ){ for ( i = 0; i < ds->numVerts; i++ ) { /* get points */ - v1 = ds->verts[ i ].xyz; - v2 = ds->verts[ least ].xyz; + const Vector3& v1 = ds->verts[ i ].xyz; + const Vector3& v2 = ds->verts[ least ].xyz; /* compare */ if ( v1[ 0 ] < v2[ 0 ] || @@ -912,38 +888,30 @@ void MakeEntityMetaTriangles( entity_t *e ){ struct edge_t { - vec3_t origin; - vec4_t edge; - vec_t length, kingpinLength; + Vector3 origin; + Plane3f edge; + float length, kingpinLength; int kingpin; - vec4_t plane; + Plane3f plane; }; -void CreateEdge( vec4_t plane, vec3_t a, vec3_t b, edge_t *edge ){ +void CreateEdge( const Plane3f& plane, const Vector3& a, const Vector3& b, edge_t *edge ){ /* copy edge origin */ - VectorCopy( a, edge->origin ); + edge->origin = a; /* create vector aligned with winding direction of edge */ - VectorSubtract( b, a, edge->edge ); + edge->edge.normal() = b - a; - if ( fabs( edge->edge[ 0 ] ) > fabs( edge->edge[ 1 ] ) && fabs( edge->edge[ 0 ] ) > fabs( edge->edge[ 2 ] ) ) { - edge->kingpin = 0; - } - else if ( fabs( edge->edge[ 1 ] ) > fabs( edge->edge[ 0 ] ) && fabs( edge->edge[ 1 ] ) > fabs( edge->edge[ 2 ] ) ) { - edge->kingpin = 1; - } - else{ - edge->kingpin = 2; - } - edge->kingpinLength = edge->edge[ edge->kingpin ]; + edge->kingpin = vector3_max_abs_component_index( edge->edge.normal() ); + edge->kingpinLength = edge->edge.normal()[ edge->kingpin ]; - VectorNormalize( edge->edge, edge->edge ); - edge->edge[ 3 ] = DotProduct( a, edge->edge ); - edge->length = DotProduct( b, edge->edge ) - edge->edge[ 3 ]; + VectorNormalize( edge->edge.normal() ); + edge->edge.dist() = vector3_dot( a, edge->edge.normal() ); + edge->length = plane3_distance_to_point( edge->edge, b ); /* create perpendicular plane that edge lies in */ - CrossProduct( plane, edge->edge, edge->plane ); - edge->plane[ 3 ] = DotProduct( a, edge->plane ); + edge->plane.normal() = vector3_cross( plane.normal(), edge->edge.normal() ); + edge->plane.dist() = vector3_dot( a, edge->plane.normal() ); } @@ -962,9 +930,8 @@ void FixMetaTJunctions( void ){ metaTriangle_t *tri, *newTri; shaderInfo_t *si; bspDrawVert_t *a, *b, *c, junc; - float dist, amount; - vec3_t pt; - vec4_t plane; + float amount; + Plane3f plane; edge_t edges[ 3 ]; @@ -999,8 +966,7 @@ void FixMetaTJunctions( void ){ } /* calculate planes */ - VectorCopy( tri->plane, plane ); - plane[ 3 ] = tri->plane[ 3 ]; + plane = tri->plane; CreateEdge( plane, metaVerts[ tri->indexes[ 0 ] ].xyz, metaVerts[ tri->indexes[ 1 ] ].xyz, &edges[ 0 ] ); CreateEdge( plane, metaVerts[ tri->indexes[ 1 ] ].xyz, metaVerts[ tri->indexes[ 2 ] ].xyz, &edges[ 1 ] ); CreateEdge( plane, metaVerts[ tri->indexes[ 2 ] ].xyz, metaVerts[ tri->indexes[ 0 ] ].xyz, &edges[ 2 ] ); @@ -1009,11 +975,10 @@ void FixMetaTJunctions( void ){ for ( j = 0; j < numMetaVerts; j++ ) { /* get vert */ - VectorCopy( metaVerts[ j ].xyz, pt ); + const Vector3 pt = metaVerts[ j ].xyz; /* determine if point lies in the triangle's plane */ - dist = DotProduct( pt, plane ) - plane[ 3 ]; - if ( fabs( dist ) > TJ_PLANE_EPSILON ) { + if ( fabs( plane3_distance_to_point( plane, pt ) ) > TJ_PLANE_EPSILON ) { continue; } @@ -1039,8 +1004,7 @@ void FixMetaTJunctions( void ){ } /* determine if point lies on the edge */ - dist = DotProduct( pt, edges[ k ].plane ) - edges[ k ].plane[ 3 ]; - if ( fabs( dist ) > TJ_EDGE_EPSILON ) { + if ( fabs( plane3_distance_to_point( edges[ k ].plane, pt ) ) > TJ_EDGE_EPSILON ) { continue; } @@ -1051,7 +1015,7 @@ void FixMetaTJunctions( void ){ } #if 0 - dist = DotProduct( pt, edges[ k ].edge ) - edges[ k ].edge[ 3 ]; + dist = plane3_distance_to_point( edges[ k ].edge, pt ); if ( dist <= -0.0f || dist >= edges[ k ].length ) { continue; } @@ -1065,7 +1029,7 @@ void FixMetaTJunctions( void ){ /* make new vert */ LerpDrawVertAmount( a, b, amount, &junc ); - VectorCopy( pt, junc.xyz ); + junc.xyz = pt; /* compare against existing verts */ if ( VectorCompare( junc.xyz, a->xyz ) || VectorCompare( junc.xyz, b->xyz ) || VectorCompare( junc.xyz, c->xyz ) ) { @@ -1109,9 +1073,7 @@ void FixMetaTJunctions( void ){ CreateEdge( plane, metaVerts[ tri->indexes[ 2 ] ].xyz, metaVerts[ tri->indexes[ 0 ] ].xyz, &edges[ 2 ] ); /* debug code */ - metaVerts[ vertIndex ].color[ 0 ][ 0 ] = 255; - metaVerts[ vertIndex ].color[ 0 ][ 1 ] = 204; - metaVerts[ vertIndex ].color[ 0 ][ 2 ] = 0; + metaVerts[ vertIndex ].color[ 0 ].rgb() = { 255, 204, 0 }; /* add to counter and end processing of this vert */ numTJuncs++; @@ -1136,7 +1098,7 @@ void FixMetaTJunctions( void ){ #define MAX_SAMPLES 256 #define THETA_EPSILON 0.000001 -#define EQUAL_NORMAL_EPSILON 0.01 +#define EQUAL_NORMAL_EPSILON 0.01f void SmoothMetaTriangles( void ){ int i, j, k, f, fOld, start, numVerts, numVotes, numSmoothed; @@ -1144,9 +1106,9 @@ void SmoothMetaTriangles( void ){ metaTriangle_t *tri; float *shadeAngles; byte *smoothed; - vec3_t average, diff; + Vector3 average; int indexes[ MAX_SAMPLES ]; - vec3_t votes[ MAX_SAMPLES ]; + Vector3 votes[ MAX_SAMPLES ]; /* note it */ Sys_FPrintf( SYS_VRB, "--- SmoothMetaTriangles ---\n" ); @@ -1158,7 +1120,7 @@ void SmoothMetaTriangles( void ){ smoothed = safe_calloc( ( numMetaVerts / 8 ) + 1 ); /* set default shade angle */ - defaultShadeAngle = DEG2RAD( npDegrees ); + defaultShadeAngle = degrees_to_radians( npDegrees ); maxShadeAngle = 0.0f; /* run through every surface and flag verts belonging to non-lightmapped surfaces @@ -1169,11 +1131,11 @@ void SmoothMetaTriangles( void ){ /* get shade angle from shader */ if ( tri->si->shadeAngleDegrees > 0.0f ) { - shadeAngle = DEG2RAD( tri->si->shadeAngleDegrees ); + shadeAngle = degrees_to_radians( tri->si->shadeAngleDegrees ); } /* get shade angle from entity */ else if ( tri->shadeAngleDegrees > 0.0f ) { - shadeAngle = DEG2RAD( tri->shadeAngleDegrees ); + shadeAngle = degrees_to_radians( tri->shadeAngleDegrees ); } if ( shadeAngle <= 0.0f ) { @@ -1223,7 +1185,7 @@ void SmoothMetaTriangles( void ){ } /* clear */ - VectorClear( average ); + average.set( 0 ); numVerts = 0; numVotes = 0; @@ -1244,7 +1206,7 @@ void SmoothMetaTriangles( void ){ shadeAngle = ( shadeAngles[ i ] < shadeAngles[ j ] ? shadeAngles[ i ] : shadeAngles[ j ] ); /* check shade angle */ - dot = DotProduct( metaVerts[ i ].normal, metaVerts[ j ].normal ); + dot = vector3_dot( metaVerts[ i ].normal, metaVerts[ j ].normal ); if ( dot > 1.0 ) { dot = 1.0; } @@ -1265,18 +1227,15 @@ void SmoothMetaTriangles( void ){ /* see if this normal has already been voted */ for ( k = 0; k < numVotes; k++ ) { - VectorSubtract( metaVerts[ j ].normal, votes[ k ], diff ); - if ( fabs( diff[ 0 ] ) < EQUAL_NORMAL_EPSILON && - fabs( diff[ 1 ] ) < EQUAL_NORMAL_EPSILON && - fabs( diff[ 2 ] ) < EQUAL_NORMAL_EPSILON ) { + if ( vector3_equal_epsilon( metaVerts[ j ].normal, votes[ k ], EQUAL_NORMAL_EPSILON ) ) { break; } } /* add a new vote? */ if ( k == numVotes && numVotes < MAX_SAMPLES ) { - VectorAdd( average, metaVerts[ j ].normal, average ); - VectorCopy( metaVerts[ j ].normal, votes[ numVotes ] ); + average += metaVerts[ j ].normal; + votes[ numVotes ] = metaVerts[ j ].normal; numVotes++; } } @@ -1287,10 +1246,10 @@ void SmoothMetaTriangles( void ){ } /* average normal */ - if ( VectorNormalize( average, average ) > 0 ) { + if ( VectorNormalize( average ) != 0 ) { /* smooth */ for ( j = 0; j < numVerts; j++ ) - VectorCopy( average, metaVerts[ indexes[ j ] ].normal ); + metaVerts[ indexes[ j ] ].normal = average; numSmoothed++; } } @@ -1340,7 +1299,7 @@ int AddMetaVertToSurface( mapDrawSurface_t *ds, bspDrawVert_t *dv1, int *coincid if ( dv1->st[ 0 ] != dv2->st[ 0 ] || dv1->st[ 1 ] != dv2->st[ 1 ] ) { continue; } - if ( dv1->color[ 0 ][ 3 ] != dv2->color[ 0 ][ 3 ] ) { + if ( dv1->color[ 0 ].alpha() != dv2->color[ 0 ].alpha() ) { continue; } @@ -1384,10 +1343,8 @@ int AddMetaVertToSurface( mapDrawSurface_t *ds, bspDrawVert_t *dv1, int *coincid #define GOOD_SCORE ( metaGoodScore >= 0 ? metaGoodScore : DEFAULT_GOOD_SCORE ) static int AddMetaTriangleToSurface( mapDrawSurface_t *ds, metaTriangle_t *tri, bool testAdd ){ - vec3_t p; int i, score, coincident, ai, bi, ci, oldTexRange[ 2 ]; float lmMax; - vec3_t mins, maxs; bool inTexRange; mapDrawSurface_t old; @@ -1410,14 +1367,14 @@ static int AddMetaTriangleToSurface( mapDrawSurface_t *ds, metaTriangle_t *tri, #if 0 if ( !( ds->shaderInfo->compileFlags & C_VERTEXLIT ) && //% !VectorCompare( ds->lightmapAxis, tri->lightmapAxis ) ) - DotProduct( ds->lightmapAxis, tri->plane ) < 0.25f ) { + vector3_dot( ds->lightmapAxis, tri->plane.normal() ) < 0.25f ) { return 0; } #endif /* planar surfaces will only merge with triangles in the same plane */ if ( npDegrees == 0.0f && !ds->shaderInfo->nonplanar && ds->planeNum >= 0 ) { - if ( !VectorCompare( mapplanes[ ds->planeNum ].normal, tri->plane ) || mapplanes[ ds->planeNum ].dist != tri->plane[ 3 ] ) { + if ( !VectorCompare( mapplanes[ ds->planeNum ].normal(), tri->plane.normal() ) || mapplanes[ ds->planeNum ].dist() != tri->plane.dist() ) { return 0; } if ( tri->planeNum >= 0 && tri->planeNum != ds->planeNum ) { @@ -1429,21 +1386,15 @@ static int AddMetaTriangleToSurface( mapDrawSurface_t *ds, metaTriangle_t *tri, if ( metaMaxBBoxDistance >= 0 ) { if ( ds->numIndexes > 0 ) { - VectorCopy( ds->mins, mins ); - VectorCopy( ds->maxs, maxs ); - mins[0] -= metaMaxBBoxDistance; - mins[1] -= metaMaxBBoxDistance; - mins[2] -= metaMaxBBoxDistance; - maxs[0] += metaMaxBBoxDistance; - maxs[1] += metaMaxBBoxDistance; - maxs[2] += metaMaxBBoxDistance; + const Vector3 mins = ds->minmax.mins - Vector3( metaMaxBBoxDistance, metaMaxBBoxDistance, metaMaxBBoxDistance ); + const Vector3 maxs = ds->minmax.maxs + Vector3( metaMaxBBoxDistance, metaMaxBBoxDistance, metaMaxBBoxDistance ); #define CHECK_1D( mins, v, maxs ) ( ( mins ) <= ( v ) && ( v ) <= ( maxs ) ) #define CHECK_3D( mins, v, maxs ) ( CHECK_1D( ( mins )[0], ( v )[0], ( maxs )[0] ) && CHECK_1D( ( mins )[1], ( v )[1], ( maxs )[1] ) && CHECK_1D( ( mins )[2], ( v )[2], ( maxs )[2] ) ) - VectorCopy( metaVerts[ tri->indexes[ 0 ] ].xyz, p ); + Vector3 p = metaVerts[ tri->indexes[ 0 ] ].xyz; if ( !CHECK_3D( mins, p, maxs ) ) { - VectorCopy( metaVerts[ tri->indexes[ 1 ] ].xyz, p ); + p = metaVerts[ tri->indexes[ 1 ] ].xyz; if ( !CHECK_3D( mins, p, maxs ) ) { - VectorCopy( metaVerts[ tri->indexes[ 2 ] ].xyz, p ); + p = metaVerts[ tri->indexes[ 2 ] ].xyz; if ( !CHECK_3D( mins, p, maxs ) ) { return 0; } @@ -1462,7 +1413,7 @@ static int AddMetaTriangleToSurface( mapDrawSurface_t *ds, metaTriangle_t *tri, score += AXIS_SCORE; } else{ - score += AXIS_SCORE * DotProduct( ds->lightmapAxis, tri->plane ); + score += AXIS_SCORE * vector3_dot( ds->lightmapAxis, tri->plane.normal() ); } /* preserve old drawsurface if this fails */ @@ -1484,23 +1435,22 @@ static int AddMetaTriangleToSurface( mapDrawSurface_t *ds, metaTriangle_t *tri, score += ( coincident * VERT_SCORE ); /* add new vertex bounds to mins/maxs */ - VectorCopy( ds->mins, mins ); - VectorCopy( ds->maxs, maxs ); - AddPointToBounds( metaVerts[ tri->indexes[ 0 ] ].xyz, mins, maxs ); - AddPointToBounds( metaVerts[ tri->indexes[ 1 ] ].xyz, mins, maxs ); - AddPointToBounds( metaVerts[ tri->indexes[ 2 ] ].xyz, mins, maxs ); + MinMax minmax( ds->minmax ); + minmax.extend( metaVerts[ tri->indexes[ 0 ] ].xyz ); + minmax.extend( metaVerts[ tri->indexes[ 1 ] ].xyz ); + minmax.extend( metaVerts[ tri->indexes[ 2 ] ].xyz ); /* check lightmap bounds overflow (after at least 1 triangle has been added) */ if ( !( ds->shaderInfo->compileFlags & C_VERTEXLIT ) && - ds->numIndexes > 0 && VectorLength( ds->lightmapAxis ) > 0.0f && - ( !VectorCompare( ds->mins, mins ) || !VectorCompare( ds->maxs, maxs ) ) ) { + ds->numIndexes > 0 && vector3_length( ds->lightmapAxis ) != 0.0f && + ( !VectorCompare( ds->minmax.mins, minmax.mins ) || !VectorCompare( ds->minmax.maxs, minmax.maxs ) ) ) { /* set maximum size before lightmap scaling (normally 2032 units) */ /* 2004-02-24: scale lightmap test size by 2 to catch larger brush faces */ /* 2004-04-11: reverting to actual lightmap size */ lmMax = ( ds->sampleSize * ( ds->shaderInfo->lmCustomWidth - 1 ) ); for ( i = 0; i < 3; i++ ) { - if ( ( maxs[ i ] - mins[ i ] ) > lmMax ) { + if ( ( minmax.maxs[ i ] - minmax.mins[ i ] ) > lmMax ) { memcpy( ds, &old, sizeof( *ds ) ); return 0; } @@ -1595,8 +1545,7 @@ static int AddMetaTriangleToSurface( mapDrawSurface_t *ds, metaTriangle_t *tri, else { /* copy bounds back to surface */ - VectorCopy( mins, ds->mins ); - VectorCopy( maxs, ds->maxs ); + ds->minmax = minmax; /* mark triangle as used */ tri->si = NULL; @@ -1655,10 +1604,10 @@ static void MetaTrianglesToSurface( int numPossibles, metaTriangle_t *possibles, ds->shadeAngleDegrees = seed->shadeAngleDegrees; ds->verts = verts; ds->indexes = indexes; - VectorCopy( seed->lightmapAxis, ds->lightmapAxis ); + ds->lightmapAxis = seed->lightmapAxis; ds->sideRef = AllocSideRef( seed->side, NULL ); - ClearBounds( ds->mins, ds->maxs ); + ds->minmax.clear(); /* clear verts/indexes */ memset( verts, 0, sizeof( *verts ) * maxSurfaceVerts ); @@ -1756,8 +1705,6 @@ static void MetaTrianglesToSurface( int numPossibles, metaTriangle_t *possibles, static int CompareMetaTriangles( const void *a, const void *b ){ int i, j, av, bv; - vec3_t aMins, bMins; - /* shader first */ if ( ( (const metaTriangle_t*) a )->si < ( (const metaTriangle_t*) b )->si ) { @@ -1809,8 +1756,8 @@ static int CompareMetaTriangles( const void *a, const void *b ){ /* then position in world */ /* find mins */ - VectorSet( aMins, 999999, 999999, 999999 ); - VectorSet( bMins, 999999, 999999, 999999 ); + Vector3 aMins( 999999, 999999, 999999 ); + Vector3 bMins( 999999, 999999, 999999 ); for ( i = 0; i < 3; i++ ) { av = ( (const metaTriangle_t*) a )->indexes[ i ]; diff --git a/tools/quake3/q3map2/tjunction.cpp b/tools/quake3/q3map2/tjunction.cpp index 2183f2ea..b577eb32 100644 --- a/tools/quake3/q3map2/tjunction.cpp +++ b/tools/quake3/q3map2/tjunction.cpp @@ -37,20 +37,20 @@ struct edgePoint_t { float intercept; - vec3_t xyz; + Vector3 xyz; struct edgePoint_t *prev, *next; }; struct edgeLine_t { - vec3_t normal1; + Vector3 normal1; float dist1; - vec3_t normal2; + Vector3 normal2; float dist2; - vec3_t origin; - vec3_t dir; + Vector3 origin; + Vector3 dir; edgePoint_t *chain; // unused element of doubly linked list }; @@ -86,17 +86,15 @@ int c_natural, c_rotate, c_cant; InsertPointOnEdge ==================== */ -void InsertPointOnEdge( vec3_t v, edgeLine_t *e ) { - vec3_t delta; +void InsertPointOnEdge( const Vector3 &v, edgeLine_t *e ) { float d; edgePoint_t *p, *scan; - VectorSubtract( v, e->origin, delta ); - d = DotProduct( delta, e->dir ); + d = vector3_dot( v - e->origin, e->dir ); p = safe_malloc( sizeof( edgePoint_t ) ); p->intercept = d; - VectorCopy( v, p->xyz ); + p->xyz = v; if ( e->chain->next == e->chain ) { e->chain->next = e->chain->prev = p; @@ -135,14 +133,16 @@ void InsertPointOnEdge( vec3_t v, edgeLine_t *e ) { AddEdge ==================== */ -int AddEdge( vec3_t v1, vec3_t v2, bool createNonAxial ) { +int AddEdge( bspDrawVert_t& dv1, bspDrawVert_t& dv2, bool createNonAxial ) { int i; edgeLine_t *e; float d; - vec3_t dir; + Vector3 dir; + const Vector3& v1 = dv1.xyz; + const Vector3& v2 = dv2.xyz; - VectorSubtract( v2, v1, dir ); - d = VectorNormalize( dir, dir ); + dir = v2 - v1; + d = VectorNormalize( dir ); if ( d < 0.1 ) { // if we added a 0 length vector, it would make degenerate planes c_degenerateEdges++; @@ -152,8 +152,8 @@ int AddEdge( vec3_t v1, vec3_t v2, bool createNonAxial ) { if ( !createNonAxial ) { if ( fabs( dir[0] + dir[1] + dir[2] ) != 1.0 ) { AUTOEXPAND_BY_REALLOC( originalEdges, numOriginalEdges, allocatedOriginalEdges, 1024 ); - originalEdges[ numOriginalEdges ].dv[0] = (bspDrawVert_t *)v1; - originalEdges[ numOriginalEdges ].dv[1] = (bspDrawVert_t *)v2; + originalEdges[ numOriginalEdges ].dv[0] = &dv1; + originalEdges[ numOriginalEdges ].dv[1] = &dv2; originalEdges[ numOriginalEdges ].length = d; numOriginalEdges++; return -1; @@ -163,20 +163,20 @@ int AddEdge( vec3_t v1, vec3_t v2, bool createNonAxial ) { for ( i = 0 ; i < numEdgeLines ; i++ ) { e = &edgeLines[i]; - d = DotProduct( v1, e->normal1 ) - e->dist1; + d = vector3_dot( v1, e->normal1 ) - e->dist1; if ( d < -POINT_ON_LINE_EPSILON || d > POINT_ON_LINE_EPSILON ) { continue; } - d = DotProduct( v1, e->normal2 ) - e->dist2; + d = vector3_dot( v1, e->normal2 ) - e->dist2; if ( d < -POINT_ON_LINE_EPSILON || d > POINT_ON_LINE_EPSILON ) { continue; } - d = DotProduct( v2, e->normal1 ) - e->dist1; + d = vector3_dot( v2, e->normal1 ) - e->dist1; if ( d < -POINT_ON_LINE_EPSILON || d > POINT_ON_LINE_EPSILON ) { continue; } - d = DotProduct( v2, e->normal2 ) - e->dist2; + d = vector3_dot( v2, e->normal2 ) - e->dist2; if ( d < -POINT_ON_LINE_EPSILON || d > POINT_ON_LINE_EPSILON ) { continue; } @@ -196,12 +196,12 @@ int AddEdge( vec3_t v1, vec3_t v2, bool createNonAxial ) { e->chain = safe_malloc( sizeof( edgePoint_t ) ); e->chain->next = e->chain->prev = e->chain; - VectorCopy( v1, e->origin ); - VectorCopy( dir, e->dir ); + e->origin = v1; + e->dir = dir; MakeNormalVectors( e->dir, e->normal1, e->normal2 ); - e->dist1 = DotProduct( e->origin, e->normal1 ); - e->dist2 = DotProduct( e->origin, e->normal2 ); + e->dist1 = vector3_dot( e->origin, e->normal1 ); + e->dist2 = vector3_dot( e->origin, e->normal2 ); InsertPointOnEdge( v1, e ); InsertPointOnEdge( v2, e ); @@ -221,7 +221,7 @@ void AddSurfaceEdges( mapDrawSurface_t *ds ){ { /* save the edge number in the lightmap field so we don't need to look it up again */ ds->verts[i].lightmap[ 0 ][ 0 ] = - AddEdge( ds->verts[ i ].xyz, ds->verts[ ( i + 1 ) % ds->numVerts ].xyz, false ); + AddEdge( ds->verts[ i ], ds->verts[ ( i + 1 ) % ds->numVerts ], false ); } } @@ -232,21 +232,20 @@ void AddSurfaceEdges( mapDrawSurface_t *ds ){ determines if an edge is colinear */ -bool ColinearEdge( vec3_t v1, vec3_t v2, vec3_t v3 ){ - vec3_t midpoint, dir, offset, on; +bool ColinearEdge( const Vector3& v1, const Vector3& v2, const Vector3& v3 ){ + Vector3 midpoint, dir, offset, on; float d; - VectorSubtract( v2, v1, midpoint ); - VectorSubtract( v3, v1, dir ); - d = VectorNormalize( dir, dir ); - if ( d == 0 ) { + midpoint = v2 - v1; + dir = v3 - v1; + if ( VectorNormalize( dir ) == 0 ) { return false; // degenerate } - d = DotProduct( midpoint, dir ); - VectorScale( dir, d, on ); - VectorSubtract( midpoint, on, offset ); - d = VectorLength( offset ); + d = vector3_dot( midpoint, dir ); + on = dir * d; + offset = midpoint - on; + d = vector3_length( offset ); if ( d < 0.1 ) { return true; @@ -267,45 +266,50 @@ bool ColinearEdge( vec3_t v1, vec3_t v2, vec3_t v3 ){ */ void AddPatchEdges( mapDrawSurface_t *ds ) { int i; - float *v1, *v2, *v3; for ( i = 0 ; i < ds->patchWidth - 2; i += 2 ) { - v1 = ds->verts[ i ].xyz; - v2 = ds->verts[ i + 1 ].xyz; - v3 = ds->verts[ i + 2 ].xyz; + { + bspDrawVert_t& v1 = ds->verts[ i ]; + bspDrawVert_t& v2 = ds->verts[ i + 1 ]; + bspDrawVert_t& v3 = ds->verts[ i + 2 ]; - // if v2 is the midpoint of v1 to v3, add an edge from v1 to v3 - if ( ColinearEdge( v1, v2, v3 ) ) { - AddEdge( v1, v3, false ); + // if v2 is the midpoint of v1 to v3, add an edge from v1 to v3 + if ( ColinearEdge( v1.xyz, v2.xyz, v3.xyz ) ) { + AddEdge( v1, v3, false ); + } } + { + bspDrawVert_t& v1 = ds->verts[ ( ds->patchHeight - 1 ) * ds->patchWidth + i ]; + bspDrawVert_t& v2 = ds->verts[ ( ds->patchHeight - 1 ) * ds->patchWidth + i + 1 ]; + bspDrawVert_t& v3 = ds->verts[ ( ds->patchHeight - 1 ) * ds->patchWidth + i + 2 ]; - v1 = ds->verts[ ( ds->patchHeight - 1 ) * ds->patchWidth + i ].xyz; - v2 = ds->verts[ ( ds->patchHeight - 1 ) * ds->patchWidth + i + 1 ].xyz; - v3 = ds->verts[ ( ds->patchHeight - 1 ) * ds->patchWidth + i + 2 ].xyz; - - // if v2 is on the v1 to v3 line, add an edge from v1 to v3 - if ( ColinearEdge( v1, v2, v3 ) ) { - AddEdge( v1, v3, false ); + // if v2 is on the v1 to v3 line, add an edge from v1 to v3 + if ( ColinearEdge( v1.xyz, v2.xyz, v3.xyz ) ) { + AddEdge( v1, v3, false ); + } } } for ( i = 0 ; i < ds->patchHeight - 2 ; i += 2 ) { - v1 = ds->verts[ i * ds->patchWidth ].xyz; - v2 = ds->verts[ ( i + 1 ) * ds->patchWidth ].xyz; - v3 = ds->verts[ ( i + 2 ) * ds->patchWidth ].xyz; + { + bspDrawVert_t& v1 = ds->verts[ i * ds->patchWidth ]; + bspDrawVert_t& v2 = ds->verts[ ( i + 1 ) * ds->patchWidth ]; + bspDrawVert_t& v3 = ds->verts[ ( i + 2 ) * ds->patchWidth ]; - // if v2 is the midpoint of v1 to v3, add an edge from v1 to v3 - if ( ColinearEdge( v1, v2, v3 ) ) { - AddEdge( v1, v3, false ); + // if v2 is the midpoint of v1 to v3, add an edge from v1 to v3 + if ( ColinearEdge( v1.xyz, v2.xyz, v3.xyz ) ) { + AddEdge( v1, v3, false ); + } } + { + bspDrawVert_t& v1 = ds->verts[ ( ds->patchWidth - 1 ) + i * ds->patchWidth ]; + bspDrawVert_t& v2 = ds->verts[ ( ds->patchWidth - 1 ) + ( i + 1 ) * ds->patchWidth ]; + bspDrawVert_t& v3 = ds->verts[ ( ds->patchWidth - 1 ) + ( i + 2 ) * ds->patchWidth ]; - v1 = ds->verts[ ( ds->patchWidth - 1 ) + i * ds->patchWidth ].xyz; - v2 = ds->verts[ ( ds->patchWidth - 1 ) + ( i + 1 ) * ds->patchWidth ].xyz; - v3 = ds->verts[ ( ds->patchWidth - 1 ) + ( i + 2 ) * ds->patchWidth ].xyz; - - // if v2 is the midpoint of v1 to v3, add an edge from v1 to v3 - if ( ColinearEdge( v1, v2, v3 ) ) { - AddEdge( v1, v3, false ); + // if v2 is the midpoint of v1 to v3, add an edge from v1 to v3 + if ( ColinearEdge( v1.xyz, v2.xyz, v3.xyz ) ) { + AddEdge( v1, v3, false ); + } } } @@ -327,8 +331,7 @@ void FixSurfaceJunctions( mapDrawSurface_t *ds ) { int originals[MAX_SURFACE_VERTS]; bspDrawVert_t verts[MAX_SURFACE_VERTS], *v1, *v2; int numVerts; - float start, end, frac, c; - vec3_t delta; + float start, end, c; numVerts = 0; @@ -354,11 +357,9 @@ void FixSurfaceJunctions( mapDrawSurface_t *ds ) { } e = &edgeLines[ j ]; - VectorSubtract( v1->xyz, e->origin, delta ); - start = DotProduct( delta, e->dir ); + start = vector3_dot( v1->xyz - e->origin, e->dir ); - VectorSubtract( v2->xyz, e->origin, delta ); - end = DotProduct( delta, e->dir ); + end = vector3_dot( v2->xyz - e->origin, e->dir ); if ( start < end ) { @@ -389,17 +390,14 @@ void FixSurfaceJunctions( mapDrawSurface_t *ds ) { } /* take the exact intercept point */ - VectorCopy( p->xyz, verts[ numVerts ].xyz ); + verts[ numVerts ].xyz = p->xyz; /* interpolate the texture coordinates */ - frac = ( p->intercept - start ) / ( end - start ); - for ( j = 0 ; j < 2 ; j++ ) { - verts[ numVerts ].st[j] = v1->st[j] + - frac * ( v2->st[j] - v1->st[j] ); - } + const float frac = ( p->intercept - start ) / ( end - start ); + verts[ numVerts ].st = v1->st + ( v2->st - v1->st ) * frac; /* copy the normal (FIXME: what about nonplanar surfaces? */ - VectorCopy( v1->normal, verts[ numVerts ].normal ); + verts[ numVerts ].normal = v1->normal; /* ydnar: interpolate the color */ for ( k = 0; k < MAX_LIGHTMAPS; k++ ) @@ -500,8 +498,6 @@ void FixSurfaceJunctions( mapDrawSurface_t *ds ) { returns false if the surface is broken */ -extern void SnapWeldVector( vec3_t a, vec3_t b, vec3_t out ); - #define DEGENERATE_EPSILON 0.1 int c_broken = 0; @@ -509,7 +505,6 @@ int c_broken = 0; bool FixBrokenSurface( mapDrawSurface_t *ds ){ bspDrawVert_t *dv1, *dv2, avg; int i, j, k; - float dist; /* dummy check */ @@ -528,24 +523,20 @@ bool FixBrokenSurface( mapDrawSurface_t *ds ){ dv2 = &ds->verts[ ( i + 1 ) % ds->numVerts ]; /* degenerate edge? */ - VectorSubtract( dv1->xyz, dv2->xyz, avg.xyz ); - dist = VectorLength( avg.xyz ); - if ( dist < DEGENERATE_EPSILON ) { + avg.xyz = dv1->xyz - dv2->xyz; + if ( vector3_length( avg.xyz ) < DEGENERATE_EPSILON ) { Sys_FPrintf( SYS_WRN | SYS_VRBflag, "WARNING: Degenerate T-junction edge found, fixing...\n" ); /* create an average drawvert */ /* ydnar 2002-01-26: added nearest-integer welding preference */ SnapWeldVector( dv1->xyz, dv2->xyz, avg.xyz ); - VectorAdd( dv1->normal, dv2->normal, avg.normal ); - VectorNormalize( avg.normal, avg.normal ); - avg.st[ 0 ] = ( dv1->st[ 0 ] + dv2->st[ 0 ] ) * 0.5f; - avg.st[ 1 ] = ( dv1->st[ 1 ] + dv2->st[ 1 ] ) * 0.5f; + avg.normal = VectorNormalized( dv1->normal + dv2->normal ); + avg.st = vector2_mid( dv1->st, dv2->st ); /* lightmap st/colors */ for ( k = 0; k < MAX_LIGHTMAPS; k++ ) { - avg.lightmap[ k ][ 0 ] = ( dv1->lightmap[ k ][ 0 ] + dv2->lightmap[ k ][ 0 ] ) * 0.5f; - avg.lightmap[ k ][ 1 ] = ( dv1->lightmap[ k ][ 1 ] + dv2->lightmap[ k ][ 1 ] ) * 0.5f; + avg.lightmap[ k ] = vector2_mid( dv1->lightmap[ k ], dv2->lightmap[ k ] ); for ( j = 0; j < 4; j++ ) avg.color[ k ][ j ] = (int) ( dv1->color[ k ][ j ] + dv2->color[ k ][ j ] ) >> 1; } @@ -670,7 +661,7 @@ void FixTJunctions( entity_t *ent ){ for ( i = 0 ; i < numOriginalEdges ; i++ ) { e = &originalEdges[i]; dv = e->dv[0]; // e might change during AddEdge - dv->lightmap[ 0 ][ 0 ] = AddEdge( e->dv[ 0 ]->xyz, e->dv[ 1 ]->xyz, true ); + dv->lightmap[ 0 ][ 0 ] = AddEdge( *e->dv[ 0 ], *e->dv[ 1 ], true ); } Sys_FPrintf( SYS_VRB, "%9d axial edge lines\n", axialEdgeLines ); diff --git a/tools/quake3/q3map2/tree.cpp b/tools/quake3/q3map2/tree.cpp index df119502..e137442b 100644 --- a/tools/quake3/q3map2/tree.cpp +++ b/tools/quake3/q3map2/tree.cpp @@ -36,15 +36,10 @@ void RemovePortalFromNode( portal_t *portal, node_t *l ); -node_t *NodeForPoint( node_t *node, vec3_t origin ){ - plane_t *plane; - vec_t d; - +node_t *NodeForPoint( node_t *node, const Vector3& origin ){ while ( node->planenum != PLANENUM_LEAF ) { - plane = &mapplanes[node->planenum]; - d = DotProduct( origin, plane->normal ) - plane->dist; - if ( d >= 0 ) { + if ( plane3_distance_to_point( mapplanes[node->planenum].plane, origin ) >= 0 ) { node = node->children[0]; } else{ @@ -143,8 +138,8 @@ void PrintTree_r( node_t *node, int depth ){ plane = &mapplanes[node->planenum]; Sys_Printf( "#%d (%5.2f %5.2f %5.2f):%5.2f\n", node->planenum, - plane->normal[0], plane->normal[1], plane->normal[2], - plane->dist ); + plane->normal()[0], plane->normal()[1], plane->normal()[2], + plane->dist() ); PrintTree_r( node->children[0], depth + 1 ); PrintTree_r( node->children[1], depth + 1 ); } diff --git a/tools/quake3/q3map2/vis.cpp b/tools/quake3/q3map2/vis.cpp index b735f542..507a71eb 100644 --- a/tools/quake3/q3map2/vis.cpp +++ b/tools/quake3/q3map2/vis.cpp @@ -34,15 +34,11 @@ -void PlaneFromWinding( fixedWinding_t *w, visPlane_t *plane ){ - vec3_t v1, v2; - -// calc plane - VectorSubtract( w->points[2], w->points[1], v1 ); - VectorSubtract( w->points[0], w->points[1], v2 ); - CrossProduct( v2, v1, plane->normal ); - VectorNormalize( plane->normal, plane->normal ); - plane->dist = DotProduct( w->points[0], plane->normal ); +visPlane_t PlaneFromWinding( const fixedWinding_t *w ){ + // calc plane + visPlane_t plane; + PlaneFromPoints( plane, w->points[0], w->points[1], w->points[2] ); + return plane; } @@ -70,7 +66,7 @@ void prl( leaf_t *l ){ { p = l->portals[i]; pl = p->plane; - Sys_Printf( "portal %4i to leaf %4i : %7.1f : (%4.1f, %4.1f, %4.1f)\n",(int)( p - portals ),p->leaf,pl.dist, pl.normal[0], pl.normal[1], pl.normal[2] ); + Sys_Printf( "portal %4i to leaf %4i : %7.1f : (%4.1f, %4.1f, %4.1f)\n",(int)( p - portals ),p->leaf,pl.dist(), pl.normal()[0], pl.normal()[1], pl.normal()[2] ); } } @@ -374,30 +370,27 @@ void CalcVis( void ){ */ void SetPortalSphere( vportal_t *p ){ int i; - vec3_t total, dist; + Vector3 total( 0, 0, 0 ); fixedWinding_t *w; float r, bestr; w = p->winding; - VectorCopy( vec3_origin, total ); for ( i = 0 ; i < w->numpoints ; i++ ) { - VectorAdd( total, w->points[i], total ); + total += w->points[i]; } - for ( i = 0 ; i < 3 ; i++ ) - total[i] /= w->numpoints; + total /= w->numpoints; bestr = 0; for ( i = 0 ; i < w->numpoints ; i++ ) { - VectorSubtract( w->points[i], total, dist ); - r = VectorLength( dist ); + r = vector3_length( w->points[i] - total ); if ( r > bestr ) { bestr = r; } } - VectorCopy( total, p->origin ); + p->origin = total; p->radius = bestr; } @@ -408,9 +401,8 @@ void SetPortalSphere( vportal_t *p ){ */ #define WCONVEX_EPSILON 0.2 -static bool Winding_PlanesConcave( fixedWinding_t *w1, fixedWinding_t *w2, - vec3_t normal1, vec3_t normal2, - float dist1, float dist2 ){ +static bool Winding_PlanesConcave( const fixedWinding_t *w1, const fixedWinding_t *w2, + const Plane3f& plane1, const Plane3f& plane2 ){ int i; if ( !w1 || !w2 ) { @@ -420,14 +412,14 @@ static bool Winding_PlanesConcave( fixedWinding_t *w1, fixedWinding_t *w2, // check if one of the points of winding 1 is at the front of the plane of winding 2 for ( i = 0; i < w1->numpoints; i++ ) { - if ( DotProduct( normal2, w1->points[i] ) - dist2 > WCONVEX_EPSILON ) { + if ( plane3_distance_to_point( plane2, w1->points[i] ) > WCONVEX_EPSILON ) { return true; } } // check if one of the points of winding 2 is at the front of the plane of winding 1 for ( i = 0; i < w2->numpoints; i++ ) { - if ( DotProduct( normal1, w2->points[i] ) - dist1 > WCONVEX_EPSILON ) { + if ( plane3_distance_to_point( plane1, w2->points[i] ) > WCONVEX_EPSILON ) { return true; } } @@ -442,7 +434,6 @@ static bool Winding_PlanesConcave( fixedWinding_t *w1, fixedWinding_t *w2, */ static bool TryMergeLeaves( int l1num, int l2num ){ int i, j, k, n, numportals; - visPlane_t plane1, plane2; leaf_t *l1, *l2; vportal_t *p1, *p2; vportal_t *portals[MAX_PORTALS_ON_LEAF]; @@ -464,7 +455,9 @@ static bool TryMergeLeaves( int l1num, int l2num ){ if ( n ) { l2 = &leafs[l2num]; } - else{l2 = &faceleafs[l2num]; } + else{ + l2 = &faceleafs[l2num]; + } for ( j = 0; j < l2->numportals; j++ ) { p2 = l2->portals[j]; @@ -472,9 +465,7 @@ static bool TryMergeLeaves( int l1num, int l2num ){ continue; } // - plane1 = p1->plane; - plane2 = p2->plane; - if ( Winding_PlanesConcave( p1->winding, p2->winding, plane1.normal, plane2.normal, plane1.dist, plane2.dist ) ) { + if ( Winding_PlanesConcave( p1->winding, p2->winding, p1->plane, p2->plane ) ) { return false; } } @@ -599,12 +590,12 @@ void MergeLeaves( void ){ */ #define CONTINUOUS_EPSILON 0.005 -fixedWinding_t *TryMergeWinding( fixedWinding_t *f1, fixedWinding_t *f2, vec3_t planenormal ){ - vec_t *p1, *p2, *p3, *p4, *back; +fixedWinding_t *TryMergeWinding( fixedWinding_t *f1, fixedWinding_t *f2, const Vector3& planenormal ){ + const Vector3 *p1, *p2, *p3, *p4, *back; fixedWinding_t *newf; int i, j, k, l; - vec3_t normal, delta; - vec_t dot; + Vector3 normal; + float dot; bool keep1, keep2; @@ -616,18 +607,18 @@ fixedWinding_t *TryMergeWinding( fixedWinding_t *f1, fixedWinding_t *f2, vec3_t for ( i = 0; i < f1->numpoints; i++ ) { - p1 = f1->points[i]; - p2 = f1->points[( i + 1 ) % f1->numpoints]; + p1 = &f1->points[i]; + p2 = &f1->points[( i + 1 ) % f1->numpoints]; for ( j = 0; j < f2->numpoints; j++ ) { - p3 = f2->points[j]; - p4 = f2->points[( j + 1 ) % f2->numpoints]; + p3 = &f2->points[j]; + p4 = &f2->points[( j + 1 ) % f2->numpoints]; for ( k = 0; k < 3; k++ ) { - if ( fabs( p1[k] - p4[k] ) > 0.1 ) { //EQUAL_EPSILON) //ME + if ( fabs( (*p1)[k] - (*p4)[k] ) > 0.1 ) { //EQUAL_EPSILON) //ME break; } - if ( fabs( p2[k] - p3[k] ) > 0.1 ) { //EQUAL_EPSILON) //ME + if ( fabs( (*p2)[k] - (*p3)[k] ) > 0.1 ) { //EQUAL_EPSILON) //ME break; } } //end for @@ -648,27 +639,21 @@ fixedWinding_t *TryMergeWinding( fixedWinding_t *f1, fixedWinding_t *f2, vec3_t // check slope of connected lines // if the slopes are colinear, the point can be removed // - back = f1->points[( i + f1->numpoints - 1 ) % f1->numpoints]; - VectorSubtract( p1, back, delta ); - CrossProduct( planenormal, delta, normal ); - VectorNormalize( normal, normal ); + back = &f1->points[( i + f1->numpoints - 1 ) % f1->numpoints]; + normal = VectorNormalized( vector3_cross( planenormal, *p1 - *back ) ); - back = f2->points[( j + 2 ) % f2->numpoints]; - VectorSubtract( back, p1, delta ); - dot = DotProduct( delta, normal ); + back = &f2->points[( j + 2 ) % f2->numpoints]; + dot = vector3_dot( *back - *p1, normal ); if ( dot > CONTINUOUS_EPSILON ) { return NULL; // not a convex polygon } keep1 = ( dot < -CONTINUOUS_EPSILON ); - back = f1->points[( i + 2 ) % f1->numpoints]; - VectorSubtract( back, p2, delta ); - CrossProduct( planenormal, delta, normal ); - VectorNormalize( normal, normal ); + back = &f1->points[( i + 2 ) % f1->numpoints]; + normal = VectorNormalized( vector3_cross( planenormal, *back - *p2 ) ); - back = f2->points[( j + f2->numpoints - 1 ) % f2->numpoints]; - VectorSubtract( back, p2, delta ); - dot = DotProduct( delta, normal ); + back = &f2->points[( j + f2->numpoints - 1 ) % f2->numpoints]; + dot = vector3_dot( *back - *p2, normal ); if ( dot > CONTINUOUS_EPSILON ) { return NULL; // not a convex polygon } @@ -686,7 +671,7 @@ fixedWinding_t *TryMergeWinding( fixedWinding_t *f1, fixedWinding_t *f2, vec3_t continue; } - VectorCopy( f1->points[k], newf->points[newf->numpoints] ); + newf->points[newf->numpoints] = f1->points[k]; newf->numpoints++; } @@ -696,7 +681,7 @@ fixedWinding_t *TryMergeWinding( fixedWinding_t *f1, fixedWinding_t *f2, vec3_t if ( l == ( j + 1 ) % f2->numpoints && !keep1 ) { continue; } - VectorCopy( f2->points[l], newf->points[newf->numpoints] ); + newf->points[newf->numpoints] = f2->points[l]; newf->numpoints++; } @@ -735,7 +720,7 @@ void MergeLeafPortals( void ){ continue; } if ( p1->leaf == p2->leaf ) { - w = TryMergeWinding( p1->winding, p2->winding, p1->plane.normal ); + w = TryMergeWinding( p1->winding, p2->winding, p1->plane.normal() ); if ( w ) { free( p1->winding ); //% FreeWinding(p1->winding); p1->winding = w; @@ -793,7 +778,7 @@ int CountActivePortals( void ){ WritePortals ============ */ -void WriteFloat( FILE *f, vec_t v ); +void WriteFloat( FILE *f, float v ); void WritePortals( char *filename ){ int i, j, num; @@ -877,7 +862,6 @@ void LoadPortals( char *name ){ int numpoints; fixedWinding_t *w; int leafnums[2]; - visPlane_t plane; if ( strEqual( name, "-" ) ) { f = stdin; @@ -963,7 +947,7 @@ void LoadPortals( char *name ){ } // calc plane - PlaneFromWinding( w, &plane ); + const visPlane_t plane = PlaneFromWinding( w ); // create forward portal l = &leafs[leafnums[0]]; @@ -977,8 +961,7 @@ void LoadPortals( char *name ){ p->hint = ((flags & 1) != 0); p->sky = ((flags & 2) != 0); p->winding = w; - VectorSubtract( vec3_origin, plane.normal, p->plane.normal ); - p->plane.dist = -plane.dist; + p->plane = plane3_flipped( plane ); p->leaf = leafnums[1]; SetPortalSphere( p ); p++; @@ -997,7 +980,7 @@ void LoadPortals( char *name ){ p->winding->numpoints = w->numpoints; for ( j = 0 ; j < w->numpoints ; j++ ) { - VectorCopy( w->points[w->numpoints - 1 - j], p->winding->points[j] ); + p->winding->points[j] = w->points[w->numpoints - 1 - j]; } p->plane = plane; @@ -1038,7 +1021,7 @@ void LoadPortals( char *name ){ } // calc plane - PlaneFromWinding( w, &plane ); + const visPlane_t plane = PlaneFromWinding( w ); l = &faceleafs[leafnums[0]]; l->merged = -1; @@ -1051,8 +1034,7 @@ void LoadPortals( char *name ){ p->num = i + 1; p->winding = w; // normal pointing out of the leaf - VectorSubtract( vec3_origin, plane.normal, p->plane.normal ); - p->plane.dist = -plane.dist; + p->plane = plane3_flipped( plane ); p->leaf = -1; SetPortalSphere( p ); p++; diff --git a/tools/quake3/q3map2/visflow.cpp b/tools/quake3/q3map2/visflow.cpp index a1e8770a..3916290b 100644 --- a/tools/quake3/q3map2/visflow.cpp +++ b/tools/quake3/q3map2/visflow.cpp @@ -122,14 +122,13 @@ void FreeStackWinding( fixedWinding_t *w, pstack_t *stack ){ ============== */ -fixedWinding_t *VisChopWinding( fixedWinding_t *in, pstack_t *stack, visPlane_t *split ){ - vec_t dists[128]; - int sides[128]; +fixedWinding_t *VisChopWinding( fixedWinding_t *in, pstack_t *stack, const visPlane_t& split ){ + float dists[128]; + EPlaneSide sides[128]; int counts[3]; - vec_t dot; + float dot; int i, j; - vec_t *p1, *p2; - vec3_t mid; + Vector3 mid; fixedWinding_t *neww; counts[0] = counts[1] = counts[2] = 0; @@ -137,18 +136,16 @@ fixedWinding_t *VisChopWinding( fixedWinding_t *in, pstack_t *stack, visPlane_t // determine sides for each point for ( i = 0 ; i < in->numpoints ; i++ ) { - dot = DotProduct( in->points[i], split->normal ); - dot -= split->dist; - dists[i] = dot; - if ( dot > ON_EPSILON ) { - sides[i] = SIDE_FRONT; + dists[i] = plane3_distance_to_point( split, in->points[i] ); + if ( dists[i] > ON_EPSILON ) { + sides[i] = eSideFront; } - else if ( dot < -ON_EPSILON ) { - sides[i] = SIDE_BACK; + else if ( dists[i] < -ON_EPSILON ) { + sides[i] = eSideBack; } else { - sides[i] = SIDE_ON; + sides[i] = eSideOn; } counts[sides[i]]++; } @@ -171,25 +168,25 @@ fixedWinding_t *VisChopWinding( fixedWinding_t *in, pstack_t *stack, visPlane_t for ( i = 0 ; i < in->numpoints ; i++ ) { - p1 = in->points[i]; + const Vector3& p1 = in->points[i]; if ( neww->numpoints == MAX_POINTS_ON_FIXED_WINDING ) { FreeStackWinding( neww, stack ); return in; // can't chop -- fall back to original } - if ( sides[i] == SIDE_ON ) { - VectorCopy( p1, neww->points[neww->numpoints] ); + if ( sides[i] == eSideOn ) { + neww->points[neww->numpoints] = p1; neww->numpoints++; continue; } - if ( sides[i] == SIDE_FRONT ) { - VectorCopy( p1, neww->points[neww->numpoints] ); + if ( sides[i] == eSideFront ) { + neww->points[neww->numpoints] = p1; neww->numpoints++; } - if ( sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i] ) { + if ( sides[i + 1] == eSideOn || sides[i + 1] == sides[i] ) { continue; } @@ -199,23 +196,23 @@ fixedWinding_t *VisChopWinding( fixedWinding_t *in, pstack_t *stack, visPlane_t } // generate a split point - p2 = in->points[( i + 1 ) % in->numpoints]; + const Vector3& p2 = in->points[( i + 1 ) % in->numpoints]; dot = dists[i] / ( dists[i] - dists[i + 1] ); for ( j = 0 ; j < 3 ; j++ ) { // avoid round off error when possible - if ( split->normal[j] == 1 ) { - mid[j] = split->dist; + if ( split.normal()[j] == 1 ) { + mid[j] = split.dist(); } - else if ( split->normal[j] == -1 ) { - mid[j] = -split->dist; + else if ( split.normal()[j] == -1 ) { + mid[j] = -split.dist(); } else{ mid[j] = p1[j] + dot * ( p2[j] - p1[j] ); } } - VectorCopy( mid, neww->points[neww->numpoints] ); + neww->points[neww->numpoints] = mid; neww->numpoints++; } @@ -243,10 +240,7 @@ fixedWinding_t *VisChopWinding( fixedWinding_t *in, pstack_t *stack, visPlane_t */ fixedWinding_t *ClipToSeperators( fixedWinding_t *source, fixedWinding_t *pass, fixedWinding_t *target, bool flipclip, pstack_t *stack ){ int i, j, k, l; - visPlane_t plane; - vec3_t v1, v2; float d; - vec_t length; int counts[3]; bool fliptest; @@ -254,37 +248,18 @@ fixedWinding_t *ClipToSeperators( fixedWinding_t *source, fixedWinding_t *pass, for ( i = 0 ; i < source->numpoints ; i++ ) { l = ( i + 1 ) % source->numpoints; - VectorSubtract( source->points[l], source->points[i], v1 ); // find a vertex of pass that makes a plane that puts all of the // vertexes of pass on the front side and all of the vertexes of // source on the back side for ( j = 0 ; j < pass->numpoints ; j++ ) { - VectorSubtract( pass->points[j], source->points[i], v2 ); - - plane.normal[0] = v1[1] * v2[2] - v1[2] * v2[1]; - plane.normal[1] = v1[2] * v2[0] - v1[0] * v2[2]; - plane.normal[2] = v1[0] * v2[1] - v1[1] * v2[0]; - + visPlane_t plane; // if points don't make a valid plane, skip it - - length = plane.normal[0] * plane.normal[0] - + plane.normal[1] * plane.normal[1] - + plane.normal[2] * plane.normal[2]; - - if ( length < ON_EPSILON ) { + if ( !PlaneFromPoints( plane, source->points[i], pass->points[j], source->points[l] ) ) { continue; } - length = 1 / sqrt( length ); - - plane.normal[0] *= length; - plane.normal[1] *= length; - plane.normal[2] *= length; - - plane.dist = DotProduct( pass->points[j], plane.normal ); - // // find out which side of the generated seperating plane has the // source portal @@ -296,7 +271,7 @@ fixedWinding_t *ClipToSeperators( fixedWinding_t *source, fixedWinding_t *pass, if ( k == i || k == l ) { continue; } - d = DotProduct( source->points[k], plane.normal ) - plane.dist; + d = plane3_distance_to_point( plane, source->points[k] ); if ( d < -ON_EPSILON ) { // source is on the negative side, so we want all // pass and target on the positive side fliptest = false; @@ -318,8 +293,7 @@ fixedWinding_t *ClipToSeperators( fixedWinding_t *source, fixedWinding_t *pass, // flip the normal if the source portal is backwards // if ( fliptest ) { - VectorSubtract( vec3_origin, plane.normal, plane.normal ); - plane.dist = -plane.dist; + plane = plane3_flipped( plane ); } #if 1 // @@ -332,7 +306,7 @@ fixedWinding_t *ClipToSeperators( fixedWinding_t *source, fixedWinding_t *pass, if ( k == j ) { continue; } - d = DotProduct( pass->points[k], plane.normal ) - plane.dist; + d = plane3_distance_to_point( plane, pass->points[k] ); if ( d < -ON_EPSILON ) { break; } @@ -352,12 +326,12 @@ fixedWinding_t *ClipToSeperators( fixedWinding_t *source, fixedWinding_t *pass, } #else k = ( j + 1 ) % pass->numpoints; - d = DotProduct( pass->points[k], plane.normal ) - plane.dist; + d = plane3_distance_to_point( plane, pass->points[k] ); if ( d < -ON_EPSILON ) { continue; } k = ( j + pass->numpoints - 1 ) % pass->numpoints; - d = DotProduct( pass->points[k], plane.normal ) - plane.dist; + d = plane3_distance_to_point( plane, pass->points[k] ); if ( d < -ON_EPSILON ) { continue; } @@ -366,8 +340,7 @@ fixedWinding_t *ClipToSeperators( fixedWinding_t *source, fixedWinding_t *pass, // flip the normal if we want the back side // if ( flipclip ) { - VectorSubtract( vec3_origin, plane.normal, plane.normal ); - plane.dist = -plane.dist; + plane = plane3_flipped( plane ); } #ifdef SEPERATORCACHE @@ -377,7 +350,7 @@ fixedWinding_t *ClipToSeperators( fixedWinding_t *source, fixedWinding_t *pass, } #endif //MrE: fast check first - d = DotProduct( stack->portal->origin, plane.normal ) - plane.dist; + d = plane3_distance_to_point( plane, stack->portal->origin ); //if completely at the back of the seperator plane if ( d < -stack->portal->radius ) { return NULL; @@ -390,7 +363,7 @@ fixedWinding_t *ClipToSeperators( fixedWinding_t *source, fixedWinding_t *pass, // // clip target by the seperating plane // - target = VisChopWinding( target, stack, &plane ); + target = VisChopWinding( target, stack, plane ); if ( !target ) { return NULL; // target is not visible @@ -495,8 +468,7 @@ void RecursiveLeafFlow( int leafnum, threaddata_t *thread, pstack_t *prevstack ) // get plane of portal, point normal into the neighbor leaf stack.portalplane = p->plane; - VectorSubtract( vec3_origin, p->plane.normal, backplane.normal ); - backplane.dist = -p->plane.dist; + backplane = plane3_flipped( p->plane ); stack.portal = p; stack.next = NULL; @@ -506,10 +478,7 @@ void RecursiveLeafFlow( int leafnum, threaddata_t *thread, pstack_t *prevstack ) #if 1 { - float d; - - d = DotProduct( p->origin, thread->pstack_head.portalplane.normal ); - d -= thread->pstack_head.portalplane.dist; + const float d = plane3_distance_to_point( thread->pstack_head.portalplane, p->origin ); if ( d < -p->radius ) { continue; } @@ -518,7 +487,7 @@ void RecursiveLeafFlow( int leafnum, threaddata_t *thread, pstack_t *prevstack ) } else { - stack.pass = VisChopWinding( p->winding, &stack, &thread->pstack_head.portalplane ); + stack.pass = VisChopWinding( p->winding, &stack, thread->pstack_head.portalplane ); if ( !stack.pass ) { continue; } @@ -534,10 +503,7 @@ void RecursiveLeafFlow( int leafnum, threaddata_t *thread, pstack_t *prevstack ) #if 1 { - float d; - - d = DotProduct( thread->base->origin, p->plane.normal ); - d -= p->plane.dist; + const float d = plane3_distance_to_point( p->plane, thread->base->origin ); //MrE: vis-bug fix //if (d > p->radius) if ( d > thread->base->radius ) { @@ -550,7 +516,7 @@ void RecursiveLeafFlow( int leafnum, threaddata_t *thread, pstack_t *prevstack ) } else { - stack.source = VisChopWinding( prevstack->source, &stack, &backplane ); + stack.source = VisChopWinding( prevstack->source, &stack, backplane ); //FIXME: shouldn't we create a new source origin and radius for fast checks? if ( !stack.source ) { continue; @@ -558,7 +524,7 @@ void RecursiveLeafFlow( int leafnum, threaddata_t *thread, pstack_t *prevstack ) } } #else - stack.source = VisChopWinding( prevstack->source, &stack, &backplane ); + stack.source = VisChopWinding( prevstack->source, &stack, backplane ); if ( !stack.source ) { continue; } @@ -577,7 +543,7 @@ void RecursiveLeafFlow( int leafnum, threaddata_t *thread, pstack_t *prevstack ) if ( stack.numseperators[0] ) { for ( n = 0; n < stack.numseperators[0]; n++ ) { - stack.pass = VisChopWinding( stack.pass, &stack, &stack.seperators[0][n] ); + stack.pass = VisChopWinding( stack.pass, &stack, stack.seperators[0][n] ); if ( !stack.pass ) { break; // target is not visible } @@ -601,7 +567,7 @@ void RecursiveLeafFlow( int leafnum, threaddata_t *thread, pstack_t *prevstack ) if ( stack.numseperators[1] ) { for ( n = 0; n < stack.numseperators[1]; n++ ) { - stack.pass = VisChopWinding( stack.pass, &stack, &stack.seperators[1][n] ); + stack.pass = VisChopWinding( stack.pass, &stack, stack.seperators[1][n] ); if ( !stack.pass ) { break; // target is not visible } @@ -884,8 +850,7 @@ void RecursivePassagePortalFlow( vportal_t *portal, threaddata_t *thread, pstack // get plane of portal, point normal into the neighbor leaf stack.portalplane = p->plane; - VectorSubtract( vec3_origin, p->plane.normal, backplane.normal ); - backplane.dist = -p->plane.dist; + backplane = plane3_flipped( p->plane ); stack.portal = p; stack.next = NULL; @@ -895,10 +860,7 @@ void RecursivePassagePortalFlow( vportal_t *portal, threaddata_t *thread, pstack #if 1 { - float d; - - d = DotProduct( p->origin, thread->pstack_head.portalplane.normal ); - d -= thread->pstack_head.portalplane.dist; + const float d = plane3_distance_to_point( thread->pstack_head.portalplane, p->origin ); if ( d < -p->radius ) { continue; } @@ -907,14 +869,14 @@ void RecursivePassagePortalFlow( vportal_t *portal, threaddata_t *thread, pstack } else { - stack.pass = VisChopWinding( p->winding, &stack, &thread->pstack_head.portalplane ); + stack.pass = VisChopWinding( p->winding, &stack, thread->pstack_head.portalplane ); if ( !stack.pass ) { continue; } } } #else - stack.pass = VisChopWinding( p->winding, &stack, &thread->pstack_head.portalplane ); + stack.pass = VisChopWinding( p->winding, &stack, thread->pstack_head.portalplane ); if ( !stack.pass ) { continue; } @@ -923,10 +885,7 @@ void RecursivePassagePortalFlow( vportal_t *portal, threaddata_t *thread, pstack #if 1 { - float d; - - d = DotProduct( thread->base->origin, p->plane.normal ); - d -= p->plane.dist; + const float d = plane3_distance_to_point( p->plane, thread->base->origin ); //MrE: vis-bug fix //if (d > p->radius) if ( d > thread->base->radius ) { @@ -939,7 +898,7 @@ void RecursivePassagePortalFlow( vportal_t *portal, threaddata_t *thread, pstack } else { - stack.source = VisChopWinding( prevstack->source, &stack, &backplane ); + stack.source = VisChopWinding( prevstack->source, &stack, backplane ); //FIXME: shouldn't we create a new source origin and radius for fast checks? if ( !stack.source ) { continue; @@ -947,7 +906,7 @@ void RecursivePassagePortalFlow( vportal_t *portal, threaddata_t *thread, pstack } } #else - stack.source = VisChopWinding( prevstack->source, &stack, &backplane ); + stack.source = VisChopWinding( prevstack->source, &stack, backplane ); if ( !stack.source ) { continue; } @@ -966,7 +925,7 @@ void RecursivePassagePortalFlow( vportal_t *portal, threaddata_t *thread, pstack if ( stack.numseperators[0] ) { for ( n = 0; n < stack.numseperators[0]; n++ ) { - stack.pass = VisChopWinding( stack.pass, &stack, &stack.seperators[0][n] ); + stack.pass = VisChopWinding( stack.pass, &stack, stack.seperators[0][n] ); if ( !stack.pass ) { break; // target is not visible } @@ -990,7 +949,7 @@ void RecursivePassagePortalFlow( vportal_t *portal, threaddata_t *thread, pstack if ( stack.numseperators[1] ) { for ( n = 0; n < stack.numseperators[1]; n++ ) { - stack.pass = VisChopWinding( stack.pass, &stack, &stack.seperators[1][n] ); + stack.pass = VisChopWinding( stack.pass, &stack, stack.seperators[1][n] ); if ( !stack.pass ) { break; // target is not visible } @@ -1065,14 +1024,13 @@ void PassagePortalFlow( int portalnum ){ */ } -fixedWinding_t *PassageChopWinding( fixedWinding_t *in, fixedWinding_t *out, visPlane_t *split ){ - vec_t dists[128]; - int sides[128]; +fixedWinding_t *PassageChopWinding( fixedWinding_t *in, fixedWinding_t *out, const visPlane_t& split ){ + float dists[128]; + EPlaneSide sides[128]; int counts[3]; - vec_t dot; + float dot; int i, j; - vec_t *p1, *p2; - vec3_t mid; + Vector3 mid; fixedWinding_t *neww; counts[0] = counts[1] = counts[2] = 0; @@ -1080,18 +1038,16 @@ fixedWinding_t *PassageChopWinding( fixedWinding_t *in, fixedWinding_t *out, vis // determine sides for each point for ( i = 0 ; i < in->numpoints ; i++ ) { - dot = DotProduct( in->points[i], split->normal ); - dot -= split->dist; - dists[i] = dot; - if ( dot > ON_EPSILON ) { - sides[i] = SIDE_FRONT; + dists[i] = plane3_distance_to_point( split, in->points[i] ); + if ( dists[i] > ON_EPSILON ) { + sides[i] = eSideFront; } - else if ( dot < -ON_EPSILON ) { - sides[i] = SIDE_BACK; + else if ( dists[i] < -ON_EPSILON ) { + sides[i] = eSideBack; } else { - sides[i] = SIDE_ON; + sides[i] = eSideOn; } counts[sides[i]]++; } @@ -1113,24 +1069,24 @@ fixedWinding_t *PassageChopWinding( fixedWinding_t *in, fixedWinding_t *out, vis for ( i = 0 ; i < in->numpoints ; i++ ) { - p1 = in->points[i]; + const Vector3& p1 = in->points[i]; if ( neww->numpoints == MAX_POINTS_ON_FIXED_WINDING ) { return in; // can't chop -- fall back to original } - if ( sides[i] == SIDE_ON ) { - VectorCopy( p1, neww->points[neww->numpoints] ); + if ( sides[i] == eSideOn ) { + neww->points[neww->numpoints] = p1; neww->numpoints++; continue; } - if ( sides[i] == SIDE_FRONT ) { - VectorCopy( p1, neww->points[neww->numpoints] ); + if ( sides[i] == eSideFront ) { + neww->points[neww->numpoints] = p1; neww->numpoints++; } - if ( sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i] ) { + if ( sides[i + 1] == eSideOn || sides[i + 1] == sides[i] ) { continue; } @@ -1139,23 +1095,23 @@ fixedWinding_t *PassageChopWinding( fixedWinding_t *in, fixedWinding_t *out, vis } // generate a split point - p2 = in->points[( i + 1 ) % in->numpoints]; + const Vector3& p2 = in->points[( i + 1 ) % in->numpoints]; dot = dists[i] / ( dists[i] - dists[i + 1] ); for ( j = 0 ; j < 3 ; j++ ) { // avoid round off error when possible - if ( split->normal[j] == 1 ) { - mid[j] = split->dist; + if ( split.normal()[j] == 1 ) { + mid[j] = split.dist(); } - else if ( split->normal[j] == -1 ) { - mid[j] = -split->dist; + else if ( split.normal()[j] == -1 ) { + mid[j] = -split.dist(); } else{ mid[j] = p1[j] + dot * ( p2[j] - p1[j] ); } } - VectorCopy( mid, neww->points[neww->numpoints] ); + neww->points[neww->numpoints] = mid; neww->numpoints++; } @@ -1169,10 +1125,6 @@ fixedWinding_t *PassageChopWinding( fixedWinding_t *in, fixedWinding_t *out, vis */ int AddSeperators( fixedWinding_t *source, fixedWinding_t *pass, bool flipclip, visPlane_t *seperators, int maxseperators ){ int i, j, k, l; - visPlane_t plane; - vec3_t v1, v2; - float d; - vec_t length; int counts[3], numseperators; bool fliptest; @@ -1181,37 +1133,18 @@ int AddSeperators( fixedWinding_t *source, fixedWinding_t *pass, bool flipclip, for ( i = 0 ; i < source->numpoints ; i++ ) { l = ( i + 1 ) % source->numpoints; - VectorSubtract( source->points[l], source->points[i], v1 ); // find a vertex of pass that makes a plane that puts all of the // vertexes of pass on the front side and all of the vertexes of // source on the back side for ( j = 0 ; j < pass->numpoints ; j++ ) { - VectorSubtract( pass->points[j], source->points[i], v2 ); - - plane.normal[0] = v1[1] * v2[2] - v1[2] * v2[1]; - plane.normal[1] = v1[2] * v2[0] - v1[0] * v2[2]; - plane.normal[2] = v1[0] * v2[1] - v1[1] * v2[0]; - + visPlane_t plane; // if points don't make a valid plane, skip it - - length = plane.normal[0] * plane.normal[0] - + plane.normal[1] * plane.normal[1] - + plane.normal[2] * plane.normal[2]; - - if ( length < ON_EPSILON ) { + if ( !PlaneFromPoints( plane, source->points[i], pass->points[j], source->points[l] ) ) { continue; } - length = 1 / sqrt( length ); - - plane.normal[0] *= length; - plane.normal[1] *= length; - plane.normal[2] *= length; - - plane.dist = DotProduct( pass->points[j], plane.normal ); - // // find out which side of the generated seperating plane has the // source portal @@ -1223,7 +1156,7 @@ int AddSeperators( fixedWinding_t *source, fixedWinding_t *pass, bool flipclip, if ( k == i || k == l ) { continue; } - d = DotProduct( source->points[k], plane.normal ) - plane.dist; + const double d = plane3_distance_to_point( plane, source->points[k] ); if ( d < -ON_EPSILON ) { // source is on the negative side, so we want all // pass and target on the positive side fliptest = false; @@ -1245,8 +1178,7 @@ int AddSeperators( fixedWinding_t *source, fixedWinding_t *pass, bool flipclip, // flip the normal if the source portal is backwards // if ( fliptest ) { - VectorSubtract( vec3_origin, plane.normal, plane.normal ); - plane.dist = -plane.dist; + plane = plane3_flipped( plane ); } #if 1 // @@ -1259,7 +1191,7 @@ int AddSeperators( fixedWinding_t *source, fixedWinding_t *pass, bool flipclip, if ( k == j ) { continue; } - d = DotProduct( pass->points[k], plane.normal ) - plane.dist; + const double d = plane3_distance_to_point( plane, pass->points[k] ); if ( d < -ON_EPSILON ) { break; } @@ -1279,12 +1211,12 @@ int AddSeperators( fixedWinding_t *source, fixedWinding_t *pass, bool flipclip, } #else k = ( j + 1 ) % pass->numpoints; - d = DotProduct( pass->points[k], plane.normal ) - plane.dist; + d = vector3_dot( pass->points[k], plane.normal ) - plane.dist; if ( d < -ON_EPSILON ) { continue; } k = ( j + pass->numpoints - 1 ) % pass->numpoints; - d = DotProduct( pass->points[k], plane.normal ) - plane.dist; + d = vector3_dot( pass->points[k], plane.normal ) - plane.dist; if ( d < -ON_EPSILON ) { continue; } @@ -1293,8 +1225,7 @@ int AddSeperators( fixedWinding_t *source, fixedWinding_t *pass, bool flipclip, // flip the normal if we want the back side // if ( flipclip ) { - VectorSubtract( vec3_origin, plane.normal, plane.normal ); - plane.dist = -plane.dist; + plane = plane3_flipped( plane ); } if ( numseperators >= maxseperators ) { @@ -1319,7 +1250,6 @@ int AddSeperators( fixedWinding_t *source, fixedWinding_t *pass, bool flipclip, */ void CreatePassages( int portalnum ){ int i, j, k, n, numseperators, numsee; - float d; vportal_t *portal, *p, *target; leaf_t *leaf; passage_t *passage, *lastpassage; @@ -1377,18 +1307,15 @@ void CreatePassages( int portalnum ){ } for ( k = 0; k < numseperators; k++ ) { - // - d = DotProduct( p->origin, seperators[k].normal ) - seperators[k].dist; //if completely at the back of the seperator plane - if ( d < -p->radius + ON_EPSILON ) { + if ( plane3_distance_to_point( seperators[k], p->origin ) < -p->radius + ON_EPSILON ) { break; } w = p->winding; for ( n = 0; n < w->numpoints; n++ ) { - d = DotProduct( w->points[n], seperators[k].normal ) - seperators[k].dist; //if at the front of the seperator - if ( d > ON_EPSILON ) { + if ( plane3_distance_to_point( seperators[k], w->points[n] ) > ON_EPSILON ) { break; } } @@ -1407,7 +1334,7 @@ void CreatePassages( int portalnum ){ /* ydnar: prefer correctness to stack overflow */ //% memcpy( &in, p->winding, (int)((fixedWinding_t *)0)->points[p->winding->numpoints] ); if ( p->winding->numpoints <= MAX_POINTS_ON_FIXED_WINDING ) { - memcpy( &in, p->winding, (size_t)((fixedWinding_t *)0)->points[p->winding->numpoints] ); + memcpy( &in, p->winding, (size_t)&( ( (fixedWinding_t *)0 )->points[p->winding->numpoints] ) ); // memcpy( &in, p->winding, offsetof( fixedWinding_t, points[p->winding->numpoints] ) ); } else{ @@ -1423,7 +1350,7 @@ void CreatePassages( int portalnum ){ in.numpoints = MAX_POINTS_ON_FIXED_WINDING; } - res = PassageChopWinding( &in, &out, &seperators[ k ] ); + res = PassageChopWinding( &in, &out, seperators[ k ] ); if ( res == &out ) { memcpy( &in, &out, sizeof( fixedWinding_t ) ); } @@ -1557,9 +1484,7 @@ void SimpleFlood( vportal_t *srcportal, int leafnum ){ void BasePortalVis( int portalnum ){ int j, k; vportal_t *tp, *p; - float d; fixedWinding_t *w; - vec3_t dir; p = portals + portalnum; @@ -1593,13 +1518,12 @@ void BasePortalVis( int portalnum ){ */ if ( !p->sky && !tp->sky && farPlaneDist != 0.0f ) { - VectorSubtract( p->origin, tp->origin, dir ); if( farPlaneDistMode == 'o' ){ - if( VectorLength( dir ) > farPlaneDist ) + if( vector3_length( p->origin - tp->origin ) > farPlaneDist ) continue; } else if( farPlaneDistMode == 'e' ){ - if( VectorLength( dir ) + p->radius + tp->radius > 2.0f * farPlaneDist ) + if( vector3_length( p->origin - tp->origin ) + p->radius + tp->radius > 2.0f * farPlaneDist ) continue; } else if( farPlaneDistMode == 'r' ){ @@ -1607,7 +1531,7 @@ void BasePortalVis( int portalnum ){ continue; } else{ /* ydnar: this is known-to-be-working farplane code */ - if ( VectorLength( dir ) - p->radius - tp->radius > farPlaneDist ) + if ( vector3_length( p->origin - tp->origin ) - p->radius - tp->radius > farPlaneDist ) continue; } @@ -1617,9 +1541,7 @@ void BasePortalVis( int portalnum ){ w = tp->winding; for ( k = 0 ; k < w->numpoints ; k++ ) { - d = DotProduct( w->points[k], p->plane.normal ) - - p->plane.dist; - if ( d > ON_EPSILON ) { + if ( plane3_distance_to_point( p->plane, w->points[k] ) > ON_EPSILON ) { break; } } @@ -1630,9 +1552,7 @@ void BasePortalVis( int portalnum ){ w = p->winding; for ( k = 0 ; k < w->numpoints ; k++ ) { - d = DotProduct( w->points[k], tp->plane.normal ) - - tp->plane.dist; - if ( d < -ON_EPSILON ) { + if ( plane3_distance_to_point( tp->plane, w->points[k] ) < -ON_EPSILON ) { break; } } diff --git a/tools/quake3/q3map2/writebsp.cpp b/tools/quake3/q3map2/writebsp.cpp index 4a99284e..ff64a05c 100644 --- a/tools/quake3/q3map2/writebsp.cpp +++ b/tools/quake3/q3map2/writebsp.cpp @@ -111,19 +111,12 @@ int EmitShader( const char *shader, int *contentFlags, int *surfaceFlags ){ */ void EmitPlanes( void ){ - int i; - bspPlane_t *bp; - plane_t *mp; - - /* walk plane list */ - mp = mapplanes; - for ( i = 0; i < nummapplanes; i++, mp++ ) + plane_t *mp = mapplanes; + for ( int i = 0; i < nummapplanes; i++, mp++ ) { AUTOEXPAND_BY_REALLOC_BSP( Planes, 1024 ); - bp = &bspPlanes[ numBSPPlanes ]; - VectorCopy( mp->normal, bp->normal ); - bp->dist = mp->dist; + bspPlanes[ numBSPPlanes ] = mp->plane; numBSPPlanes++; } @@ -156,8 +149,8 @@ void EmitLeaf( node_t *node ){ leaf_p->area = node->area; /* emit bounding box */ - VectorCopy( node->mins, leaf_p->mins ); - VectorCopy( node->maxs, leaf_p->maxs ); + leaf_p->minmax.maxs = node->minmax.maxs; + leaf_p->minmax.mins = node->minmax.mins; /* emit leaf brushes */ leaf_p->firstBSPLeafBrush = numBSPLeafBrushes; @@ -218,8 +211,8 @@ int EmitDrawNode_r( node_t *node ){ n = &bspNodes[ n0 ]; numBSPNodes++; - VectorCopy( node->mins, n->mins ); - VectorCopy( node->maxs, n->maxs ); + n->minmax.mins = node->minmax.mins; + n->minmax.maxs = node->minmax.maxs; if ( node->planenum & 1 ) { Error( "WriteDrawNodes_r: odd planenum" ); @@ -534,66 +527,52 @@ void EmitFogs( void ){ */ void BeginModel( void ){ - bspModel_t *mod; - brush_t *b; - entity_t *e; - vec3_t mins, maxs; - vec3_t lgMins, lgMaxs; /* ydnar: lightgrid mins/maxs */ - parseMesh_t *p; - int i; - + MinMax minmax; + MinMax lgMinmax; /* ydnar: lightgrid mins/maxs */ /* test limits */ AUTOEXPAND_BY_REALLOC_BSP( Models, 256 ); /* get model and entity */ - mod = &bspModels[ numBSPModels ]; - e = &entities[ mapEntityNum ]; - - /* ydnar: lightgrid mins/maxs */ - ClearBounds( lgMins, lgMaxs ); + bspModel_t *mod = &bspModels[ numBSPModels ]; + const entity_t& e = entities[ mapEntityNum ]; /* bound the brushes */ - ClearBounds( mins, maxs ); - for ( b = e->brushes; b; b = b->next ) + for ( const brush_t *b = e.brushes; b; b = b->next ) { /* ignore non-real brushes (origin, etc) */ if ( b->numsides == 0 ) { continue; } - AddPointToBounds( b->mins, mins, maxs ); - AddPointToBounds( b->maxs, mins, maxs ); + minmax.extend( b->minmax ); /* ydnar: lightgrid bounds */ if ( b->compileFlags & C_LIGHTGRID ) { - AddPointToBounds( b->mins, lgMins, lgMaxs ); - AddPointToBounds( b->maxs, lgMins, lgMaxs ); + lgMinmax.extend( b->minmax ); } } /* bound patches */ - for ( p = e->patches; p; p = p->next ) + for ( const parseMesh_t *p = e.patches; p; p = p->next ) { - for ( i = 0; i < ( p->mesh.width * p->mesh.height ); i++ ) - AddPointToBounds( p->mesh.verts[i].xyz, mins, maxs ); + for ( int i = 0; i < ( p->mesh.width * p->mesh.height ); i++ ) + minmax.extend( p->mesh.verts[i].xyz ); } /* ydnar: lightgrid mins/maxs */ - if ( lgMins[ 0 ] < 99999 ) { + if ( lgMinmax.mins[ 0 ] < 99999 ) { /* use lightgrid bounds */ - VectorCopy( lgMins, mod->mins ); - VectorCopy( lgMaxs, mod->maxs ); + mod->minmax = lgMinmax; } else { /* use brush/patch bounds */ - VectorCopy( mins, mod->mins ); - VectorCopy( maxs, mod->maxs ); + mod->minmax = minmax; } /* note size */ - Sys_FPrintf( SYS_VRB, "BSP bounds: { %f %f %f } { %f %f %f }\n", mins[ 0 ], mins[ 1 ], mins[ 2 ], maxs[ 0 ], maxs[ 1 ], maxs[ 2 ] ); - Sys_FPrintf( SYS_VRB, "Lightgrid bounds: { %f %f %f } { %f %f %f }\n", lgMins[ 0 ], lgMins[ 1 ], lgMins[ 2 ], lgMaxs[ 0 ], lgMaxs[ 1 ], lgMaxs[ 2 ] ); + Sys_FPrintf( SYS_VRB, "BSP bounds: { %f %f %f } { %f %f %f }\n", minmax.mins[0], minmax.mins[1], minmax.mins[2], minmax.maxs[0], minmax.maxs[1], minmax.maxs[2] ); + Sys_FPrintf( SYS_VRB, "Lightgrid bounds: { %f %f %f } { %f %f %f }\n", lgMinmax.mins[0], lgMinmax.mins[1], lgMinmax.mins[2], lgMinmax.maxs[0], lgMinmax.maxs[1], lgMinmax.maxs[2] ); /* set firsts */ mod->firstBSPSurface = numBSPDrawSurfaces;