mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 12:44:46 +00:00
Fixed handling of convex shape editor's active and default materials Fixed assignment of material for convex shapes via editor Fixed material editor map assignment logic Added utility function to detect possible duplicate files in project to ProjectImporter Added conversion of legacy sky and water classes to importer Fixed bufferLen issue with guiTreeViewCtrl
460 lines
13 KiB
C++
460 lines
13 KiB
C++
//-----------------------------------------------------------------------------
|
|
// Copyright (c) 2012 GarageGames, LLC
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to
|
|
// deal in the Software without restriction, including without limitation the
|
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
// sell copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
// IN THE SOFTWARE.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "platform/platform.h"
|
|
#include "postFx/postEffectVis.h"
|
|
#include "gui/containers/guiWindowCtrl.h"
|
|
#include "gui/controls/guiBitmapCtrl.h"
|
|
#include "gui/core/guiCanvas.h"
|
|
#include "postFx/postEffectManager.h"
|
|
#include "core/module.h"
|
|
|
|
ConsoleDoc(
|
|
"@class PfxVis\n"
|
|
"@brief Singleton class that exposes ConsoleStaticFunctions for debug visualizing PostEffects.\n\n"
|
|
"@tsexample\n"
|
|
"// Script interface...\n"
|
|
"PfxVis::open( PostEffect ) // Multiple PostEffects can be visualized at the same time\n"
|
|
"PfxVis::clear() // Clear all visualizer windows\n"
|
|
"PfxVis::hide() // Hide all windows (are not destroyed)\n"
|
|
"PfxVis::show()\n"
|
|
"@endtsexample\n\n"
|
|
"@ingroup GFX\n"
|
|
);
|
|
|
|
IMPLEMENT_STATIC_CLASS(PfxVis, , "")
|
|
|
|
MODULE_BEGIN( PostEffectVis )
|
|
|
|
MODULE_INIT
|
|
{
|
|
ManagedSingleton< PostEffectVis >::createSingleton();
|
|
}
|
|
|
|
MODULE_SHUTDOWN
|
|
{
|
|
ManagedSingleton< PostEffectVis >::deleteSingleton();
|
|
}
|
|
|
|
MODULE_END;
|
|
|
|
|
|
PostEffectVis::PostEffectVis()
|
|
: mContent( NULL )
|
|
{
|
|
}
|
|
|
|
PostEffectVis::~PostEffectVis()
|
|
{
|
|
}
|
|
|
|
void PostEffectVis::open( PostEffect *pfx )
|
|
{
|
|
GuiControl *content = _getContentControl();
|
|
|
|
// If we already have this PostEffect added
|
|
// remove it first so we can recreate its controls.
|
|
VisVector::iterator itr = mWindows.begin();
|
|
for ( ; itr != mWindows.end(); itr++ )
|
|
{
|
|
if ( itr->pfx == pfx )
|
|
{
|
|
for ( U32 i = 0; i < TexCount; i++ )
|
|
{
|
|
// Deleting the GuiWindowCtrl will automatically also delete
|
|
// any child controls we have allocated.
|
|
if ( itr->window[i] )
|
|
itr->window[i]->deleteObject();
|
|
}
|
|
|
|
mWindows.erase_fast( itr );
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Allocate VisWindow struct.
|
|
mWindows.increment();
|
|
VisWindow &window = mWindows.last();
|
|
window.pfx = pfx;
|
|
|
|
for ( U32 i = 0; i < TexCount; i++ )
|
|
{
|
|
// Only allocate window/bitmaps for input textures that are actually used.
|
|
if ( i > Target )
|
|
{
|
|
if ( pfx->mTextureName[i-1] == StringTable->EmptyString())
|
|
{
|
|
window.window[i] = NULL;
|
|
window.bmp[i] = NULL;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Allocate GuiWindowCtrl
|
|
GuiWindowCtrl *winCtrl = new GuiWindowCtrl();
|
|
winCtrl->setPosition( Point2I( 50, 50 ) + Point2I( 15, 15 ) * i );
|
|
winCtrl->setExtent( 347, 209 );
|
|
winCtrl->setMinExtent( Point2I( 150, 100 ) );
|
|
winCtrl->setMobility( true, true, true, true, false, false );
|
|
winCtrl->setCanResize( true, true );
|
|
winCtrl->setDataField( StringTable->insert( "closeCommand" ), NULL, "PfxVis::onWindowClosed( $ThisControl );" );
|
|
winCtrl->registerObject();
|
|
|
|
window.window[i] = winCtrl;
|
|
|
|
_setDefaultCaption( window, i );
|
|
|
|
// Allocate background GuiBitmapCtrl
|
|
GuiBitmapCtrl *bmpCtrl = new GuiBitmapCtrl();
|
|
bmpCtrl->setPosition( 3, 23 );
|
|
bmpCtrl->setSizing( GuiControl::horizResizeWidth, GuiControl::vertResizeHeight );
|
|
bmpCtrl->setExtent( 341, 181 );
|
|
bmpCtrl->setDataField( StringTable->insert( "wrap" ), NULL, "1" );
|
|
bmpCtrl->setBitmap( "ToolsModule:transp_grid_image" );
|
|
bmpCtrl->registerObject();
|
|
winCtrl->addObject( bmpCtrl );
|
|
|
|
// Allocate GuiBitmapCtrl
|
|
bmpCtrl = new GuiBitmapCtrl();
|
|
bmpCtrl->setPosition( 3, 23 );
|
|
bmpCtrl->setSizing( GuiControl::horizResizeWidth, GuiControl::vertResizeHeight );
|
|
bmpCtrl->setExtent( 341, 181 );
|
|
bmpCtrl->registerObject();
|
|
winCtrl->addObject( bmpCtrl );
|
|
|
|
window.bmp[i] = bmpCtrl;
|
|
|
|
content->addObject( winCtrl );
|
|
}
|
|
|
|
// Make sure we visible.
|
|
setVisible( true );
|
|
}
|
|
|
|
void PostEffectVis::setVisible( bool visible )
|
|
{
|
|
GuiCanvas *canvas = NULL;
|
|
if ( !Sim::findObject( "Canvas", canvas ) )
|
|
{
|
|
Con::errorf( "PostEffectVis::setVisible, Canvas was not found." );
|
|
return;
|
|
}
|
|
|
|
GuiControl *content = _getContentControl();
|
|
|
|
if ( visible && !content->isAwake() )
|
|
canvas->pushDialogControl( content, 100 );
|
|
|
|
if ( !visible && content->isAwake() )
|
|
canvas->popDialogControl( content );
|
|
}
|
|
|
|
void PostEffectVis::clear()
|
|
{
|
|
GuiControl *content = _getContentControl();
|
|
|
|
content->clear();
|
|
mWindows.clear();
|
|
}
|
|
|
|
void PostEffectVis::onStartOfFrame()
|
|
{
|
|
if ( mWindows.empty() )
|
|
return;
|
|
if ( !_getContentControl()->isAwake() )
|
|
return;
|
|
|
|
// Restore vis windows to a default state.
|
|
// This ensures to users that open PostEffects that are not
|
|
// actively being processed are obvious.
|
|
|
|
VisVector::iterator itr = mWindows.begin();
|
|
for ( ; itr != mWindows.end(); itr++ )
|
|
{
|
|
for ( U32 i = 0; i < TexCount; i++ )
|
|
{
|
|
if ( !itr->bmp[i] || itr->pfx->getRenderTime() == PFXTexGenOnDemand )
|
|
continue;
|
|
|
|
itr->bmp[i]->setBitmap( NULL );
|
|
_setDefaultCaption( *itr, i );
|
|
}
|
|
}
|
|
}
|
|
|
|
void PostEffectVis::onPFXProcessed( PostEffect *pfx )
|
|
{
|
|
// If we have no windows we can early out before even testing
|
|
// isAwake so we avoid creating the content control unnecessarily.
|
|
if ( mWindows.empty() )
|
|
return;
|
|
|
|
if ( !_getContentControl()->isAwake() )
|
|
return;
|
|
|
|
VisVector::iterator itr = mWindows.begin();
|
|
for ( ; itr != mWindows.end(); itr++ )
|
|
{
|
|
if ( itr->pfx == pfx )
|
|
{
|
|
GuiBitmapCtrl *pBmpCtrl = NULL;
|
|
GuiWindowCtrl *pWinCtrl = NULL;
|
|
|
|
if ( itr->bmp[Target] != NULL )
|
|
{
|
|
pBmpCtrl = itr->bmp[Target];
|
|
pWinCtrl = itr->window[Target];
|
|
|
|
GFXTextureObject *tex;
|
|
|
|
if ( pfx->mTargetTex )
|
|
tex = pfx->mTargetTex;
|
|
else
|
|
tex = PFXMGR->getBackBufferTex();
|
|
|
|
pBmpCtrl->setBitmapHandle( tex );
|
|
|
|
char caption[256];
|
|
char name[256];
|
|
|
|
if ( pfx->getName() == NULL || dStrlen( pfx->getName() ) == 0 )
|
|
dSprintf( name, 256, "(none)" );
|
|
else
|
|
dSprintf( name, 256, "%s", pfx->getName() );
|
|
|
|
|
|
if ( tex )
|
|
dSprintf( caption, 256, "%s[%i] target - %s [ %ix%i ]", name, pfx->getId(), pfx->mTargetName.c_str(), tex->getWidth(), tex->getHeight() );
|
|
else
|
|
dSprintf( caption, 256, "%s[%i] target", name, pfx->getId() );
|
|
|
|
|
|
pWinCtrl->setDataField( StringTable->insert("text"), NULL, caption );
|
|
}
|
|
|
|
for ( U32 i = Input1; i < TexCount; i++ )
|
|
{
|
|
if ( itr->bmp[i] == NULL )
|
|
continue;
|
|
|
|
pBmpCtrl = itr->bmp[i];
|
|
pWinCtrl = itr->window[i];
|
|
|
|
GFXTextureObject *tex = pfx->mActiveTextures[i-1];
|
|
|
|
pBmpCtrl->setBitmapHandle( tex );
|
|
|
|
char caption[256];
|
|
char name[256];
|
|
|
|
if ( pfx->getName() == NULL || dStrlen( pfx->getName() ) == 0 )
|
|
dSprintf( name, 256, "(none)" );
|
|
else
|
|
dSprintf( name, 256, "%s", pfx->getName() );
|
|
|
|
|
|
if ( tex )
|
|
dSprintf( caption, 256, "%s[%i] input%i - %s [ %ix%i ]", name, pfx->getId(), i-1, pfx->mTextureName[i-1], tex->getWidth(), tex->getHeight() );
|
|
else
|
|
dSprintf( caption, 256, "%s[%i] input%i - %s", name, pfx->getId(), i-1, pfx->mTextureName[i-1] );
|
|
|
|
pWinCtrl->setDataField( StringTable->insert("text"), NULL, caption );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void PostEffectVis::onWindowClosed( GuiWindowCtrl *ctrl )
|
|
{
|
|
VisVector::iterator itr = mWindows.begin();
|
|
|
|
for ( ; itr != mWindows.end(); itr++ )
|
|
{
|
|
for ( U32 i = 0; i < TexCount; i++ )
|
|
{
|
|
if ( itr->window[i] == ctrl )
|
|
{
|
|
itr->window[i] = NULL;
|
|
itr->bmp[i] = NULL;
|
|
ctrl->setVisible( false );
|
|
|
|
// Avoid deleting immediately since this happens in response to a
|
|
// script callback.
|
|
Con::evaluate( "%i.schedule( 1, \"delete\" );" );
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
Con::errorf( "PostEffectVis::onWindowClosed, passed window (%s) [%i] was found.", StringTable->insert( ctrl->getName() ), ctrl->getId() );
|
|
}
|
|
|
|
GuiControl* PostEffectVis::_getContentControl()
|
|
{
|
|
if ( mContent == NULL )
|
|
{
|
|
GuiCanvas *canvas = NULL;
|
|
if ( !Sim::findObject( "Canvas", canvas ) )
|
|
{
|
|
AssertFatal( false, "PostEffectVis::_getContentControl, Canvas not found." );
|
|
return NULL;
|
|
}
|
|
|
|
mContent = new GuiControl();
|
|
mContent->setPosition( 0, 0 );
|
|
mContent->setExtent( 1024, 768 );
|
|
mContent->setDataField( StringTable->insert( "noCursor" ), NULL, "1" );
|
|
mContent->setDataField( StringTable->insert( "profile" ), NULL, "GuiModelessDialogProfile" );
|
|
mContent->registerObject( "PfxVisContent" );
|
|
|
|
canvas->pushDialogControl( mContent, 100 );
|
|
}
|
|
|
|
return mContent;
|
|
}
|
|
|
|
void PostEffectVis::_setDefaultCaption( VisWindow &vis, U32 texIndex )
|
|
{
|
|
PostEffect *pfx = vis.pfx;
|
|
GuiWindowCtrl *winCtrl = vis.window[texIndex];
|
|
|
|
if ( texIndex == Target )
|
|
{
|
|
char caption[256];
|
|
char name[256];
|
|
|
|
if ( pfx->getName() == NULL || dStrlen( pfx->getName() ) == 0 )
|
|
dSprintf( name, 256, "(none)" );
|
|
else
|
|
dSprintf( name, 256, "%s", pfx->getName() );
|
|
|
|
dSprintf( caption, 256, "%s[%i] target [NOT ENABLED]", name, pfx->getId() );
|
|
|
|
winCtrl->setDataField( StringTable->insert("text"), NULL, caption );
|
|
}
|
|
else
|
|
{
|
|
char caption[256];
|
|
char name[256];
|
|
|
|
if ( pfx->getName() == NULL || dStrlen( pfx->getName() ) == 0 )
|
|
dSprintf( name, 256, "(none)" );
|
|
else
|
|
dSprintf( name, 256, "%s", pfx->getName() );
|
|
|
|
dSprintf( caption, 256, "%s[%i] input%i - %s [NOT ENABLED]", name, pfx->getId(), texIndex-1, pfx->mTextureName[texIndex-1] );
|
|
|
|
winCtrl->setDataField( StringTable->insert("text"), NULL, caption );
|
|
}
|
|
}
|
|
|
|
static ConsoleDocFragment _PfxVisclear(
|
|
"@brief Close all visualization windows.\n\n"
|
|
"@tsexample\n"
|
|
"PfxVis::clear();"
|
|
"@endtsexample\n\n",
|
|
"PfxVis",
|
|
"void clear();" );
|
|
|
|
|
|
DefineEngineStaticMethod( PfxVis, clear, void, (),,
|
|
"@hide")
|
|
{
|
|
PFXVIS->clear();
|
|
}
|
|
|
|
static ConsoleDocFragment _PfxVisopen(
|
|
"@brief Open visualization windows for all input and target textures.\n\n"
|
|
"@param effect Name of the PostEffect to open\n"
|
|
"@param clear True to close all visualization windows before opening the effect\n\n"
|
|
"@tsexample\n"
|
|
"// Multiple PostEffects can be visualized at the same time\n"
|
|
"PfxVis::open( PostEffect )\n"
|
|
"@endtsexample\n\n",
|
|
"PfxVis",
|
|
"void open(PostEffect effect, bool clear);" );
|
|
|
|
DefineEngineStaticMethod( PfxVis, open, void, (PostEffect* pfx, bool clear), (false), "( PostEffect, [bool clear = false] )"
|
|
"@hide")
|
|
{
|
|
if ( clear )
|
|
PFXVIS->clear();
|
|
|
|
if ( !pfx )
|
|
{
|
|
Con::errorf( "PfxVis::add, argument was not a PostEffect");
|
|
return;
|
|
}
|
|
|
|
PFXVIS->open( pfx );
|
|
}
|
|
|
|
static ConsoleDocFragment _PfxVishide(
|
|
"@brief Hide all visualization windows (they are not destroyed).\n\n"
|
|
"@tsexample\n"
|
|
"PfxVis::hide();"
|
|
"@endtsexample\n\n",
|
|
"PfxVis",
|
|
"void hide();" );
|
|
|
|
DefineEngineStaticMethod( PfxVis, hide, void, (),,
|
|
"@hide")
|
|
{
|
|
PFXVIS->setVisible( false );
|
|
}
|
|
|
|
static ConsoleDocFragment _PfxVisshow(
|
|
"@brief Show all visualization windows.\n\n"
|
|
"@tsexample\n"
|
|
"PfxVis::show();"
|
|
"@endtsexample\n\n",
|
|
"PfxVis",
|
|
"void show();" );
|
|
|
|
DefineEngineStaticMethod( PfxVis, show, void, (),,
|
|
"@hide")
|
|
{
|
|
PFXVIS->setVisible( true );
|
|
}
|
|
|
|
static ConsoleDocFragment _PfxVisonWindowClosed(
|
|
"@brief Callback when a visualization window is closed.\n\n"
|
|
"@param ctrl Name of the GUI control being closed\n"
|
|
"@tsexample\n"
|
|
"PfxVis::onWindowClosed( VisWindow )\n"
|
|
"@endtsexample\n\n",
|
|
"PfxVis",
|
|
"void onWindowClosed(GuiWindowCtrl *ctrl);" );
|
|
|
|
DefineEngineStaticMethod( PfxVis, onWindowClosed, void, (GuiWindowCtrl* ctrl),,
|
|
"@hide")
|
|
{
|
|
if ( !ctrl )
|
|
{
|
|
Con::errorf( "PfxVis::onWindowClosed, argument was not a GuiWindowCtrl");
|
|
return;
|
|
}
|
|
|
|
PFXVIS->onWindowClosed( ctrl );
|
|
}
|