* region build: widen temp box to handle small volumes, light entities at the edge and flat primitives

* region build: pull temporal respawn to the box instead of error
This commit is contained in:
Garux 2021-10-21 04:48:54 +03:00
parent 36a1495e33
commit 512d14736c
3 changed files with 61 additions and 93 deletions

View File

@ -473,12 +473,12 @@ void Brush_ConstructPrefab( Brush& brush, EBrushPrefab type, const AABB& bounds,
void ConstructRegionBrushes( scene::Node* brushes[6], const Vector3& region_mins, const Vector3& region_maxs ){
{
// set mins
Vector3 mins( region_mins[0] - 32, region_mins[1] - 32, region_mins[2] - 32 );
const Vector3 mins( region_mins - Vector3( 32 ) );
// vary maxs
for ( std::size_t i = 0; i < 3; i++ )
{
Vector3 maxs( region_maxs[0] + 32, region_maxs[1] + 32, region_maxs[2] + 32 );
Vector3 maxs( region_maxs + Vector3( 32 ) );
maxs[i] = region_mins[i];
Brush_ConstructCuboid( *Node_getBrush( *brushes[i] ), aabb_for_minmax( mins, maxs ), texdef_name_default(), TextureProjection() );
}
@ -486,12 +486,12 @@ void ConstructRegionBrushes( scene::Node* brushes[6], const Vector3& region_mins
{
// set maxs
Vector3 maxs( region_maxs[0] + 32, region_maxs[1] + 32, region_maxs[2] + 32 );
const Vector3 maxs( region_maxs + Vector3( 32 ) );
// vary mins
for ( std::size_t i = 0; i < 3; i++ )
{
Vector3 mins( region_mins[0] - 32, region_mins[1] - 32, region_mins[2] - 32 );
Vector3 mins( region_mins - Vector3( 32 ) );
mins[i] = region_maxs[i];
Brush_ConstructCuboid( *Node_getBrush( *brushes[i + 3] ), aabb_for_minmax( mins, maxs ), texdef_name_default(), TextureProjection() );
}

View File

@ -390,10 +390,6 @@ void Map_SetWorldspawn( Map& map, scene::Node* node ){
}
void AddRegionBrushes( void );
void RemoveRegionBrushes( void );
/*
================
Map_Free
@ -1338,16 +1334,6 @@ void Map_Traverse_Region( scene::Node& root, const scene::Traversable::Walker& w
}
}
bool Map_SaveRegion( const char *filename ){
AddRegionBrushes();
bool success = MapResource_saveFile( MapFormat_forFile( filename ), GlobalSceneGraph().root(), Map_Traverse_Region, filename );
RemoveRegionBrushes();
return success;
}
void Map_RenameAbsolute( const char* absolute ){
Resource* resource = GlobalReferenceCache().capture( absolute );
@ -1419,33 +1405,6 @@ void Map_New(){
GridStatus_changed();
}
extern void ConstructRegionBrushes( scene::Node * brushes[6], const Vector3 &region_mins, const Vector3 &region_maxs );
void ConstructRegionStartpoint( scene::Node* startpoint, const Vector3& region_mins, const Vector3& region_maxs ){
/*!
\todo we need to make sure that the player start IS inside the region and bail out if it's not
the compiler will refuse to compile a map with a player_start somewhere in empty space..
for now, let's just print an error
*/
Vector3 vOrig( Camera_getOrigin( *g_pParentWnd->GetCamWnd() ) );
for ( int i = 0 ; i < 3 ; i++ )
{
if ( vOrig[i] > region_maxs[i] || vOrig[i] < region_mins[i] ) {
globalErrorStream() << "Camera is NOT in the region, it's likely that the region won't compile correctly\n";
break;
}
}
// write the info_playerstart
char sTmp[1024];
sprintf( sTmp, "%d %d %d", (int)vOrig[0], (int)vOrig[1], (int)vOrig[2] );
Node_getEntity( *startpoint )->setKeyValue( "origin", sTmp );
sprintf( sTmp, "%d", (int)Camera_getAngles( *g_pParentWnd->GetCamWnd() )[CAMERA_YAW] );
Node_getEntity( *startpoint )->setKeyValue( "angle", sTmp );
}
/*
===========================================================
@ -1461,13 +1420,10 @@ ToggleItem g_region_item( g_region_caller );
Vector3 g_region_mins;
Vector3 g_region_maxs;
void Region_defaultMinMax(){
g_region_maxs[0] = g_region_maxs[1] = g_region_maxs[2] = GetMaxGridCoord();
g_region_mins[0] = g_region_mins[1] = g_region_mins[2] = -GetMaxGridCoord();
g_region_maxs = Vector3( GetMaxGridCoord() );
g_region_mins = -g_region_maxs;
}
scene::Node* region_sides[6];
scene::Node* region_startpoint = 0;
/*
===========
AddRegionBrushes
@ -1477,30 +1433,61 @@ scene::Node* region_startpoint = 0;
with the new implementation we should be able to append them in a temporary manner to the data we pass to the map module
===========
*/
void AddRegionBrushes( void ){
int i;
extern void ConstructRegionBrushes( scene::Node * brushes[6], const Vector3 &region_mins, const Vector3 &region_maxs );
for ( i = 0; i < 6; i++ )
{
region_sides[i] = &GlobalBrushCreator().createBrush();
Node_getTraversable( Map_FindOrInsertWorldspawn( g_map ) )->insert( NodeSmartReference( *region_sides[i] ) );
class ScopeRegionBrushes
{
scene::Node* m_brushes[6];
scene::Node* m_startpoint;
void ConstructRegionStartpoint( const Vector3& vOrig ){
// write the info_playerstart
char sTmp[1024];
sprintf( sTmp, "%d %d %d", (int)vOrig[0], (int)vOrig[1], (int)vOrig[2] );
Node_getEntity( *m_startpoint )->setKeyValue( "origin", sTmp );
sprintf( sTmp, "%d", (int)Camera_getAngles( *g_pParentWnd->GetCamWnd() )[CAMERA_YAW] );
Node_getEntity( *m_startpoint )->setKeyValue( "angle", sTmp );
}
public:
ScopeRegionBrushes(){
for ( auto&& brush : m_brushes )
{
brush = &GlobalBrushCreator().createBrush();
Node_getTraversable( Map_FindOrInsertWorldspawn( g_map ) )->insert( NodeSmartReference( *brush ) );
}
region_startpoint = &GlobalEntityCreator().createEntity( GlobalEntityClassManager().findOrInsert( "info_player_start", false ) );
m_startpoint = &GlobalEntityCreator().createEntity( GlobalEntityClassManager().findOrInsert( "info_player_start", false ) );
ConstructRegionBrushes( region_sides, g_region_mins, g_region_maxs );
ConstructRegionStartpoint( region_startpoint, g_region_mins, g_region_maxs );
/* adjust temp box: space may be too small, also help with lights and flat primitives */
const Vector3 min( g_region_mins - Vector3( 256, 256, 8 ) ), max( g_region_maxs + Vector3( 256, 256, 512 ) );
Vector3 spawn( Camera_getOrigin( *g_pParentWnd->GetCamWnd() ) );
/* pull spawn point to the box, if needed */
for( size_t i = 0; i < 3; ++i )
{
spawn[i] = std::max( spawn[i], min[i] + 64 );
spawn[i] = std::min( spawn[i], max[i] - 64 );
}
Node_getTraversable( GlobalSceneGraph().root() )->insert( NodeSmartReference( *region_startpoint ) );
ConstructRegionBrushes( m_brushes, min, max );
ConstructRegionStartpoint( spawn );
Node_getTraversable( GlobalSceneGraph().root() )->insert( NodeSmartReference( *m_startpoint ) );
}
~ScopeRegionBrushes(){
for ( auto&& brush : m_brushes )
{
Node_getTraversable( *Map_GetWorldspawn( g_map ) )->erase( *brush );
}
Node_getTraversable( GlobalSceneGraph().root() )->erase( *m_startpoint );
}
ScopeRegionBrushes( ScopeRegionBrushes&& ) noexcept = delete;
};
bool Map_SaveRegion( const char *filename ){
ScopeRegionBrushes tmp;
return MapResource_saveFile( MapFormat_forFile( filename ), GlobalSceneGraph().root(), Map_Traverse_Region, filename );
}
void RemoveRegionBrushes( void ){
for ( std::size_t i = 0; i < 6; i++ )
{
Node_getTraversable( *Map_GetWorldspawn( g_map ) )->erase( *region_sides[i] );
}
Node_getTraversable( GlobalSceneGraph().root() )->erase( *region_startpoint );
}
inline void exclude_node( scene::Node& node, bool exclude ){
exclude
@ -2340,8 +2327,8 @@ void map_autocaulk_selected(){
const Vector3 spawn( Camera_getOrigin( *g_pParentWnd->GetCamWnd() ) );
Vector3 mins, maxs;
Select_GetBounds( mins, maxs );
mins -= Vector3( 1024, 1024, 1024 );
maxs += Vector3( 1024, 1024, 1024 );
mins -= Vector3( 1024 );
maxs += Vector3( 1024 );
if( !aabb_intersects_point( aabb_for_minmax( mins, maxs ), spawn ) ){
globalErrorStream() << "map_autocaulk_selected(): camera must be near selection!\n";
@ -2433,11 +2420,11 @@ void map_autocaulk_selected(){
StringOutputStream str( 256 );
str << AppPath_get() << "q3map2." << RADIANT_EXECUTABLE
<< " -game quake3"
<< " -fs_basepath \"" << EnginePath_get()
<< "\" -fs_homepath \"" << g_qeglobals.m_userEnginePath
<< "\" -fs_game " << gamename_get()
<< " -autocaulk -fulldetail"
<< " \"" << filename.c_str() << "\"";
<< " -fs_basepath " << makeQuoted( EnginePath_get() )
<< " -fs_homepath " << makeQuoted( g_qeglobals.m_userEnginePath )
<< " -fs_game " << gamename_get()
<< " -autocaulk -fulldetail "
<< makeQuoted( filename.c_str() );
// run
Q_Exec( NULL, str.c_str(), NULL, false, true );
}

View File

@ -230,27 +230,8 @@ public:
}
};
bool Region_cameraValid(){
Vector3 vOrig( vector3_snapped( Camera_getOrigin( *g_pParentWnd->GetCamWnd() ) ) );
for ( int i = 0 ; i < 3 ; i++ )
{
if ( vOrig[i] > g_region_maxs[i] || vOrig[i] < g_region_mins[i] ) {
return false;
}
}
return true;
}
void RunBSP( const char* name ){
// http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=503
// make sure we don't attempt to region compile a map with the camera outside the region
if ( g_region_active && !Region_cameraValid() ) {
globalErrorStream() << "The camera must be in the region to start a region compile.\n";
return;
}
if( !g_region_active )
SaveMap();