diff --git a/cmake/DaemonFlags.cmake b/cmake/DaemonFlags.cmake index 0bd6eb94f0..d257d6f6af 100644 --- a/cmake/DaemonFlags.cmake +++ b/cmake/DaemonFlags.cmake @@ -68,10 +68,19 @@ macro(set_c_cxx_flag FLAG) set_c_flag(${FLAG} ${ARGN}) set_cxx_flag(${FLAG} ${ARGN}) endmacro() + +macro(set_kind_linker_flag KIND FLAG) + if (KIND STREQUAL "exe") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAG}") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FLAG}") + else() + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FLAG}") + endif() +endmacro() + macro(set_linker_flag FLAG) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAG}") - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FLAG}") - set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FLAG}") + set_kind_linker_flag("exe" FLAG) + set_kind_linker_flag("shared" FLAG) endmacro() function(try_flag LIST FLAG) @@ -142,6 +151,16 @@ macro(try_linker_flag PROP FLAG) endif() endmacro() +macro(try_kind_linker_flag KIND PROP FLAG) + # Check it with the C compiler + set(CMAKE_REQUIRED_FLAGS ${FLAG}) + check_C_compiler_flag(${FLAG} FLAG_${KIND}_${PROP}) + set(CMAKE_REQUIRED_FLAGS "") + if (FLAG_${KIND}_${PROP}) + set_kind_linker_flag(${KIND} ${FLAG} ${ARGN}) + endif() +endmacro() + if (BE_VERBOSE) set(WARNMODE "no-error=") else() @@ -348,13 +367,19 @@ else() try_c_cxx_flag(WSTACK_PROTECTOR "-Wstack-protector") if (NOT NACL OR (NACL AND GAME_PIE)) - try_c_cxx_flag(FPIE "-fPIE") + if (BUILD_GAME_NATIVE_DLL AND (BUILD_CGAME OR BUILD_SGAME)) + try_c_cxx_flag(FPIC "-fPIC") + else() + try_c_cxx_flag(FPIE "-fPIE") + endif() + if (NOT APPLE) - try_linker_flag(LINKER_PIE "-pie") + try_kind_linker_flag("shared" LINKER_PIC "-pic") + try_kind_linker_flag("exe" LINKER_PIE "-pie") endif() endif() - if ("${FLAG_LINKER_PIE}" AND MINGW) + if ("${FLAG_shared_LINKER_PIE}" AND MINGW) # https://github.com/msys2/MINGW-packages/issues/4100 if (ARCH STREQUAL "i686") set_linker_flag("-Wl,-e,_mainCRTStartup") diff --git a/src/common/cm/cm_load.cpp b/src/common/cm/cm_load.cpp index 199399cf48..53e3a9b851 100644 --- a/src/common/cm/cm_load.cpp +++ b/src/common/cm/cm_load.cpp @@ -247,14 +247,14 @@ CM_BoundBrush */ void CM_BoundBrush( cbrush_t *b ) { - b->bounds[ 0 ][ 0 ] = -b->sides[ 0 ].plane->dist; - b->bounds[ 1 ][ 0 ] = b->sides[ 1 ].plane->dist; + b->bounds.mins[ 0 ] = -b->sides[ 0 ].plane->dist; + b->bounds.maxs[ 0 ] = b->sides[ 1 ].plane->dist; - b->bounds[ 0 ][ 1 ] = -b->sides[ 2 ].plane->dist; - b->bounds[ 1 ][ 1 ] = b->sides[ 3 ].plane->dist; + b->bounds.mins[ 1 ] = -b->sides[ 2 ].plane->dist; + b->bounds.maxs[ 1 ] = b->sides[ 3 ].plane->dist; - b->bounds[ 0 ][ 2 ] = -b->sides[ 4 ].plane->dist; - b->bounds[ 1 ][ 2 ] = b->sides[ 5 ].plane->dist; + b->bounds.mins[ 2 ] = -b->sides[ 4 ].plane->dist; + b->bounds.maxs[ 2 ] = b->sides[ 5 ].plane->dist; } /* @@ -999,8 +999,7 @@ clipHandle_t CM_TempBoxModel( const vec3_t mins, const vec3_t maxs, bool capsule box_planes[ 10 ].dist = mins[ 2 ]; box_planes[ 11 ].dist = -mins[ 2 ]; - VectorCopy( mins, box_brush->bounds[ 0 ] ); - VectorCopy( maxs, box_brush->bounds[ 1 ] ); + BoundsSet( box_brush->bounds, mins, maxs ); return BOX_MODEL_HANDLE; } diff --git a/src/common/cm/cm_local.h b/src/common/cm/cm_local.h index 09ff99311d..98266b349e 100644 --- a/src/common/cm/cm_local.h +++ b/src/common/cm/cm_local.h @@ -77,7 +77,7 @@ struct cbrushside_t struct cbrush_t { int contents; - vec3_t bounds[ 2 ]; + bounds_t bounds; int numsides; cbrushside_t *sides; int checkcount; // to avoid repeated testings @@ -129,7 +129,7 @@ struct cFacet_t struct cSurfaceCollide_t { - vec3_t bounds[ 2 ]; + bounds_t bounds; int numPlanes; // surface planes plus edge planes cPlane_t *planes; @@ -238,7 +238,7 @@ struct traceWork_t vec3_t offsets[ 8 ]; // [signbits][x] = either size[0][x] or size[1][x] float maxOffset; // longest corner length from origin vec3_t extents; // greatest of abs(size[0]) and abs(size[1]) - vec3_t bounds[ 2 ]; // enclosing box of start and end surrounding by size + bounds_t bounds; // enclosing box of start and end surrounding by size vec3_t modelOrigin; // origin of the model tracing through int contents; // ored contents of the model tracing through int skipContents; // ored contents that shall be ignored @@ -253,7 +253,7 @@ struct leafList_t int maxcount; bool overflowed; int *list; - vec3_t bounds[ 2 ]; + bounds_t bounds; // for bounding box culling int lastLeaf; // for overflows where each leaf can't be stored individually void ( *storeLeafs )( leafList_t *ll, int nodenum ); }; diff --git a/src/common/cm/cm_patch.cpp b/src/common/cm/cm_patch.cpp index d43c0f1c0d..57da9d672b 100644 --- a/src/common/cm/cm_patch.cpp +++ b/src/common/cm/cm_patch.cpp @@ -822,13 +822,13 @@ cSurfaceCollide_t *CM_GeneratePatchCollide( int width, int height, const vec3_t // the approximate surface defined by these points will be // collided against sc = ( cSurfaceCollide_t * ) CM_Alloc( sizeof( *sc ) ); - ClearBounds( sc->bounds[ 0 ], sc->bounds[ 1 ] ); + ClearBounds( sc->bounds ); for ( i = 0; i < grid.width; i++ ) { for ( j = 0; j < grid.height; j++ ) { - AddPointToBounds( grid.points[ i ][ j ], sc->bounds[ 0 ], sc->bounds[ 1 ] ); + AddPointToBounds( grid.points[ i ][ j ], sc->bounds ); } } @@ -838,13 +838,13 @@ cSurfaceCollide_t *CM_GeneratePatchCollide( int width, int height, const vec3_t CM_SurfaceCollideFromGrid( &grid, sc ); // expand by one unit for epsilon purposes - sc->bounds[ 0 ][ 0 ] -= 1; - sc->bounds[ 0 ][ 1 ] -= 1; - sc->bounds[ 0 ][ 2 ] -= 1; + sc->bounds.mins[ 0 ] -= 1; + sc->bounds.mins[ 1 ] -= 1; + sc->bounds.mins[ 2 ] -= 1; - sc->bounds[ 1 ][ 0 ] += 1; - sc->bounds[ 1 ][ 1 ] += 1; - sc->bounds[ 1 ][ 2 ] += 1; + sc->bounds.maxs[ 0 ] += 1; + sc->bounds.maxs[ 1 ] += 1; + sc->bounds.maxs[ 2 ] += 1; return sc; } diff --git a/src/common/cm/cm_test.cpp b/src/common/cm/cm_test.cpp index 2ff39ddf92..bb8026a768 100644 --- a/src/common/cm/cm_test.cpp +++ b/src/common/cm/cm_test.cpp @@ -140,7 +140,7 @@ void CM_BoxLeafnums_r( leafList_t *ll, int nodenum ) node = &cm.nodes[ nodenum ]; plane = node->plane; - s = BoxOnPlaneSide( ll->bounds[ 0 ], ll->bounds[ 1 ], plane ); + s = BoxOnPlaneSide( ll->bounds, plane ); if ( s == 1 ) { @@ -170,8 +170,7 @@ int CM_BoxLeafnums( const vec3_t mins, const vec3_t maxs, int *list, int listsiz cm.checkcount++; - VectorCopy( mins, ll.bounds[ 0 ] ); - VectorCopy( maxs, ll.bounds[ 1 ] ); + BoundsSet( ll.bounds, mins, maxs ); ll.count = 0; ll.maxcount = listsize; ll.list = list; @@ -236,7 +235,7 @@ int CM_PointContents( const vec3_t p, clipHandle_t model ) const cbrush_t *b = &cm.brushes[ *brushNum ]; // XreaL BEGIN - if ( !CM_BoundsIntersectPoint( b->bounds[ 0 ], b->bounds[ 1 ], p ) ) + if ( !CM_BoundsIntersectPoint( b->bounds.mins, b->bounds.maxs, p ) ) { continue; } diff --git a/src/common/cm/cm_trace.cpp b/src/common/cm/cm_trace.cpp index baa386a24e..0780fe9d38 100644 --- a/src/common/cm/cm_trace.cpp +++ b/src/common/cm/cm_trace.cpp @@ -177,11 +177,12 @@ static void CM_TestBoxInBrush( traceWork_t *tw, const cbrush_t *brush ) // special test for axial // the first 6 brush planes are always axial - if ( tw->bounds[ 0 ][ 0 ] > brush->bounds[ 1 ][ 0 ] - || tw->bounds[ 0 ][ 1 ] > brush->bounds[ 1 ][ 1 ] - || tw->bounds[ 0 ][ 2 ] > brush->bounds[ 1 ][ 2 ] - || tw->bounds[ 1 ][ 0 ] < brush->bounds[ 0 ][ 0 ] - || tw->bounds[ 1 ][ 1 ] < brush->bounds[ 0 ][ 1 ] || tw->bounds[ 1 ][ 2 ] < brush->bounds[ 0 ][ 2 ] ) + if ( tw->bounds.mins[ 0 ] > brush->bounds.maxs[ 0 ] + || tw->bounds.mins[ 1 ] > brush->bounds.maxs[ 1 ] + || tw->bounds.mins[ 2 ] > brush->bounds.maxs[ 2 ] + || tw->bounds.maxs[ 0 ] < brush->bounds.mins[ 0 ] + || tw->bounds.maxs[ 1 ] < brush->bounds.mins[ 1 ] + || tw->bounds.maxs[ 2 ] < brush->bounds.mins[ 2 ] ) { return; } @@ -613,17 +614,17 @@ void CM_PositionTest( traceWork_t *tw ) leafList_t ll; // identify the leafs we are touching - VectorAdd( tw->start, tw->size[ 0 ], ll.bounds[ 0 ] ); - VectorAdd( tw->start, tw->size[ 1 ], ll.bounds[ 1 ] ); + VectorAdd( tw->start, tw->size[ 0 ], ll.bounds.mins ); + VectorAdd( tw->start, tw->size[ 1 ], ll.bounds.maxs ); { - ll.bounds[ 0 ][ 0 ] -= 1; - ll.bounds[ 0 ][ 1 ] -= 1; - ll.bounds[ 0 ][ 2 ] -= 1; + ll.bounds.mins[ 0 ] -= 1; + ll.bounds.mins[ 1 ] -= 1; + ll.bounds.mins[ 2 ] -= 1; - ll.bounds[ 1 ][ 0 ] += 1; - ll.bounds[ 1 ][ 1 ] += 1; - ll.bounds[ 1 ][ 2 ] += 1; + ll.bounds.maxs[ 0 ] += 1; + ll.bounds.maxs[ 1 ] += 1; + ll.bounds.maxs[ 2 ] += 1; } ll.count = 0; @@ -850,7 +851,7 @@ void CM_TraceThroughSurfaceCollide( traceWork_t *tw, const cSurfaceCollide_t *sc cFacet_t *facet; vec3_t startp, endp; - if ( !CM_BoundsIntersect( tw->bounds[ 0 ], tw->bounds[ 1 ], sc->bounds[ 0 ], sc->bounds[ 1 ] ) ) + if ( !CM_BoundsIntersect( tw->bounds.mins, tw->bounds.maxs, sc->bounds.mins, sc->bounds.maxs ) ) { return; } @@ -1290,7 +1291,7 @@ void CM_TraceThroughLeaf( traceWork_t *tw, const cLeaf_t *leaf ) continue; } - if ( !CM_BoundsIntersect( tw->bounds[ 0 ], tw->bounds[ 1 ], b->bounds[ 0 ], b->bounds[ 1 ] ) ) + if ( !CM_BoundsIntersect( tw->bounds.mins, tw->bounds.maxs, b->bounds.mins, b->bounds.maxs ) ) { continue; } @@ -1338,7 +1339,7 @@ void CM_TraceThroughLeaf( traceWork_t *tw, const cLeaf_t *leaf ) continue; } - if ( !CM_BoundsIntersect( tw->bounds[ 0 ], tw->bounds[ 1 ], surface->sc->bounds[ 0 ], surface->sc->bounds[ 1 ] ) ) + if ( !CM_BoundsIntersect( tw->bounds.mins, tw->bounds.maxs, surface->sc->bounds.mins, surface->sc->bounds.maxs ) ) { continue; } @@ -1590,12 +1591,12 @@ void CM_TraceCapsuleThroughCapsule( traceWork_t *tw, clipHandle_t model ) CM_ModelBounds( model, mins, maxs ); // test trace bounds vs. capsule bounds - if ( tw->bounds[ 0 ][ 0 ] > maxs[ 0 ] + RADIUS_EPSILON - || tw->bounds[ 0 ][ 1 ] > maxs[ 1 ] + RADIUS_EPSILON - || tw->bounds[ 0 ][ 2 ] > maxs[ 2 ] + RADIUS_EPSILON - || tw->bounds[ 1 ][ 0 ] < mins[ 0 ] - RADIUS_EPSILON - || tw->bounds[ 1 ][ 1 ] < mins[ 1 ] - RADIUS_EPSILON - || tw->bounds[ 1 ][ 2 ] < mins[ 2 ] - RADIUS_EPSILON ) + if ( tw->bounds.mins[ 0 ] > maxs[ 0 ] + RADIUS_EPSILON + || tw->bounds.mins[ 1 ] > maxs[ 1 ] + RADIUS_EPSILON + || tw->bounds.mins[ 2 ] > maxs[ 2 ] + RADIUS_EPSILON + || tw->bounds.maxs[ 0 ] < mins[ 0 ] - RADIUS_EPSILON + || tw->bounds.maxs[ 1 ] < mins[ 1 ] - RADIUS_EPSILON + || tw->bounds.maxs[ 2 ] < mins[ 2 ] - RADIUS_EPSILON ) { return; } @@ -1964,13 +1965,13 @@ static void CM_Trace( trace_t *results, const vec3_t start, const vec3_t end, co { if ( tw.start[ i ] < tw.end[ i ] ) { - tw.bounds[ 0 ][ i ] = tw.start[ i ] - fabsf( tw.sphere.offset[ i ] ) - tw.sphere.radius; - tw.bounds[ 1 ][ i ] = tw.end[ i ] + fabsf( tw.sphere.offset[ i ] ) + tw.sphere.radius; + tw.bounds.mins[ i ] = tw.start[ i ] - fabsf( tw.sphere.offset[ i ] ) - tw.sphere.radius; + tw.bounds.maxs[ i ] = tw.end[ i ] + fabsf( tw.sphere.offset[ i ] ) + tw.sphere.radius; } else { - tw.bounds[ 0 ][ i ] = tw.end[ i ] - fabsf( tw.sphere.offset[ i ] ) - tw.sphere.radius; - tw.bounds[ 1 ][ i ] = tw.start[ i ] + fabsf( tw.sphere.offset[ i ] ) + tw.sphere.radius; + tw.bounds.mins[ i ] = tw.end[ i ] - fabsf( tw.sphere.offset[ i ] ) - tw.sphere.radius; + tw.bounds.maxs[ i ] = tw.start[ i ] + fabsf( tw.sphere.offset[ i ] ) + tw.sphere.radius; } } } @@ -1980,13 +1981,13 @@ static void CM_Trace( trace_t *results, const vec3_t start, const vec3_t end, co { if ( tw.start[ i ] < tw.end[ i ] ) { - tw.bounds[ 0 ][ i ] = tw.start[ i ] + tw.size[ 0 ][ i ]; - tw.bounds[ 1 ][ i ] = tw.end[ i ] + tw.size[ 1 ][ i ]; + tw.bounds.mins[ i ] = tw.start[ i ] + tw.size[ 0 ][ i ]; + tw.bounds.maxs[ i ] = tw.end[ i ] + tw.size[ 1 ][ i ]; } else { - tw.bounds[ 0 ][ i ] = tw.end[ i ] + tw.size[ 0 ][ i ]; - tw.bounds[ 1 ][ i ] = tw.start[ i ] + tw.size[ 1 ][ i ]; + tw.bounds.mins[ i ] = tw.end[ i ] + tw.size[ 0 ][ i ]; + tw.bounds.maxs[ i ] = tw.start[ i ] + tw.size[ 1 ][ i ]; } } } diff --git a/src/common/cm/cm_trisoup.cpp b/src/common/cm/cm_trisoup.cpp index f751237ccd..be39ab0315 100644 --- a/src/common/cm/cm_trisoup.cpp +++ b/src/common/cm/cm_trisoup.cpp @@ -318,13 +318,13 @@ cSurfaceCollide_t *CM_GenerateTriangleSoupCollide( int numVertexes, vec3_t *vert //for(i = 0; i < triSoup.num sc = ( cSurfaceCollide_t * ) CM_Alloc( sizeof( *sc ) ); - ClearBounds( sc->bounds[ 0 ], sc->bounds[ 1 ] ); + ClearBounds( sc->bounds ); for ( i = 0; i < triSoup.numTriangles; i++ ) { for ( j = 0; j < 3; j++ ) { - AddPointToBounds( triSoup.points[ i ][ j ], sc->bounds[ 0 ], sc->bounds[ 1 ] ); + AddPointToBounds( triSoup.points[ i ][ j ], sc->bounds ); } } @@ -332,13 +332,13 @@ cSurfaceCollide_t *CM_GenerateTriangleSoupCollide( int numVertexes, vec3_t *vert CM_SurfaceCollideFromTriangleSoup( &triSoup, sc ); // expand by one unit for epsilon purposes - sc->bounds[ 0 ][ 0 ] -= 1; - sc->bounds[ 0 ][ 1 ] -= 1; - sc->bounds[ 0 ][ 2 ] -= 1; + sc->bounds.mins[ 0 ] -= 1; + sc->bounds.mins[ 1 ] -= 1; + sc->bounds.mins[ 2 ] -= 1; - sc->bounds[ 1 ][ 0 ] += 1; - sc->bounds[ 1 ][ 1 ] += 1; - sc->bounds[ 1 ][ 2 ] += 1; + sc->bounds.maxs[ 0 ] += 1; + sc->bounds.maxs[ 1 ] += 1; + sc->bounds.maxs[ 2 ] += 1; cmLog.Debug( "CM_GenerateTriangleSoupCollide: %i planes %i facets", sc->numPlanes, sc->numFacets ); diff --git a/src/engine/client/cg_msgdef.h b/src/engine/client/cg_msgdef.h index 37e0c8ec37..0ac06fe0bd 100644 --- a/src/engine/client/cg_msgdef.h +++ b/src/engine/client/cg_msgdef.h @@ -66,11 +66,12 @@ namespace Util { { stream.Write(Util::ordinal(skel.type)); stream.WriteSize(skel.numBones); - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 3; j++) { - stream.Write(skel.bounds[i][j]); - } - } + stream.Write(skel.bounds.mins[0]); + stream.Write(skel.bounds.mins[1]); + stream.Write(skel.bounds.mins[2]); + stream.Write(skel.bounds.maxs[0]); + stream.Write(skel.bounds.maxs[1]); + stream.Write(skel.bounds.maxs[2]); stream.Write(skel.scale); size_t length = sizeof(refBone_t) * skel.numBones; stream.WriteData(&skel.bones, length); @@ -80,11 +81,12 @@ namespace Util { refSkeleton_t skel; skel.type = static_cast(stream.Read()); skel.numBones = stream.ReadSize(); - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 3; j++) { - skel.bounds[i][j] = stream.Read(); - } - } + skel.bounds.mins[0] = stream.Read(); + skel.bounds.mins[1] = stream.Read(); + skel.bounds.mins[2] = stream.Read(); + skel.bounds.maxs[0] = stream.Read(); + skel.bounds.maxs[1] = stream.Read(); + skel.bounds.maxs[2] = stream.Read(); skel.scale = stream.Read(); if (skel.numBones > sizeof(skel.bones) / sizeof(refBone_t)) { diff --git a/src/engine/client/cl_cgame.cpp b/src/engine/client/cl_cgame.cpp index 23f9325064..082a6d570f 100644 --- a/src/engine/client/cl_cgame.cpp +++ b/src/engine/client/cl_cgame.cpp @@ -1265,7 +1265,10 @@ void CGameVM::QVMSyscall(int syscallNum, Util::Reader& reader, IPC::Channel& cha case CG_R_MODELBOUNDS: IPC::HandleMsg(channel, std::move(reader), [this] (int handle, std::array& mins, std::array& maxs) { - re.ModelBounds(handle, mins.data(), maxs.data()); + bounds_t bounds; + re.ModelBounds(handle, bounds); + VectorCopy(bounds.mins, mins.data()); + VectorCopy(bounds.maxs, maxs.data()); }); break; diff --git a/src/engine/null/null_renderer.cpp b/src/engine/null/null_renderer.cpp index 9e4b6e24c0..d9ffec6052 100644 --- a/src/engine/null/null_renderer.cpp +++ b/src/engine/null/null_renderer.cpp @@ -106,7 +106,7 @@ int R_LerpTag( orientation_t*, const refEntity_t*, const char*, int ) { return 0; } -void R_ModelBounds( qhandle_t, vec3_t, vec3_t ) { } +void R_ModelBounds( qhandle_t, bounds_t& ) { } void R_RemapShader( const char*, const char*, const char* ) { } bool R_GetEntityToken( char*, int ) { diff --git a/src/engine/qcommon/q_math.cpp b/src/engine/qcommon/q_math.cpp index 4de91b1a34..6b2485bf74 100644 --- a/src/engine/qcommon/q_math.cpp +++ b/src/engine/qcommon/q_math.cpp @@ -741,12 +741,12 @@ void SetPlaneSignbits( cplane_t *out ) * ================== */ -int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const cplane_t *p ) +int BoxOnPlaneSide( const bounds_t &bounds, const cplane_t *p ) { #if defined(DAEMON_USE_ARCH_INTRINSICS_i686_sse) - auto mins = sseLoadVec3Unsafe( emins ); - auto maxs = sseLoadVec3Unsafe( emaxs ); - auto normal = sseLoadVec3Unsafe( p->normal ); + auto mins = _mm_load_ps( bounds.mins ); + auto maxs = _mm_load_ps( bounds.maxs ); + auto normal = _mm_load_ps( p->normal ); auto prod0 = _mm_mul_ps( maxs, normal ); auto prod1 = _mm_mul_ps( mins, normal ); @@ -754,26 +754,25 @@ int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const cplane_t *p ) auto pmax = _mm_max_ps( prod0, prod1 ); auto pmin = _mm_min_ps( prod0, prod1 ); - alignas(16) vec4_t pmaxv; - alignas(16) vec4_t pminv; - _mm_store_ps( pmaxv, pmax ); - _mm_store_ps( pminv, pmin ); + bounds_t b; + _mm_store_ps( b.maxs, pmax ); + _mm_store_ps( b.mins, pmin ); float dist[ 2 ]; - dist[ 0 ] = pmaxv[ 0 ] + pmaxv[ 1 ] + pmaxv[ 2 ]; - dist[ 1 ] = pminv[ 0 ] + pminv[ 1 ] + pminv[ 2 ]; + dist[ 0 ] = b.maxs[ 0 ] + b.maxs[ 1 ] + b.maxs[ 2 ]; + dist[ 1 ] = b.mins[ 0 ] + b.mins[ 1 ] + b.mins[ 2 ]; #else ASSERT_LT( p->signbits, 8 ); // fast axial cases if ( p->type < 3 ) { - if ( p->dist <= emins[ p->type ] ) + if ( p->dist <= bounds.mins[ p->type ] ) { return 1; } - if ( p->dist >= emaxs[ p->type ] ) + if ( p->dist >= bounds.maxs[ p->type ] ) { return 2; } @@ -792,8 +791,8 @@ int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const cplane_t *p ) index[ 2 ] &= 1; vec3_t mmins, mmaxs; - VectorMultiply( p->normal, emins, mmins ); - VectorMultiply( p->normal, emaxs, mmaxs ); + VectorMultiply( p->normal, bounds.mins, mmins ); + VectorMultiply( p->normal, bounds.maxs, mmaxs ); float dist[ 2 ] = {}; dist[ index[ 0 ] ] += mmaxs[ 0 ]; @@ -815,116 +814,123 @@ int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const cplane_t *p ) * RadiusFromBounds * ================= */ -float RadiusFromBounds( const vec3_t mins, const vec3_t maxs ) +float RadiusFromBounds( const bounds_t &b ) { - int i; vec3_t corner; - float a, b; - for ( i = 0; i < 3; i++ ) + for ( int i = 0; i < 3; i++ ) { - a = Q_fabs( mins[ i ] ); - b = Q_fabs( maxs[ i ] ); - corner[ i ] = a > b ? a : b; + vec_t mins = Q_fabs( b.mins[ i ] ); + vec_t maxs = Q_fabs( b.maxs[ i ] ); + corner[ i ] = mins > maxs ? mins : maxs; } return VectorLength( corner ); } -void ZeroBounds( vec3_t mins, vec3_t maxs ) +void ZeroBounds( bounds_t &b ) { - mins[ 0 ] = mins[ 1 ] = mins[ 2 ] = 0; - maxs[ 0 ] = maxs[ 1 ] = maxs[ 2 ] = 0; + b = {}; } -void ClearBounds( vec3_t mins, vec3_t maxs ) +void ClearBounds( bounds_t &b ) { - mins[ 0 ] = mins[ 1 ] = mins[ 2 ] = 99999; - maxs[ 0 ] = maxs[ 1 ] = maxs[ 2 ] = -99999; + static const bounds_t cleared = { + { 99999, 99999, 99999 }, 0, + { -99999, -99999, -99999 }, 0, + }; + + BoundsCopy( cleared, b ); } -void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs ) +void AddPointToBounds( const vec3_t v, bounds_t &b ) { - if ( v[ 0 ] < mins[ 0 ] ) + if ( v[ 0 ] < b.mins[ 0 ] ) { - mins[ 0 ] = v[ 0 ]; + b.mins[ 0 ] = v[ 0 ]; } - if ( v[ 0 ] > maxs[ 0 ] ) + if ( v[ 0 ] > b.maxs[ 0 ] ) { - maxs[ 0 ] = v[ 0 ]; + b.maxs[ 0 ] = v[ 0 ]; } - if ( v[ 1 ] < mins[ 1 ] ) + if ( v[ 1 ] < b.mins[ 1 ] ) { - mins[ 1 ] = v[ 1 ]; + b.mins[ 1 ] = v[ 1 ]; } - if ( v[ 1 ] > maxs[ 1 ] ) + if ( v[ 1 ] > b.maxs[ 1 ] ) { - maxs[ 1 ] = v[ 1 ]; + b.maxs[ 1 ] = v[ 1 ]; } - if ( v[ 2 ] < mins[ 2 ] ) + if ( v[ 2 ] < b.mins[ 2 ] ) { - mins[ 2 ] = v[ 2 ]; + b.mins[ 2 ] = v[ 2 ]; } - if ( v[ 2 ] > maxs[ 2 ] ) + if ( v[ 2 ] > b.maxs[ 2 ] ) { - maxs[ 2 ] = v[ 2 ]; + b.maxs[ 2 ] = v[ 2 ]; } } -void BoundsAdd( vec3_t mins, vec3_t maxs, const vec3_t mins2, const vec3_t maxs2 ) +void BoundsAdd( bounds_t &b1, const bounds_t &b2 ) { - if ( mins2[ 0 ] < mins[ 0 ] ) + if ( b2.mins[ 0 ] < b1.mins[ 0 ] ) { - mins[ 0 ] = mins2[ 0 ]; + b1.mins[ 0 ] = b2.mins[ 0 ]; } - if ( mins2[ 1 ] < mins[ 1 ] ) + if ( b2.mins[ 1 ] < b1.mins[ 1 ] ) { - mins[ 1 ] = mins2[ 1 ]; + b1.mins[ 1 ] = b2.mins[ 1 ]; } - if ( mins2[ 2 ] < mins[ 2 ] ) + if ( b2.mins[ 2 ] < b1.mins[ 2 ] ) { - mins[ 2 ] = mins2[ 2 ]; + b1.mins[ 2 ] = b2.mins[ 2 ]; } - if ( maxs2[ 0 ] > maxs[ 0 ] ) + if ( b2.maxs[ 0 ] > b1.maxs[ 0 ] ) { - maxs[ 0 ] = maxs2[ 0 ]; + b1.maxs[ 0 ] = b2.maxs[ 0 ]; } - if ( maxs2[ 1 ] > maxs[ 1 ] ) + if ( b2.maxs[ 1 ] > b1.maxs[ 1 ] ) { - maxs[ 1 ] = maxs2[ 1 ]; + b1.maxs[ 1 ] = b2.maxs[ 1 ]; } - if ( maxs2[ 2 ] > maxs[ 2 ] ) + if ( b2.maxs[ 2 ] > b1.maxs[ 2 ] ) { - maxs[ 2 ] = maxs2[ 2 ]; + b1.maxs[ 2 ] = b2.maxs[ 2 ]; } } -bool BoundsIntersect( const vec3_t mins, const vec3_t maxs, const vec3_t mins2, const vec3_t maxs2 ) +bool BoundsIntersect( const bounds_t &b1, const bounds_t &b2 ) { - if ( maxs[ 0 ] < mins2[ 0 ] || - maxs[ 1 ] < mins2[ 1 ] || maxs[ 2 ] < mins2[ 2 ] || mins[ 0 ] > maxs2[ 0 ] || mins[ 1 ] > maxs2[ 1 ] || mins[ 2 ] > maxs2[ 2 ] ) + if ( b1.maxs[ 0 ] < b2.mins[ 0 ] + || b1.maxs[ 1 ] < b2.mins[ 1 ] + || b1.maxs[ 2 ] < b2.mins[ 2 ] + || b1.mins[ 0 ] > b2.maxs[ 0 ] + || b1.mins[ 1 ] > b2.maxs[ 1 ] + || b1.mins[ 2 ] > b2.maxs[ 2 ] ) { return false; } return true; } -bool BoundsIntersectSphere( const vec3_t mins, const vec3_t maxs, const vec3_t origin, vec_t radius ) +bool BoundsIntersectSphere( const bounds_t &b, const vec3_t origin, vec_t radius ) { - if ( origin[ 0 ] - radius > maxs[ 0 ] || - origin[ 0 ] + radius < mins[ 0 ] || - origin[ 1 ] - radius > maxs[ 1 ] || - origin[ 1 ] + radius < mins[ 1 ] || origin[ 2 ] - radius > maxs[ 2 ] || origin[ 2 ] + radius < mins[ 2 ] ) + if ( origin[ 0 ] - radius > b.maxs[ 0 ] + || origin[ 0 ] + radius < b.mins[ 0 ] + || origin[ 1 ] - radius > b.maxs[ 1 ] + || origin[ 1 ] + radius < b.mins[ 1 ] + || origin[ 2 ] - radius > b.maxs[ 2 ] + || origin[ 2 ] + radius < b.mins[ 2 ] ) { return false; } @@ -932,10 +938,14 @@ bool BoundsIntersectSphere( const vec3_t mins, const vec3_t maxs, const vec3_t o return true; } -bool BoundsIntersectPoint( const vec3_t mins, const vec3_t maxs, const vec3_t origin ) +bool BoundsIntersectPoint( const bounds_t &b, const vec3_t origin ) { - if ( origin[ 0 ] > maxs[ 0 ] || - origin[ 0 ] < mins[ 0 ] || origin[ 1 ] > maxs[ 1 ] || origin[ 1 ] < mins[ 1 ] || origin[ 2 ] > maxs[ 2 ] || origin[ 2 ] < mins[ 2 ] ) + if ( origin[ 0 ] > b.maxs[ 0 ] + || origin[ 0 ] < b.mins[ 0 ] + || origin[ 1 ] > b.maxs[ 1 ] + || origin[ 1 ] < b.mins[ 1 ] + || origin[ 2 ] > b.maxs[ 2 ] + || origin[ 2 ] < b.mins[ 2 ] ) { return false; } @@ -943,14 +953,14 @@ bool BoundsIntersectPoint( const vec3_t mins, const vec3_t maxs, const vec3_t or return true; } -float BoundsMaxExtent( const vec3_t mins, const vec3_t maxs ) { - float result = Q_fabs( mins[0] ); +float BoundsMaxExtent( const bounds_t &b ) { + float result = Q_fabs( b.mins[0] ); - result = std::max( result, Q_fabs( mins[ 1 ] ) ); - result = std::max( result, Q_fabs( mins[ 2 ] ) ); - result = std::max( result, Q_fabs( maxs[ 0 ] ) ); - result = std::max( result, Q_fabs( maxs[ 1 ] ) ); - result = std::max( result, Q_fabs( maxs[ 2 ] ) ); + result = std::max( result, Q_fabs( b.mins[ 1 ] ) ); + result = std::max( result, Q_fabs( b.mins[ 2 ] ) ); + result = std::max( result, Q_fabs( b.maxs[ 0 ] ) ); + result = std::max( result, Q_fabs( b.maxs[ 1 ] ) ); + result = std::max( result, Q_fabs( b.maxs[ 2 ] ) ); return result; } @@ -2346,45 +2356,43 @@ void MatrixTransformPlane2( const matrix_t m, plane_t &inout ) * omaxs = max(mins.x*m.c1, maxs.x*m.c1) + max(mins.y*m.c2, maxs.y*m.c2) + max(mins.z*m.c3, maxs.z*m.c3) + c4 * ================= */ -void MatrixTransformBounds(const matrix_t m, const vec3_t mins, const vec3_t maxs, vec3_t omins, vec3_t omaxs) +void MatrixTransformBounds( const matrix_t m, const bounds_t &b, bounds_t &o ) { - vec3_t minx, maxx; - vec3_t miny, maxy; - vec3_t minz, maxz; + bounds_t x, y, z; const float* c1 = m; const float* c2 = m + 4; const float* c3 = m + 8; const float* c4 = m + 12; - VectorScale(c1, mins[0], minx); - VectorScale(c1, maxs[0], maxx); + VectorScale(c1, b.mins[0], x.mins); + VectorScale(c1, b.maxs[0], x.maxs); - VectorScale(c2, mins[1], miny); - VectorScale(c2, maxs[1], maxy); + VectorScale(c2, b.mins[1], y.mins); + VectorScale(c2, b.maxs[1], y.maxs); - VectorScale(c3, mins[2], minz); - VectorScale(c3, maxs[2], maxz); + VectorScale(c3, b.mins[2], z.mins); + VectorScale(c3, b.maxs[2], z.maxs); - vec3_t tmins, tmaxs; + bounds_t t; vec3_t tmp; - VectorMin(minx, maxx, tmins); - VectorMax(minx, maxx, tmaxs); - VectorAdd(tmins, c4, tmins); - VectorAdd(tmaxs, c4, tmaxs); + VectorMin(x.mins, x.maxs, t.mins); + VectorMax(x.mins, x.maxs, t.maxs); + VectorAdd(t.mins, c4, t.mins); + VectorAdd(t.maxs, c4, t.maxs); - VectorMin(miny, maxy, tmp); - VectorAdd(tmp, tmins, tmins); + VectorMin(y.mins, y.maxs, tmp); + VectorAdd(tmp, t.mins, t.mins); - VectorMax(miny, maxy, tmp); - VectorAdd(tmp, tmaxs, tmaxs); + VectorMax(y.mins, y.maxs, tmp); + VectorAdd(tmp, t.maxs, t.maxs); - VectorMin(minz, maxz, tmp); - VectorAdd(tmp, tmins, omins); + VectorMin(z.mins, z.maxs, tmp); + VectorAdd(tmp, t.mins, o.mins); - VectorMax(minz, maxz, tmp); - VectorAdd(tmp, tmaxs, omaxs); + VectorMax(z.mins, z.maxs, tmp); + VectorAdd(tmp, t.maxs, o.maxs); } /* diff --git a/src/engine/qcommon/q_shared.h b/src/engine/qcommon/q_shared.h index d7bf43ccc1..c02926ad6f 100644 --- a/src/engine/qcommon/q_shared.h +++ b/src/engine/qcommon/q_shared.h @@ -226,7 +226,7 @@ void Com_Free_Aligned( void *ptr ); using matrix_t = vec_t[4 * 4]; using quat_t = vec_t[4]; - struct plane_t { + struct alignas(16) plane_t { vec3_t normal; vec_t dist; }; @@ -296,6 +296,24 @@ void Com_Free_Aligned( void *ptr ); #define YAW 1 // left / right #define ROLL 2 // fall over +struct bounds_t +{ + alignas(16) vec3_t mins; + vec_t pad_mins; + alignas(16) vec3_t maxs; + vec_t pad_maxs; + + vec3_t& at( bool index ) + { + if ( index ) + { + return maxs; + } + + return mins; + } +}; + // plane sides enum class planeSide_t : int { @@ -329,7 +347,7 @@ void Com_Free_Aligned( void *ptr ); #define DEG2RAD( a ) ( ( ( a ) * M_PI ) / 180.0f ) #define RAD2DEG( a ) ( ( ( a ) * 180.0f ) / M_PI ) -struct cplane_t; +struct alignas(16) cplane_t; extern const vec3_t vec3_origin; extern const vec3_t axisDefault[ 3 ]; @@ -581,28 +599,44 @@ void SnapVector( V &&v ) ( r )[ 1 ] = ( s )[ 1 ] + ( f ) * (( e )[ 1 ] - ( s )[ 1 ] ), \ ( r )[ 2 ] = ( s )[ 2 ] + ( f ) * (( e )[ 2 ] - ( s )[ 2 ] )) - float RadiusFromBounds( const vec3_t mins, const vec3_t maxs ); - void ZeroBounds( vec3_t mins, vec3_t maxs ); - void ClearBounds( vec3_t mins, vec3_t maxs ); - void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs ); +inline void BoundsSet( bounds_t &b, const vec3_t mins, const vec3_t maxs ) +{ + VectorCopy( mins, b.mins ); + VectorCopy( maxs, b.maxs ); +} - void BoundsAdd( vec3_t mins, vec3_t maxs, const vec3_t mins2, const vec3_t maxs2 ); - bool BoundsIntersect( const vec3_t mins, const vec3_t maxs, const vec3_t mins2, const vec3_t maxs2 ); - bool BoundsIntersectSphere( const vec3_t mins, const vec3_t maxs, const vec3_t origin, vec_t radius ); - bool BoundsIntersectPoint( const vec3_t mins, const vec3_t maxs, const vec3_t origin ); - float BoundsMaxExtent( const vec3_t mins, const vec3_t maxs ); +inline void BoundsCopy( const bounds_t &b, bounds_t &o ) +{ + memcpy( &o, &b, sizeof(bounds_t) ); +} - inline void BoundsToCorners( const vec3_t mins, const vec3_t maxs, vec3_t corners[ 8 ] ) - { - VectorSet( corners[ 0 ], mins[ 0 ], maxs[ 1 ], maxs[ 2 ] ); - VectorSet( corners[ 1 ], maxs[ 0 ], maxs[ 1 ], maxs[ 2 ] ); - VectorSet( corners[ 2 ], maxs[ 0 ], mins[ 1 ], maxs[ 2 ] ); - VectorSet( corners[ 3 ], mins[ 0 ], mins[ 1 ], maxs[ 2 ] ); - VectorSet( corners[ 4 ], mins[ 0 ], maxs[ 1 ], mins[ 2 ] ); - VectorSet( corners[ 5 ], maxs[ 0 ], maxs[ 1 ], mins[ 2 ] ); - VectorSet( corners[ 6 ], maxs[ 0 ], mins[ 1 ], mins[ 2 ] ); - VectorSet( corners[ 7 ], mins[ 0 ], mins[ 1 ], mins[ 2 ] ); - } +inline void BoundsScale( const bounds_t &b, vec_t s, bounds_t &o ) +{ + VectorScale( b.mins, s, o.mins ); + VectorScale( b.maxs, s, o.maxs ); +} + +float RadiusFromBounds( const bounds_t &b ); +void ZeroBounds( bounds_t &b ); +void ClearBounds( bounds_t &b ); +void AddPointToBounds( const vec3_t v, bounds_t &b ); +void BoundsAdd( bounds_t &b1, const bounds_t &b2 ); +bool BoundsIntersect( const bounds_t &b1, const bounds_t &b2 ); +bool BoundsIntersectSphere( const bounds_t &b, const vec3_t origin, vec_t radius ); +bool BoundsIntersectPoint( const bounds_t &b, const vec3_t origin ); +float BoundsMaxExtent( const bounds_t &b ); + +inline void BoundsToCorners( const bounds_t &b, vec3_t corners[ 8 ] ) +{ + VectorSet( corners[ 0 ], b.mins[ 0 ], b.maxs[ 1 ], b.maxs[ 2 ] ); + VectorSet( corners[ 1 ], b.maxs[ 0 ], b.maxs[ 1 ], b.maxs[ 2 ] ); + VectorSet( corners[ 2 ], b.maxs[ 0 ], b.mins[ 1 ], b.maxs[ 2 ] ); + VectorSet( corners[ 3 ], b.mins[ 0 ], b.mins[ 1 ], b.maxs[ 2 ] ); + VectorSet( corners[ 4 ], b.mins[ 0 ], b.maxs[ 1 ], b.mins[ 2 ] ); + VectorSet( corners[ 5 ], b.maxs[ 0 ], b.maxs[ 1 ], b.mins[ 2 ] ); + VectorSet( corners[ 6 ], b.maxs[ 0 ], b.mins[ 1 ], b.mins[ 2 ] ); + VectorSet( corners[ 7 ], b.mins[ 0 ], b.mins[ 1 ], b.mins[ 2 ] ); +} inline void VectorLerp( const vec3_t from, const vec3_t to, float frac, vec3_t out ) { @@ -745,7 +779,7 @@ inline vec_t VectorNormalize2( const vec3_t v, vec3_t out ) void AxisCopy( const vec3_t in[ 3 ], vec3_t out[ 3 ] ); void SetPlaneSignbits( struct cplane_t *out ); - int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const struct cplane_t *plane ); +int BoxOnPlaneSide( const bounds_t &bounds, const struct cplane_t *plane ); float AngleMod( float a ); float LerpAngle( float from, float to, float frac ); @@ -852,7 +886,7 @@ inline vec_t VectorNormalize2( const vec3_t v, vec3_t out ) void MatrixTransform4( const matrix_t m, const vec4_t in, vec4_t out ); void MatrixTransformPlane( const matrix_t m, const plane_t &in, plane_t &out ); void MatrixTransformPlane2( const matrix_t m, plane_t &inout ); - void MatrixTransformBounds( const matrix_t m, const vec3_t mins, const vec3_t maxs, vec3_t omins, vec3_t omaxs ); +void MatrixTransformBounds( const matrix_t m, const bounds_t &b, bounds_t &o ); void MatrixPerspectiveProjection( matrix_t m, vec_t left, vec_t right, vec_t bottom, vec_t top, vec_t near, vec_t far ); void MatrixPerspectiveProjectionLH( matrix_t m, vec_t left, vec_t right, vec_t bottom, vec_t top, vec_t near, vec_t far ); void MatrixPerspectiveProjectionRH( matrix_t m, vec_t left, vec_t right, vec_t bottom, vec_t top, vec_t near, vec_t far ); @@ -1686,13 +1720,13 @@ inline vec_t VectorNormalize2( const vec3_t v, vec3_t out ) #define PlaneTypeForNormal( x ) ( x[ 0 ] == 1.0f ? PLANE_X : ( x[ 1 ] == 1.0f ? PLANE_Y : ( x[ 2 ] == 1.0f ? PLANE_Z : ( x[ 0 ] == 0.f && x[ 1 ] == 0.f && x[ 2 ] == 0.f ? PLANE_NON_PLANAR : PLANE_NON_AXIAL ) ) ) ) // cplane_t structure - struct cplane_t + struct alignas(16) cplane_t { vec3_t normal; - float dist; + vec_t dist; byte type; // for fast side tests: 0,1,2 = axial, 3 = nonaxial byte signbits; // signx + (signy<<1) + (signz<<2), used as lookup during collision - byte pad[ 2 ]; + byte pad[ 14 ]; }; enum class traceType_t diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 07fcaa61d2..ce07965628 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -1422,10 +1422,11 @@ void MaterialSystem::GenerateWorldMaterials() { ++tr.viewCountNoReset; R_AddWorldSurfaces(); - Log::Notice( "World bounds: min: %f %f %f max: %f %f %f", tr.viewParms.visBounds[0][0], tr.viewParms.visBounds[0][1], - tr.viewParms.visBounds[0][2], tr.viewParms.visBounds[1][0], tr.viewParms.visBounds[1][1], tr.viewParms.visBounds[1][2] ); - VectorCopy( tr.viewParms.visBounds[0], worldViewBounds[0] ); - VectorCopy( tr.viewParms.visBounds[1], worldViewBounds[1] ); + Log::Notice( "World bounds: min: %f %f %f max: %f %f %f", + tr.viewParms.visBounds.mins[0], tr.viewParms.visBounds.mins[1], tr.viewParms.visBounds.mins[2], + tr.viewParms.visBounds.maxs[0], tr.viewParms.visBounds.maxs[1], tr.viewParms.visBounds.maxs[2] ); + + BoundsCopy( tr.viewParms.visBounds, worldViewBounds); backEnd.currentEntity = &tr.worldEntity; diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index ea49e676b1..d215f89883 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -295,7 +295,7 @@ class MaterialSystem { public: bool generatedWorldCommandBuffer = false; bool generatingWorldCommandBuffer = false; - vec3_t worldViewBounds[2] = {}; + bounds_t worldViewBounds = {}; uint8_t maxStages = 0; uint32_t descriptorSize; diff --git a/src/engine/renderer/tr_animation.cpp b/src/engine/renderer/tr_animation.cpp index ea39201019..96357ecd08 100644 --- a/src/engine/renderer/tr_animation.cpp +++ b/src/engine/renderer/tr_animation.cpp @@ -239,7 +239,7 @@ static bool R_LoadMD5Anim( skelAnimation_t *skelAnim, const char *buffer, const for ( int j = 0; j < 3; j++ ) { token = COM_ParseExt2( &buf_p, false ); - frame->bounds[ 0 ][ j ] = atof( token ); + frame->bounds.mins[ j ] = atof( token ); } // skip ) @@ -263,7 +263,7 @@ static bool R_LoadMD5Anim( skelAnimation_t *skelAnim, const char *buffer, const for ( int j = 0; j < 3; j++ ) { token = COM_ParseExt2( &buf_p, false ); - frame->bounds[ 1 ][ j ] = atof( token ); + frame->bounds.maxs[ j ] = atof( token ); } // skip ) @@ -611,24 +611,17 @@ R_CullMD5 */ static void R_CullMD5( trRefEntity_t *ent ) { - int i; - if ( ent->e.skeleton.type == refSkeletonType_t::SK_INVALID ) { // no properly set skeleton so use the bounding box by the model instead by the animations md5Model_t *model = tr.currentModel->md5; - VectorCopy( model->bounds[ 0 ], ent->localBounds[ 0 ] ); - VectorCopy( model->bounds[ 1 ], ent->localBounds[ 1 ] ); + BoundsCopy( model->bounds, ent->localBounds ); } else { // copy a bounding box in the current coordinate system provided by skeleton - for ( i = 0; i < 3; i++ ) - { - ent->localBounds[ 0 ][ i ] = ent->e.skeleton.bounds[ 0 ][ i ] * ent->e.skeleton.scale; - ent->localBounds[ 1 ][ i ] = ent->e.skeleton.bounds[ 1 ][ i ] * ent->e.skeleton.scale; - } + BoundsScale( ent->e.skeleton.bounds, ent->e.skeleton.scale, ent->localBounds ); } R_SetupEntityWorldBounds(ent); @@ -843,7 +836,7 @@ void R_AddIQMInteractions( trRefEntity_t *ent, trRefLight_t *light, interactionT model = tr.currentModel->iqm; // do a quick AABB cull - if ( !BoundsIntersect( light->worldBounds[ 0 ], light->worldBounds[ 1 ], ent->worldBounds[ 0 ], ent->worldBounds[ 1 ] ) ) + if ( !BoundsIntersect( light->worldBounds, ent->worldBounds ) ) { tr.pc.c_dlightSurfacesCulled += model->num_surfaces; return; @@ -965,7 +958,7 @@ void R_AddMD5Interactions( trRefEntity_t *ent, trRefLight_t *light, interactionT model = tr.currentModel->md5; // do a quick AABB cull - if ( !BoundsIntersect( light->worldBounds[ 0 ], light->worldBounds[ 1 ], ent->worldBounds[ 0 ], ent->worldBounds[ 1 ] ) ) + if ( !BoundsIntersect( light->worldBounds, ent->worldBounds ) ) { tr.pc.c_dlightSurfacesCulled += model->numSurfaces; return; @@ -1255,7 +1248,6 @@ static int IQMBuildSkeleton( refSkeleton_t *skel, skelAnimation_t *skelAnim, int i; IQAnim_t *anim; transform_t *newPose, *oldPose; - vec3_t mins, maxs; anim = skelAnim->iqm; @@ -1275,14 +1267,18 @@ static int IQMBuildSkeleton( refSkeleton_t *skel, skelAnimation_t *skelAnim, oldPose = &anim->poses[ startFrame * anim->num_joints ]; newPose = &anim->poses[ endFrame * anim->num_joints ]; + bounds_t bounds; + // calculate a bounding box in the current coordinate system if( anim->bounds ) { - float *bounds = &anim->bounds[ 6 * startFrame ]; - VectorCopy( bounds, mins ); - VectorCopy( bounds + 3, maxs ); + float *pBounds = &anim->bounds[ 6 * startFrame ]; + BoundsSet( bounds, pBounds, pBounds + 3 ); + + pBounds = &anim->bounds[ 6 * endFrame ]; + bounds_t endBounds; + BoundsSet( endBounds, pBounds, pBounds + 3 ); - bounds = &anim->bounds[ 6 * endFrame ]; - BoundsAdd( mins, maxs, bounds, bounds + 3 ); + BoundsAdd( bounds, endBounds ); } #if defined( REFBONE_NAMES ) @@ -1305,8 +1301,7 @@ static int IQMBuildSkeleton( refSkeleton_t *skel, skelAnimation_t *skelAnim, skel->numBones = anim->num_joints; skel->type = refSkeletonType_t::SK_RELATIVE; - VectorCopy( mins, skel->bounds[ 0 ] ); - VectorCopy( maxs, skel->bounds[ 1 ] ); + BoundsCopy( bounds, skel->bounds ); return true; } @@ -1360,10 +1355,15 @@ int RE_BuildSkeleton( refSkeleton_t *skel, qhandle_t hAnim, int startFrame, int // calculate a bounding box in the current coordinate system for ( i = 0; i < 3; i++ ) { - skel->bounds[ 0 ][ i ] = - oldFrame->bounds[ 0 ][ i ] < newFrame->bounds[ 0 ][ i ] ? oldFrame->bounds[ 0 ][ i ] : newFrame->bounds[ 0 ][ i ]; - skel->bounds[ 1 ][ i ] = - oldFrame->bounds[ 1 ][ i ] > newFrame->bounds[ 1 ][ i ] ? oldFrame->bounds[ 1 ][ i ] : newFrame->bounds[ 1 ][ i ]; + skel->bounds.mins[ i ] = + oldFrame->bounds.mins[ i ] < newFrame->bounds.mins[ i ] + ? oldFrame->bounds.mins[ i ] + : newFrame->bounds.mins[ i ]; + + skel->bounds.maxs[ i ] = + oldFrame->bounds.maxs[ i ] > newFrame->bounds.maxs[ i ] + ? oldFrame->bounds.maxs[ i ] + : newFrame->bounds.maxs[ i ]; } for ( i = 0, channel = anim->channels; i < anim->numChannels; i++, channel++ ) @@ -1443,8 +1443,8 @@ int RE_BuildSkeleton( refSkeleton_t *skel, qhandle_t hAnim, int startFrame, int QuatClear( skel->bones[ i ].t.rot ); // move bounding box back - VectorSubtract( skel->bounds[ 0 ], lerpedOrigin, skel->bounds[ 0 ] ); - VectorSubtract( skel->bounds[ 1 ], lerpedOrigin, skel->bounds[ 1 ] ); + VectorSubtract( skel->bounds.mins, lerpedOrigin, skel->bounds.mins ); + VectorSubtract( skel->bounds.maxs, lerpedOrigin, skel->bounds.maxs ); } else { @@ -1475,9 +1475,6 @@ RE_BlendSkeleton */ int RE_BlendSkeleton( refSkeleton_t *skel, const refSkeleton_t *blend, float frac ) { - int i; - vec3_t bounds[ 2 ]; - if ( skel->numBones != blend->numBones ) { Log::Warn("RE_BlendSkeleton: different number of bones %d != %d", skel->numBones, blend->numBones ); @@ -1485,7 +1482,7 @@ int RE_BlendSkeleton( refSkeleton_t *skel, const refSkeleton_t *blend, float fra } // lerp between the 2 bone poses - for ( i = 0; i < skel->numBones; i++ ) + for ( int i = 0; i < skel->numBones; i++ ) { transform_t trans; @@ -1497,15 +1494,23 @@ int RE_BlendSkeleton( refSkeleton_t *skel, const refSkeleton_t *blend, float fra skel->bones[ i ].t = trans; } + bounds_t bounds; + // calculate a bounding box in the current coordinate system - for ( i = 0; i < 3; i++ ) + for ( int i = 0; i < 3; i++ ) { - bounds[ 0 ][ i ] = skel->bounds[ 0 ][ i ] < blend->bounds[ 0 ][ i ] ? skel->bounds[ 0 ][ i ] : blend->bounds[ 0 ][ i ]; - bounds[ 1 ][ i ] = skel->bounds[ 1 ][ i ] > blend->bounds[ 1 ][ i ] ? skel->bounds[ 1 ][ i ] : blend->bounds[ 1 ][ i ]; + bounds.mins[ i ] = + skel->bounds.mins[ i ] < blend->bounds.mins[ i ] + ? skel->bounds.mins[ i ] + : blend->bounds.mins[ i ]; + + bounds.maxs[ i ] = + skel->bounds.maxs[ i ] > blend->bounds.maxs[ i ] + ? skel->bounds.maxs[ i ] + : blend->bounds.maxs[ i ]; } - VectorCopy( bounds[ 0 ], skel->bounds[ 0 ] ); - VectorCopy( bounds[ 1 ], skel->bounds[ 1 ] ); + BoundsCopy( bounds, skel->bounds ); return true; } diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index 72c040ab27..85e868b2af 100644 --- a/src/engine/renderer/tr_backend.cpp +++ b/src/engine/renderer/tr_backend.cpp @@ -1011,14 +1011,13 @@ static void RB_RenderDrawSurfaces( shaderSort_t fromSort, shaderSort_t toSort, /* * helper function for parallel split shadow mapping */ -static int MergeInteractionBounds( const matrix_t lightViewProjectionMatrix, interaction_t *ia, int iaCount, vec3_t bounds[ 2 ], bool shadowCasters ) +static int MergeInteractionBounds( const matrix_t lightViewProjectionMatrix, interaction_t *ia, int iaCount, bounds_t &bounds, bool shadowCasters ) { int i; int j; surfaceType_t *surface; vec4_t point; vec4_t transf; - vec3_t worldBounds[ 2 ]; int numCasters; frustum_t frustum; @@ -1026,7 +1025,7 @@ static int MergeInteractionBounds( const matrix_t lightViewProjectionMatrix, int int r; numCasters = 0; - ClearBounds( bounds[ 0 ], bounds[ 1 ] ); + ClearBounds( bounds ); // calculate frustum planes using the modelview projection matrix R_SetupFrustum2( frustum, lightViewProjectionMatrix ); @@ -1051,19 +1050,19 @@ static int MergeInteractionBounds( const matrix_t lightViewProjectionMatrix, int } } + bounds_t worldBounds; + if ( *surface == surfaceType_t::SF_FACE || *surface == surfaceType_t::SF_GRID || *surface == surfaceType_t::SF_TRIANGLES ) { srfGeneric_t *gen = ( srfGeneric_t * ) surface; - VectorCopy( gen->bounds[ 0 ], worldBounds[ 0 ] ); - VectorCopy( gen->bounds[ 1 ], worldBounds[ 1 ] ); + BoundsCopy( gen->bounds, worldBounds ); } else if ( *surface == surfaceType_t::SF_VBO_MESH ) { srfVBOMesh_t *srf = ( srfVBOMesh_t * ) surface; - VectorCopy( srf->bounds[ 0 ], worldBounds[ 0 ] ); - VectorCopy( srf->bounds[ 1 ], worldBounds[ 1 ] ); + BoundsCopy( srf->bounds, worldBounds ); } else if ( *surface == surfaceType_t::SF_MDV ) { @@ -1085,7 +1084,7 @@ static int MergeInteractionBounds( const matrix_t lightViewProjectionMatrix, int continue; } - r = BoxOnPlaneSide( worldBounds[ 0 ], worldBounds[ 1 ], clipPlane ); + r = BoxOnPlaneSide( worldBounds, clipPlane ); if ( r == 2 ) { @@ -1100,9 +1099,9 @@ static int MergeInteractionBounds( const matrix_t lightViewProjectionMatrix, int for ( j = 0; j < 8; j++ ) { - point[ 0 ] = worldBounds[ j & 1 ][ 0 ]; - point[ 1 ] = worldBounds[( j >> 1 ) & 1 ][ 1 ]; - point[ 2 ] = worldBounds[( j >> 2 ) & 1 ][ 2 ]; + point[ 0 ] = worldBounds.at( j & 1 )[ 0 ]; + point[ 1 ] = worldBounds.at( ( j >> 1 ) & 1 )[ 1 ]; + point[ 2 ] = worldBounds.at( ( j >> 2 ) & 1 )[ 2 ]; point[ 3 ] = 1; MatrixTransform4( lightViewProjectionMatrix, point, transf ); @@ -1110,7 +1109,7 @@ static int MergeInteractionBounds( const matrix_t lightViewProjectionMatrix, int transf[ 1 ] /= transf[ 3 ]; transf[ 2 ] /= transf[ 3 ]; - AddPointToBounds( transf, bounds[ 0 ], bounds[ 1 ] ); + AddPointToBounds( transf, bounds ); } skipInteraction: @@ -1562,12 +1561,9 @@ static void RB_SetupLightForShadowing( trRefLight_t *light, int index, matrix_t cropMatrix; vec3_t splitFrustumNearCorners[ 4 ]; vec3_t splitFrustumFarCorners[ 4 ]; - vec3_t splitFrustumBounds[ 2 ]; - vec3_t splitFrustumClipBounds[ 2 ]; + bounds_t splitFrustumBounds, splitFrustumClipBounds; int numCasters; - vec3_t casterBounds[ 2 ]; - vec3_t receiverBounds[ 2 ]; - vec3_t cropBounds[ 2 ]; + bounds_t casterBounds, receiverBounds, cropBounds; vec4_t point; vec4_t transf; @@ -1665,16 +1661,16 @@ static void RB_SetupLightForShadowing( trRefLight_t *light, int index, } } - ClearBounds( splitFrustumBounds[ 0 ], splitFrustumBounds[ 1 ] ); + ClearBounds( splitFrustumBounds ); for ( auto nearCorner : splitFrustumNearCorners ) { - AddPointToBounds( nearCorner, splitFrustumBounds[ 0 ], splitFrustumBounds[ 1 ] ); + AddPointToBounds( nearCorner, splitFrustumBounds ); } for ( auto farCorner : splitFrustumFarCorners ) { - AddPointToBounds( farCorner, splitFrustumBounds[ 0 ], splitFrustumBounds[ 1 ] ); + AddPointToBounds( farCorner, splitFrustumBounds ); } // @@ -1682,7 +1678,7 @@ static void RB_SetupLightForShadowing( trRefLight_t *light, int index, // // find the bounding box of the current split in the light's view space - ClearBounds( cropBounds[ 0 ], cropBounds[ 1 ] ); + ClearBounds( cropBounds ); const auto pointsToViewBounds = [&]( vec_t *c ) { VectorCopy( c, point ); @@ -1692,7 +1688,7 @@ static void RB_SetupLightForShadowing( trRefLight_t *light, int index, transf[ 1 ] /= transf[ 3 ]; transf[ 2 ] /= transf[ 3 ]; - AddPointToBounds( transf, cropBounds[ 0 ], cropBounds[ 1 ] ); + AddPointToBounds( transf, cropBounds ); }; for ( auto nearCorner : splitFrustumNearCorners ) @@ -1705,7 +1701,10 @@ static void RB_SetupLightForShadowing( trRefLight_t *light, int index, pointsToViewBounds( farCorner ); } - MatrixOrthogonalProjectionRH( projectionMatrix, cropBounds[ 0 ][ 0 ], cropBounds[ 1 ][ 0 ], cropBounds[ 0 ][ 1 ], cropBounds[ 1 ][ 1 ], -cropBounds[ 1 ][ 2 ], -cropBounds[ 0 ][ 2 ] ); + MatrixOrthogonalProjectionRH( projectionMatrix, + cropBounds.mins[ 0 ], cropBounds.maxs[ 0 ], + cropBounds.mins[ 1 ], cropBounds.maxs[ 1 ], + -cropBounds.maxs[ 2 ], -cropBounds.mins[ 2 ] ); MatrixMultiply( projectionMatrix, light->viewMatrix, viewProjectionMatrix ); @@ -1713,7 +1712,7 @@ static void RB_SetupLightForShadowing( trRefLight_t *light, int index, MergeInteractionBounds( viewProjectionMatrix, ia, iaCount, receiverBounds, false ); // find the bounding box of the current split in the light's clip space - ClearBounds( splitFrustumClipBounds[ 0 ], splitFrustumClipBounds[ 1 ] ); + ClearBounds( splitFrustumClipBounds ); const auto pointsToViewProjectionBounds = [&]( vec_t* c ) { VectorCopy( c, point ); @@ -1724,7 +1723,7 @@ static void RB_SetupLightForShadowing( trRefLight_t *light, int index, transf[ 1 ] /= transf[ 3 ]; transf[ 2 ] /= transf[ 3 ]; - AddPointToBounds( transf, splitFrustumClipBounds[ 0 ], splitFrustumClipBounds[ 1 ] ); + AddPointToBounds( transf, splitFrustumClipBounds ); }; for ( auto nearCorner : splitFrustumNearCorners ) @@ -1742,35 +1741,34 @@ static void RB_SetupLightForShadowing( trRefLight_t *light, int index, GLimp_LogComment( va( "shadow casters = %i\n", numCasters ) ); GLimp_LogComment( va( "split frustum light space clip bounds (%5.3f, %5.3f, %5.3f) (%5.3f, %5.3f, %5.3f)\n", - splitFrustumClipBounds[ 0 ][ 0 ], splitFrustumClipBounds[ 0 ][ 1 ], splitFrustumClipBounds[ 0 ][ 2 ], - splitFrustumClipBounds[ 1 ][ 0 ], splitFrustumClipBounds[ 1 ][ 1 ], splitFrustumClipBounds[ 1 ][ 2 ] ) ); + splitFrustumClipBounds.mins[ 0 ], splitFrustumClipBounds.mins[ 1 ], splitFrustumClipBounds.mins[ 2 ], + splitFrustumClipBounds.maxs[ 0 ], splitFrustumClipBounds.maxs[ 1 ], splitFrustumClipBounds.maxs[ 2 ] ) ); GLimp_LogComment( va( "shadow caster light space clip bounds (%5.3f, %5.3f, %5.3f) (%5.3f, %5.3f, %5.3f)\n", - casterBounds[ 0 ][ 0 ], casterBounds[ 0 ][ 1 ], casterBounds[ 0 ][ 2 ], - casterBounds[ 1 ][ 0 ], casterBounds[ 1 ][ 1 ], casterBounds[ 1 ][ 2 ] ) ); + casterBounds.mins[ 0 ], casterBounds.mins[ 1 ], casterBounds.mins[ 2 ], + casterBounds.maxs[ 0 ], casterBounds.maxs[ 1 ], casterBounds.maxs[ 2 ] ) ); GLimp_LogComment( va( "light receiver light space clip bounds (%5.3f, %5.3f, %5.3f) (%5.3f, %5.3f, %5.3f)\n", - receiverBounds[ 0 ][ 0 ], receiverBounds[ 0 ][ 1 ], receiverBounds[ 0 ][ 2 ], - receiverBounds[ 1 ][ 0 ], receiverBounds[ 1 ][ 1 ], receiverBounds[ 1 ][ 2 ] ) ); + receiverBounds.mins[ 0 ], receiverBounds.mins[ 1 ], receiverBounds.mins[ 2 ], + receiverBounds.maxs[ 0 ], receiverBounds.maxs[ 1 ], receiverBounds.maxs[ 2 ] ) ); } // scene-dependent bounding volume - cropBounds[ 0 ][ 0 ] = std::max( std::max( casterBounds[ 0 ][ 0 ], receiverBounds[ 0 ][ 0 ] ), splitFrustumClipBounds[ 0 ][ 0 ] ); - cropBounds[ 0 ][ 1 ] = std::max( std::max( casterBounds[ 0 ][ 1 ], receiverBounds[ 0 ][ 1 ] ), splitFrustumClipBounds[ 0 ][ 1 ] ); + cropBounds.mins[ 0 ] = std::max( std::max( casterBounds.mins[ 0 ], receiverBounds.mins[ 0 ] ), splitFrustumClipBounds.mins[ 0 ] ); + cropBounds.mins[ 1 ] = std::max( std::max( casterBounds.mins[ 1 ], receiverBounds.mins[ 1 ] ), splitFrustumClipBounds.mins[ 1 ] ); - cropBounds[ 1 ][ 0 ] = std::min( std::min( casterBounds[ 1 ][ 0 ], receiverBounds[ 1 ][ 0 ] ), splitFrustumClipBounds[ 1 ][ 0 ] ); - cropBounds[ 1 ][ 1 ] = std::min( std::min( casterBounds[ 1 ][ 1 ], receiverBounds[ 1 ][ 1 ] ), splitFrustumClipBounds[ 1 ][ 1 ] ); + cropBounds.maxs[ 0 ] = std::min( std::min( casterBounds.maxs[ 0 ], receiverBounds.maxs[ 0 ] ), splitFrustumClipBounds.maxs[ 0 ] ); + cropBounds.maxs[ 1 ] = std::min( std::min( casterBounds.maxs[ 1 ], receiverBounds.maxs[ 1 ] ), splitFrustumClipBounds.maxs[ 1 ] ); - cropBounds[ 0 ][ 2 ] = std::min( casterBounds[ 0 ][ 2 ], splitFrustumClipBounds[ 0 ][ 2 ] ); - cropBounds[ 1 ][ 2 ] = std::min( receiverBounds[ 1 ][ 2 ], splitFrustumClipBounds[ 1 ][ 2 ] ); + cropBounds.mins[ 2 ] = std::min( casterBounds.mins[ 2 ], splitFrustumClipBounds.mins[ 2 ] ); + cropBounds.maxs[ 2 ] = std::min( receiverBounds.maxs[ 2 ], splitFrustumClipBounds.maxs[ 2 ] ); if ( numCasters == 0 ) { - VectorCopy( splitFrustumClipBounds[ 0 ], cropBounds[ 0 ] ); - VectorCopy( splitFrustumClipBounds[ 1 ], cropBounds[ 1 ] ); + BoundsCopy( splitFrustumClipBounds, cropBounds ); } - MatrixCrop( cropMatrix, cropBounds[ 0 ], cropBounds[ 1 ] ); + MatrixCrop( cropMatrix, cropBounds.mins, cropBounds.maxs ); MatrixMultiply( cropMatrix, projectionMatrix, light->projectionMatrix ); @@ -1788,17 +1786,17 @@ static void RB_SetupLightForShadowing( trRefLight_t *light, int index, MatrixAffineInverse( transformMatrix, viewMatrix ); MatrixMultiply( quakeToOpenGLMatrix, viewMatrix, light->viewMatrix ); - ClearBounds( splitFrustumBounds[ 0 ], splitFrustumBounds[ 1 ] ); - //BoundsAdd(splitFrustumBounds[0], splitFrustumBounds[1], backEnd.viewParms.visBounds[0], backEnd.viewParms.visBounds[1]); - BoundsAdd( splitFrustumBounds[ 0 ], splitFrustumBounds[ 1 ], light->worldBounds[ 0 ], light->worldBounds[ 1 ] ); + ClearBounds( splitFrustumBounds ); + // BoundsAdd( splitFrustumBounds, backEnd.viewParms.visBounds ); + BoundsAdd( splitFrustumBounds, light->worldBounds ); - ClearBounds( cropBounds[ 0 ], cropBounds[ 1 ] ); + ClearBounds( cropBounds ); for ( j = 0; j < 8; j++ ) { - point[ 0 ] = splitFrustumBounds[ j & 1 ][ 0 ]; - point[ 1 ] = splitFrustumBounds[( j >> 1 ) & 1 ][ 1 ]; - point[ 2 ] = splitFrustumBounds[( j >> 2 ) & 1 ][ 2 ]; + point[ 0 ] = splitFrustumBounds.at( j & 1 )[ 0 ]; + point[ 1 ] = splitFrustumBounds.at( ( j >> 1 ) & 1 )[ 1 ]; + point[ 2 ] = splitFrustumBounds.at( ( j >> 2 ) & 1 )[ 2 ]; point[ 3 ] = 1; MatrixTransform4( light->viewMatrix, point, transf ); @@ -1806,10 +1804,14 @@ static void RB_SetupLightForShadowing( trRefLight_t *light, int index, transf[ 1 ] /= transf[ 3 ]; transf[ 2 ] /= transf[ 3 ]; - AddPointToBounds( transf, cropBounds[ 0 ], cropBounds[ 1 ] ); + AddPointToBounds( transf, cropBounds ); } - MatrixOrthogonalProjectionRH( light->projectionMatrix, cropBounds[ 0 ][ 0 ], cropBounds[ 1 ][ 0 ], cropBounds[ 0 ][ 1 ], cropBounds[ 1 ][ 1 ], -cropBounds[ 1 ][ 2 ], -cropBounds[ 0 ][ 2 ] ); + MatrixOrthogonalProjectionRH( light->projectionMatrix, + cropBounds.mins[ 0 ], cropBounds.maxs[ 0 ], + cropBounds.mins[ 1 ], cropBounds.maxs[ 1 ], + -cropBounds.maxs[ 2 ], -cropBounds.mins[ 2 ] ); + GL_LoadProjectionMatrix( light->projectionMatrix ); } @@ -3365,8 +3367,10 @@ static void RB_RenderDebugUtils() trRefLight_t *light; vec3_t forward, left, up; - static const vec3_t minSize = { -2, -2, -2 }; - static const vec3_t maxSize = { 2, 2, 2 }; + static const bounds_t size = { + { -2, -2, -2 }, 0, + { 2, 2, 2 }, 0, + }; gl_genericShader->SetVertexSkinning( false ); gl_genericShader->SetVertexAnimation( false ); @@ -3458,7 +3462,7 @@ static void RB_RenderDebugUtils() { if ( !VectorCompare( light->l.center, vec3_origin ) ) { - Tess_AddCube( light->l.center, minSize, maxSize, Color::Yellow ); + Tess_AddCube( light->l.center, size, Color::Yellow ); } break; } @@ -3466,18 +3470,18 @@ static void RB_RenderDebugUtils() case refLightType_t::RL_PROJ: { // draw light_target - Tess_AddCube( light->l.projTarget, minSize, maxSize, Color::Red ); - Tess_AddCube( light->l.projRight, minSize, maxSize, Color::Green ); - Tess_AddCube( light->l.projUp, minSize, maxSize, Color::Blue ); + Tess_AddCube( light->l.projTarget, size, Color::Red ); + Tess_AddCube( light->l.projRight, size, Color::Green ); + Tess_AddCube( light->l.projUp, size, Color::Blue ); if ( !VectorCompare( light->l.projStart, vec3_origin ) ) { - Tess_AddCube( light->l.projStart, minSize, maxSize, Color::Yellow ); + Tess_AddCube( light->l.projStart, size, Color::Yellow ); } if ( !VectorCompare( light->l.projEnd, vec3_origin ) ) { - Tess_AddCube( light->l.projEnd, minSize, maxSize, Color::Magenta ); + Tess_AddCube( light->l.projEnd, size, Color::Magenta ); } break; } @@ -3506,8 +3510,10 @@ static void RB_RenderDebugUtils() surfaceType_t *surface; Color::Color lightColor; - static const vec3_t mins = { -1, -1, -1 }; - static const vec3_t maxs = { 1, 1, 1 }; + static const bounds_t size = { + { -1, -1, -1 }, 0, + { 1, 1, 1 }, 0, + }; gl_genericShader->SetVertexSkinning( false ); gl_genericShader->SetVertexAnimation( false ); @@ -3595,18 +3601,18 @@ static void RB_RenderDebugUtils() lightColor = Color::MdGrey; } - Tess_AddCube( vec3_origin, gen->bounds[ 0 ], gen->bounds[ 1 ], lightColor ); + Tess_AddCube( vec3_origin, gen->bounds, lightColor ); - Tess_AddCube( gen->origin, mins, maxs, Color::White ); + Tess_AddCube( gen->origin, size, Color::White ); } else if ( *surface == surfaceType_t::SF_VBO_MESH ) { srfVBOMesh_t *srf = ( srfVBOMesh_t * ) surface; - Tess_AddCube( vec3_origin, srf->bounds[ 0 ], srf->bounds[ 1 ], lightColor ); + Tess_AddCube( vec3_origin, srf->bounds, lightColor ); } else if ( *surface == surfaceType_t::SF_MDV ) { - Tess_AddCube( vec3_origin, entity->localBounds[ 0 ], entity->localBounds[ 1 ], lightColor ); + Tess_AddCube( vec3_origin, entity->localBounds, lightColor ); } Tess_End(); @@ -3621,8 +3627,11 @@ static void RB_RenderDebugUtils() { trRefEntity_t *ent; int i; - static const vec3_t mins = { -1, -1, -1 }; - static const vec3_t maxs = { 1, 1, 1 }; + + static const bounds_t size = { + { -1, -1, -1 }, 0, + { 1, 1, 1 }, 0, + }; gl_genericShader->SetVertexSkinning( false ); gl_genericShader->SetVertexAnimation( false ); @@ -3667,9 +3676,9 @@ static void RB_RenderDebugUtils() Tess_Begin( Tess_StageIteratorDebug, nullptr, nullptr, true, -1, 0 ); - Tess_AddCube( vec3_origin, ent->localBounds[ 0 ], ent->localBounds[ 1 ], Color::Blue ); + Tess_AddCube( vec3_origin, ent->localBounds, Color::Blue ); - Tess_AddCube( vec3_origin, mins, maxs,Color::White ); + Tess_AddCube( vec3_origin, size, Color::White ); Tess_End(); } @@ -3967,11 +3976,15 @@ static void RB_RenderDebugUtils() if ( r_showCubeProbes.Get() && glConfig2.reflectionMapping && !( backEnd.refdef.rdflags & ( RDF_NOWORLDMODEL | RDF_NOCUBEMAP ) ) ) { - static const vec3_t mins = { -8, -8, -8 }; - static const vec3_t maxs = { 8, 8, 8 }; + static const bounds_t size = { + { -8, -8, -8 }, 0, + { 8, 8, 8 }, 0, + }; - static const vec3_t outlineMins = { -9, -9, -9 }; - static const vec3_t outlineMaxs = { 9, 9, 9 }; + static const bounds_t outline = { + { -9, -9, -9 }, 0, + { 9, 9, 9 }, 0, + }; // choose right shader program ---------------------------------- gl_reflectionShader->SetVertexSkinning( false ); @@ -4003,7 +4016,7 @@ static void RB_RenderDebugUtils() vec3_t position{ ( float ) x * tr.cubeProbeSpacing, ( float ) y * tr.cubeProbeSpacing, ( float ) z * tr.cubeProbeSpacing }; // Match the map's start coords - VectorAdd( position, tr.world->nodes[0].mins, position ); + VectorAdd( position, tr.world->nodes[0].bounds.mins, position ); cubemapProbe_t* cubeProbe = &tr.cubeProbes[tr.cubeProbeGrid( x, y, z )]; @@ -4016,7 +4029,7 @@ static void RB_RenderDebugUtils() GL_BindToTMU( 0, cubeProbe->cubemap ) ); - Tess_AddCubeWithNormals( position, mins, maxs, Color::White ); + Tess_AddCubeWithNormals( position, size, Color::White ); Tess_End(); } @@ -4032,7 +4045,7 @@ static void RB_RenderDebugUtils() GL_BindToTMU( 0, cubeProbe.cubemap ) ); - Tess_AddCubeWithNormals( cubeProbe.origin, mins, maxs, Color::White ); + Tess_AddCubeWithNormals( cubeProbe.origin, size, Color::White ); Tess_End(); } @@ -4084,24 +4097,24 @@ static void RB_RenderDebugUtils() gridPoints[0][2] * tr.cubeProbeSpacing ); // Match the map's start coords - VectorAdd( position, tr.world->nodes[0].mins, position ); + VectorAdd( position, tr.world->nodes[0].bounds.mins, position ); } else { VectorCopy( probes[0]->origin, position ); } - Tess_AddCubeWithNormals( position, outlineMins, outlineMaxs, Color::Green ); + Tess_AddCubeWithNormals( position, outline, Color::Green ); if ( r_showCubeProbes.Get() == Util::ordinal( showCubeProbesMode::GRID ) ) { VectorSet( position, gridPoints[1][0] * tr.cubeProbeSpacing, gridPoints[1][1] * tr.cubeProbeSpacing, gridPoints[1][2] * tr.cubeProbeSpacing ); // Match the map's start coords - VectorAdd( position, tr.world->nodes[0].mins, position ); + VectorAdd( position, tr.world->nodes[0].bounds.mins, position ); } else { VectorCopy( probes[1]->origin, position ); } - Tess_AddCubeWithNormals( position, outlineMins, outlineMaxs, Color::Red ); + Tess_AddCubeWithNormals( position, outline, Color::Red ); Tess_End(); } @@ -4269,7 +4282,6 @@ static void RB_RenderDebugUtils() int j; vec3_t farCorners[ 4 ]; vec3_t nearCorners[ 4 ]; - vec3_t cropBounds[ 2 ]; vec4_t point, transf; GL_Viewport( x, y, w, h ); @@ -4287,13 +4299,14 @@ static void RB_RenderDebugUtils() // Quake -> OpenGL view matrix from light perspective MatrixLookAtRH( viewMatrix, backEnd.viewParms.orientation.origin, forward, up ); - ClearBounds( cropBounds[ 0 ], cropBounds[ 1 ] ); + bounds_t cropBounds; + ClearBounds( cropBounds ); for ( j = 0; j < 8; j++ ) { - point[ 0 ] = tr.world->models[ 0 ].bounds[ j & 1 ][ 0 ]; - point[ 1 ] = tr.world->models[ 0 ].bounds[( j >> 1 ) & 1 ][ 1 ]; - point[ 2 ] = tr.world->models[ 0 ].bounds[( j >> 2 ) & 1 ][ 2 ]; + point[ 0 ] = tr.world->models[ 0 ].bounds.at( j & 1 )[ 0 ]; + point[ 1 ] = tr.world->models[ 0 ].bounds.at( ( j >> 1 ) & 1 )[ 1 ]; + point[ 2 ] = tr.world->models[ 0 ].bounds.at( ( j >> 2 ) & 1 )[ 2 ]; point[ 3 ] = 1; MatrixTransform4( viewMatrix, point, transf ); @@ -4301,10 +4314,13 @@ static void RB_RenderDebugUtils() transf[ 1 ] /= transf[ 3 ]; transf[ 2 ] /= transf[ 3 ]; - AddPointToBounds( transf, cropBounds[ 0 ], cropBounds[ 1 ] ); + AddPointToBounds( transf, cropBounds ); } - MatrixOrthogonalProjectionRH( projectionMatrix, cropBounds[ 0 ][ 0 ], cropBounds[ 1 ][ 0 ], cropBounds[ 0 ][ 1 ], cropBounds[ 1 ][ 1 ], -cropBounds[ 1 ][ 2 ], -cropBounds[ 0 ][ 2 ] ); + MatrixOrthogonalProjectionRH( projectionMatrix, + cropBounds.mins[ 0 ], cropBounds.maxs[ 0 ], + cropBounds.mins[ 1 ], cropBounds.maxs[ 1 ], + -cropBounds.maxs[ 2 ], -cropBounds.mins[ 2 ] ); GL_LoadModelViewMatrix( viewMatrix ); GL_LoadProjectionMatrix( projectionMatrix ); @@ -4434,7 +4450,7 @@ static void RB_RenderDebugUtils() } Tess_Begin( Tess_StageIteratorDebug, nullptr, nullptr, true, -1, 0 ); - Tess_AddCube( vec3_origin, node->mins, node->maxs, Color::White ); + Tess_AddCube( vec3_origin, node->bounds, Color::White ); Tess_End(); if ( node->contents != -1 ) diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index be7529506f..a8be5dca8d 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -828,13 +828,13 @@ SphereFromBounds() - ydnar creates a bounding sphere from a bounding box */ -static void SphereFromBounds( vec3_t mins, vec3_t maxs, vec3_t origin, float *radius ) +static void SphereFromBounds( const bounds_t &b, vec3_t origin, float *radius ) { - vec3_t temp; - - VectorAdd( mins, maxs, origin ); + VectorAdd( b.mins, b.maxs, origin ); VectorScale( origin, 0.5, origin ); - VectorSubtract( maxs, origin, temp ); + + vec3_t temp; + VectorSubtract( b.maxs, origin, temp ); *radius = VectorLength( temp ); } @@ -846,7 +846,7 @@ handles final surface classification static void FinishGenericSurface( dsurface_t *ds, srfGeneric_t *gen, vec3_t pt ) { // set bounding sphere - SphereFromBounds( gen->bounds[ 0 ], gen->bounds[ 1 ], gen->origin, &gen->radius ); + SphereFromBounds( gen->bounds, gen->origin, &gen->radius ); if ( gen->surfaceType == surfaceType_t::SF_FACE ) { @@ -996,7 +996,7 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, bspSurface_t *surf, in surf->data = ( surfaceType_t * ) cv; // copy vertexes - ClearBounds( cv->bounds[ 0 ], cv->bounds[ 1 ] ); + ClearBounds( cv->bounds ); verts += LittleLong( ds->firstVert ); components = (struct vertexComponent_t *)ri.Hunk_AllocateTempMemory( numVerts * sizeof( struct vertexComponent_t ) ); @@ -1009,7 +1009,7 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, bspSurface_t *surf, in cv->verts[ i ].normal[ j ] = LittleFloat( verts[ i ].normal[ j ] ); } - AddPointToBounds( cv->verts[ i ].xyz, cv->bounds[ 0 ], cv->bounds[ 1 ] ); + AddPointToBounds( cv->verts[ i ].xyz, cv->bounds ); components[ i ].minVertex = i; @@ -1437,13 +1437,13 @@ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, bspSurface_t *surf, // calc bounding box // HACK: don't loop only through the vertices because they can contain bad data with .lwo models ... - ClearBounds( cv->bounds[ 0 ], cv->bounds[ 1 ] ); + ClearBounds( cv->bounds ); for ( i = 0, tri = cv->triangles; i < numTriangles; i++, tri++ ) { - AddPointToBounds( cv->verts[ tri->indexes[ 0 ] ].xyz, cv->bounds[ 0 ], cv->bounds[ 1 ] ); - AddPointToBounds( cv->verts[ tri->indexes[ 1 ] ].xyz, cv->bounds[ 0 ], cv->bounds[ 1 ] ); - AddPointToBounds( cv->verts[ tri->indexes[ 2 ] ].xyz, cv->bounds[ 0 ], cv->bounds[ 1 ] ); + AddPointToBounds( cv->verts[ tri->indexes[ 0 ] ].xyz, cv->bounds ); + AddPointToBounds( cv->verts[ tri->indexes[ 1 ] ].xyz, cv->bounds ); + AddPointToBounds( cv->verts[ tri->indexes[ 2 ] ].xyz, cv->bounds ); } // Tr3B - calc tangent spaces @@ -3174,8 +3174,8 @@ static void R_CreateWorldVBO() { srfGeneric_t* srf = ( srfGeneric_t* ) surface->data; VectorCopy( srf->origin, aabb->origin ); - VectorCopy( srf->bounds[0], aabb->mins ); - VectorCopy( srf->bounds[1], aabb->maxs ); + VectorCopy( srf->bounds.mins, aabb->mins ); + VectorCopy( srf->bounds.maxs, aabb->maxs ); Log::Warn( "Grid portals aren't properly supported" ); break; } @@ -3184,8 +3184,8 @@ static void R_CreateWorldVBO() { srfGeneric_t* srf = ( srfGeneric_t* ) surface->data; VectorCopy( srf->origin, aabb->origin ); - VectorCopy( srf->bounds[0], aabb->mins ); - VectorCopy( srf->bounds[1], aabb->maxs ); + VectorCopy( srf->bounds.mins, aabb->mins ); + VectorCopy( srf->bounds.maxs, aabb->maxs ); break; } default: @@ -3245,7 +3245,6 @@ static void R_CreateWorldVBO() oldViewCount = -2; for ( i = 0; i < numSurfaces; i++ ) { - vec3_t bounds[ 2 ]; int surfVerts = 0; int surfIndexes = 0; int firstIndex = numTriangles * 3; @@ -3283,7 +3282,9 @@ static void R_CreateWorldVBO() } // count verts and indexes and add bounds for the merged surface - ClearBounds( bounds[ 0 ], bounds[ 1 ] ); + bounds_t bounds; + ClearBounds( bounds ); + for ( j = i; j < numSurfaces; j++ ) { bspSurface_t *surf2 = surfaces[ j ]; @@ -3299,21 +3300,21 @@ static void R_CreateWorldVBO() srfSurfaceFace_t *face = ( srfSurfaceFace_t * ) surf2->data; surfIndexes += face->numTriangles * 3; surfVerts += face->numVerts; - BoundsAdd( bounds[ 0 ], bounds[ 1 ], face->bounds[ 0 ], face->bounds[ 1 ] ); + BoundsAdd( bounds, face->bounds ); } else if ( *surf2->data == surfaceType_t::SF_TRIANGLES ) { srfTriangles_t *tris = ( srfTriangles_t * ) surf2->data; surfIndexes += tris->numTriangles * 3; surfVerts += tris->numVerts; - BoundsAdd( bounds[ 0 ], bounds[ 1 ], tris->bounds[ 0 ], tris->bounds[ 1 ] ); + BoundsAdd( bounds, tris->bounds ); } else if ( *surf2->data == surfaceType_t::SF_GRID ) { srfGridMesh_t *grid = ( srfGridMesh_t * ) surf2->data; surfIndexes += grid->numTriangles * 3; surfVerts += grid->numVerts; - BoundsAdd( bounds[ 0 ], bounds[ 1 ], grid->bounds[ 0 ], grid->bounds[ 1 ] ); + BoundsAdd( bounds, grid->bounds ); } } @@ -3336,9 +3337,8 @@ static void R_CreateWorldVBO() vboSurf->vbo = s_worldData.vbo; vboSurf->ibo = s_worldData.ibo; - VectorCopy( bounds[ 0 ], vboSurf->bounds[ 0 ] ); - VectorCopy( bounds[ 1 ], vboSurf->bounds[ 1 ] ); - SphereFromBounds( vboSurf->bounds[ 0 ], vboSurf->bounds[ 1 ], vboSurf->origin, &vboSurf->radius ); + BoundsCopy( bounds, vboSurf->bounds ); + SphereFromBounds( vboSurf->bounds, vboSurf->origin, &vboSurf->radius ); mergedSurf->data = ( surfaceType_t * ) vboSurf; mergedSurf->fogIndex = surf1->fogIndex; @@ -3510,7 +3510,6 @@ static void R_LoadSubmodels( lump_t *l ) { dmodel_t *in; bspModel_t *out; - int i, j, count; Log::Debug("...loading submodels" ); @@ -3521,12 +3520,12 @@ static void R_LoadSubmodels( lump_t *l ) Sys::Drop( "LoadMap: funny lump size in %s", s_worldData.name ); } - count = l->filelen / sizeof( *in ); + int count = l->filelen / sizeof( *in ); s_worldData.numModels = count; s_worldData.models = out = (bspModel_t*) ri.Hunk_Alloc( count * sizeof( *out ), ha_pref::h_low ); - for ( i = 0; i < count; i++, in++, out++ ) + for ( int i = 0; i < count; i++, in++, out++ ) { model_t *model; @@ -3543,11 +3542,12 @@ static void R_LoadSubmodels( lump_t *l ) model->bsp = out; Com_sprintf( model->name, sizeof( model->name ), "*%d", i ); - for ( j = 0; j < 3; j++ ) - { - out->bounds[ 0 ][ j ] = LittleFloat( in->mins[ j ] ); - out->bounds[ 1 ][ j ] = LittleFloat( in->maxs[ j ] ); - } + out->bounds.mins[ 0 ] = LittleFloat( in->mins[ 0 ] ); + out->bounds.mins[ 1 ] = LittleFloat( in->mins[ 1 ] ); + out->bounds.mins[ 2 ] = LittleFloat( in->mins[ 2 ] ); + out->bounds.maxs[ 0 ] = LittleFloat( in->maxs[ 0 ] ); + out->bounds.maxs[ 1 ] = LittleFloat( in->maxs[ 1 ] ); + out->bounds.maxs[ 2 ] = LittleFloat( in->maxs[ 2 ] ); out->firstSurface = s_worldData.surfaces + LittleLong( in->firstSurface ); out->numSurfaces = LittleLong( in->numSurfaces ); @@ -3612,11 +3612,12 @@ static void R_LoadNodesAndLeafs( lump_t *nodeLump, lump_t *leafLump ) // load nodes for ( i = 0; i < numNodes; i++, in++, out++ ) { - for ( j = 0; j < 3; j++ ) - { - out->mins[ j ] = LittleLong( in->mins[ j ] ); - out->maxs[ j ] = LittleLong( in->maxs[ j ] ); - } + out->bounds.mins[ 0 ] = LittleLong( in->mins[ 0 ] ); + out->bounds.mins[ 1 ] = LittleLong( in->mins[ 1 ] ); + out->bounds.mins[ 2 ] = LittleLong( in->mins[ 2 ] ); + out->bounds.maxs[ 0 ] = LittleLong( in->maxs[ 0 ] ); + out->bounds.maxs[ 1 ] = LittleLong( in->maxs[ 1 ] ); + out->bounds.maxs[ 2 ] = LittleLong( in->maxs[ 2 ] ); p = LittleLong( in->planeNum ); out->plane = s_worldData.planes + p; @@ -3643,11 +3644,12 @@ static void R_LoadNodesAndLeafs( lump_t *nodeLump, lump_t *leafLump ) for ( i = 0; i < numLeafs; i++, inLeaf++, out++ ) { - for ( j = 0; j < 3; j++ ) - { - out->mins[ j ] = LittleLong( inLeaf->mins[ j ] ); - out->maxs[ j ] = LittleLong( inLeaf->maxs[ j ] ); - } + out->bounds.mins[ 0 ] = LittleLong( inLeaf->mins[ 0 ] ); + out->bounds.mins[ 1 ] = LittleLong( inLeaf->mins[ 1 ] ); + out->bounds.mins[ 2 ] = LittleLong( inLeaf->mins[ 2 ] ); + out->bounds.maxs[ 0 ] = LittleLong( inLeaf->maxs[ 0 ] ); + out->bounds.maxs[ 1 ] = LittleLong( inLeaf->maxs[ 1 ] ); + out->bounds.maxs[ 2 ] = LittleLong( inLeaf->maxs[ 2 ] ); out->cluster = LittleLong( inLeaf->cluster ); out->area = LittleLong( inLeaf->area ); @@ -3860,8 +3862,8 @@ static void R_LoadFogs( lump_t *l, lump_t *brushesLump, lump_t *sidesLump ) // ydnar: global fog has a brush number of -1, and no visible side if ( out->originalBrushNumber == -1 ) { - VectorSet( out->bounds[ 0 ], MIN_WORLD_COORD, MIN_WORLD_COORD, MIN_WORLD_COORD ); - VectorSet( out->bounds[ 1 ], MAX_WORLD_COORD, MAX_WORLD_COORD, MAX_WORLD_COORD ); + VectorSet( out->bounds.mins, MIN_WORLD_COORD, MIN_WORLD_COORD, MIN_WORLD_COORD ); + VectorSet( out->bounds.maxs, MAX_WORLD_COORD, MAX_WORLD_COORD, MAX_WORLD_COORD ); } else { @@ -3882,27 +3884,27 @@ static void R_LoadFogs( lump_t *l, lump_t *brushesLump, lump_t *sidesLump ) // brushes are always sorted with the axial sides first sideNum = firstSide + 0; planeNum = LittleLong( sides[ sideNum ].planeNum ); - out->bounds[ 0 ][ 0 ] = -s_worldData.planes[ planeNum ].dist; + out->bounds.mins[ 0 ] = -s_worldData.planes[ planeNum ].dist; sideNum = firstSide + 1; planeNum = LittleLong( sides[ sideNum ].planeNum ); - out->bounds[ 1 ][ 0 ] = s_worldData.planes[ planeNum ].dist; + out->bounds.maxs[ 0 ] = s_worldData.planes[ planeNum ].dist; sideNum = firstSide + 2; planeNum = LittleLong( sides[ sideNum ].planeNum ); - out->bounds[ 0 ][ 1 ] = -s_worldData.planes[ planeNum ].dist; + out->bounds.mins[ 1 ] = -s_worldData.planes[ planeNum ].dist; sideNum = firstSide + 3; planeNum = LittleLong( sides[ sideNum ].planeNum ); - out->bounds[ 1 ][ 1 ] = s_worldData.planes[ planeNum ].dist; + out->bounds.maxs[ 1 ] = s_worldData.planes[ planeNum ].dist; sideNum = firstSide + 4; planeNum = LittleLong( sides[ sideNum ].planeNum ); - out->bounds[ 0 ][ 2 ] = -s_worldData.planes[ planeNum ].dist; + out->bounds.mins[ 2 ] = -s_worldData.planes[ planeNum ].dist; sideNum = firstSide + 5; planeNum = LittleLong( sides[ sideNum ].planeNum ); - out->bounds[ 1 ][ 2 ] = s_worldData.planes[ planeNum ].dist; + out->bounds.maxs[ 2 ] = s_worldData.planes[ planeNum ].dist; } // get information from the shader for fog parameters @@ -4027,7 +4029,6 @@ void R_LoadLightGrid( lump_t *l ) int i, j, k; world_t *w; - float *wMins, *wMaxs; dgridPoint_t *in; bspGridPoint1_t *gridPoint1; bspGridPoint2_t *gridPoint2; @@ -4059,8 +4060,8 @@ void R_LoadLightGrid( lump_t *l ) w->lightGridInverseSize[ 1 ] = 1.0f / w->lightGridSize[ 1 ]; w->lightGridInverseSize[ 2 ] = 1.0f / w->lightGridSize[ 2 ]; - wMins = w->models[ 0 ].bounds[ 0 ]; - wMaxs = w->models[ 0 ].bounds[ 1 ]; + vec_t *wMins = w->models[ 0 ].bounds.mins; + vec_t *wMaxs = w->models[ 0 ].bounds.maxs; for ( i = 0; i < 3; i++ ) { @@ -4596,7 +4597,7 @@ void R_GetNearestCubeMaps( const vec3_t position, cubemapProbe_t** cubeProbes, v vec3_t pos; VectorCopy( position, pos ); - VectorSubtract( pos, tr.world->nodes[0].mins, pos ); + VectorSubtract( pos, tr.world->nodes[0].bounds.mins, pos ); VectorScale( pos, 1.0 / tr.cubeProbeSpacing, pos ); struct ProbeTrilerp { @@ -4695,8 +4696,8 @@ int R_FindNearestCubeMapForGrid( const vec3_t position, bspNode_t* node ) { } vec3_t origin; - VectorCopy( node->mins, origin ); - VectorAdd( origin, node->maxs, origin ); + VectorCopy( node->bounds.mins, origin ); + VectorAdd( origin, node->bounds.maxs, origin ); VectorScale( origin, 0.5, origin ); const byte* vis = R_ClusterPVS( node->cluster ); @@ -4772,7 +4773,7 @@ void R_BuildCubeMaps() } vec3_t origin; - VectorAdd( node->maxs, node->mins, origin ); + VectorAdd( node->bounds.maxs, node->bounds.mins, origin ); VectorScale( origin, 0.5, origin ); // Don't spam probes where there's a lot of leafs @@ -4780,7 +4781,7 @@ void R_BuildCubeMaps() if ( std::find_if( cubeProbeMap.begin(), cubeProbeMap.end(), [&origin]( const std::unordered_map::value_type& nodeCheck ) { vec3_t nodeOrigin; - VectorAdd( nodeCheck.first->mins, nodeCheck.first->maxs, nodeOrigin ); + VectorAdd( nodeCheck.first->bounds.mins, nodeCheck.first->bounds.maxs, nodeOrigin ); VectorScale( nodeOrigin, 0.5, nodeOrigin ); return Distance( origin, nodeOrigin ) <= tr.cubeProbeSpacing; @@ -4805,7 +4806,7 @@ void R_BuildCubeMaps() vec3_t position{ ( float ) x * tr.cubeProbeSpacing, ( float ) y * tr.cubeProbeSpacing, ( float ) z * tr.cubeProbeSpacing }; // Match the map's start coords - VectorAdd( position, tr.world->nodes[0].mins, position ); + VectorAdd( position, tr.world->nodes[0].bounds.mins, position ); int cubeProbe = R_FindNearestCubeMapForGrid( position, &tr.world->nodes[0] ); @@ -5261,8 +5262,8 @@ void RE_LoadWorldMap( const char *name ) tr.cubeProbeSpacing = r_cubeProbeSpacing.Get(); vec3_t worldSize; - VectorCopy( tr.world->nodes[0].maxs, worldSize ); - VectorSubtract( worldSize, tr.world->nodes[0].mins, worldSize ); + VectorCopy( tr.world->nodes[0].bounds.maxs, worldSize ); + VectorSubtract( worldSize, tr.world->nodes[0].bounds.mins, worldSize ); uint32_t gridSize[3]; gridSize[0] = ( worldSize[0] + tr.cubeProbeSpacing - 1 ) / tr.cubeProbeSpacing; diff --git a/src/engine/renderer/tr_curve.cpp b/src/engine/renderer/tr_curve.cpp index 2d53d824e4..2744dd24aa 100644 --- a/src/engine/renderer/tr_curve.cpp +++ b/src/engine/renderer/tr_curve.cpp @@ -459,7 +459,7 @@ static srfGridMesh_t *R_CreateSurfaceGridMesh( int width, int height, grid->width = width; grid->height = height; grid->surfaceType = surfaceType_t::SF_GRID; - ClearBounds( grid->bounds[ 0 ], grid->bounds[ 1 ] ); + ClearBounds( grid->bounds ); for ( i = 0; i < width; i++ ) { @@ -467,14 +467,14 @@ static srfGridMesh_t *R_CreateSurfaceGridMesh( int width, int height, { vert = &grid->verts[ j * width + i ]; *vert = ctrl[ j ][ i ]; - AddPointToBounds( vert->xyz, grid->bounds[ 0 ], grid->bounds[ 1 ] ); + AddPointToBounds( vert->xyz, grid->bounds ); } } // compute local origin and bounds - VectorAdd( grid->bounds[ 0 ], grid->bounds[ 1 ], grid->origin ); + VectorAdd( grid->bounds.mins, grid->bounds.maxs, grid->origin ); VectorScale( grid->origin, 0.5f, grid->origin ); - VectorSubtract( grid->bounds[ 0 ], grid->origin, tmpVec ); + VectorSubtract( grid->bounds.mins, grid->origin, tmpVec ); grid->radius = VectorLength( tmpVec ); VectorCopy( grid->origin, grid->lodOrigin ); diff --git a/src/engine/renderer/tr_light.cpp b/src/engine/renderer/tr_light.cpp index c6fbaf27db..d428a1b54a 100644 --- a/src/engine/renderer/tr_light.cpp +++ b/src/engine/renderer/tr_light.cpp @@ -73,7 +73,7 @@ void R_AddBrushModelInteractions( trRefEntity_t *ent, trRefLight_t *light, inter bspModel = pModel->bsp; // do a quick AABB cull - if ( !BoundsIntersect( light->worldBounds[ 0 ], light->worldBounds[ 1 ], ent->worldBounds[ 0 ], ent->worldBounds[ 1 ] ) ) + if ( !BoundsIntersect( light->worldBounds, ent->worldBounds ) ) { tr.pc.c_dlightSurfacesCulled += bspModel->numSurfaces; return; @@ -311,12 +311,12 @@ void R_SetupLightLocalBounds( trRefLight_t *light ) case refLightType_t::RL_OMNI: case refLightType_t::RL_DIRECTIONAL: { - light->localBounds[ 0 ][ 0 ] = -light->l.radius; - light->localBounds[ 0 ][ 1 ] = -light->l.radius; - light->localBounds[ 0 ][ 2 ] = -light->l.radius; - light->localBounds[ 1 ][ 0 ] = light->l.radius; - light->localBounds[ 1 ][ 1 ] = light->l.radius; - light->localBounds[ 1 ][ 2 ] = light->l.radius; + light->localBounds.mins[ 0 ] = -light->l.radius; + light->localBounds.mins[ 1 ] = -light->l.radius; + light->localBounds.mins[ 2 ] = -light->l.radius; + light->localBounds.maxs[ 0 ] = light->l.radius; + light->localBounds.maxs[ 1 ] = light->l.radius; + light->localBounds.maxs[ 2 ] = light->l.radius; break; } @@ -325,7 +325,7 @@ void R_SetupLightLocalBounds( trRefLight_t *light ) int j; vec3_t farCorners[ 4 ]; - ClearBounds( light->localBounds[ 0 ], light->localBounds[ 1 ] ); + ClearBounds( light->localBounds ); // transform frustum from world space to local space R_CalcFrustumFarCorners( light->localFrustum, farCorners ); @@ -339,8 +339,8 @@ void R_SetupLightLocalBounds( trRefLight_t *light ) for ( j = 0; j < 4; j++ ) { - AddPointToBounds( farCorners[ j ], light->localBounds[ 0 ], light->localBounds[ 1 ] ); - AddPointToBounds( nearCorners[ j ], light->localBounds[ 0 ], light->localBounds[ 1 ] ); + AddPointToBounds( farCorners[ j ], light->localBounds ); + AddPointToBounds( nearCorners[ j ], light->localBounds ); } } else @@ -349,11 +349,11 @@ void R_SetupLightLocalBounds( trRefLight_t *light ) const plane_t* frustum = light->localFrustum; PlanesGetIntersectionPoint( frustum[ FRUSTUM_LEFT ], frustum[ FRUSTUM_RIGHT ], frustum[ FRUSTUM_TOP ], top ); - AddPointToBounds( top, light->localBounds[ 0 ], light->localBounds[ 1 ] ); + AddPointToBounds( top, light->localBounds ); for ( j = 0; j < 4; j++ ) { - AddPointToBounds( farCorners[ j ], light->localBounds[ 0 ], light->localBounds[ 1 ] ); + AddPointToBounds( farCorners[ j ], light->localBounds ); } } @@ -364,7 +364,7 @@ void R_SetupLightLocalBounds( trRefLight_t *light ) break; } - light->sphereRadius = RadiusFromBounds( light->localBounds[ 0 ], light->localBounds[ 1 ] ); + light->sphereRadius = RadiusFromBounds( light->localBounds ); } /* @@ -375,7 +375,7 @@ Tr3B - needs finished transformMatrix */ void R_SetupLightWorldBounds( trRefLight_t *light ) { - MatrixTransformBounds(light->transformMatrix, light->localBounds[0], light->localBounds[1], light->worldBounds[0], light->worldBounds[1]); + MatrixTransformBounds( light->transformMatrix, light->localBounds, light->worldBounds ); } /* @@ -407,7 +407,7 @@ void R_TessLight( const trRefLight_t *light, const Color::Color& color, bool use { case refLightType_t::RL_OMNI: case refLightType_t::RL_DIRECTIONAL: - Tess_AddCube( vec3_origin, light->localBounds[ 0 ], light->localBounds[ 1 ], use_default_color ? Color::White : color ); + Tess_AddCube( vec3_origin, light->localBounds, use_default_color ? Color::White : color ); break; case refLightType_t::RL_PROJ: { @@ -1086,54 +1086,54 @@ void R_SetupLightScissor( trRefLight_t *light ) case refLightType_t::RL_OMNI: { // top plane - VectorSet( v1, light->worldBounds[ 1 ][ 0 ], light->worldBounds[ 1 ][ 1 ], light->worldBounds[ 1 ][ 2 ] ); - VectorSet( v2, light->worldBounds[ 0 ][ 0 ], light->worldBounds[ 1 ][ 1 ], light->worldBounds[ 1 ][ 2 ] ); + VectorSet( v1, light->worldBounds.maxs[ 0 ], light->worldBounds.maxs[ 1 ], light->worldBounds.maxs[ 2 ] ); + VectorSet( v2, light->worldBounds.mins[ 0 ], light->worldBounds.maxs[ 1 ], light->worldBounds.maxs[ 2 ] ); R_AddEdgeToLightScissor( light, v1, v2 ); - VectorSet( v1, light->worldBounds[ 1 ][ 0 ], light->worldBounds[ 1 ][ 1 ], light->worldBounds[ 1 ][ 2 ] ); - VectorSet( v2, light->worldBounds[ 1 ][ 0 ], light->worldBounds[ 0 ][ 1 ], light->worldBounds[ 1 ][ 2 ] ); + VectorSet( v1, light->worldBounds.maxs[ 0 ], light->worldBounds.maxs[ 1 ], light->worldBounds.maxs[ 2 ] ); + VectorSet( v2, light->worldBounds.maxs[ 0 ], light->worldBounds.mins[ 1 ], light->worldBounds.maxs[ 2 ] ); R_AddEdgeToLightScissor( light, v1, v2 ); - VectorSet( v1, light->worldBounds[ 0 ][ 0 ], light->worldBounds[ 0 ][ 1 ], light->worldBounds[ 1 ][ 2 ] ); - VectorSet( v2, light->worldBounds[ 0 ][ 0 ], light->worldBounds[ 1 ][ 1 ], light->worldBounds[ 1 ][ 2 ] ); + VectorSet( v1, light->worldBounds.mins[ 0 ], light->worldBounds.mins[ 1 ], light->worldBounds.maxs[ 2 ] ); + VectorSet( v2, light->worldBounds.mins[ 0 ], light->worldBounds.maxs[ 1 ], light->worldBounds.maxs[ 2 ] ); R_AddEdgeToLightScissor( light, v1, v2 ); - VectorSet( v1, light->worldBounds[ 0 ][ 0 ], light->worldBounds[ 0 ][ 1 ], light->worldBounds[ 1 ][ 2 ] ); - VectorSet( v2, light->worldBounds[ 1 ][ 0 ], light->worldBounds[ 0 ][ 1 ], light->worldBounds[ 1 ][ 2 ] ); + VectorSet( v1, light->worldBounds.mins[ 0 ], light->worldBounds.mins[ 1 ], light->worldBounds.maxs[ 2 ] ); + VectorSet( v2, light->worldBounds.maxs[ 0 ], light->worldBounds.mins[ 1 ], light->worldBounds.maxs[ 2 ] ); R_AddEdgeToLightScissor( light, v1, v2 ); // bottom plane - VectorSet( v1, light->worldBounds[ 1 ][ 0 ], light->worldBounds[ 1 ][ 1 ], light->worldBounds[ 0 ][ 2 ] ); - VectorSet( v2, light->worldBounds[ 0 ][ 0 ], light->worldBounds[ 1 ][ 1 ], light->worldBounds[ 0 ][ 2 ] ); + VectorSet( v1, light->worldBounds.maxs[ 0 ], light->worldBounds.maxs[ 1 ], light->worldBounds.mins[ 2 ] ); + VectorSet( v2, light->worldBounds.mins[ 0 ], light->worldBounds.maxs[ 1 ], light->worldBounds.mins[ 2 ] ); R_AddEdgeToLightScissor( light, v1, v2 ); - VectorSet( v1, light->worldBounds[ 1 ][ 0 ], light->worldBounds[ 1 ][ 1 ], light->worldBounds[ 0 ][ 2 ] ); - VectorSet( v2, light->worldBounds[ 1 ][ 0 ], light->worldBounds[ 0 ][ 1 ], light->worldBounds[ 0 ][ 2 ] ); + VectorSet( v1, light->worldBounds.maxs[ 0 ], light->worldBounds.maxs[ 1 ], light->worldBounds.mins[ 2 ] ); + VectorSet( v2, light->worldBounds.maxs[ 0 ], light->worldBounds.mins[ 1 ], light->worldBounds.mins[ 2 ] ); R_AddEdgeToLightScissor( light, v1, v2 ); - VectorSet( v1, light->worldBounds[ 0 ][ 0 ], light->worldBounds[ 0 ][ 1 ], light->worldBounds[ 0 ][ 2 ] ); - VectorSet( v2, light->worldBounds[ 0 ][ 0 ], light->worldBounds[ 1 ][ 1 ], light->worldBounds[ 0 ][ 2 ] ); + VectorSet( v1, light->worldBounds.mins[ 0 ], light->worldBounds.mins[ 1 ], light->worldBounds.mins[ 2 ] ); + VectorSet( v2, light->worldBounds.mins[ 0 ], light->worldBounds.maxs[ 1 ], light->worldBounds.mins[ 2 ] ); R_AddEdgeToLightScissor( light, v1, v2 ); - VectorSet( v1, light->worldBounds[ 0 ][ 0 ], light->worldBounds[ 0 ][ 1 ], light->worldBounds[ 0 ][ 2 ] ); - VectorSet( v2, light->worldBounds[ 1 ][ 0 ], light->worldBounds[ 0 ][ 1 ], light->worldBounds[ 0 ][ 2 ] ); + VectorSet( v1, light->worldBounds.mins[ 0 ], light->worldBounds.mins[ 1 ], light->worldBounds.mins[ 2 ] ); + VectorSet( v2, light->worldBounds.maxs[ 0 ], light->worldBounds.mins[ 1 ], light->worldBounds.mins[ 2 ] ); R_AddEdgeToLightScissor( light, v1, v2 ); // sides - VectorSet( v1, light->worldBounds[ 0 ][ 0 ], light->worldBounds[ 1 ][ 1 ], light->worldBounds[ 0 ][ 2 ] ); - VectorSet( v2, light->worldBounds[ 0 ][ 0 ], light->worldBounds[ 1 ][ 1 ], light->worldBounds[ 1 ][ 2 ] ); + VectorSet( v1, light->worldBounds.mins[ 0 ], light->worldBounds.maxs[ 1 ], light->worldBounds.mins[ 2 ] ); + VectorSet( v2, light->worldBounds.mins[ 0 ], light->worldBounds.maxs[ 1 ], light->worldBounds.maxs[ 2 ] ); R_AddEdgeToLightScissor( light, v1, v2 ); - VectorSet( v1, light->worldBounds[ 1 ][ 0 ], light->worldBounds[ 1 ][ 1 ], light->worldBounds[ 0 ][ 2 ] ); - VectorSet( v2, light->worldBounds[ 1 ][ 0 ], light->worldBounds[ 1 ][ 1 ], light->worldBounds[ 1 ][ 2 ] ); + VectorSet( v1, light->worldBounds.maxs[ 0 ], light->worldBounds.maxs[ 1 ], light->worldBounds.mins[ 2 ] ); + VectorSet( v2, light->worldBounds.maxs[ 0 ], light->worldBounds.maxs[ 1 ], light->worldBounds.maxs[ 2 ] ); R_AddEdgeToLightScissor( light, v1, v2 ); - VectorSet( v1, light->worldBounds[ 0 ][ 0 ], light->worldBounds[ 0 ][ 1 ], light->worldBounds[ 0 ][ 2 ] ); - VectorSet( v2, light->worldBounds[ 0 ][ 0 ], light->worldBounds[ 0 ][ 1 ], light->worldBounds[ 1 ][ 2 ] ); + VectorSet( v1, light->worldBounds.mins[ 0 ], light->worldBounds.mins[ 1 ], light->worldBounds.mins[ 2 ] ); + VectorSet( v2, light->worldBounds.mins[ 0 ], light->worldBounds.mins[ 1 ], light->worldBounds.maxs[ 2 ] ); R_AddEdgeToLightScissor( light, v1, v2 ); - VectorSet( v1, light->worldBounds[ 1 ][ 0 ], light->worldBounds[ 0 ][ 1 ], light->worldBounds[ 0 ][ 2 ] ); - VectorSet( v2, light->worldBounds[ 1 ][ 0 ], light->worldBounds[ 0 ][ 1 ], light->worldBounds[ 1 ][ 2 ] ); + VectorSet( v1, light->worldBounds.maxs[ 0 ], light->worldBounds.mins[ 1 ], light->worldBounds.mins[ 2 ] ); + VectorSet( v2, light->worldBounds.maxs[ 0 ], light->worldBounds.mins[ 1 ], light->worldBounds.maxs[ 2 ] ); R_AddEdgeToLightScissor( light, v1, v2 ); break; } @@ -1207,7 +1207,7 @@ R_CalcLightCubeSideBits ============= */ // *INDENT-OFF* -byte R_CalcLightCubeSideBits( trRefLight_t *light, vec3_t worldBounds[ 2 ] ) +byte R_CalcLightCubeSideBits( trRefLight_t *light, const bounds_t &worldBounds ) { int i; int cubeSide; @@ -1308,7 +1308,7 @@ byte R_CalcLightCubeSideBits( trRefLight_t *light, vec3_t worldBounds[ 2 ] ) { clipPlane = &frustum[ i ]; - r = BoxOnPlaneSide( worldBounds[ 0 ], worldBounds[ 1 ], clipPlane ); + r = BoxOnPlaneSide( worldBounds, clipPlane ); if ( r == 2 ) { @@ -1479,7 +1479,7 @@ R_CullLightTriangle Returns CULL_IN, CULL_CLIP, or CULL_OUT ================= */ -cullResult_t R_CullLightWorldBounds( trRefLight_t *light, vec3_t worldBounds[ 2 ] ) +cullResult_t R_CullLightWorldBounds( trRefLight_t *light, const bounds_t &worldBounds ) { int i; cplane_t *frust; @@ -1498,7 +1498,7 @@ cullResult_t R_CullLightWorldBounds( trRefLight_t *light, vec3_t worldBounds[ 2 { frust = &light->frustum[ i ]; - r = BoxOnPlaneSide( worldBounds[ 0 ], worldBounds[ 1 ], frust ); + r = BoxOnPlaneSide( worldBounds, frust ); if ( r == 2 ) { diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 201f142a0a..eaafa0a28b 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -418,8 +418,8 @@ enum class shaderProfilerRenderSubGroupsMode { matrix_t attenuationMatrix; // attenuation * (light view * entity transform) matrix_t attenuationMatrix2; // attenuation * tcMod matrices - vec3_t localBounds[ 2 ]; - vec3_t worldBounds[ 2 ]; + bounds_t localBounds; + bounds_t worldBounds; float sphereRadius; // calculated from localBounds int8_t shadowLOD; // Level of Detail for shadow mapping @@ -467,8 +467,8 @@ enum class shaderProfilerRenderSubGroupsMode { float axisLength; // compensate for non-normalized axis cullResult_t cull; - vec3_t localBounds[ 2 ]; - vec3_t worldBounds[ 2 ]; + bounds_t localBounds; + bounds_t worldBounds; }; struct orientationr_t @@ -1509,7 +1509,7 @@ enum class shaderProfilerRenderSubGroupsMode { struct fog_t { int originalBrushNumber; - vec3_t bounds[ 2 ]; + bounds_t bounds; Color::Color color; // in packed byte format float tcScale; // texture coordinate vector scales @@ -1554,7 +1554,7 @@ enum class shaderProfilerRenderSubGroupsMode { frustum_t frustums[ MAX_SHADOWMAPS + 1 ]; // first frustum is the default one with complete zNear - zFar range // and the other ones are for PSSM - vec3_t visBounds[ 2 ]; + bounds_t visBounds; float zNear; float zFar; @@ -1778,7 +1778,7 @@ enum class shaderProfilerRenderSubGroupsMode { surfaceType_t surfaceType; // culling information - vec3_t bounds[ 2 ]; + bounds_t bounds; vec3_t origin; float radius; }; @@ -1935,7 +1935,8 @@ enum class shaderProfilerRenderSubGroupsMode { int contents; // -1 for nodes, to differentiate from leafs int visCounts[ MAX_VISCOUNTS ]; // node needs to be traversed if current - vec3_t mins, maxs; // for bounding box culling + bounds_t bounds; // for bounding box culling + bspNode_t *parent; // node specific @@ -1952,7 +1953,7 @@ enum class shaderProfilerRenderSubGroupsMode { struct bspModel_t { - vec3_t bounds[ 2 ]; // for culling + bounds_t bounds; // for culling uint32_t numSurfaces; bspSurface_t *firstSurface; @@ -2203,7 +2204,7 @@ enum class shaderProfilerRenderSubGroupsMode { uint16_t numVBOSurfaces; srfVBOMD5Mesh_t **vboSurfaces; - vec3_t bounds[ 2 ]; + bounds_t bounds; float internalScale; }; @@ -2238,7 +2239,7 @@ enum class shaderProfilerRenderSubGroupsMode { struct md5Frame_t { - vec3_t bounds[ 2 ]; // bounds of all surfaces of all LODs for this frame + bounds_t bounds; // bounds of all surfaces of all LODs for this frame float *components; // numAnimatedComponents many }; @@ -2279,7 +2280,7 @@ enum class shaderProfilerRenderSubGroupsMode { struct srfIQModel_t *surfaces; struct IQAnim_t *anims; - vec3_t bounds[2]; + bounds_t bounds; float internalScale; // vertex data @@ -2380,7 +2381,7 @@ enum class shaderProfilerRenderSubGroupsMode { int RE_BoneIndex( qhandle_t hModel, const char *boneName ); - void R_ModelBounds( qhandle_t handle, vec3_t mins, vec3_t maxs ); +void R_ModelBounds( qhandle_t handle, bounds_t &bounds ); //==================================================== extern refimport_t ri; @@ -3167,12 +3168,13 @@ inline bool checkGLErrors() void R_LocalNormalToWorld( const vec3_t local, vec3_t world ); void R_LocalPointToWorld( const vec3_t local, vec3_t world ); - cullResult_t R_CullBox( vec3_t worldBounds[ 2 ] ); - cullResult_t R_CullLocalBox( vec3_t bounds[ 2 ] ); +cullResult_t R_CullBox( const bounds_t &worldBounds ); +cullResult_t R_CullLocalBox( const bounds_t &bounds ); + cullResult_t R_CullLocalPointAndRadius( vec3_t origin, float radius ); cullResult_t R_CullPointAndRadius( vec3_t origin, float radius ); - int R_FogWorldBox( vec3_t bounds[ 2 ] ); +int R_FogWorldBox( const bounds_t &bounds ); void R_SetupEntityWorldBounds( trRefEntity_t *ent ); @@ -3556,8 +3558,8 @@ inline bool checkGLErrors() */ void Tess_AddTetrahedron( vec4_t tetraVerts[ 4 ], const Color::Color& color ); - void Tess_AddCube( const vec3_t position, const vec3_t minSize, const vec3_t maxSize, const Color::Color& color ); - void Tess_AddCubeWithNormals( const vec3_t position, const vec3_t minSize, const vec3_t maxSize, const Color::Color& color ); + void Tess_AddCube( const vec3_t position, const bounds_t &size, const Color::Color& color ); + void Tess_AddCubeWithNormals( const vec3_t position, const bounds_t &size, const Color::Color& color ); class u_ModelViewProjectionMatrix; void Tess_InstantQuad( u_ModelViewProjectionMatrix &shader, float x, float y, float width, float height ); @@ -3642,9 +3644,9 @@ inline bool checkGLErrors() void R_SetupLightShader( trRefLight_t *light ); - byte R_CalcLightCubeSideBits( trRefLight_t *light, vec3_t worldBounds[ 2 ] ); +byte R_CalcLightCubeSideBits( trRefLight_t *light, const bounds_t &worldBounds ); - cullResult_t R_CullLightWorldBounds( trRefLight_t *light, vec3_t worldBounds[ 2 ] ); +cullResult_t R_CullLightWorldBounds( trRefLight_t *light, const bounds_t &worldBounds ); void R_ComputeFinalAttenuation( shaderStage_t *pStage, trRefLight_t *light ); diff --git a/src/engine/renderer/tr_main.cpp b/src/engine/renderer/tr_main.cpp index 2c8ac3d501..0c65009a0c 100644 --- a/src/engine/renderer/tr_main.cpp +++ b/src/engine/renderer/tr_main.cpp @@ -336,7 +336,7 @@ R_CullBox Returns CULL_IN, CULL_CLIP, or CULL_OUT ================= */ -cullResult_t R_CullBox( vec3_t worldBounds[ 2 ] ) +cullResult_t R_CullBox( const bounds_t &worldBounds ) { bool anyClip; cplane_t *frust; @@ -354,7 +354,7 @@ cullResult_t R_CullBox( vec3_t worldBounds[ 2 ] ) { frust = &tr.viewParms.frustums[ 0 ][ i ]; - r = BoxOnPlaneSide( worldBounds[ 0 ], worldBounds[ 1 ], frust ); + r = BoxOnPlaneSide( worldBounds, frust ); if ( r == 2 ) { @@ -385,12 +385,12 @@ R_CullLocalBox Returns CULL_IN, CULL_CLIP, or CULL_OUT ================= */ -cullResult_t R_CullLocalBox( vec3_t localBounds[ 2 ] ) +cullResult_t R_CullLocalBox( const bounds_t &localBounds ) { - vec3_t worldBounds[ 2 ]; + bounds_t worldBounds; // transform into world space - MatrixTransformBounds(tr.orientation.transformMatrix, localBounds[0], localBounds[1], worldBounds[0], worldBounds[1]); + MatrixTransformBounds( tr.orientation.transformMatrix, localBounds, worldBounds ); return R_CullBox( worldBounds ); } @@ -456,7 +456,7 @@ cullResult_t R_CullPointAndRadius( vec3_t pt, float radius ) R_FogWorldBox ================= */ -int R_FogWorldBox( vec3_t bounds[ 2 ] ) +int R_FogWorldBox( const bounds_t &bounds ) { int i, j; fog_t *fog; @@ -472,12 +472,12 @@ int R_FogWorldBox( vec3_t bounds[ 2 ] ) for ( j = 0; j < 3; j++ ) { - if ( bounds[ 0 ][ j ] >= fog->bounds[ 1 ][ j ] ) + if ( bounds.mins[ j ] >= fog->bounds.maxs[ j ] ) { break; } - if ( bounds[ 1 ][ j ] <= fog->bounds[ 0 ][ j ] ) + if ( bounds.maxs[ j ] <= fog->bounds.mins[ j ] ) { break; } @@ -619,7 +619,7 @@ Tr3B - needs R_RotateEntityForViewParms */ void R_SetupEntityWorldBounds( trRefEntity_t *ent ) { - MatrixTransformBounds(tr.orientation.transformMatrix, ent->localBounds[0], ent->localBounds[1], ent->worldBounds[0], ent->worldBounds[1]); + MatrixTransformBounds( tr.orientation.transformMatrix, ent->localBounds, ent->worldBounds ); } /* @@ -836,35 +836,34 @@ static void SetFarClip() float distance; if ( glConfig2.usingMaterialSystem ) { - VectorCopy( materialSystem.worldViewBounds[0], tr.viewParms.visBounds[0] ); - VectorCopy( materialSystem.worldViewBounds[1], tr.viewParms.visBounds[1] ); + BoundsCopy( materialSystem.worldViewBounds, tr.viewParms.visBounds ); } if ( i & 1 ) { - v[ 0 ] = tr.viewParms.visBounds[ 0 ][ 0 ]; + v[ 0 ] = tr.viewParms.visBounds.mins[ 0 ]; } else { - v[ 0 ] = tr.viewParms.visBounds[ 1 ][ 0 ]; + v[ 0 ] = tr.viewParms.visBounds.maxs[ 0 ]; } if ( i & 2 ) { - v[ 1 ] = tr.viewParms.visBounds[ 0 ][ 1 ]; + v[ 1 ] = tr.viewParms.visBounds.mins[ 1 ]; } else { - v[ 1 ] = tr.viewParms.visBounds[ 1 ][ 1 ]; + v[ 1 ] = tr.viewParms.visBounds.maxs[ 1 ]; } if ( i & 4 ) { - v[ 2 ] = tr.viewParms.visBounds[ 0 ][ 2 ]; + v[ 2 ] = tr.viewParms.visBounds.mins[ 2 ]; } else { - v[ 2 ] = tr.viewParms.visBounds[ 1 ][ 2 ]; + v[ 2 ] = tr.viewParms.visBounds.maxs[ 2 ]; } distance = DistanceSquared( v, tr.viewParms.orientation.origin ); @@ -1113,12 +1112,7 @@ void R_CalcFrustumFarCornersUnsafe( const plane_t frustum[ FRUSTUM_FAR + 1 ], ve static void CopyPlane( const cplane_t *in, cplane_t *out ) { - VectorCopy( in->normal, out->normal ); - out->dist = in->dist; - out->type = in->type; - out->signbits = in->signbits; - out->pad[ 0 ] = in->pad[ 0 ]; - out->pad[ 1 ] = in->pad[ 1 ]; + memcpy( out, in, sizeof(cplane_t) ); } static void R_SetupSplitFrustums() @@ -1529,8 +1523,8 @@ int PortalOffScreenOrOutOfRange( const drawSurf_t *drawSurf, screenRect_t& surfR AABB aabb; if ( tr.currentEntity != &tr.worldEntity ) { VectorCopy( tr.currentEntity->e.origin, aabb.origin ); - VectorCopy( tr.currentEntity->localBounds[0], aabb.mins ); - VectorCopy( tr.currentEntity->localBounds[1], aabb.maxs ); + VectorCopy( tr.currentEntity->localBounds.mins, aabb.mins ); + VectorCopy( tr.currentEntity->localBounds.maxs, aabb.maxs ); } else { tr.orientation = tr.viewParms.world; VectorCopy( tr.world->portals[drawSurf->portalNum].origin, aabb.origin ); @@ -1825,12 +1819,12 @@ int R_SpriteFogNum( trRefEntity_t *ent ) for ( j = 0; j < 3; j++ ) { - if ( ent->e.origin[ j ] - ent->e.radius >= fog->bounds[ 1 ][ j ] ) + if ( ent->e.origin[ j ] - ent->e.radius >= fog->bounds.maxs[ j ] ) { break; } - if ( ent->e.origin[ j ] + ent->e.radius <= fog->bounds[ 0 ][ j ] ) + if ( ent->e.origin[ j ] + ent->e.radius <= fog->bounds.mins[ j ] ) { break; } @@ -2120,10 +2114,8 @@ void R_AddEntitySurfaces() break; } - VectorClear( ent->localBounds[ 0 ] ); - VectorClear( ent->localBounds[ 1 ] ); - VectorClear( ent->worldBounds[ 0 ] ); - VectorClear( ent->worldBounds[ 1 ] ); + ZeroBounds( ent->localBounds ); + ZeroBounds( ent->worldBounds ); shader = R_GetShaderByHandle( ent->e.customShader ); R_AddDrawSurf( &entitySurface, tr.defaultShader, -1, 0 ); break; @@ -2248,7 +2240,6 @@ check if OMNI shadow light can be turned into PROJ for better shadow map quality */ void R_TransformShadowLight( trRefLight_t *light ) { int i; - vec3_t mins, maxs, mids; vec3_t forward, right, up; float radius; @@ -2256,18 +2247,21 @@ void R_TransformShadowLight( trRefLight_t *light ) { light->restrictInteractionFirst < 0 ) return; - ClearBounds( mins, maxs ); + bounds_t bounds; + ClearBounds( bounds ); + for( i = light->restrictInteractionFirst; i <= light->restrictInteractionLast; i++ ) { trRefEntity_t *ent = &tr.refdef.entities[ i ]; - BoundsAdd(ent->worldBounds[0], ent->worldBounds[1], mins, maxs); + BoundsAdd( ent->worldBounds, bounds ); } // if light origin is outside BBox of shadow receivers, build // a projection light on the closest plane of the BBox - VectorAdd( mins, maxs, mids ); + vec3_t mids; + VectorAdd( bounds.mins, bounds.maxs, mids ); VectorScale( mids, 0.5f, mids ); - radius = Distance( mids, maxs ); + radius = Distance( mids, bounds.maxs ); light->l.rlType = refLightType_t::RL_PROJ; VectorSubtract( mids, light->l.origin, forward ); @@ -2358,8 +2352,7 @@ void R_AddLightInteractions() R_SetupLightFrustum( light ); // ignore if not in visible bounds - if ( !BoundsIntersect - ( light->worldBounds[ 0 ], light->worldBounds[ 1 ], tr.viewParms.visBounds[ 0 ], tr.viewParms.visBounds[ 1 ] ) ) + if ( !BoundsIntersect( light->worldBounds, tr.viewParms.visBounds ) ) { continue; } diff --git a/src/engine/renderer/tr_marks.cpp b/src/engine/renderer/tr_marks.cpp index c54e82f383..3e2d87e2f3 100644 --- a/src/engine/renderer/tr_marks.cpp +++ b/src/engine/renderer/tr_marks.cpp @@ -150,7 +150,7 @@ static void R_ChopPolyBehindPlane( int numInPoints, vec3_t inPoints[ MAX_VERTS_O R_BoxSurfaces_r ================= */ -void R_BoxSurfaces_r( bspNode_t *node, vec3_t mins, vec3_t maxs, surfaceType_t **list, int listsize, int *listlength, vec3_t dir ) +static void R_BoxSurfaces_r( bspNode_t *node, const bounds_t &bounds, surfaceType_t **list, int listsize, int *listlength, vec3_t dir ) { int s, c; bspSurface_t *surf, **mark; @@ -158,7 +158,7 @@ void R_BoxSurfaces_r( bspNode_t *node, vec3_t mins, vec3_t maxs, surfaceType_t * // do the tail recursion in a loop while ( node->contents == -1 ) { - s = BoxOnPlaneSide( mins, maxs, node->plane ); + s = BoxOnPlaneSide( bounds, node->plane ); if ( s == 1 ) { @@ -170,7 +170,7 @@ void R_BoxSurfaces_r( bspNode_t *node, vec3_t mins, vec3_t maxs, surfaceType_t * } else { - R_BoxSurfaces_r( node->children[ 0 ], mins, maxs, list, listsize, listlength, dir ); + R_BoxSurfaces_r( node->children[ 0 ], bounds, list, listsize, listlength, dir ); node = node->children[ 1 ]; } } @@ -199,7 +199,7 @@ void R_BoxSurfaces_r( bspNode_t *node, vec3_t mins, vec3_t maxs, surfaceType_t * else if ( * ( surf->data ) == surfaceType_t::SF_FACE ) { // the face plane should go through the box - s = BoxOnPlaneSide( mins, maxs, & ( ( srfSurfaceFace_t * ) surf->data )->plane ); + s = BoxOnPlaneSide( bounds, & ( ( srfSurfaceFace_t * ) surf->data )->plane ); if ( s == 1 || s == 2 ) { @@ -293,7 +293,6 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio int numsurfaces, numPlanes; int i, j, k, m, n; surfaceType_t *surfaces[ 64 ]; - vec3_t mins, maxs; int returnedFragments; int returnedPoints; vec3_t normals[ MAX_VERTS_ON_POLY + 2 ]; @@ -313,21 +312,22 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio //increment view count for double check prevention tr.viewCountNoReset++; - // VectorNormalize2( projection, projectionDir ); + // find all the brushes that are to be considered - ClearBounds( mins, maxs ); + bounds_t bounds; + ClearBounds( bounds ); for ( i = 0; i < numPoints; i++ ) { vec3_t temp; - AddPointToBounds( points[ i ], mins, maxs ); + AddPointToBounds( points[ i ], bounds ); VectorAdd( points[ i ], projection, temp ); - AddPointToBounds( temp, mins, maxs ); + AddPointToBounds( temp, bounds ); // make sure we get all the leafs (also the one(s) in front of the hit surface) VectorMA( points[ i ], -20, projectionDir, temp ); - AddPointToBounds( temp, mins, maxs ); + AddPointToBounds( temp, bounds ); } if ( numPoints > MAX_VERTS_ON_POLY ) @@ -355,7 +355,7 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio numPlanes = numPoints + 2; numsurfaces = 0; - R_BoxSurfaces_r( tr.world->nodes, mins, maxs, surfaces, 64, &numsurfaces, projectionDir ); + R_BoxSurfaces_r( tr.world->nodes, bounds, surfaces, 64, &numsurfaces, projectionDir ); returnedPoints = 0; returnedFragments = 0; diff --git a/src/engine/renderer/tr_mesh.cpp b/src/engine/renderer/tr_mesh.cpp index 8aefcda50b..db3332958d 100644 --- a/src/engine/renderer/tr_mesh.cpp +++ b/src/engine/renderer/tr_mesh.cpp @@ -40,10 +40,15 @@ static void R_CullMDV( mdvModel_t *model, trRefEntity_t *ent ) // calculate a bounding box in the current coordinate system for ( i = 0; i < 3; i++ ) { - ent->localBounds[ 0 ][ i ] = - oldFrame->bounds[ 0 ][ i ] < newFrame->bounds[ 0 ][ i ] ? oldFrame->bounds[ 0 ][ i ] : newFrame->bounds[ 0 ][ i ]; - ent->localBounds[ 1 ][ i ] = - oldFrame->bounds[ 1 ][ i ] > newFrame->bounds[ 1 ][ i ] ? oldFrame->bounds[ 1 ][ i ] : newFrame->bounds[ 1 ][ i ]; + ent->localBounds.mins[ i ] = + oldFrame->bounds[ 0 ][ i ] < newFrame->bounds[ 0 ][ i ] + ? oldFrame->bounds[ 0 ][ i ] + : newFrame->bounds[ 0 ][ i ]; + + ent->localBounds.maxs[ i ] = + oldFrame->bounds[ 1 ][ i ] > newFrame->bounds[ 1 ][ i ] + ? oldFrame->bounds[ 1 ][ i ] + : newFrame->bounds[ 1 ][ i ]; } // setup world bounds for intersection tests @@ -153,7 +158,9 @@ int R_ComputeLOD( trRefEntity_t *ent ) frame = tr.currentModel->mdv[ 0 ]->frames; frame += ent->e.frame; - radius = RadiusFromBounds( frame->bounds[ 0 ], frame->bounds[ 1 ] ); + bounds_t bounds; + BoundsSet( bounds, frame->bounds[ 0 ], frame->bounds[ 1 ] ); + radius = RadiusFromBounds( bounds ); if ( ( projectedRadius = R_ProjectRadius( radius, ent->e.origin ) ) != 0 ) { @@ -397,7 +404,7 @@ void R_AddMDVInteractions( trRefEntity_t *ent, trRefLight_t *light, interactionT model = tr.currentModel->mdv[ lod ]; // do a quick AABB cull - if ( !BoundsIntersect( light->worldBounds[ 0 ], light->worldBounds[ 1 ], ent->worldBounds[ 0 ], ent->worldBounds[ 1 ] ) ) + if ( !BoundsIntersect( light->worldBounds, ent->worldBounds ) ) { tr.pc.c_dlightSurfacesCulled += model->numSurfaces; return; diff --git a/src/engine/renderer/tr_model.cpp b/src/engine/renderer/tr_model.cpp index 8d85386946..d48da73082 100644 --- a/src/engine/renderer/tr_model.cpp +++ b/src/engine/renderer/tr_model.cpp @@ -567,7 +567,7 @@ int RE_BoneIndex( qhandle_t hModel, const char *boneName ) R_ModelBounds ==================== */ -void R_ModelBounds( qhandle_t handle, vec3_t mins, vec3_t maxs ) +void R_ModelBounds( qhandle_t handle, bounds_t &bounds ) { model_t *model; mdvModel_t *header; @@ -578,32 +578,25 @@ void R_ModelBounds( qhandle_t handle, vec3_t mins, vec3_t maxs ) switch ( model->type ) { case modtype_t::MOD_BSP: - VectorCopy( model->bsp->bounds[ 0 ], mins ); - VectorCopy( model->bsp->bounds[ 1 ], maxs ); + BoundsCopy( model->bsp->bounds, bounds); break; case modtype_t::MOD_MESH: header = model->mdv[ 0 ]; - frame = header->frames; - - VectorCopy( frame->bounds[ 0 ], mins ); - VectorCopy( frame->bounds[ 1 ], maxs ); + BoundsSet( bounds, frame->bounds[ 0 ], frame->bounds[ 1 ] ); break; case modtype_t::MOD_MD5: - VectorCopy( model->md5->bounds[ 0 ], mins ); - VectorCopy( model->md5->bounds[ 1 ], maxs ); + BoundsCopy( model->md5->bounds, bounds ); break; case modtype_t::MOD_IQM: - VectorCopy( model->iqm->bounds[ 0 ], mins ); - VectorCopy( model->iqm->bounds[ 1 ], maxs ); + BoundsCopy( model->iqm->bounds, bounds ); break; default: - VectorClear( mins ); - VectorClear( maxs ); + ZeroBounds( bounds ); break; } } diff --git a/src/engine/renderer/tr_model_iqm.cpp b/src/engine/renderer/tr_model_iqm.cpp index c865571542..19d6f67095 100644 --- a/src/engine/renderer/tr_model_iqm.cpp +++ b/src/engine/renderer/tr_model_iqm.cpp @@ -692,16 +692,14 @@ bool R_LoadIQModel( model_t *mod, const void *buffer, int filesize, switch( vertexarray->type ) { case IQM_POSITION: - ClearBounds( IQModel->bounds[ 0 ], IQModel->bounds[ 1 ] ); + ClearBounds( IQModel->bounds ); memcpy( IQModel->positions, IQMPtr( header, vertexarray->offset ), n * sizeof(float) ); for( int j = 0; j < n; j += vertexarray->size ) { - AddPointToBounds( &IQModel->positions[ j ], - IQModel->bounds[ 0 ], - IQModel->bounds[ 1 ] ); + AddPointToBounds( &IQModel->positions[ j ], IQModel->bounds ); } - IQModel->internalScale = BoundsMaxExtent( IQModel->bounds[ 0 ], IQModel->bounds[ 1 ] ); + IQModel->internalScale = BoundsMaxExtent( IQModel->bounds ); if( IQModel->internalScale > 0.0f ) { float inverseScale = 1.0f / IQModel->internalScale; for( int j = 0; j < n; j += vertexarray->size ) { @@ -880,31 +878,26 @@ R_CullIQM ============= */ static void R_CullIQM( trRefEntity_t *ent ) { - vec3_t localBounds[ 2 ]; float scale = ent->e.skeleton.scale; IQModel_t *model = tr.currentModel->iqm; IQAnim_t *anim = model->anims; - float *bounds; // use the bounding box by the model - bounds = model->bounds[0]; - VectorCopy( bounds, localBounds[ 0 ] ); - VectorCopy( bounds + 3, localBounds[ 1 ] ); + bounds_t localBounds; + BoundsCopy( model->bounds, localBounds ); - if ( anim && ( bounds = anim->bounds ) ) { + if ( anim && anim->bounds ) { // merge bounding box provided by the animation - BoundsAdd( localBounds[ 0 ], localBounds[ 1 ], - bounds, bounds + 3 ); + bounds_t bounds; + BoundsSet( bounds, anim->bounds, anim->bounds + 3 ); + BoundsAdd( localBounds, bounds ); } // merge bounding box provided by skeleton - BoundsAdd( localBounds[ 0 ], localBounds[ 1 ], - ent->e.skeleton.bounds[ 0 ], ent->e.skeleton.bounds[ 1 ] ); + BoundsAdd( localBounds, ent->e.skeleton.bounds ); - VectorScale( localBounds[0], scale, ent->localBounds[ 0 ] ); - VectorScale( localBounds[1], scale, ent->localBounds[ 1 ] ); + BoundsScale( localBounds, scale, ent->localBounds ); - R_SetupEntityWorldBounds(ent); switch ( R_CullBox( ent->worldBounds ) ) diff --git a/src/engine/renderer/tr_model_md5.cpp b/src/engine/renderer/tr_model_md5.cpp index 3af84dc226..7f16e40d21 100644 --- a/src/engine/renderer/tr_model_md5.cpp +++ b/src/engine/renderer/tr_model_md5.cpp @@ -542,7 +542,7 @@ bool R_LoadMD5( model_t *mod, const char *buffer, const char *modName ) } // loading is done now calculate the bounding box - ClearBounds( md5->bounds[ 0 ], md5->bounds[ 1 ] ); + ClearBounds( md5->bounds ); surf = md5->surfaces; for (unsigned i = 0; i < md5->numSurfaces; i++, surf++ ) @@ -550,11 +550,11 @@ bool R_LoadMD5( model_t *mod, const char *buffer, const char *modName ) v = surf->verts; for (unsigned j = 0; j < surf->numVerts; j++, v++ ) { - AddPointToBounds( v->position, md5->bounds[ 0 ], md5->bounds[ 1 ] ); + AddPointToBounds( v->position, md5->bounds ); } } - md5->internalScale = BoundsMaxExtent( md5->bounds[ 0 ], md5->bounds[ 1 ] ); + md5->internalScale = BoundsMaxExtent( md5->bounds ); if( md5->internalScale > 0.0f ) { float invScale = 1.0f / md5->internalScale; diff --git a/src/engine/renderer/tr_public.h b/src/engine/renderer/tr_public.h index 5f4a253aaf..575b5988f7 100644 --- a/src/engine/renderer/tr_public.h +++ b/src/engine/renderer/tr_public.h @@ -226,7 +226,7 @@ struct refexport_t int maxPoints, vec3_t pointBuffer, int maxFragments, markFragment_t *fragmentBuffer ); int ( *LerpTag )( orientation_t *tag, const refEntity_t *refent, const char *tagName, int startIndex ); - void ( *ModelBounds )( qhandle_t model, vec3_t mins, vec3_t maxs ); + void ( *ModelBounds )( qhandle_t model, bounds_t &bounds ); void ( *RemapShader )( const char *oldShader, const char *newShader, const char *offsetTime ); diff --git a/src/engine/renderer/tr_scene.cpp b/src/engine/renderer/tr_scene.cpp index aa02565b4a..6c84e10834 100644 --- a/src/engine/renderer/tr_scene.cpp +++ b/src/engine/renderer/tr_scene.cpp @@ -143,7 +143,6 @@ static void R_AddPolysToScene( qhandle_t hShader, int numVerts, const polyVert_t int i, j; int fogIndex; fog_t *fog; - vec3_t bounds[ 2 ]; if ( !tr.registered ) { @@ -200,19 +199,19 @@ static void R_AddPolysToScene( qhandle_t hShader, int numVerts, const polyVert_t else { // find which fog volume the poly is in - VectorCopy( poly->verts[ 0 ].xyz, bounds[ 0 ] ); - VectorCopy( poly->verts[ 0 ].xyz, bounds[ 1 ] ); + bounds_t bounds; + BoundsSet( bounds, poly->verts[ 0 ].xyz, poly->verts[ 0 ].xyz ); for ( i = 1; i < poly->numVerts; i++ ) { - AddPointToBounds( poly->verts[ i ].xyz, bounds[ 0 ], bounds[ 1 ] ); + AddPointToBounds( poly->verts[ i ].xyz, bounds ); } for ( fogIndex = 1; fogIndex < tr.world->numFogs; fogIndex++ ) { fog = &tr.world->fogs[ fogIndex ]; - if ( BoundsIntersect( bounds[ 0 ], bounds[ 1 ], fog->bounds[ 0 ], fog->bounds[ 1 ] ) ) + if ( BoundsIntersect( bounds, fog->bounds ) ) { break; } diff --git a/src/engine/renderer/tr_surface.cpp b/src/engine/renderer/tr_surface.cpp index 7540948fb2..8d80389161 100644 --- a/src/engine/renderer/tr_surface.cpp +++ b/src/engine/renderer/tr_surface.cpp @@ -442,95 +442,91 @@ void Tess_AddTetrahedron( vec4_t tetraVerts[ 4 ], const Color::Color& colorf ) } } -void Tess_AddCube( const vec3_t position, const vec3_t minSize, const vec3_t maxSize, const Color::Color& color ) +void Tess_AddCube( const vec3_t position, const bounds_t &size, const Color::Color& color ) { - vec4_t quadVerts[ 4 ]; - vec3_t mins; - vec3_t maxs; - - VectorAdd( position, minSize, mins ); - VectorAdd( position, maxSize, maxs ); + bounds_t t; + VectorAdd( position, size.mins, t.mins ); + VectorAdd( position, size.maxs, t.maxs ); - Vector4Set( quadVerts[ 0 ], mins[ 0 ], mins[ 1 ], mins[ 2 ], 1 ); - Vector4Set( quadVerts[ 1 ], mins[ 0 ], maxs[ 1 ], mins[ 2 ], 1 ); - Vector4Set( quadVerts[ 2 ], mins[ 0 ], maxs[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 3 ], mins[ 0 ], mins[ 1 ], maxs[ 2 ], 1 ); + vec4_t quadVerts[ 4 ]; + Vector4Set( quadVerts[ 0 ], t.mins[ 0 ], t.mins[ 1 ], t.mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 1 ], t.mins[ 0 ], t.maxs[ 1 ], t.mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 2 ], t.mins[ 0 ], t.maxs[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 3 ], t.mins[ 0 ], t.mins[ 1 ], t.maxs[ 2 ], 1 ); Tess_AddQuadStamp2( quadVerts, color ); - Vector4Set( quadVerts[ 0 ], maxs[ 0 ], mins[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 1 ], maxs[ 0 ], maxs[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 2 ], maxs[ 0 ], maxs[ 1 ], mins[ 2 ], 1 ); - Vector4Set( quadVerts[ 3 ], maxs[ 0 ], mins[ 1 ], mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 0 ], t.maxs[ 0 ], t.mins[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 1 ], t.maxs[ 0 ], t.maxs[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 2 ], t.maxs[ 0 ], t.maxs[ 1 ], t.mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 3 ], t.maxs[ 0 ], t.mins[ 1 ], t.mins[ 2 ], 1 ); Tess_AddQuadStamp2( quadVerts, color ); - Vector4Set( quadVerts[ 0 ], mins[ 0 ], mins[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 1 ], mins[ 0 ], maxs[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 2 ], maxs[ 0 ], maxs[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 3 ], maxs[ 0 ], mins[ 1 ], maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 0 ], t.mins[ 0 ], t.mins[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 1 ], t.mins[ 0 ], t.maxs[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 2 ], t.maxs[ 0 ], t.maxs[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 3 ], t.maxs[ 0 ], t.mins[ 1 ], t.maxs[ 2 ], 1 ); Tess_AddQuadStamp2( quadVerts, color ); - Vector4Set( quadVerts[ 0 ], maxs[ 0 ], mins[ 1 ], mins[ 2 ], 1 ); - Vector4Set( quadVerts[ 1 ], maxs[ 0 ], maxs[ 1 ], mins[ 2 ], 1 ); - Vector4Set( quadVerts[ 2 ], mins[ 0 ], maxs[ 1 ], mins[ 2 ], 1 ); - Vector4Set( quadVerts[ 3 ], mins[ 0 ], mins[ 1 ], mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 0 ], t.maxs[ 0 ], t.mins[ 1 ], t.mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 1 ], t.maxs[ 0 ], t.maxs[ 1 ], t.mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 2 ], t.mins[ 0 ], t.maxs[ 1 ], t.mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 3 ], t.mins[ 0 ], t.mins[ 1 ], t.mins[ 2 ], 1 ); Tess_AddQuadStamp2( quadVerts, color ); - Vector4Set( quadVerts[ 0 ], mins[ 0 ], mins[ 1 ], mins[ 2 ], 1 ); - Vector4Set( quadVerts[ 1 ], mins[ 0 ], mins[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 2 ], maxs[ 0 ], mins[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 3 ], maxs[ 0 ], mins[ 1 ], mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 0 ], t.mins[ 0 ], t.mins[ 1 ], t.mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 1 ], t.mins[ 0 ], t.mins[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 2 ], t.maxs[ 0 ], t.mins[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 3 ], t.maxs[ 0 ], t.mins[ 1 ], t.mins[ 2 ], 1 ); Tess_AddQuadStamp2( quadVerts, color ); - Vector4Set( quadVerts[ 0 ], maxs[ 0 ], maxs[ 1 ], mins[ 2 ], 1 ); - Vector4Set( quadVerts[ 1 ], maxs[ 0 ], maxs[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 2 ], mins[ 0 ], maxs[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 3 ], mins[ 0 ], maxs[ 1 ], mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 0 ], t.maxs[ 0 ], t.maxs[ 1 ], t.mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 1 ], t.maxs[ 0 ], t.maxs[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 2 ], t.mins[ 0 ], t.maxs[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 3 ], t.mins[ 0 ], t.maxs[ 1 ], t.mins[ 2 ], 1 ); Tess_AddQuadStamp2( quadVerts, color ); } -void Tess_AddCubeWithNormals( const vec3_t position, const vec3_t minSize, const vec3_t maxSize, const Color::Color& color ) +void Tess_AddCubeWithNormals( const vec3_t position, const bounds_t &size, const Color::Color& color ) { - vec4_t quadVerts[ 4 ]; - vec3_t mins; - vec3_t maxs; - - VectorAdd( position, minSize, mins ); - VectorAdd( position, maxSize, maxs ); + bounds_t t; + VectorAdd( position, size.mins, t.mins ); + VectorAdd( position, size.maxs, t.maxs ); - Vector4Set( quadVerts[ 0 ], mins[ 0 ], mins[ 1 ], mins[ 2 ], 1 ); - Vector4Set( quadVerts[ 1 ], mins[ 0 ], maxs[ 1 ], mins[ 2 ], 1 ); - Vector4Set( quadVerts[ 2 ], mins[ 0 ], maxs[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 3 ], mins[ 0 ], mins[ 1 ], maxs[ 2 ], 1 ); + vec4_t quadVerts[ 4 ]; + Vector4Set( quadVerts[ 0 ], t.mins[ 0 ], t.mins[ 1 ], t.mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 1 ], t.mins[ 0 ], t.maxs[ 1 ], t.mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 2 ], t.mins[ 0 ], t.maxs[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 3 ], t.mins[ 0 ], t.mins[ 1 ], t.maxs[ 2 ], 1 ); Tess_AddQuadStamp2WithNormals( quadVerts, color ); - Vector4Set( quadVerts[ 0 ], maxs[ 0 ], mins[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 1 ], maxs[ 0 ], maxs[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 2 ], maxs[ 0 ], maxs[ 1 ], mins[ 2 ], 1 ); - Vector4Set( quadVerts[ 3 ], maxs[ 0 ], mins[ 1 ], mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 0 ], t.maxs[ 0 ], t.mins[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 1 ], t.maxs[ 0 ], t.maxs[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 2 ], t.maxs[ 0 ], t.maxs[ 1 ], t.mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 3 ], t.maxs[ 0 ], t.mins[ 1 ], t.mins[ 2 ], 1 ); Tess_AddQuadStamp2WithNormals( quadVerts, color ); - Vector4Set( quadVerts[ 0 ], mins[ 0 ], mins[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 1 ], mins[ 0 ], maxs[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 2 ], maxs[ 0 ], maxs[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 3 ], maxs[ 0 ], mins[ 1 ], maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 0 ], t.mins[ 0 ], t.mins[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 1 ], t.mins[ 0 ], t.maxs[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 2 ], t.maxs[ 0 ], t.maxs[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 3 ], t.maxs[ 0 ], t.mins[ 1 ], t.maxs[ 2 ], 1 ); Tess_AddQuadStamp2WithNormals( quadVerts, color ); - Vector4Set( quadVerts[ 0 ], maxs[ 0 ], mins[ 1 ], mins[ 2 ], 1 ); - Vector4Set( quadVerts[ 1 ], maxs[ 0 ], maxs[ 1 ], mins[ 2 ], 1 ); - Vector4Set( quadVerts[ 2 ], mins[ 0 ], maxs[ 1 ], mins[ 2 ], 1 ); - Vector4Set( quadVerts[ 3 ], mins[ 0 ], mins[ 1 ], mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 0 ], t.maxs[ 0 ], t.mins[ 1 ], t.mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 1 ], t.maxs[ 0 ], t.maxs[ 1 ], t.mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 2 ], t.mins[ 0 ], t.maxs[ 1 ], t.mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 3 ], t.mins[ 0 ], t.mins[ 1 ], t.mins[ 2 ], 1 ); Tess_AddQuadStamp2WithNormals( quadVerts, color ); - Vector4Set( quadVerts[ 0 ], mins[ 0 ], mins[ 1 ], mins[ 2 ], 1 ); - Vector4Set( quadVerts[ 1 ], mins[ 0 ], mins[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 2 ], maxs[ 0 ], mins[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 3 ], maxs[ 0 ], mins[ 1 ], mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 0 ], t.mins[ 0 ], t.mins[ 1 ], t.mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 1 ], t.mins[ 0 ], t.mins[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 2 ], t.maxs[ 0 ], t.mins[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 3 ], t.maxs[ 0 ], t.mins[ 1 ], t.mins[ 2 ], 1 ); Tess_AddQuadStamp2WithNormals( quadVerts, color ); - Vector4Set( quadVerts[ 0 ], maxs[ 0 ], maxs[ 1 ], mins[ 2 ], 1 ); - Vector4Set( quadVerts[ 1 ], maxs[ 0 ], maxs[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 2 ], mins[ 0 ], maxs[ 1 ], maxs[ 2 ], 1 ); - Vector4Set( quadVerts[ 3 ], mins[ 0 ], maxs[ 1 ], mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 0 ], t.maxs[ 0 ], t.maxs[ 1 ], t.mins[ 2 ], 1 ); + Vector4Set( quadVerts[ 1 ], t.maxs[ 0 ], t.maxs[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 2 ], t.mins[ 0 ], t.maxs[ 1 ], t.maxs[ 2 ], 1 ); + Vector4Set( quadVerts[ 3 ], t.mins[ 0 ], t.maxs[ 1 ], t.mins[ 2 ], 1 ); Tess_AddQuadStamp2WithNormals( quadVerts, color ); } diff --git a/src/engine/renderer/tr_types.h b/src/engine/renderer/tr_types.h index e00a2cd016..0c719cfe6f 100644 --- a/src/engine/renderer/tr_types.h +++ b/src/engine/renderer/tr_types.h @@ -162,7 +162,8 @@ struct alignas(16) refSkeleton_t unsigned short numBones; - vec3_t bounds[ 2 ]; // bounds of all applied animations + bounds_t bounds; // bounds of all applied animations + vec_t scale; refBone_t bones[ MAX_BONES ]; diff --git a/src/engine/renderer/tr_world.cpp b/src/engine/renderer/tr_world.cpp index 4ca207aec0..045f5011b4 100644 --- a/src/engine/renderer/tr_world.cpp +++ b/src/engine/renderer/tr_world.cpp @@ -150,7 +150,7 @@ static bool R_CullLightSurface( surfaceType_t *surface, shader_t *shader, trRefL gen = ( srfGeneric_t * ) surface; // do a quick AABB cull - if ( !BoundsIntersect( light->worldBounds[ 0 ], light->worldBounds[ 1 ], gen->bounds[ 0 ], gen->bounds[ 1 ] ) ) + if ( !BoundsIntersect( light->worldBounds, gen->bounds ) ) { return true; } @@ -304,15 +304,11 @@ void R_AddBSPModelSurfaces( trRefEntity_t *ent ) bspModel = pModel->bsp; // copy local bounds - for ( i = 0; i < 3; i++ ) - { - ent->localBounds[ 0 ][ i ] = bspModel->bounds[ 0 ][ i ]; - ent->localBounds[ 1 ][ i ] = bspModel->bounds[ 1 ][ i ]; - } + BoundsCopy( bspModel->bounds, ent->localBounds ); R_SetupEntityWorldBounds(ent); - VectorAdd( ent->worldBounds[ 0 ], ent->worldBounds[ 1 ], boundsCenter ); + VectorAdd( ent->worldBounds.mins, ent->worldBounds.maxs, boundsCenter ); VectorScale( boundsCenter, 0.5f, boundsCenter ); ent->cull = R_CullBox( ent->worldBounds ); @@ -347,34 +343,34 @@ static void R_AddLeafSurfaces( bspNode_t *node, int planeBits ) tr.pc.c_leafs++; // add to z buffer bounds - if ( node->mins[ 0 ] < tr.viewParms.visBounds[ 0 ][ 0 ] ) + if ( node->bounds.mins[ 0 ] < tr.viewParms.visBounds.mins[ 0 ] ) { - tr.viewParms.visBounds[ 0 ][ 0 ] = node->mins[ 0 ]; + tr.viewParms.visBounds.mins[ 0 ] = node->bounds.mins[ 0 ]; } - if ( node->mins[ 1 ] < tr.viewParms.visBounds[ 0 ][ 1 ] ) + if ( node->bounds.mins[ 1 ] < tr.viewParms.visBounds.mins[ 1 ] ) { - tr.viewParms.visBounds[ 0 ][ 1 ] = node->mins[ 1 ]; + tr.viewParms.visBounds.mins[ 1 ] = node->bounds.mins[ 1 ]; } - if ( node->mins[ 2 ] < tr.viewParms.visBounds[ 0 ][ 2 ] ) + if ( node->bounds.mins[ 2 ] < tr.viewParms.visBounds.mins[ 2 ] ) { - tr.viewParms.visBounds[ 0 ][ 2 ] = node->mins[ 2 ]; + tr.viewParms.visBounds.mins[ 2 ] = node->bounds.mins[ 2 ]; } - if ( node->maxs[ 0 ] > tr.viewParms.visBounds[ 1 ][ 0 ] ) + if ( node->bounds.maxs[ 0 ] > tr.viewParms.visBounds.maxs[ 0 ] ) { - tr.viewParms.visBounds[ 1 ][ 0 ] = node->maxs[ 0 ]; + tr.viewParms.visBounds.maxs[ 0 ] = node->bounds.maxs[ 0 ]; } - if ( node->maxs[ 1 ] > tr.viewParms.visBounds[ 1 ][ 1 ] ) + if ( node->bounds.maxs[ 1 ] > tr.viewParms.visBounds.maxs[ 1 ] ) { - tr.viewParms.visBounds[ 1 ][ 1 ] = node->maxs[ 1 ]; + tr.viewParms.visBounds.maxs[ 1 ] = node->bounds.maxs[ 1 ]; } - if ( node->maxs[ 2 ] > tr.viewParms.visBounds[ 1 ][ 2 ] ) + if ( node->bounds.maxs[ 2 ] > tr.viewParms.visBounds.maxs[ 2 ] ) { - tr.viewParms.visBounds[ 1 ][ 2 ] = node->maxs[ 2 ]; + tr.viewParms.visBounds.maxs[ 2 ] = node->bounds.maxs[ 2 ]; } // add the individual surfaces @@ -427,7 +423,7 @@ static void R_RecursiveWorldNode( bspNode_t *node, int planeBits ) { if ( planeBits & ( 1 << i ) ) { - r = BoxOnPlaneSide( node->mins, node->maxs, &tr.viewParms.frustums[ 0 ][ i ] ); + r = BoxOnPlaneSide( node->bounds, &tr.viewParms.frustums[ 0 ][ i ] ); if ( r == 2 ) { @@ -498,7 +494,7 @@ static void R_RecursiveInteractionNode( bspNode_t *node, trRefLight_t *light, in { if ( planeBits & ( 1 << i ) ) { - r = BoxOnPlaneSide( node->mins, node->maxs, &tr.viewParms.frustums[ 0 ][ i ] ); + r = BoxOnPlaneSide( node->bounds, &tr.viewParms.frustums[ 0 ][ i ] ); if ( r == 2 ) { @@ -528,7 +524,7 @@ static void R_RecursiveInteractionNode( bspNode_t *node, trRefLight_t *light, in // node is just a decision point, so go down both sides // since we don't care about sort orders, just go positive to negative - r = BoxOnPlaneSide( light->worldBounds[ 0 ], light->worldBounds[ 1 ], node->plane ); + r = BoxOnPlaneSide( light->worldBounds, node->plane ); switch ( r ) { @@ -844,7 +840,7 @@ void R_AddWorldSurfaces() tr.currentEntity = &tr.worldEntity; // clear out the visible min/max - ClearBounds( tr.viewParms.visBounds[ 0 ], tr.viewParms.visBounds[ 1 ] ); + ClearBounds( tr.viewParms.visBounds ); // render sky or world? if ( tr.refdef.rdflags & RDF_SKYBOXPORTAL && tr.world->numSkyNodes > 0 ) diff --git a/src/shared/client/cg_api.cpp b/src/shared/client/cg_api.cpp index 6cdf2e9338..b621cf8e49 100644 --- a/src/shared/client/cg_api.cpp +++ b/src/shared/client/cg_api.cpp @@ -510,7 +510,6 @@ int trap_R_BuildSkeleton( refSkeleton_t *skel, qhandle_t anim, int startFrame, i int trap_R_BlendSkeleton( refSkeleton_t *skel, const refSkeleton_t *blend, float frac ) { int i; - vec3_t bounds[ 2 ]; if ( skel->numBones != blend->numBones ) { @@ -532,14 +531,22 @@ int trap_R_BlendSkeleton( refSkeleton_t *skel, const refSkeleton_t *blend, float } // calculate a bounding box in the current coordinate system + bounds_t bounds; + for ( i = 0; i < 3; i++ ) { - bounds[ 0 ][ i ] = skel->bounds[ 0 ][ i ] < blend->bounds[ 0 ][ i ] ? skel->bounds[ 0 ][ i ] : blend->bounds[ 0 ][ i ]; - bounds[ 1 ][ i ] = skel->bounds[ 1 ][ i ] > blend->bounds[ 1 ][ i ] ? skel->bounds[ 1 ][ i ] : blend->bounds[ 1 ][ i ]; + bounds.maxs[ i ] = skel->bounds.maxs[ i ] + < blend->bounds.mins[ i ] + ? skel->bounds.mins[ i ] + : blend->bounds.mins[ i ]; + + bounds.maxs[ i ] = skel->bounds.maxs[ i ] + > blend->bounds.maxs[ i ] + ? skel->bounds.maxs[ i ] + : blend->bounds.maxs[ i ]; } - VectorCopy( bounds[ 0 ], skel->bounds[ 0 ] ); - VectorCopy( bounds[ 1 ], skel->bounds[ 1 ] ); + BoundsCopy( bounds, skel->bounds ); return true; }