From 4382b5f6d9d94c032c8f9c859b0be397a957f467 Mon Sep 17 00:00:00 2001 From: Garux Date: Thu, 7 Mar 2019 00:50:25 +0300 Subject: [PATCH] * bobToolz::Vis Viewer repair (shows current vis cluster brush drawsurfaces in green and rest visible ones in other colours for Q3 and Wolf/QL .bsp): don't crash on bsp w/o vis don't crash with origin in the void (includes inside of structural brush)(do reset) grab point to analyse from camera position with nothing selected; grab from any objects selection too fix rendering issues read surfaces written by q3map2 correctly + faster rendering code print number of loaded drawsurfaces to console for evaluation of optimization done fix a couple of of leaks and crashes after new/delete --- contrib/bobtoolz/DVisDrawer.cpp | 47 +++++++-------- contrib/bobtoolz/DVisDrawer.h | 26 +++++++- contrib/bobtoolz/bsploader.cpp | 87 +++++++++++---------------- contrib/bobtoolz/bsploader.h | 4 +- contrib/bobtoolz/funchandlers-GTK.cpp | 49 +++++---------- contrib/bobtoolz/txt/readme.txt | 2 +- contrib/bobtoolz/visfind.cpp | 68 +++++++++++---------- contrib/bobtoolz/visfind.h | 5 +- include/qerplugin.h | 3 + radiant/plugin.cpp | 7 +++ 10 files changed, 149 insertions(+), 149 deletions(-) diff --git a/contrib/bobtoolz/DVisDrawer.cpp b/contrib/bobtoolz/DVisDrawer.cpp index 9dc37db5..8ffb4aa2 100644 --- a/contrib/bobtoolz/DVisDrawer.cpp +++ b/contrib/bobtoolz/DVisDrawer.cpp @@ -30,7 +30,6 @@ #include "str.h" #include "DPoint.h" -#include "DWinding.h" #include "misc.h" #include "funchandlers.h" @@ -50,6 +49,8 @@ DVisDrawer::~DVisDrawer(){ GlobalShaderCache().detachRenderable( *this ); destroyShaders(); + ClearPoints(); + g_VisView = NULL; } @@ -62,13 +63,15 @@ const char* g_state_wireframe = "$bobtoolz/visdrawer/wireframe"; void DVisDrawer::constructShaders(){ OpenGLState state; GlobalOpenGLStateLibrary().getDefaultState( state ); + state.m_sort = OpenGLState::eSortOverlayFirst; state.m_state = RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_COLOURCHANGE; state.m_linewidth = 1; GlobalOpenGLStateLibrary().insert( g_state_wireframe, state ); GlobalOpenGLStateLibrary().getDefaultState( state ); - state.m_state = RENDER_FILL | RENDER_BLEND | RENDER_COLOURWRITE | RENDER_COLOURCHANGE | RENDER_SMOOTH | RENDER_DEPTHWRITE; + state.m_depthfunc = GL_LEQUAL; + state.m_state = RENDER_FILL | RENDER_BLEND | RENDER_COLOURWRITE | RENDER_COLOURCHANGE | RENDER_DEPTHTEST; GlobalOpenGLStateLibrary().insert( g_state_solid, state ); @@ -84,21 +87,15 @@ void DVisDrawer::destroyShaders(){ } void DVisDrawer::render( RenderStateFlags state ) const { - //bleh - std::list::const_iterator l = m_list->begin(); - - for (; l != m_list->end(); l++ ) - { - DWinding* w = *l; - - glColor4f( w->clr[0], w->clr[1], w->clr[2], 0.5f ); - - glBegin( GL_POLYGON ); - for ( int i = 0; i < w->numpoints; i++ ) { - glVertex3f( ( w->p[i] )[0], ( w->p[i] )[1], ( w->p[i] )[2] ); - } - glEnd(); + glEnable( GL_POLYGON_OFFSET_FILL ); + for( const auto surf : *m_list ){ + const DMetaSurf& s = *surf; + glColor4f( s.colour[0], s.colour[1], s.colour[2], 0.5f ); + glVertexPointer( 3, GL_FLOAT, sizeof( vec3_t ), s.verts ); + glDrawElements( GL_TRIANGLES, GLsizei( s.indicesN ), GL_UNSIGNED_INT, s.indices ); } + glDisable( GL_POLYGON_OFFSET_FILL ); + glColor4f( 1, 1, 1, 1 ); } void DVisDrawer::renderWireframe( Renderer& renderer, const VolumeTest& volume ) const { @@ -122,17 +119,17 @@ void DVisDrawer::renderSolid( Renderer& renderer, const VolumeTest& volume ) con renderer.addRenderable( *this, g_matrix4_identity ); } -void DVisDrawer::SetList( std::list *pointList ){ - if ( m_list ) { - ClearPoints(); - } - +void DVisDrawer::SetList( DMetaSurfaces* pointList ){ + ClearPoints(); m_list = pointList; } void DVisDrawer::ClearPoints(){ - std::list::const_iterator deadPoint = m_list->begin(); - for (; deadPoint != m_list->end(); deadPoint++ ) - delete *deadPoint; - m_list->clear(); + if ( m_list ) { + for ( auto deadPoint : *m_list ) + delete deadPoint; + m_list->clear(); + delete m_list; + m_list = 0; + } } diff --git a/contrib/bobtoolz/DVisDrawer.h b/contrib/bobtoolz/DVisDrawer.h index 3ec5e217..c17b3a8f 100644 --- a/contrib/bobtoolz/DVisDrawer.h +++ b/contrib/bobtoolz/DVisDrawer.h @@ -32,8 +32,28 @@ #include #include "renderable.h" #include "irender.h" +#include "mathlib.h" -#include "DWinding.h" +class DMetaSurf +{ +public: + DMetaSurf() = delete; + DMetaSurf( int numverts, int numindices ){ + verts = new vec3_t[numverts]; + indices = new unsigned int[numindices]; + indicesN = numindices; + } + ~DMetaSurf(){ + delete[] verts; + delete[] indices; + } + vec3_t* verts; + unsigned int* indices; + int indicesN; + vec3_t colour; +}; + +typedef std::list DMetaSurfaces; class DVisDrawer : public Renderable, public OpenGLRenderable { @@ -44,11 +64,11 @@ DVisDrawer(); virtual ~DVisDrawer(); protected: -std::list* m_list; +DMetaSurfaces* m_list; int refCount; public: void ClearPoints(); -void SetList( std::list* pointList ); +void SetList( DMetaSurfaces* pointList ); void render( RenderStateFlags state ) const; void renderSolid( Renderer& renderer, const VolumeTest& volume ) const; diff --git a/contrib/bobtoolz/bsploader.cpp b/contrib/bobtoolz/bsploader.cpp index 6c8b09e9..12d17928 100644 --- a/contrib/bobtoolz/bsploader.cpp +++ b/contrib/bobtoolz/bsploader.cpp @@ -8,21 +8,23 @@ int numleafs; int numleafsurfaces; int numVisBytes; int numDrawVerts; +int numDrawVertsIndices; int numDrawSurfaces; int numbrushes; int numbrushsides; int numleafbrushes; -byte *visBytes = NULL; -dnode_t *dnodes = NULL; -dplane_t *dplanes = NULL; -dleaf_t *dleafs = NULL; +byte *visBytes = NULL; +dnode_t *dnodes = NULL; +dplane_t *dplanes = NULL; +dleaf_t *dleafs = NULL; qdrawVert_t *drawVerts = NULL; -dsurface_t *drawSurfaces = NULL; -int *dleafsurfaces = NULL; -dbrush_t *dbrushes = NULL; -dbrushside_t *dbrushsides = NULL; -int *dleafbrushes = NULL; +int *drawVertsIndices = NULL; +dsurface_t *drawSurfaces = NULL; +int *dleafsurfaces = NULL; +dbrush_t *dbrushes = NULL; +dbrushside_t *dbrushsides = NULL; +int *dleafbrushes = NULL; #define BSP_IDENT ( ( 'P' << 24 ) + ( 'S' << 16 ) + ( 'B' << 8 ) + 'I' ) #define Q3_BSP_VERSION 46 @@ -159,7 +161,7 @@ void SwapBSPFile( void ) { } // drawindexes -// SwapBlock( (int *)drawIndexes, numDrawIndexes * sizeof( drawIndexes[0] ) ); + SwapBlock( (int *)drawVertsIndices, numDrawVertsIndices * sizeof( drawVertsIndices[0] ) ); // drawsurfs SwapBlock( (int *)drawSurfaces, numDrawSurfaces * sizeof( drawSurfaces[0] ) ); @@ -218,18 +220,19 @@ bool LoadBSPFile( const char *filename ) { return false; } - numbrushsides = CopyLump( header, LUMP_BRUSHES, (void**)&dbrushsides, sizeof( dbrushside_t ) ); - numbrushes = CopyLump( header, LUMP_BRUSHES, (void**)&dbrushes, sizeof( dbrush_t ) ); - numplanes = CopyLump( header, LUMP_PLANES, (void**)&dplanes, sizeof( dplane_t ) ); - numleafs = CopyLump( header, LUMP_LEAFS, (void**)&dleafs, sizeof( dleaf_t ) ); - numnodes = CopyLump( header, LUMP_NODES, (void**)&dnodes, sizeof( dnode_t ) ); - numDrawVerts = CopyLump( header, LUMP_DRAWVERTS, (void**)&drawVerts, sizeof( qdrawVert_t ) ); - numDrawSurfaces = CopyLump( header, LUMP_SURFACES, (void**)&drawSurfaces, sizeof( dsurface_t ) ); - numleafsurfaces = CopyLump( header, LUMP_LEAFSURFACES, (void**)&dleafsurfaces, sizeof( int ) ); - numVisBytes = CopyLump( header, LUMP_VISIBILITY, (void**)&visBytes, 1 ); - numleafbrushes = CopyLump( header, LUMP_LEAFBRUSHES, (void**)&dleafbrushes, sizeof( int ) ); + numbrushsides = CopyLump( header, LUMP_BRUSHES, (void**)&dbrushsides, sizeof( dbrushside_t ) ); + numbrushes = CopyLump( header, LUMP_BRUSHES, (void**)&dbrushes, sizeof( dbrush_t ) ); + numplanes = CopyLump( header, LUMP_PLANES, (void**)&dplanes, sizeof( dplane_t ) ); + numleafs = CopyLump( header, LUMP_LEAFS, (void**)&dleafs, sizeof( dleaf_t ) ); + numnodes = CopyLump( header, LUMP_NODES, (void**)&dnodes, sizeof( dnode_t ) ); + numDrawVerts = CopyLump( header, LUMP_DRAWVERTS, (void**)&drawVerts, sizeof( qdrawVert_t ) ); + numDrawVertsIndices = CopyLump( header, LUMP_DRAWINDEXES, (void**)&drawVertsIndices, sizeof( int ) ); + numDrawSurfaces = CopyLump( header, LUMP_SURFACES, (void**)&drawSurfaces, sizeof( dsurface_t ) ); + numleafsurfaces = CopyLump( header, LUMP_LEAFSURFACES, (void**)&dleafsurfaces, sizeof( int ) ); + numVisBytes = CopyLump( header, LUMP_VISIBILITY, (void**)&visBytes, 1 ); + numleafbrushes = CopyLump( header, LUMP_LEAFBRUSHES, (void**)&dleafbrushes, sizeof( int ) ); - delete header; // everything has been copied out + delete[] header; // everything has been copied out // swap everything SwapBSPFile(); @@ -238,34 +241,16 @@ bool LoadBSPFile( const char *filename ) { } void FreeBSPData(){ - if ( visBytes ) { - delete visBytes; - } - if ( dnodes ) { - delete dnodes; - } - if ( dplanes ) { - delete dplanes; - } - if ( dleafs ) { - delete dleafs; - } - if ( drawVerts ) { - delete drawVerts; - } - if ( drawSurfaces ) { - delete drawSurfaces; - } - if ( dleafsurfaces ) { - delete dleafsurfaces; - } - if ( dleafbrushes ) { - delete dleafbrushes; - } - if ( dbrushes ) { - delete dbrushes; - } - if ( dbrushsides ) { - delete dbrushsides; - } + #define DEL( a ) delete[] a; a = 0; + DEL( visBytes ); + DEL( dnodes ); + DEL( dplanes ); + DEL( dleafs ); + DEL( drawVerts ); + DEL( drawVertsIndices ); + DEL( drawSurfaces ); + DEL( dleafsurfaces ); + DEL( dleafbrushes ); + DEL( dbrushes ); + DEL( dbrushsides ); } diff --git a/contrib/bobtoolz/bsploader.h b/contrib/bobtoolz/bsploader.h index 2ca6a8a7..e88d97a6 100644 --- a/contrib/bobtoolz/bsploader.h +++ b/contrib/bobtoolz/bsploader.h @@ -108,7 +108,7 @@ typedef enum { #define MAX_MAP_VISIBILITY 0x200000 #define MAX_MAP_NODES 0x20000 -#define MAX_MAP_PLANES 0x20000 +#define MAX_MAP_PLANES 0x100000 #define MAX_MAP_LEAFS 0x20000 extern int numVisBytes; @@ -116,6 +116,7 @@ extern int numleafs; extern int numplanes; extern int numnodes; extern int numDrawVerts; +extern int numDrawVertsIndices; extern int numDrawSurfaces; extern int numleafsurfaces; extern int numbrushes; @@ -127,6 +128,7 @@ extern dplane_t *dplanes; extern dleaf_t *dleafs; extern byte *visBytes; extern qdrawVert_t *drawVerts; +extern int *drawVertsIndices; extern dsurface_t *drawSurfaces; extern int *dleafsurfaces; extern dbrush_t *dbrushes; diff --git a/contrib/bobtoolz/funchandlers-GTK.cpp b/contrib/bobtoolz/funchandlers-GTK.cpp index a5c1d4cd..dcba269b 100644 --- a/contrib/bobtoolz/funchandlers-GTK.cpp +++ b/contrib/bobtoolz/funchandlers-GTK.cpp @@ -588,40 +588,6 @@ void DoSplitPatchRows() { } void DoVisAnalyse(){ - char filename[1024]; - - if ( GlobalSelectionSystem().countSelected() == 0 ) { - globalErrorStream() << "bobToolz VisAnalyse: Invalid number of objects selected, choose 1 only.\n"; - if ( g_VisView ) { - delete g_VisView; - return; - } - } - - // ensure we have something selected - if ( GlobalSelectionSystem().countSelected() != 1 ) { - //DoMessageBox("Invalid number of objects selected, choose 1 only", "Error", eMB_OK); - globalErrorStream() << "bobToolz VisAnalyse: Invalid number of objects selected, choose 1 only.\n"; - return; - } - - scene::Instance& brush = GlobalSelectionSystem().ultimateSelected(); - //ensure we have a brush selected - if ( !Node_isBrush( brush.path().top() ) ) { - //DoMessageBox("No brush selected, select ONLY one brush", "Error", eMB_OK); - globalErrorStream() << "bobToolz VisAnalyse: No brush selected, select ONLY 1 brush.\n"; - return; - } - DBrush orgBrush; - orgBrush.LoadFromBrush( brush, false ); - - orgBrush.BuildBounds(); - vec3_t origin; - origin[0] = ( orgBrush.bbox_max[0] + orgBrush.bbox_min[0] ) / 2.f; - origin[1] = ( orgBrush.bbox_max[1] + orgBrush.bbox_min[1] ) / 2.f; - origin[2] = ( orgBrush.bbox_max[2] + orgBrush.bbox_min[2] ) / 2.f; - - const char* rad_filename = GlobalRadiant().getMapName(); if ( !rad_filename ) { //DoMessageBox("An ERROR occurred while trying\n to get the map filename", "Error", eMB_OK); @@ -629,18 +595,31 @@ void DoVisAnalyse(){ return; } + char filename[1024]; strcpy( filename, rad_filename ); char* ext = strrchr( filename, '.' ) + 1; strcpy( ext, "bsp" ); // rename the extension - std::list *pointList = BuildTrace( filename, origin ); + vec3_t origin; + if ( GlobalSelectionSystem().countSelected() == 0 ) { + memcpy( origin, GlobalRadiant().Camera_getOrigin().data(), 3 * sizeof ( ( ( Vector3* ) ( 0 ) ) -> x() ) ); + } + else{ + memcpy( origin, GlobalSelectionSystem().getBoundsSelected().origin.data(), 3 * sizeof ( ( ( Vector3* ) ( 0 ) ) -> x() ) ); + } + + DMetaSurfaces* pointList = BuildTrace( filename, origin ); + + if( pointList && pointList->size() ) + globalOutputStream() << "bobToolz VisAnalyse: " << pointList->size() << " drawsurfaces loaded\n"; if ( !g_VisView ) { g_VisView = new DVisDrawer; } g_VisView->SetList( pointList ); + SceneChangeNotify(); } void DoTrainPathPlot() { diff --git a/contrib/bobtoolz/txt/readme.txt b/contrib/bobtoolz/txt/readme.txt index 5c0feddb..c01be05a 100644 --- a/contrib/bobtoolz/txt/readme.txt +++ b/contrib/bobtoolz/txt/readme.txt @@ -24,7 +24,7 @@ Files Contained In This Package: Readme.txt --- This file. Changelog.txt --- Version information. -bobToolz.dll --- The plugin itsself. +bobToolz.dll --- The plugin itself. bt/*.txt --- A few text files required by the plugin. diff --git a/contrib/bobtoolz/visfind.cpp b/contrib/bobtoolz/visfind.cpp index 33aa5bc8..4c23d314 100644 --- a/contrib/bobtoolz/visfind.cpp +++ b/contrib/bobtoolz/visfind.cpp @@ -4,8 +4,8 @@ #include "visfind.h" #include "dialogs/dialogs-gtk.h" -#include "DWinding.h" #include "bsploader.h" +#include "DVisDrawer.h" #include @@ -127,9 +127,7 @@ int bsp_countclusters_mask( byte *bitvector, byte *maskvector, int length ){ return( c ); } -void AddCluster( std::list *pointlist, dleaf_t *cl, bool* repeatlist, vec3_t clr ){ - DWinding* w; - +void AddCluster( DMetaSurfaces* pointlist, dleaf_t *cl, bool* repeatlist, const vec3_t clr ){ int* leafsurf = &dleafsurfaces[cl->firstLeafSurface]; for ( int k = 0; k < cl->numLeafSurfaces; k++, leafsurf++ ) { @@ -147,20 +145,15 @@ void AddCluster( std::list *pointlist, dleaf_t *cl, bool* repeatli DoMessageBox( "Warning", "Warning", eMB_OK ); } - w = new DWinding(); - w->AllocWinding( surf->numVerts ); + DMetaSurf* meta = new DMetaSurf( surf->numVerts, surf->numIndexes ); - for ( int l = 0; l < surf->numVerts; l++, vert++ ) - { - ( w->p[l] )[0] = vert->xyz[0]; - ( w->p[l] )[1] = vert->xyz[1]; - ( w->p[l] )[2] = vert->xyz[2]; + for ( int l = 0; l < surf->numIndexes; ++l ) + meta->indices[l] = drawVertsIndices[ surf->firstIndex + l ]; + for ( int l = 0; l < surf->numVerts; ++l, ++vert ) + VectorCopy( vert->xyz, meta->verts[l] ); + VectorCopy( clr, meta->colour ); - w->clr[0] = clr[0]; - w->clr[1] = clr[1]; - w->clr[2] = clr[2]; - } - pointlist->push_back( w ); + pointlist->push_back( meta ); repeatlist[*leafsurf] = true; } @@ -171,22 +164,14 @@ void AddCluster( std::list *pointlist, dleaf_t *cl, bool* repeatli CreateTrace ============= */ -std::list *CreateTrace( dleaf_t *leaf, int c, vis_header *header, byte *visdata, byte *seen ){ +DMetaSurfaces *CreateTrace( dleaf_t *leaf, int c, vis_header *header, byte *visdata, byte *seen ){ byte *vis; int i, j, clusterNum; - std::list *pointlist = new std::list; + DMetaSurfaces* pointlist = new DMetaSurfaces; bool* repeatlist = new bool[numDrawSurfaces]; dleaf_t *cl; - vec3_t clrRnd[5] = { - {0.f, 0.f, 1.f}, - {0.f, 1.f, 1.f}, - {1.f, 0.f, 0.f}, - {1.f, 0.f, 1.f}, - {1.f, 1.f, 0.f}, - }; - - vec3_t clrGreen = {0.f, 1.f, 0.f}; + const vec3_t clrGreen = {0.f, 1.f, 0.f}; memset( repeatlist, 0, sizeof( bool ) * numDrawSurfaces ); @@ -203,7 +188,16 @@ std::list *CreateTrace( dleaf_t *leaf, int c, vis_header *header, byt cl = &( dleafs[bsp_leafnumforcluster( clusterNum )] ); if ( ( *( vis + i ) & ( 1 << j ) ) && ( *( seen + i ) & ( 1 << j ) ) && ( leaf->area == cl->area ) ) { - AddCluster( pointlist, cl, repeatlist, clrRnd[rand() % 5] ); + vec3_t clr; + do { + VectorSet( clr, + ( rand() % 256 ) / 255.f, + ( rand() % 256 ) / 255.f, + ( rand() % 256 ) / 255.f ); + }while( ( clr[0] + clr[2] < clr[1] * 1.5f ) || //too green + ( clr[0] < .3 && clr[1] < .3 && clr[2] < .3 ) ); //too dark + + AddCluster( pointlist, cl, repeatlist, clr ); } clusterNum++; } @@ -221,7 +215,7 @@ std::list *CreateTrace( dleaf_t *leaf, int c, vis_header *header, byt setup for CreateTrace ============= */ -std::list *TraceCluster( int leafnum ){ +DMetaSurfaces* TraceCluster( int leafnum ){ byte seen[( MAX_MAP_LEAFS / 8 ) + 1]; vis_header *vheader; byte *visdata; @@ -238,14 +232,26 @@ std::list *TraceCluster( int leafnum ){ return CreateTrace( leaf, leaf->cluster, vheader, visdata, seen ); } -std::list* BuildTrace( char* filename, vec3_t v_origin ){ +DMetaSurfaces* BuildTrace( char* filename, vec3_t v_origin ){ if ( !LoadBSPFile( filename ) ) { return NULL; } + if( numVisBytes == 0 ){ + FreeBSPData(); + globalErrorStream() << "bobToolz VisAnalyse: Bsp has no visibility data!\n"; + return 0; + } + int leafnum = bsp_leafnumfororigin( v_origin ); - std::list *pointlist = TraceCluster( leafnum ); + if( dleafs[leafnum].cluster == -1 ){ + FreeBSPData(); + globalErrorStream() << "bobToolz VisAnalyse: Point of interest is in the void!\n"; + return 0; + } + + DMetaSurfaces* pointlist = TraceCluster( leafnum ); FreeBSPData(); diff --git a/contrib/bobtoolz/visfind.h b/contrib/bobtoolz/visfind.h index 54b3660d..0929258c 100644 --- a/contrib/bobtoolz/visfind.h +++ b/contrib/bobtoolz/visfind.h @@ -2,6 +2,7 @@ #include #include "mathlib.h" -class DWinding; +class DMetaSurf; +typedef std::list DMetaSurfaces; -std::list *BuildTrace( char* filename, vec3_t v_origin ); +DMetaSurfaces* BuildTrace( char* filename, vec3_t v_origin ); diff --git a/include/qerplugin.h b/include/qerplugin.h index 3c1db046..0132ff5b 100644 --- a/include/qerplugin.h +++ b/include/qerplugin.h @@ -149,6 +149,9 @@ struct _QERFuncTable_1 void ( *XYWindowMouseDown_disconnect )( MouseEventHandlerId id ); VIEWTYPE ( *XYWindow_getViewType )(); Vector3 ( *XYWindow_windowToWorld )( const WindowVector& position ); + + Vector3 ( *Camera_getOrigin )(); + const char* ( *TextureBrowser_getSelectedShader )( ); // GTK+ functions diff --git a/radiant/plugin.cpp b/radiant/plugin.cpp index f94ecb0d..addd404d 100644 --- a/radiant/plugin.cpp +++ b/radiant/plugin.cpp @@ -109,6 +109,10 @@ Vector3 XYWindow_windowToWorld( const WindowVector& position ){ return result; } +Vector3 Camera_getOrigin(){ + return Camera_getOrigin( *g_pParentWnd->GetCamWnd() ); +} + class RadiantCoreAPI { _QERFuncTable_1 m_radiantcore; @@ -149,6 +153,9 @@ RadiantCoreAPI(){ m_radiantcore.XYWindowMouseDown_disconnect = XYWindowMouseDown_disconnect; m_radiantcore.XYWindow_getViewType = XYWindow_getViewType; m_radiantcore.XYWindow_windowToWorld = XYWindow_windowToWorld; + + m_radiantcore.Camera_getOrigin = Camera_getOrigin; + m_radiantcore.TextureBrowser_getSelectedShader = TextureBrowser_GetSelectedShader; m_radiantcore.m_pfnMessageBox = >k_MessageBox;