/*==LICENSE==*
CyanWorlds . com Engine - MMOG client , server and tools
Copyright ( C ) 2011 Cyan Worlds , Inc .
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
You can contact Cyan Worlds , Inc . by email legal @ cyan . com
or by snail mail at :
Cyan Worlds , Inc .
14617 N Newport Hwy
Mead , WA 99021
* = = LICENSE = = */
///////////////////////////////////////////////////////////////////////////////
// //
// plLayerConverter - Utility class that converts plPlasmaMAXLayers into //
// other stuff. //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 1.13.2002 mcn - Created. //
// //
//// Notes ////////////////////////////////////////////////////////////////////
// //
// If you add a new PlasmaMAXLayer type, you need to add the appropriate //
// test in ConvertTexmap() as well as your own function to do the //
// conversion. Messy, but thanks to the dependencies of the convert process,//
// we can't do it the nice, pretty, OOP way. //
// //
///////////////////////////////////////////////////////////////////////////////
# include "hsWindows.h"
# include "Max.h"
# include "stdmat.h"
# include "istdplug.h"
# include "iparamb2.h"
# include "iparamm2.h"
# include "hsUtils.h"
# include "hsExceptionStack.h"
# include "plLayerConverter.h"
# include "../MaxConvert/hsMaxLayerBase.h"
# include "../MaxConvert/hsConverterUtils.h"
# include "../MaxConvert/hsControlConverter.h"
# include "../MaxConvert/hsMaterialConverter.h"
# include "../MaxConvert/plBitmapCreator.h"
# include "hsResMgr.h"
# include "../MaxExport/plErrorMsg.h"
# include "../MaxMain/plMaxNode.h"
# include "../pnKeyedObject/plUoid.h"
# include "../pnKeyedObject/plKey.h"
# include "../pnSceneObject/plSceneObject.h"
# include "../plSurface/plLayerInterface.h"
# include "../plSurface/plLayer.h"
# include "../pnMessage/plRefMsg.h"
# include "../pnMessage/plObjRefMsg.h"
# include "../plMessage/plLayRefMsg.h"
# include "../plDrawable/plGeometrySpan.h"
# include "../plGImage/plMipmap.h"
# include "../plGImage/plDynamicTextMap.h"
# include "../plGImage/plCubicEnvironmap.h"
# include "../plPipeline/plCubicRenderTarget.h"
# include "../plPipeline/plCubicRenderTargetModifier.h"
# include "../plPipeline/plDynamicEnvMap.h"
# include "../pfSurface/plLayerAVI.h"
# include "../pfSurface/plLayerBink.h"
# include "../MaxPlasmaMtls/Layers/plPlasmaMAXLayer.h"
# include "../MaxPlasmaMtls/Layers/plLayerTex.h"
# include "../MaxPlasmaMtls/Layers/plLayerTexBasicPB.h"
# include "../MaxPlasmaMtls/Layers/plLayerTexBitmapPB.h"
# include "../MaxPlasmaMtls/Layers/plStaticEnvLayer.h"
# include "../MaxPlasmaMtls/Layers/plDynamicEnvLayer.h"
# include "../MaxPlasmaMtls/Layers/plDynamicTextLayer.h"
# include "../MaxPlasmaMtls/Layers/plAngleAttenLayer.h"
# include "../MaxPlasmaMtls/Layers/plMAXCameraLayer.h"
# include "../MaxComponent/plComponent.h"
# include "../MaxComponent/plWaterComponent.h"
# include "../pfCamera/plCameraModifier.h"
//// Local Static Stuff ///////////////////////////////////////////////////////
namespace
{
enum {
kWarnedTooManyUVs = 0x01 ,
kWarnedNoBaseTexture = 0x02 ,
kWarnedUpperTextureMissing = 0x04 ,
kWarnedNoUpperTexture = 0x08 ,
} ;
const char sWarnBaseTextureMissing [ ] = " The object \" %s \" 's material has a base layer that is assigned texture \" %s \" , but the texture file is missing. "
" This can cause unwanted effects during runtime. " ;
const char sWarnUpperTextureMissing [ ] = " The object \" %s \" 's material has an upper layer that is assigned texture \" %s \" , but the texture file is missing. "
" This is not supported in the engine, so the upper layer will be ignored. " ;
const char sWarnNoUpperTexture [ ] = " The object \" %s \" 's material has an uppper layer that is not assigned a texture. "
" This is not supported in the engine, so the upper layer will be disabled. " ;
}
//// Constructor/Destructor ///////////////////////////////////////////////////
plLayerConverter : : plLayerConverter ( ) :
fInterface ( nil ) ,
fConverterUtils ( hsConverterUtils : : Instance ( ) )
{
fErrorMsg = nil ;
fWarned = 0 ;
fSaving = false ;
}
plLayerConverter : : ~ plLayerConverter ( )
{
}
plLayerConverter & plLayerConverter : : Instance ( void )
{
hsGuardBegin ( " plLayerConverter::Instance " ) ;
static plLayerConverter instance ;
return instance ;
hsGuardEnd ;
}
void plLayerConverter : : Init ( hsBool save , plErrorMsg * msg )
{
fSaving = save ;
fErrorMsg = msg ;
fWarned = 0 ;
fInterface = GetCOREInterface ( ) ;
}
void plLayerConverter : : DeInit ( void )
{
int i ;
for ( i = 0 ; i < fConvertedLayers . GetCount ( ) ; i + + )
{
if ( fConvertedLayers [ i ] ! = nil )
fConvertedLayers [ i ] - > IClearConversionTargets ( ) ;
}
fConvertedLayers . Reset ( ) ;
}
//// Mute/Unmute Warnings /////////////////////////////////////////////////////
void plLayerConverter : : MuteWarnings ( void )
{
fSavedWarned = fWarned ;
fWarned | = kWarnedNoBaseTexture | kWarnedUpperTextureMissing ;
}
void plLayerConverter : : UnmuteWarnings ( void )
{
fWarned = fSavedWarned ;
}
///////////////////////////////////////////////////////////////////////////////
//// Main Switcheroo //////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//// ConvertTexmap ////////////////////////////////////////////////////////////
plLayerInterface * plLayerConverter : : ConvertTexmap ( Texmap * texmap ,
plMaxNode * maxNode ,
UInt32 blendFlags , hsBool preserveUVOffset ,
hsBool upperLayer )
{
hsGuardBegin ( " plLayerConverter::ConvertTexmap " ) ;
fDbgNodeName = maxNode - > GetName ( ) ;
// We only convert plPlasmaMAXLayers
plPlasmaMAXLayer * layer = plPlasmaMAXLayer : : GetPlasmaMAXLayer ( texmap ) ;
if ( layer = = nil )
{
fErrorMsg - > Set ( true , " Plasma Layer Error " , " Cannot convert layer '%s'--unrecognized MAX layer type " , texmap - > GetName ( ) ) ;
fErrorMsg - > Show ( ) ;
fErrorMsg - > Set ( ) ;
return nil ;
}
// KLUDGE - Some things don't set the name for their layers (ie projected
// runtime lights). So that we don't end up with an empty keyname, set the
// name to the nodes name if there isn't one. -Colin
const char * layerName = layer - > GetName ( ) ;
if ( ! layerName | | layerName [ 0 ] = = ' \0 ' )
layer - > SetName ( maxNode - > GetName ( ) ) ;
// Switch on the class ID
plLayerInterface * plasmaLayer = nil ;
if ( layer - > ClassID ( ) = = LAYER_TEX_CLASS_ID )
plasmaLayer = IConvertLayerTex ( layer , maxNode , blendFlags , preserveUVOffset , upperLayer ) ;
else if ( layer - > ClassID ( ) = = STATIC_ENV_LAYER_CLASS_ID )
plasmaLayer = IConvertStaticEnvLayer ( layer , maxNode , blendFlags , preserveUVOffset , upperLayer ) ;
else if ( layer - > ClassID ( ) = = DYNAMIC_ENV_LAYER_CLASS_ID )
plasmaLayer = IConvertDynamicEnvLayer ( layer , maxNode , blendFlags , preserveUVOffset , upperLayer ) ;
else if ( layer - > ClassID ( ) = = DYN_TEXT_LAYER_CLASS_ID )
plasmaLayer = IConvertDynamicTextLayer ( layer , maxNode , blendFlags , preserveUVOffset , upperLayer ) ;
else if ( layer - > ClassID ( ) = = ANGLE_ATTEN_LAYER_CLASS_ID )
plasmaLayer = IConvertAngleAttenLayer ( layer , maxNode , blendFlags , preserveUVOffset , upperLayer ) ;
else if ( layer - > ClassID ( ) = = MAX_CAMERA_LAYER_CLASS_ID )
plasmaLayer = IConvertCameraLayer ( layer , maxNode , blendFlags , preserveUVOffset , upperLayer ) ;
IRegisterConversion ( layer , plasmaLayer ) ;
return plasmaLayer ;
hsGuardEnd ;
}
//// IRegisterConversion //////////////////////////////////////////////////////
void plLayerConverter : : IRegisterConversion ( plPlasmaMAXLayer * origLayer , plLayerInterface * convertedLayer )
{
if ( convertedLayer = = nil )
return ;
// Add this to our list of converted layers (so we can clean them up later)
if ( fConvertedLayers . Find ( origLayer ) = = fConvertedLayers . kMissingIndex )
fConvertedLayers . Append ( origLayer ) ;
// Now add the converted layer to that layer's list of conversion targets.
// (easier than us keeping a huge lookup table, since this is *acting*
// as that lookup table more or less)
origLayer - > IAddConversionTarget ( convertedLayer ) ;
}
///////////////////////////////////////////////////////////////////////////////
//// Main Processing Functions ////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//// IConvertLayerTex /////////////////////////////////////////////////////////
plLayerInterface * plLayerConverter : : IConvertLayerTex ( plPlasmaMAXLayer * layer ,
plMaxNode * maxNode , UInt32 blendFlags ,
hsBool preserveUVOffset , hsBool upperLayer )
{
hsGuardBegin ( " plLayerConverter::IConvertLayerTex " ) ;
IParamBlock2 * bitmapPB ;
plLocation loc ;
loc = maxNode - > GetLocation ( ) ;
bitmapPB = layer - > GetParamBlockByID ( plLayerTex : : kBlkBitmap ) ;
if ( ! bitmapPB )
{
fErrorMsg - > Set ( ! bitmapPB , " Plasma Layer Error " , " Bitmap paramblock for Plasma Layer not found " ) . Show ( ) ;
fErrorMsg - > Set ( ) ;
return nil ;
}
// Get a new layer to play with
plLayer * plasmaLayer = ICreateLayer ( layer - > GetName ( ) , upperLayer , loc ) ;
// We're using a texture, try and get its info
PBBitmap * pbbm = nil ;
BitmapInfo * bi = nil ;
if ( bitmapPB - > GetInt ( kBmpUseBitmap ) )
{
if ( bitmapPB )
pbbm = bitmapPB - > GetBitmap ( kBmpBitmap ) ;
if ( pbbm )
bi = & pbbm - > bi ;
}
// If the texture had bad info, assert and return the empty layer
if ( ! bi | | ! bi - > Name ( ) | | ! strcmp ( bi - > Name ( ) , " " ) )
{
if ( upperLayer )
{
if ( fErrorMsg - > Set ( ! ( fWarned & kWarnedNoUpperTexture ) , " Plasma Export Error " , sWarnNoUpperTexture , maxNode - > GetName ( ) ) . CheckAskOrCancel ( ) )
fWarned | = kWarnedNoUpperTexture ;
fErrorMsg - > Set ( false ) ;
delete plasmaLayer ;
return nil ;
}
else
{
return ( plLayerInterface * ) plasmaLayer ;
}
}
// Setup the texture creation parameters
plBitmapData bd ;
bd . fileName = bi - > Name ( ) ;
// Create texture and add it to list if unique
Int32 texFlags = 0 ; //hsGTexture::kMipMap;
// Texture Alpha/Color
if ( bitmapPB - > GetInt ( kBmpInvertColor ) )
plasmaLayer - > SetBlendFlags ( plasmaLayer - > GetBlendFlags ( ) | hsGMatState : : kBlendInvertColor ) ;
if ( bitmapPB - > GetInt ( kBmpDiscardColor ) )
plasmaLayer - > SetBlendFlags ( plasmaLayer - > GetBlendFlags ( ) | hsGMatState : : kBlendNoTexColor ) ;
if ( bitmapPB - > GetInt ( kBmpDiscardAlpha ) )
plasmaLayer - > SetBlendFlags ( plasmaLayer - > GetBlendFlags ( ) | hsGMatState : : kBlendNoTexAlpha ) ;
if ( bitmapPB - > GetInt ( kBmpInvertAlpha ) )
bd . invertAlpha = true ;
// Texture quality
if ( bitmapPB - > GetInt ( kBmpNonCompressed ) )
texFlags | = plBitmap : : kForceNonCompressed ;
if ( bitmapPB - > GetInt ( kBmpNoDiscard ) )
texFlags | = plBitmap : : kDontThrowAwayImage ;
switch ( bitmapPB - > GetInt ( kBmpScaling ) )
{
case kScalingHalf : texFlags | = plBitmap : : kHalfSize ; break ;
case kScalingNone : texFlags | = plBitmap : : kNoMaxSize ; break ;
}
// Mip map filtering.
if ( bitmapPB - > GetInt ( kBmpNoFilter ) )
texFlags | = plBitmap : : kForceOneMipLevel ;
if ( bitmapPB - > GetInt ( kBmpMipBias ) )
{
plasmaLayer - > SetZFlags ( plasmaLayer - > GetZFlags ( ) | hsGMatState : : kZLODBias ) ;
plasmaLayer - > SetLODBias ( bitmapPB - > GetFloat ( kBmpMipBiasAmt , fConverterUtils . GetTime ( fInterface ) ) ) ;
}
float sig = bitmapPB - > GetFloat ( kBmpMipBlur ) ;
bd . texFlags = texFlags ;
bd . sig = sig ;
// Get detail parameters
if ( bitmapPB - > GetInt ( kBmpUseDetail ) )
{ // TODO: be smarter
if ( blendFlags & hsGMatState : : kBlendAdd )
bd . createFlags | = plMipmap : : kCreateDetailAdd ;
else if ( blendFlags & hsGMatState : : kBlendMult )
bd . createFlags | = plMipmap : : kCreateDetailMult ;
else
bd . createFlags | = plMipmap : : kCreateDetailAlpha ;
bd . detailDropoffStart = float ( bitmapPB - > GetInt ( kBmpDetailStartSize ) ) / 100.f ;
bd . detailDropoffStop = float ( bitmapPB - > GetInt ( kBmpDetailStopSize ) ) / 100.f ;
bd . detailMax = float ( bitmapPB - > GetInt ( kBmpDetailStartOpac ) ) / 100.f ;
bd . detailMin = float ( bitmapPB - > GetInt ( kBmpDetailStopOpac ) ) / 100.f ;
}
// Get max export dimension (since the function we eventually call
// expects the max of the two dimensions, we figure that out here and
// pass it on)
bd . maxDimension = bitmapPB - > GetInt ( kBmpExportWidth ) ;
int expHt = bitmapPB - > GetInt ( kBmpExportHeight ) ;
if ( bd . maxDimension < expHt )
bd . maxDimension = expHt ;
int clipID = 0 , w ;
for ( clipID = 0 , w = bi - > Width ( ) ; w > bd . maxDimension ; w > > = 1 , clipID + + ) ;
// Do the UV gen (before we do texture, since it could modify the bitmapData struct)
IProcessUVGen ( layer , plasmaLayer , & bd , preserveUVOffset ) ;
// Create the texture. If it works, assign it to the layer
if ( ( plasmaLayer = IAssignTexture ( & bd , maxNode , plasmaLayer , upperLayer , clipID ) ) = = nil )
return nil ;
// All done!
return ( plLayerInterface * ) plasmaLayer ;
hsGuardEnd ;
}
//// IConvertStaticEnvLayer ///////////////////////////////////////////////////
plLayerInterface * plLayerConverter : : IConvertStaticEnvLayer ( plPlasmaMAXLayer * layer ,
plMaxNode * maxNode , UInt32 blendFlags ,
hsBool preserveUVOffset , hsBool upperLayer )
{
hsGuardBegin ( " plLayerConverter::IConvertStaticEnvLayer " ) ;
IParamBlock2 * bitmapPB ;
plLocation loc ;
loc = maxNode - > GetLocation ( ) ;
bitmapPB = layer - > GetParamBlockByID ( plStaticEnvLayer : : kBlkBitmap ) ;
if ( ! bitmapPB )
{
fErrorMsg - > Set ( ! bitmapPB , " Plasma Layer Error " , " Bitmap paramblock for Plasma Layer not found " ) . Show ( ) ;
fErrorMsg - > Set ( ) ;
return nil ;
}
// Get a new layer to play with
plLayer * plasmaLayer = ICreateLayer ( layer - > GetName ( ) , upperLayer , loc ) ;
// Get the texture info
PBBitmap * pbbm = bitmapPB - > GetBitmap ( plStaticEnvLayer : : kBmpFrontBitmap + 0 ) ;
BitmapInfo * bi = nil ;
if ( pbbm )
bi = & pbbm - > bi ;
// If the texture had bad info, assert and return the empty layer
if ( ! bi | | ! bi - > Name ( ) | | ! strcmp ( bi - > Name ( ) , " " ) )
{
// Or don't assert since it can get annoying when you are using someone
// elses file and don't have all the textures.
return ( plLayerInterface * ) plasmaLayer ;
}
// Setup the texture creation parameters
plBitmapData bd ;
bd . fileName = bi - > Name ( ) ;
// Create texture and add it to list if unique
Int32 texFlags = 0 ;
// Texture Alpha/Color
if ( bitmapPB - > GetInt ( plStaticEnvLayer : : kBmpInvertColor ) )
plasmaLayer - > SetBlendFlags ( plasmaLayer - > GetBlendFlags ( ) | hsGMatState : : kBlendInvertColor ) ;
if ( bitmapPB - > GetInt ( plStaticEnvLayer : : kBmpDiscardColor ) )
plasmaLayer - > SetBlendFlags ( plasmaLayer - > GetBlendFlags ( ) | hsGMatState : : kBlendNoTexColor ) ;
if ( bitmapPB - > GetInt ( kBmpDiscardAlpha ) )
plasmaLayer - > SetBlendFlags ( plasmaLayer - > GetBlendFlags ( ) | hsGMatState : : kBlendNoTexAlpha ) ;
if ( bitmapPB - > GetInt ( plStaticEnvLayer : : kBmpInvertAlpha ) )
bd . invertAlpha = true ;
// Texture quality
if ( bitmapPB - > GetInt ( plStaticEnvLayer : : kBmpNonCompressed ) )
texFlags | = plBitmap : : kForceNonCompressed ;
switch ( bitmapPB - > GetInt ( plStaticEnvLayer : : kBmpScaling ) )
{
case plStaticEnvLayer : : kScalingHalf : texFlags | = plBitmap : : kHalfSize ; break ;
case plStaticEnvLayer : : kScalingNone : texFlags | = plBitmap : : kNoMaxSize ; break ;
}
bd . texFlags = texFlags ;
bd . isStaticCubicEnvMap = true ;
for ( int i = 0 ; i < 6 ; i + + )
{
PBBitmap * face = bitmapPB - > GetBitmap ( plStaticEnvLayer : : kBmpFrontBitmap + i ) ;
if ( ! face )
return ( plLayerInterface * ) plasmaLayer ;
bd . faceNames [ i ] = face - > bi . Name ( ) ;
}
// Get detail parameters
if ( bitmapPB - > GetInt ( plStaticEnvLayer : : kBmpUseDetail ) )
{ // TODO: be smarter
if ( blendFlags & hsGMatState : : kBlendAdd )
bd . createFlags = plMipmap : : kCreateDetailAdd ;
else if ( blendFlags & hsGMatState : : kBlendMult )
bd . createFlags = plMipmap : : kCreateDetailMult ;
else
bd . createFlags = plMipmap : : kCreateDetailAlpha ;
bd . detailDropoffStart = float ( bitmapPB - > GetInt ( plStaticEnvLayer : : kBmpDetailStartSize ) ) / 100.f ;
bd . detailDropoffStop = float ( bitmapPB - > GetInt ( plStaticEnvLayer : : kBmpDetailStopSize ) ) / 100.f ;
bd . detailMax = float ( bitmapPB - > GetInt ( plStaticEnvLayer : : kBmpDetailStartOpac ) ) / 100.f ;
bd . detailMin = float ( bitmapPB - > GetInt ( plStaticEnvLayer : : kBmpDetailStopOpac ) ) / 100.f ;
}
/// Since we're a cubic environMap, we don't care about the UV transform nor the uvwSrc
plasmaLayer - > SetUVWSrc ( 0 ) ;
plasmaLayer - > SetUVWSrc ( plasmaLayer - > GetUVWSrc ( ) | plLayerInterface : : kUVWReflect ) ;
// Create the texture. If it works, assign it to the layer
if ( ( plasmaLayer = IAssignTexture ( & bd , maxNode , plasmaLayer , upperLayer ) ) = = nil )
return nil ;
// Tag this layer as reflective cubic environmentmapping
if ( bitmapPB - > GetInt ( plStaticEnvLayer : : kBmpRefract ) )
plasmaLayer - > SetMiscFlags ( plasmaLayer - > GetMiscFlags ( ) | hsGMatState : : kMiscUseRefractionXform ) ;
else
plasmaLayer - > SetMiscFlags ( plasmaLayer - > GetMiscFlags ( ) | hsGMatState : : kMiscUseReflectionXform ) ;
return ( plLayerInterface * ) plasmaLayer ;
hsGuardEnd ;
}
//// IConvertDynamicEnvLayer //////////////////////////////////////////////////
plLayerInterface * plLayerConverter : : IConvertDynamicEnvLayer ( plPlasmaMAXLayer * layer ,
plMaxNode * maxNode , UInt32 blendFlags ,
hsBool preserveUVOffset , hsBool upperLayer )
{
hsGuardBegin ( " plLayerConverter::IConvertDynamicEnvLayer " ) ;
IParamBlock2 * bitmapPB ;
plLocation loc ;
loc = maxNode - > GetLocation ( ) ;
bitmapPB = layer - > GetParamBlockByID ( plDynamicEnvLayer : : kBlkBitmap ) ;
if ( ! bitmapPB )
{
fErrorMsg - > Set ( ! bitmapPB , " Plasma Layer Error " , " Bitmap paramblock for Plasma Layer not found " ) . Show ( ) ;
fErrorMsg - > Set ( ) ;
return nil ;
}
// Get a new layer to play with
plLayer * plasmaLayer = ICreateLayer ( layer - > GetName ( ) , upperLayer , loc ) ;
// Get the anchor node
plMaxNode * anchor = ( plMaxNode * ) bitmapPB - > GetINode ( plDynamicEnvLayer : : kBmpAnchorNode ) ;
if ( anchor = = nil )
// Default to self as the anchor--just make sure we make unique versions of this material!
anchor = maxNode ;
if ( ! anchor - > CanConvert ( ) | | ! ( anchor - > GetForceLocal ( ) | | anchor - > GetDrawable ( ) ) )
{
fErrorMsg - > Set ( true , " Plasma Layer Error " , " The dynamic envMap material %s has an invalid anchor specified. Please specify a valid Plasma scene object as an anchor. " , plasmaLayer - > GetKeyName ( ) ) . Show ( ) ;
fErrorMsg - > Set ( ) ;
return ( plLayerInterface * ) plasmaLayer ;
}
// Create texture and add it to list if unique
Int32 texFlags = 0 ;
/// Since we're a cubic environMap, we don't care about the UV transform nor the uvwSrc
plasmaLayer - > SetUVWSrc ( 0 ) ;
plasmaLayer - > SetUVWSrc ( plasmaLayer - > GetUVWSrc ( ) | plLayerInterface : : kUVWReflect ) ;
// Create the texture. If it works, assign it to the layer
char texName [ 256 ] ;
if ( anchor = = maxNode )
{
// Self-anchoring material, make sure the name is unique via the nodeName
sprintf ( texName , " %s_cubicRT@%s " , plasmaLayer - > GetKeyName ( ) , maxNode - > GetName ( ) ) ;
}
else
sprintf ( texName , " %s_cubicRT " , plasmaLayer - > GetKeyName ( ) ) ;
plBitmap * texture = ( plBitmap * ) IMakeCubicRenderTarget ( texName , maxNode , anchor ) ;
if ( texture )
hsgResMgr : : ResMgr ( ) - > AddViaNotify ( texture - > GetKey ( ) , TRACKED_NEW plLayRefMsg ( plasmaLayer - > GetKey ( ) , plRefMsg : : kOnCreate , 0 , plLayRefMsg : : kTexture ) , plRefFlags : : kActiveRef ) ;
// Tag this layer as reflective cubic environmentmapping
if ( bitmapPB - > GetInt ( plDynamicEnvLayer : : kBmpRefract ) )
plasmaLayer - > SetMiscFlags ( plasmaLayer - > GetMiscFlags ( ) | hsGMatState : : kMiscUseRefractionXform ) ;
else
plasmaLayer - > SetMiscFlags ( plasmaLayer - > GetMiscFlags ( ) | hsGMatState : : kMiscUseReflectionXform ) ;
return ( plLayerInterface * ) plasmaLayer ;
hsGuardEnd ;
}
plLayerInterface * plLayerConverter : : IConvertCameraLayer ( plPlasmaMAXLayer * layer ,
plMaxNode * maxNode , UInt32 blendFlags ,
hsBool preserveUVOffset , hsBool upperLayer )
{
hsGuardBegin ( " plLayerConverter::IConvertCameraLayer " ) ;
IParamBlock2 * pb ;
plLocation loc ;
loc = maxNode - > GetLocation ( ) ;
pb = layer - > GetParamBlockByID ( plMAXCameraLayer : : kBlkMain ) ;
if ( ! pb )
{
fErrorMsg - > Set ( ! pb , " Plasma Layer Error " , " Paramblock for Plasma Camera Layer not found " ) . Show ( ) ;
fErrorMsg - > Set ( ) ;
return nil ;
}
plLayer * plasmaLayer = ICreateLayer ( layer - > GetName ( ) , upperLayer , loc ) ;
plMaxNode * rootNode = ( plMaxNode * ) pb - > GetINode ( ParamID ( plMAXCameraLayer : : kRootNode ) ) ;
plDynamicCamMap * map = plEnvMapComponent : : GetCamMap ( rootNode ? rootNode : maxNode ) ;
if ( map )
{
Int32 texFlags = 0 ;
if ( ! pb - > GetInt ( ParamID ( plMAXCameraLayer : : kExplicitCam ) ) )
{
plasmaLayer - > SetUVWSrc ( plLayerInterface : : kUVWPosition ) ;
plasmaLayer - > SetMiscFlags ( hsGMatState : : kMiscCam2Screen | hsGMatState : : kMiscPerspProjection ) ;
hsgResMgr : : ResMgr ( ) - > AddViaNotify ( rootNode - > GetSceneObject ( ) - > GetKey ( ) , TRACKED_NEW plGenRefMsg ( map - > GetKey ( ) , plRefMsg : : kOnCreate , - 1 , plDynamicCamMap : : kRefRootNode ) , plRefFlags : : kActiveRef ) ;
hsgResMgr : : ResMgr ( ) - > AddViaNotify ( plasmaLayer - > GetKey ( ) , TRACKED_NEW plGenRefMsg ( map - > GetKey ( ) , plRefMsg : : kOnCreate , - 1 , plDynamicCamMap : : kRefMatLayer ) , plRefFlags : : kActiveRef ) ;
if ( ! pb - > GetInt ( ParamID ( plMAXCameraLayer : : kForce ) ) )
{
plBitmap * disableTexture = hsMaterialConverter : : Instance ( ) . GetStaticColorTexture ( pb - > GetColor ( ParamID ( plMAXCameraLayer : : kDisableColor ) ) , loc ) ;
hsgResMgr : : ResMgr ( ) - > AddViaNotify ( disableTexture - > GetKey ( ) , TRACKED_NEW plGenRefMsg ( map - > GetKey ( ) , plRefMsg : : kOnCreate , - 1 , plDynamicCamMap : : kRefDisableTexture ) , plRefFlags : : kActiveRef ) ;
}
}
else
{
plMaxNode * camNode = ( plMaxNode * ) pb - > GetINode ( ParamID ( plMAXCameraLayer : : kCamera ) ) ;
if ( camNode )
{
const plCameraModifier1 * mod = plCameraModifier1 : : ConvertNoRef ( camNode - > GetSceneObject ( ) - > GetModifierByType ( plCameraModifier1 : : Index ( ) ) ) ;
if ( mod )
hsgResMgr : : ResMgr ( ) - > AddViaNotify ( mod - > GetKey ( ) , TRACKED_NEW plGenRefMsg ( map - > GetKey ( ) , plRefMsg : : kOnCreate , - 1 , plDynamicCamMap : : kRefCamera ) , plRefFlags : : kActiveRef ) ;
}
plasmaLayer - > SetUVWSrc ( pb - > GetInt ( ParamID ( plMAXCameraLayer : : kUVSource ) ) ) ;
}
hsTArray < plMaxNode * > nodeList ;
hsMaterialConverter : : GetNodesByMaterial ( maxNode - > GetMtl ( ) , nodeList ) ;
int i ;
for ( i = 0 ; i < nodeList . GetCount ( ) ; i + + )
{
hsgResMgr : : ResMgr ( ) - > AddViaNotify ( nodeList [ i ] - > GetSceneObject ( ) - > GetKey ( ) , TRACKED_NEW plGenRefMsg ( map - > GetKey ( ) , plRefMsg : : kOnCreate , - 1 , plDynamicCamMap : : kRefTargetNode ) , plRefFlags : : kActiveRef ) ;
}
hsgResMgr : : ResMgr ( ) - > AddViaNotify ( map - > GetKey ( ) , TRACKED_NEW plLayRefMsg ( plasmaLayer - > GetKey ( ) , plRefMsg : : kOnCreate , - 1 , plLayRefMsg : : kTexture ) , plRefFlags : : kActiveRef ) ;
}
return plasmaLayer ;
hsGuardEnd ;
}
//// IConvertDynamicTextLayer /////////////////////////////////////////////////
plLayerInterface * plLayerConverter : : IConvertDynamicTextLayer ( plPlasmaMAXLayer * layer ,
plMaxNode * maxNode , UInt32 blendFlags ,
hsBool preserveUVOffset , hsBool upperLayer )
{
hsGuardBegin ( " plLayerConverter::IConvertDynamicTextLayer " ) ;
plDynamicTextLayer * maxLayer ;
IParamBlock2 * bitmapPB ;
plLocation loc ;
maxLayer = ( plDynamicTextLayer * ) layer ;
loc = maxNode - > GetLocation ( ) ;
bitmapPB = maxLayer - > GetParamBlockByID ( plDynamicTextLayer : : kBlkBitmap ) ;
if ( ! bitmapPB )
{
fErrorMsg - > Set ( ! bitmapPB , " Plasma Layer Error " , " Bitmap paramblock for Plasma Layer not found " ) . Show ( ) ;
fErrorMsg - > Set ( ) ;
return nil ;
}
// Get a new layer to play with
plLayer * plasmaLayer = ICreateLayer ( maxLayer - > GetName ( ) , upperLayer , loc ) ;
/// UV Gen
IProcessUVGen ( maxLayer , plasmaLayer , nil , preserveUVOffset ) ;
// Create the "texture"
plDynamicTextMap * texture = ICreateDynTextMap ( plasmaLayer - > GetKeyName ( ) ,
bitmapPB - > GetInt ( plDynamicTextLayer : : kBmpExportWidth ) ,
bitmapPB - > GetInt ( plDynamicTextLayer : : kBmpExportHeight ) ,
bitmapPB - > GetInt ( plDynamicTextLayer : : kBmpIncludeAlphaChannel ) ,
maxNode ) ;
// Set the initial bitmap if necessary
UInt32 * initBuffer = IGetInitBitmapBuffer ( maxLayer ) ;
if ( initBuffer ! = nil )
{
texture - > SetInitBuffer ( initBuffer ) ;
delete [ ] initBuffer ;
}
// Add the texture in
hsgResMgr : : ResMgr ( ) - > AddViaNotify ( texture - > GetKey ( ) , TRACKED_NEW plLayRefMsg ( plasmaLayer - > GetKey ( ) , plRefMsg : : kOnCreate , 0 , plLayRefMsg : : kTexture ) , plRefFlags : : kActiveRef ) ;
// All done!
return ( plLayerInterface * ) plasmaLayer ;
hsGuardEnd ;
}
//// IGetInitBitmapBuffer /////////////////////////////////////////////////////
// Called to get a 32-bit uncompressed ARGB version of the init bitmap of
// a dynamic text layer
UInt32 * plLayerConverter : : IGetInitBitmapBuffer ( plDynamicTextLayer * layer ) const
{
UInt32 * buffer ;
hsRGBAColor32 * buffPtr ;
UInt16 width , height ;
IParamBlock2 * bitmapPB = layer - > GetParamBlockByID ( plDynamicTextLayer : : kBlkBitmap ) ;
Bitmap * initBitmap = layer - > GetBitmap ( TimeValue ( 0 ) ) ;
if ( bitmapPB - > GetInt ( ( ParamID ) plDynamicTextLayer : : kBmpUseInitImage ) = = 0 | | initBitmap = = nil )
return nil ;
width = bitmapPB - > GetInt ( ( ParamID ) plDynamicTextLayer : : kBmpExportWidth ) ;
height = bitmapPB - > GetInt ( ( ParamID ) plDynamicTextLayer : : kBmpExportHeight ) ;
buffer = TRACKED_NEW UInt32 [ width * height ] ;
if ( buffer = = nil )
return nil ;
// Fill buffer from the MAX bitmap
PixelBuf l64 ( width ) ;
BMM_Color_64 * p64 = l64 . Ptr ( ) ;
buffPtr = ( hsRGBAColor32 * ) buffer ;
for ( int y = 0 ; y < height ; y + + )
{
hsRGBAColor32 color ;
if ( ! initBitmap - > GetLinearPixels ( 0 , y , width , p64 ) )
{
delete [ ] buffer ;
return nil ;
}
for ( int x = 0 ; x < width ; x + + )
{
color . SetARGB ( p64 [ x ] . a * 255.f / 65535.f ,
p64 [ x ] . r * 255.f / 65535.f ,
p64 [ x ] . g * 255.f / 65535.f ,
p64 [ x ] . b * 255.f / 65535.f ) ;
buffPtr [ x ] = color ;
}
buffPtr + = width ;
}
return buffer ;
}
static UInt32 MakeUInt32Color ( float r , float g , float b , float a )
{
return ( UInt32 ( a * 255.9f ) < < 24 )
| ( UInt32 ( r * 255.9f ) < < 16 )
| ( UInt32 ( g * 255.9f ) < < 8 )
| ( UInt32 ( b * 255.9f ) < < 0 ) ;
}
plBitmap * plLayerConverter : : IGetAttenRamp ( plMaxNode * node , BOOL isAdd , int loClamp , int hiClamp )
{
char funkName [ 512 ] ;
sprintf ( funkName , " %s_%d_%d " ,
isAdd ? " AttenRampAdd " : " AttenRampMult " ,
loClamp ,
hiClamp ) ;
float range = float ( hiClamp - loClamp ) * 1.e-2 f ;
float lowest = float ( loClamp ) * 1.e-2 f ;
const int kLUTWidth = 16 ;
const int kLUTHeight = 16 ;
// NOTE: CreateBlankMipmap might return an old mipmap if it was already created, so in those
// cases we wouldn't really need to re-write the texture. However, there's no harm in doing so,
// and since we're close to Alpha, I don't want to shake up the code any more than absolutely
// necessary. -mcn
plMipmap * texture = plBitmapCreator : : Instance ( ) . CreateBlankMipmap ( kLUTWidth , kLUTHeight , plMipmap : : kARGB32Config , 1 , funkName , node - > GetLocation ( ) ) ;
UInt32 * pix = ( UInt32 * ) texture - > GetImage ( ) ;
if ( isAdd )
{
int i ;
for ( i = 0 ; i < kLUTHeight ; i + + )
{
int j ;
for ( j = 0 ; j < kLUTWidth ; j + + )
{
float x = float ( j ) / ( kLUTWidth - 1 ) ;
float y = float ( i ) / ( kLUTHeight - 1 ) ;
if ( x < y )
x = y ;
x * = range ;
x + = lowest ;
* pix + + = MakeUInt32Color ( 1.f , 1.f , 1.f , x ) ;
}
}
}
else
{
int i ;
for ( i = 0 ; i < kLUTHeight ; i + + )
{
int j ;
for ( j = 0 ; j < kLUTWidth ; j + + )
{
float x = float ( j ) / ( kLUTWidth - 1 ) ;
float y = float ( i ) / ( kLUTHeight - 1 ) ;
float val = x * y ;
val * = range ;
val + = lowest ;
* pix + + = MakeUInt32Color ( 1.f , 1.f , 1.f , val ) ;
}
}
}
return texture ;
}
plLayer * plLayerConverter : : ICreateAttenuationLayer ( const char * name , plMaxNode * node , int uvwSrc ,
float tr0 , float op0 , float tr1 , float op1 ,
int loClamp , int hiClamp )
{
hsMatrix44 uvwXfm ;
uvwXfm . Reset ( ) ;
uvwXfm . fMap [ 0 ] [ 0 ] = uvwXfm . fMap [ 1 ] [ 1 ] = uvwXfm . fMap [ 2 ] [ 2 ] = 0 ;
uvwXfm . NotIdentity ( ) ;
if ( op0 ! = tr0 )
{
uvwXfm . fMap [ 0 ] [ 2 ] = - 1.f / ( tr0 - op0 ) ;
uvwXfm . fMap [ 0 ] [ 3 ] = uvwXfm . fMap [ 0 ] [ 2 ] * - tr0 ;
}
else
{
uvwXfm . fMap [ 0 ] [ 3 ] = 1.f ;
}
if ( op1 ! = tr1 )
{
uvwXfm . fMap [ 1 ] [ 2 ] = - 1.f / ( tr1 - op1 ) ;
uvwXfm . fMap [ 1 ] [ 3 ] = uvwXfm . fMap [ 1 ] [ 2 ] * - tr1 ;
}
else
{
uvwXfm . fMap [ 1 ] [ 3 ] = 1.f ;
}
BOOL chanAdd = false ;
if ( op0 < tr0 )
{
if ( ( op0 < op1 ) & & ( tr1 < op1 ) )
chanAdd = true ;
}
else if ( op0 > tr0 )
{
if ( ( op0 > op1 ) & & ( tr1 > op1 ) )
chanAdd = true ;
}
plBitmap * funkRamp = IGetAttenRamp ( node , chanAdd , loClamp , hiClamp ) ;
plLayer * layer = TRACKED_NEW plLayer ;
layer - > InitToDefault ( ) ;
hsgResMgr : : ResMgr ( ) - > NewKey ( name , layer , node - > GetLocation ( ) ) ;
hsgResMgr : : ResMgr ( ) - > AddViaNotify ( funkRamp - > GetKey ( ) , TRACKED_NEW plLayRefMsg ( layer - > GetKey ( ) , plRefMsg : : kOnCreate , 0 , plLayRefMsg : : kTexture ) , plRefFlags : : kActiveRef ) ;
layer - > SetAmbientColor ( hsColorRGBA ( ) . Set ( 1.f , 1.f , 1.f , 1.f ) ) ;
layer - > SetPreshadeColor ( hsColorRGBA ( ) . Set ( 0 , 0 , 0 , 1.f ) ) ;
layer - > SetRuntimeColor ( hsColorRGBA ( ) . Set ( 0 , 0 , 0 , 1.f ) ) ;
layer - > SetZFlags ( hsGMatState : : kZNoZWrite ) ;
UInt32 blendFlags = hsGMatState : : kBlendAlpha | hsGMatState : : kBlendNoTexColor | hsGMatState : : kBlendAlphaMult ;
layer - > SetBlendFlags ( blendFlags ) ;
layer - > SetClampFlags ( hsGMatState : : kClampTexture ) ;
layer - > SetTransform ( uvwXfm ) ;
layer - > SetUVWSrc ( uvwSrc ) ;
return layer ;
}
plLayerInterface * plLayerConverter : : IConvertAngleAttenLayer ( plPlasmaMAXLayer * layer ,
plMaxNode * maxNode , UInt32 blendFlags ,
hsBool preserveUVOffset , hsBool upperLayer )
{
hsGuardBegin ( " plPlasmaMAXLayer::IConvertAngleAttenLayer " ) ;
if ( ! upperLayer )
{
fErrorMsg - > Set ( true , maxNode - > GetName ( ) , " Angle Attenuation layers can only be used as a top layer " ) . Show ( ) ;
fErrorMsg - > Set ( ) ;
return nil ;
}
plAngleAttenLayer * aaLay = ( plAngleAttenLayer * ) layer ;
Box3 fade = aaLay - > GetFade ( ) ;
float tr0 = cosf ( DegToRad ( 180.f - fade . Min ( ) . x ) ) ;
float op0 = cosf ( DegToRad ( 180.f - fade . Min ( ) . y ) ) ;
float tr1 = cosf ( DegToRad ( 180.f - fade . Max ( ) . x ) ) ;
float op1 = cosf ( DegToRad ( 180.f - fade . Max ( ) . y ) ) ;
int loClamp = aaLay - > GetLoClamp ( ) ;
int hiClamp = aaLay - > GetHiClamp ( ) ;
int uvwSrc = aaLay - > Reflect ( ) ? plLayerInterface : : kUVWReflect : plLayerInterface : : kUVWNormal ;
plLayer * lut = ICreateAttenuationLayer ( layer - > GetName ( ) , maxNode , uvwSrc , tr0 , op0 , tr1 , op1 , loClamp , hiClamp ) ;
return lut ;
hsGuardEnd ;
}
//// ICreateLayer /////////////////////////////////////////////////////////////
plLayer * plLayerConverter : : ICreateLayer ( const char * name , hsBool upperLayer , plLocation & loc )
{
hsGuardBegin ( " plPlasmaMAXLayer::ICreateLayer " ) ;
plLayer * layer = TRACKED_NEW plLayer ;
layer - > InitToDefault ( ) ;
hsgResMgr : : ResMgr ( ) - > NewKey ( name , layer , loc ) ;
return layer ;
hsGuardEnd ;
}
//// IProcessUVGen ////////////////////////////////////////////////////////////
void plLayerConverter : : IProcessUVGen ( plPlasmaMAXLayer * srcLayer , plLayer * destLayer ,
plBitmapData * bitmapData , hsBool preserveUVOffset )
{
hsGuardBegin ( " plPlasmaMAXLayer::IProcessUVGen " ) ;
StdUVGen * uvGen = ( StdUVGen * ) srcLayer - > GetTheUVGen ( ) ;
int tiling = uvGen - > GetTextureTiling ( ) ;
// If set this indicates the texture map is tiled in U
if ( ! ( tiling & U_WRAP ) )
{
destLayer - > SetClampFlags ( destLayer - > GetClampFlags ( ) | hsGMatState : : kClampTextureU ) ;
if ( bitmapData ! = nil )
bitmapData - > clampFlags | = plBitmapData : : kClampU ;
}
// If set this indicates the texture map is tiled in V
if ( ! ( tiling & V_WRAP ) )
{
destLayer - > SetClampFlags ( destLayer - > GetClampFlags ( ) | hsGMatState : : kClampTextureV ) ;
if ( bitmapData ! = nil )
bitmapData - > clampFlags | = plBitmapData : : kClampV ;
}
// UVW Src
Int32 uvwSrc = srcLayer - > GetMapChannel ( ) - 1 ;
if ( fErrorMsg - > Set ( ! ( fWarned & kWarnedTooManyUVs ) & &
( ( uvwSrc < 0 ) | | ( uvwSrc > = plGeometrySpan : : kMaxNumUVChannels ) ) ,
destLayer - > GetKeyName ( ) , " Only %d UVW channels (1-%d) currently supported " ,
plGeometrySpan : : kMaxNumUVChannels , plGeometrySpan : : kMaxNumUVChannels ) . CheckAskOrCancel ( ) )
fWarned | = kWarnedTooManyUVs ;
fErrorMsg - > Set ( false ) ;
destLayer - > SetUVWSrc ( uvwSrc ) ;
// Get the actual texture transform
hsMatrix44 hsTopX ;
if ( uvGen & & ( hsControlConverter : : Instance ( ) . StdUVGenToHsMatrix44 ( & hsTopX , uvGen , preserveUVOffset = = true ) ) )
destLayer - > SetTransform ( hsTopX ) ;
// All done!
hsGuardEnd ;
}
//// ICreateDynTextMap ////////////////////////////////////////////////////////
plDynamicTextMap * plLayerConverter : : ICreateDynTextMap ( const char * layerName , UInt32 width , UInt32 height ,
hsBool includeAlphaChannel , plMaxNode * node )
{
hsGuardBegin ( " plPlasmaMAXLayer::ICreateDynTextMap " ) ;
char texName [ 256 ] ;
plKey key ;
plDynamicTextMap * map = nil ;
// Need a unique key name for every layer that uses one. We could also key
// off of width and height, but layerName should be more than plenty
sprintf ( texName , " %s_dynText " , layerName ) ;
// Does it already exist?
key = node - > FindPageKey ( plDynamicTextMap : : Index ( ) , texName ) ;
if ( key ! = nil )
{
map = plDynamicTextMap : : ConvertNoRef ( key - > GetObjectPtr ( ) ) ;
if ( map ! = nil )
return map ;
}
// Create
map = TRACKED_NEW plDynamicTextMap ( ) ;
map - > SetNoCreate ( width , height , includeAlphaChannel ) ;
/// Add a key for it
key = hsgResMgr : : ResMgr ( ) - > NewKey ( texName , map , node - > GetLocation ( ) ) ;
// All done!
return map ;
hsGuardEnd ;
}
///////////////////////////////////////////////////////////////////////////////
//// Texture/Bitmap Management ////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
plBitmap * plLayerConverter : : CreateSimpleTexture ( const char * fileName , const plLocation & loc ,
UInt32 clipID /* = 0 */ , UInt32 texFlags /* = 0 */ , bool useJPEG /* = false */ )
{
plBitmapData bd ;
bd . fileName = fileName ;
bd . texFlags = texFlags ;
bd . createFlags = 0 ;
bd . detailDropoffStart = 0 ;
bd . detailDropoffStop = 0 ;
bd . detailMax = 0 ;
bd . detailMin = 0 ;
bd . sig = 0 ;
bd . isStaticCubicEnvMap = false ;
bd . invertAlpha = false ;
bd . clampFlags = 0 ;
bd . useJPEG = useJPEG ;
return plBitmapCreator : : Instance ( ) . CreateTexture ( & bd , loc , clipID ) ;
}
//// IAssignTexture ///////////////////////////////////////////////////////////
// Create a texture and assign it to the layer given. Returns the layer again,
// or nil if there was an error and it got deleted.
plLayer * plLayerConverter : : IAssignTexture ( plBitmapData * bd , plMaxNode * maxNode , plLayer * destLayer , hsBool upperLayer , int clipID )
{
plBitmap * texture = plBitmapCreator : : Instance ( ) . CreateTexture ( bd , maxNode - > GetLocation ( ) , clipID ) ;
if ( texture = = nil )
{
if ( upperLayer )
{
if ( fErrorMsg - > Set ( ! ( fWarned & kWarnedUpperTextureMissing ) , " Plasma Export Error " , sWarnUpperTextureMissing , maxNode - > GetName ( ) , bd - > fileName ) . CheckAskOrCancel ( ) )
fWarned | = kWarnedUpperTextureMissing ;
fErrorMsg - > Set ( false ) ;
delete destLayer ;
return nil ;
}
else
{
if ( fErrorMsg - > Set ( ! ( fWarned & kWarnedNoBaseTexture ) , " Plasma Export Error " , sWarnBaseTextureMissing , maxNode - > GetName ( ) , bd - > fileName ) . CheckAskOrCancel ( ) )
fWarned | = kWarnedNoBaseTexture ;
fErrorMsg - > Set ( false ) ;
return destLayer ;
}
}
else
hsgResMgr : : ResMgr ( ) - > AddViaNotify ( texture - > GetKey ( ) , TRACKED_NEW plLayRefMsg ( destLayer - > GetKey ( ) , plRefMsg : : kOnCreate , 0 , plLayRefMsg : : kTexture ) , plRefFlags : : kActiveRef ) ;
return destLayer ;
}
//// IMakeCubicRenderTarget ///////////////////////////////////////////////////
// Makes a plCubicRenderTarget as a texture. Also constructs the associated
// modifier and attaches it to the necessary object (hacked for now)
plCubicRenderTarget * plLayerConverter : : IMakeCubicRenderTarget ( const char * name , plMaxNode * node , plMaxNode * anchor )
{
plDynamicEnvMap * env = plEnvMapComponent : : GetEnvMap ( anchor ) ;
if ( env )
return env ;
char modName [ 256 ] ;
plCubicRenderTarget * cubic = nil ;
plKey key ;
key = node - > FindPageKey ( plCubicRenderTarget : : Index ( ) , name ) ;
if ( key ! = nil )
{
plCubicRenderTarget * cubic = plCubicRenderTarget : : ConvertNoRef ( key - > GetObjectPtr ( ) ) ;
if ( cubic ! = nil )
return cubic ;
}
/// Get the key from the anchor
if ( anchor = = nil | | anchor - > GetSceneObject ( ) = = nil )
return nil ;
plKey sObjKey = anchor - > GetSceneObject ( ) - > GetKey ( ) ;
if ( sObjKey = = nil )
return nil ;
/// Create
cubic = TRACKED_NEW plCubicRenderTarget ( plRenderTarget : : kIsTexture , 256 , 256 , 32 ) ;
hsAssert ( cubic ! = nil , " Cannot create cubic render target! " ) ;
/// Add a key
key = hsgResMgr : : ResMgr ( ) - > NewKey ( name , cubic , node - > GetLocation ( ) ) ;
/// Now make a modifier
plCubicRenderTargetModifier * mod = TRACKED_NEW plCubicRenderTargetModifier ( ) ;
sprintf ( modName , " %s_mod " , name ) ;
hsgResMgr : : ResMgr ( ) - > NewKey ( modName , mod , node - > GetLocation ( ) ) ;
hsgResMgr : : ResMgr ( ) - > AddViaNotify ( cubic - > GetKey ( ) , TRACKED_NEW plGenRefMsg ( mod - > GetKey ( ) , plRefMsg : : kOnCreate , 0 , 0 ) , plRefFlags : : kPassiveRef ) ;
hsgResMgr : : ResMgr ( ) - > AddViaNotify ( mod - > GetKey ( ) , TRACKED_NEW plObjRefMsg ( sObjKey , plRefMsg : : kOnCreate , 0 , plObjRefMsg : : kModifier ) , plRefFlags : : kActiveRef ) ;
return cubic ;
}