mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 23:54:35 +00:00
Engine directory for ticket #1
This commit is contained in:
parent
352279af7a
commit
7dbfe6994d
3795 changed files with 1363358 additions and 0 deletions
481
Engine/source/T3D/decal/decalData.cpp
Normal file
481
Engine/source/T3D/decal/decalData.cpp
Normal file
|
|
@ -0,0 +1,481 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 "T3D/decal/decalData.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "math/mathIO.h"
|
||||
#include "materials/materialManager.h"
|
||||
#include "materials/baseMatInstance.h"
|
||||
#include "T3D/objectTypes.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
GFXImplementVertexFormat( DecalVertex )
|
||||
{
|
||||
addElement( "POSITION", GFXDeclType_Float3 );
|
||||
addElement( "NORMAL", GFXDeclType_Float3 );
|
||||
addElement( "TANGENT", GFXDeclType_Float3 );
|
||||
addElement( "COLOR", GFXDeclType_Color );
|
||||
addElement( "TEXCOORD", GFXDeclType_Float2, 0 );
|
||||
}
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1( DecalData );
|
||||
|
||||
ConsoleDocClass( DecalData,
|
||||
"@brief A datablock describing an individual decal.\n\n"
|
||||
|
||||
"The textures defined by the decal Material can be divided into multiple "
|
||||
"rectangular sub-textures as shown below, with a different sub-texture "
|
||||
"selected by all decals using the same DecalData (via #frame) or each decal "
|
||||
"instance (via #randomize).\n"
|
||||
|
||||
"@image html images/decal_example.png \"Example of a Decal imagemap\"\n"
|
||||
|
||||
"@tsexample\n"
|
||||
"datablock DecalData(BulletHoleDecal)\n"
|
||||
"{\n"
|
||||
" material = \"DECAL_BulletHole\";\n"
|
||||
" size = \"5.0\";\n"
|
||||
" lifeSpan = \"50000\";\n"
|
||||
" randomize = \"1\";\n"
|
||||
" texRows = \"2\";\n"
|
||||
" texCols = \"2\";\n"
|
||||
" clippingAngle = \"60\";\n"
|
||||
"};\n"
|
||||
"@endtsexample\n\n"
|
||||
"@see Decals\n"
|
||||
"@ingroup Decals\n"
|
||||
"@ingroup FX\n"
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// DecalData
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
DecalData::DecalData()
|
||||
{
|
||||
size = 5;
|
||||
materialName = "";
|
||||
|
||||
lifeSpan = 5000;
|
||||
fadeTime = 1000;
|
||||
|
||||
frame = 0;
|
||||
randomize = false;
|
||||
texRows = 1;
|
||||
texCols = 1;
|
||||
|
||||
fadeStartPixelSize = -1.0f;
|
||||
fadeEndPixelSize = 200.0f;
|
||||
|
||||
material = NULL;
|
||||
matInst = NULL;
|
||||
|
||||
renderPriority = 10;
|
||||
clippingMasks = STATIC_COLLISION_TYPEMASK;
|
||||
clippingAngle = 89.0f;
|
||||
|
||||
texCoordCount = 1;
|
||||
|
||||
// TODO: We could in theory calculate if we can skip
|
||||
// normals on the decal by checking the material features.
|
||||
skipVertexNormals = false;
|
||||
|
||||
for ( S32 i = 0; i < 16; i++ )
|
||||
{
|
||||
texRect[i].point.set( 0.0f, 0.0f );
|
||||
texRect[i].extent.set( 1.0f, 1.0f );
|
||||
}
|
||||
}
|
||||
|
||||
DecalData::~DecalData()
|
||||
{
|
||||
SAFE_DELETE( matInst );
|
||||
}
|
||||
|
||||
bool DecalData::onAdd()
|
||||
{
|
||||
if ( !Parent::onAdd() )
|
||||
return false;
|
||||
|
||||
if (size < 0.0) {
|
||||
Con::warnf("DecalData::onAdd: size < 0");
|
||||
size = 0;
|
||||
}
|
||||
|
||||
getSet()->addObject( this );
|
||||
|
||||
if( texRows > 1 || texCols > 1 )
|
||||
reloadRects();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DecalData::onRemove()
|
||||
{
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
void DecalData::initPersistFields()
|
||||
{
|
||||
addGroup( "Decal" );
|
||||
|
||||
addField( "size", TypeF32, Offset( size, DecalData ),
|
||||
"Width and height of the decal in meters before scale is applied." );
|
||||
|
||||
addField( "material", TypeMaterialName, Offset( materialName, DecalData ),
|
||||
"Material to use for this decal." );
|
||||
|
||||
addField( "lifeSpan", TypeS32, Offset( lifeSpan, DecalData ),
|
||||
"Time (in milliseconds) before this decal will be automatically deleted." );
|
||||
|
||||
addField( "fadeTime", TypeS32, Offset( fadeTime, DecalData ),
|
||||
"@brief Time (in milliseconds) over which to fade out the decal before "
|
||||
"deleting it at the end of its lifetime.\n\n"
|
||||
"@see lifeSpan" );
|
||||
|
||||
endGroup( "Decal" );
|
||||
|
||||
addGroup( "Rendering" );
|
||||
|
||||
addField( "fadeStartPixelSize", TypeF32, Offset( fadeStartPixelSize, DecalData ),
|
||||
"@brief LOD value - size in pixels at which decals of this type begin "
|
||||
"to fade out.\n\n"
|
||||
"This should be a larger value than #fadeEndPixelSize. However, you may "
|
||||
"also set this to a negative value to disable lod-based fading." );
|
||||
|
||||
addField( "fadeEndPixelSize", TypeF32, Offset( fadeEndPixelSize, DecalData ),
|
||||
"@brief LOD value - size in pixels at which decals of this type are "
|
||||
"fully faded out.\n\n"
|
||||
"This should be a smaller value than #fadeStartPixelSize." );
|
||||
|
||||
addField( "renderPriority", TypeS8, Offset( renderPriority, DecalData ),
|
||||
"Default renderPriority for decals of this type (determines draw "
|
||||
"order when decals overlap)." );
|
||||
|
||||
addField( "clippingAngle", TypeF32, Offset( clippingAngle, DecalData ),
|
||||
"The angle in degrees used to clip geometry that faces away from the "
|
||||
"decal projection direction." );
|
||||
|
||||
endGroup( "Rendering" );
|
||||
|
||||
addGroup( "Texturing" );
|
||||
|
||||
addField( "frame", TypeS32, Offset( frame, DecalData ),
|
||||
"Index of the texture rectangle within the imagemap to use for this decal." );
|
||||
|
||||
addField( "randomize", TypeBool, Offset( randomize, DecalData ),
|
||||
"If true, a random frame from the imagemap is selected for each "
|
||||
"instance of the decal." );
|
||||
|
||||
addField( "textureCoordCount", TypeS32, Offset( texCoordCount, DecalData ),
|
||||
"Number of individual frames in the imagemap (maximum 16)." );
|
||||
|
||||
addField( "texRows", TypeS32, Offset( texRows, DecalData ),
|
||||
"@brief Number of rows in the supplied imagemap.\n\n"
|
||||
"Use #texRows and #texCols if the imagemap frames are arranged in a "
|
||||
"grid; use #textureCoords to manually specify UV coordinates for "
|
||||
"irregular sized frames." );
|
||||
|
||||
addField( "texCols", TypeS32, Offset( texCols, DecalData ),
|
||||
"@brief Number of columns in the supplied imagemap.\n\n"
|
||||
"Use #texRows and #texCols if the imagemap frames are arranged in a "
|
||||
"grid; use #textureCoords to manually specify UV coordinates for "
|
||||
"irregular sized frames." );
|
||||
|
||||
addField( "textureCoords", TypeRectF, Offset( texRect, DecalData ), MAX_TEXCOORD_COUNT,
|
||||
"@brief An array of RectFs (topleft.x topleft.y extent.x extent.y) "
|
||||
"representing the UV coordinates for each frame in the imagemap.\n\n"
|
||||
"@note This field should only be set if the imagemap frames are "
|
||||
"irregular in size. Otherwise use the #texRows and #texCols fields "
|
||||
"and the UV coordinates will be calculated automatically." );
|
||||
|
||||
endGroup( "Texturing" );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
void DecalData::onStaticModified( const char *slotName, const char *newValue )
|
||||
{
|
||||
Parent::onStaticModified( slotName, newValue );
|
||||
|
||||
if ( !isProperlyAdded() )
|
||||
return;
|
||||
|
||||
// To allow changing materials live.
|
||||
if ( dStricmp( slotName, "material" ) == 0 )
|
||||
{
|
||||
materialName = newValue;
|
||||
_updateMaterial();
|
||||
}
|
||||
// To allow changing name live.
|
||||
else if ( dStricmp( slotName, "name" ) == 0 )
|
||||
{
|
||||
lookupName = getName();
|
||||
}
|
||||
else if ( dStricmp( slotName, "renderPriority" ) == 0 )
|
||||
{
|
||||
renderPriority = getMax( renderPriority, (U8)1 );
|
||||
}
|
||||
}
|
||||
|
||||
bool DecalData::preload( bool server, String &errorStr )
|
||||
{
|
||||
if (Parent::preload(server, errorStr) == false)
|
||||
return false;
|
||||
|
||||
// Server assigns name to lookupName,
|
||||
// client assigns lookupName in unpack.
|
||||
if ( server )
|
||||
lookupName = getName();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DecalData::packData( BitStream *stream )
|
||||
{
|
||||
Parent::packData( stream );
|
||||
|
||||
stream->write( lookupName );
|
||||
stream->write( size );
|
||||
stream->write( materialName );
|
||||
stream->write( lifeSpan );
|
||||
stream->write( fadeTime );
|
||||
stream->write( texCoordCount );
|
||||
|
||||
for (S32 i = 0; i < texCoordCount; i++)
|
||||
mathWrite( *stream, texRect[i] );
|
||||
|
||||
stream->write( fadeStartPixelSize );
|
||||
stream->write( fadeEndPixelSize );
|
||||
stream->write( renderPriority );
|
||||
stream->write( clippingMasks );
|
||||
stream->write( clippingAngle );
|
||||
|
||||
stream->write( texRows );
|
||||
stream->write( texCols );
|
||||
stream->write( frame );
|
||||
stream->write( randomize );
|
||||
}
|
||||
|
||||
void DecalData::unpackData( BitStream *stream )
|
||||
{
|
||||
Parent::unpackData( stream );
|
||||
|
||||
stream->read( &lookupName );
|
||||
stream->read( &size );
|
||||
stream->read( &materialName );
|
||||
_updateMaterial();
|
||||
stream->read( &lifeSpan );
|
||||
stream->read( &fadeTime );
|
||||
stream->read( &texCoordCount );
|
||||
|
||||
for (S32 i = 0; i < texCoordCount; i++)
|
||||
mathRead(*stream, &texRect[i]);
|
||||
|
||||
stream->read( &fadeStartPixelSize );
|
||||
stream->read( &fadeEndPixelSize );
|
||||
stream->read( &renderPriority );
|
||||
stream->read( &clippingMasks );
|
||||
stream->read( &clippingAngle );
|
||||
|
||||
stream->read( &texRows );
|
||||
stream->read( &texCols );
|
||||
stream->read( &frame );
|
||||
stream->read( &randomize );
|
||||
}
|
||||
|
||||
void DecalData::_initMaterial()
|
||||
{
|
||||
SAFE_DELETE( matInst );
|
||||
|
||||
if ( material )
|
||||
matInst = material->createMatInstance();
|
||||
else
|
||||
matInst = MATMGR->createMatInstance( "WarningMaterial" );
|
||||
|
||||
GFXStateBlockDesc desc;
|
||||
desc.setZReadWrite( true, false );
|
||||
//desc.zFunc = GFXCmpLess;
|
||||
matInst->addStateBlockDesc( desc );
|
||||
|
||||
matInst->init( MATMGR->getDefaultFeatures(), getGFXVertexFormat<DecalVertex>() );
|
||||
if( !matInst->isValid() )
|
||||
{
|
||||
Con::errorf( "DecalData::_initMaterial - failed to create material instance for '%s'", materialName.c_str() );
|
||||
SAFE_DELETE( matInst );
|
||||
matInst = MATMGR->createMatInstance( "WarningMaterial" );
|
||||
matInst->init( MATMGR->getDefaultFeatures(), getGFXVertexFormat< DecalVertex >() );
|
||||
}
|
||||
}
|
||||
|
||||
void DecalData::_updateMaterial()
|
||||
{
|
||||
if ( materialName.isEmpty() )
|
||||
return;
|
||||
|
||||
Material *pMat = NULL;
|
||||
if ( !Sim::findObject( materialName, pMat ) )
|
||||
{
|
||||
Con::printf( "DecalData::unpackUpdate, failed to find Material of name %s!", materialName.c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
material = pMat;
|
||||
|
||||
// Only update material instance if we have one allocated.
|
||||
if ( matInst )
|
||||
_initMaterial();
|
||||
}
|
||||
|
||||
Material* DecalData::getMaterial()
|
||||
{
|
||||
if ( !material )
|
||||
{
|
||||
_updateMaterial();
|
||||
if ( !material )
|
||||
material = static_cast<Material*>( Sim::findObject("WarningMaterial") );
|
||||
}
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
BaseMatInstance* DecalData::getMaterialInstance()
|
||||
{
|
||||
if ( !material || !matInst || matInst->getMaterial() != material )
|
||||
_initMaterial();
|
||||
|
||||
return matInst;
|
||||
}
|
||||
|
||||
DecalData* DecalData::findDatablock( String searchName )
|
||||
{
|
||||
StringTableEntry className = DecalData::getStaticClassRep()->getClassName();
|
||||
DecalData *pData;
|
||||
SimSet *set = getSet();
|
||||
SimSetIterator iter( set );
|
||||
|
||||
for ( ; *iter; ++iter )
|
||||
{
|
||||
if ( (*iter)->getClassName() != className )
|
||||
{
|
||||
Con::errorf( "DecalData::findDatablock - found a class %s object in DecalDataSet!", (*iter)->getClassName() );
|
||||
continue;
|
||||
}
|
||||
|
||||
pData = static_cast<DecalData*>( *iter );
|
||||
if ( pData->lookupName.equal( searchName, String::NoCase ) )
|
||||
return pData;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DecalData::inspectPostApply()
|
||||
{
|
||||
reloadRects();
|
||||
}
|
||||
|
||||
void DecalData::reloadRects()
|
||||
{
|
||||
F32 rowsBase = 0;
|
||||
F32 colsBase = 0;
|
||||
bool canRenderRowsByFrame = false;
|
||||
bool canRenderColsByFrame = false;
|
||||
S32 id = 0;
|
||||
|
||||
texRect[id].point.x = 0.f;
|
||||
texRect[id].extent.x = 1.f;
|
||||
texRect[id].point.y = 0.f;
|
||||
texRect[id].extent.y = 1.f;
|
||||
|
||||
texCoordCount = (texRows * texCols) - 1;
|
||||
|
||||
if( texCoordCount > 16 )
|
||||
{
|
||||
Con::warnf("Coordinate max must be lower than 16 to be a valid decal !");
|
||||
texRows = 1;
|
||||
texCols = 1;
|
||||
texCoordCount = 1;
|
||||
}
|
||||
|
||||
// use current datablock information in order to build a template to extract
|
||||
// coordinates from.
|
||||
if( texRows > 1 )
|
||||
{
|
||||
rowsBase = ( 1.f / texRows );
|
||||
canRenderRowsByFrame = true;
|
||||
}
|
||||
if( texCols > 1 )
|
||||
{
|
||||
colsBase = ( 1.f / texCols );
|
||||
canRenderColsByFrame = true;
|
||||
}
|
||||
|
||||
// if were able, lets enter the loop
|
||||
if( frame >= 0 && (canRenderRowsByFrame || canRenderColsByFrame) )
|
||||
{
|
||||
// columns first then rows
|
||||
for ( S32 colId = 1; colId <= texCols; colId++ )
|
||||
{
|
||||
for ( S32 rowId = 1; rowId <= texRows; rowId++, id++ )
|
||||
{
|
||||
// if were over the coord count, lets go
|
||||
if(id > texCoordCount)
|
||||
return;
|
||||
|
||||
// keep our dimensions correct
|
||||
if(rowId > texRows)
|
||||
rowId = 1;
|
||||
|
||||
if(colId > texCols)
|
||||
colId = 1;
|
||||
|
||||
// start setting our rect values per frame
|
||||
if( canRenderRowsByFrame )
|
||||
{
|
||||
texRect[id].point.x = rowsBase * ( rowId - 1 );
|
||||
texRect[id].extent.x = rowsBase;
|
||||
}
|
||||
|
||||
if( canRenderColsByFrame )
|
||||
{
|
||||
texRect[id].point.y = colsBase * ( colId - 1 );
|
||||
texRect[id].extent.y = colsBase;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DefineEngineMethod(DecalData, postApply, void, (),,
|
||||
"Recompute the imagemap sub-texture rectangles for this DecalData.\n"
|
||||
"@tsexample\n"
|
||||
"// Inform the decal object to reload its imagemap and frame data.\n"
|
||||
"%decalData.texRows = 4;\n"
|
||||
"%decalData.postApply();\n"
|
||||
"@endtsexample\n")
|
||||
{
|
||||
object->inspectPostApply();
|
||||
}
|
||||
143
Engine/source/T3D/decal/decalData.h
Normal file
143
Engine/source/T3D/decal/decalData.h
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _DECALDATA_H_
|
||||
#define _DECALDATA_H_
|
||||
|
||||
#ifndef _SIMDATABLOCK_H_
|
||||
#include "console/simDatablock.h"
|
||||
#endif
|
||||
#ifndef _MATERIALDEFINITION_H_
|
||||
#include "materials/materialDefinition.h"
|
||||
#endif
|
||||
#ifndef _MRECT_H_
|
||||
#include "math/mRect.h"
|
||||
#endif
|
||||
#ifndef _DYNAMIC_CONSOLETYPES_H_
|
||||
#include "console/dynamicTypes.h"
|
||||
#endif
|
||||
|
||||
GFXDeclareVertexFormat( DecalVertex )
|
||||
{
|
||||
// .xyz = coords
|
||||
Point3F point;
|
||||
Point3F normal;
|
||||
Point3F tangent;
|
||||
GFXVertexColor color;
|
||||
Point2F texCoord;
|
||||
};
|
||||
|
||||
/// DataBlock implementation for decals.
|
||||
class DecalData : public SimDataBlock
|
||||
{
|
||||
typedef SimDataBlock Parent;
|
||||
|
||||
public:
|
||||
|
||||
enum { MAX_TEXCOORD_COUNT = 16 };
|
||||
|
||||
F32 size;
|
||||
|
||||
/// Milliseconds for decal to expire.
|
||||
U32 lifeSpan;
|
||||
|
||||
/// Milliseconds for decal to fade after expiration.
|
||||
U32 fadeTime;
|
||||
|
||||
S32 texCoordCount;
|
||||
RectF texRect[MAX_TEXCOORD_COUNT];
|
||||
|
||||
///
|
||||
S32 frame;
|
||||
bool randomize;
|
||||
S32 texRows;
|
||||
S32 texCols;
|
||||
|
||||
F32 fadeStartPixelSize;
|
||||
F32 fadeEndPixelSize;
|
||||
|
||||
/// Name of material to use.
|
||||
String materialName;
|
||||
|
||||
/// Render material for decal.
|
||||
SimObjectPtr<Material> material;
|
||||
|
||||
/// Material instance for decal.
|
||||
BaseMatInstance *matInst;
|
||||
|
||||
String lookupName;
|
||||
|
||||
U8 renderPriority;
|
||||
|
||||
S32 clippingMasks;
|
||||
|
||||
/// The angle in degress used to clip geometry
|
||||
/// that faces away from the decal projection.
|
||||
F32 clippingAngle;
|
||||
|
||||
/// Skip generating and collecting vertex normals for decals.
|
||||
bool skipVertexNormals;
|
||||
|
||||
public:
|
||||
|
||||
DecalData();
|
||||
~DecalData();
|
||||
|
||||
DECLARE_CONOBJECT(DecalData);
|
||||
static void initPersistFields();
|
||||
virtual void onStaticModified( const char *slotName, const char *newValue = NULL );
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
|
||||
virtual bool preload( bool server, String &errorStr );
|
||||
virtual void packData( BitStream* );
|
||||
virtual void unpackData( BitStream* );
|
||||
|
||||
Material* getMaterial();
|
||||
BaseMatInstance* getMaterialInstance();
|
||||
|
||||
static SimSet* getSet();
|
||||
static DecalData* findDatablock( String lookupName );
|
||||
|
||||
virtual void inspectPostApply();
|
||||
void reloadRects();
|
||||
|
||||
protected:
|
||||
|
||||
void _initMaterial();
|
||||
void _updateMaterial();
|
||||
};
|
||||
|
||||
inline SimSet* DecalData::getSet()
|
||||
{
|
||||
SimSet *set = NULL;
|
||||
if ( !Sim::findObject( "DecalDataSet", set ) )
|
||||
{
|
||||
set = new SimSet;
|
||||
set->registerObject( "DecalDataSet" );
|
||||
Sim::getRootGroup()->addObject( set );
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
#endif // _DECALDATA_H_
|
||||
407
Engine/source/T3D/decal/decalDataFile.cpp
Normal file
407
Engine/source/T3D/decal/decalDataFile.cpp
Normal file
|
|
@ -0,0 +1,407 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 "decalDataFile.h"
|
||||
|
||||
#include "math/mathIO.h"
|
||||
#include "core/tAlgorithm.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
|
||||
#include "T3D/decal/decalManager.h"
|
||||
#include "T3D/decal/decalData.h"
|
||||
|
||||
|
||||
template<>
|
||||
void* Resource<DecalDataFile>::create( const Torque::Path &path )
|
||||
{
|
||||
FileStream stream;
|
||||
stream.open( path.getFullPath(), Torque::FS::File::Read );
|
||||
if ( stream.getStatus() != Stream::Ok )
|
||||
return NULL;
|
||||
|
||||
DecalDataFile *file = new DecalDataFile();
|
||||
if ( !file->read( stream ) )
|
||||
{
|
||||
delete file;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
template<>
|
||||
ResourceBase::Signature Resource<DecalDataFile>::signature()
|
||||
{
|
||||
return MakeFourCC('d','e','c','f');
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DecalDataFile::DecalDataFile()
|
||||
: mIsDirty( false ),
|
||||
mSphereWithLastInsertion( NULL )
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mSphereList );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DecalDataFile::~DecalDataFile()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void DecalDataFile::clear()
|
||||
{
|
||||
for ( U32 i=0; i < mSphereList.size(); i++ )
|
||||
delete mSphereList[i];
|
||||
|
||||
mSphereList.clear();
|
||||
mSphereWithLastInsertion = NULL;
|
||||
mChunker.freeBlocks();
|
||||
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool DecalDataFile::write( Stream& stream )
|
||||
{
|
||||
// Write our identifier... so we have a better
|
||||
// idea if we're reading pure garbage.
|
||||
// This identifier stands for "Torque Decal Data File".
|
||||
stream.write( 4, "TDDF" );
|
||||
|
||||
// Now the version number.
|
||||
stream.write( (U8)FILE_VERSION );
|
||||
|
||||
Vector<DecalInstance*> allDecals;
|
||||
|
||||
// Gather all DecalInstances that should be saved.
|
||||
for ( U32 i = 0; i < mSphereList.size(); i++ )
|
||||
{
|
||||
Vector<DecalInstance*>::const_iterator item = mSphereList[i]->mItems.begin();
|
||||
for ( ; item != mSphereList[i]->mItems.end(); item++ )
|
||||
{
|
||||
if ( (*item)->mFlags & SaveDecal )
|
||||
allDecals.push_back( (*item) );
|
||||
}
|
||||
}
|
||||
|
||||
// Gather all the DecalData datablocks used.
|
||||
Vector<const DecalData*> allDatablocks;
|
||||
for ( U32 i = 0; i < allDecals.size(); i++ )
|
||||
allDatablocks.push_back_unique( allDecals[i]->mDataBlock );
|
||||
|
||||
// Write out datablock lookupNames.
|
||||
U32 count = allDatablocks.size();
|
||||
stream.write( count );
|
||||
for ( U32 i = 0; i < count; i++ )
|
||||
stream.write( allDatablocks[i]->lookupName );
|
||||
|
||||
Vector<const DecalData*>::iterator dataIter;
|
||||
|
||||
// Write out the DecalInstance list.
|
||||
count = allDecals.size();
|
||||
stream.write( count );
|
||||
for ( U32 i = 0; i < count; i++ )
|
||||
{
|
||||
DecalInstance *inst = allDecals[i];
|
||||
|
||||
dataIter = find( allDatablocks.begin(), allDatablocks.end(), inst->mDataBlock );
|
||||
U8 dataIndex = dataIter - allDatablocks.begin();
|
||||
|
||||
stream.write( dataIndex );
|
||||
mathWrite( stream, inst->mPosition );
|
||||
mathWrite( stream, inst->mNormal );
|
||||
mathWrite( stream, inst->mTangent );
|
||||
stream.write( inst->mTextureRectIdx );
|
||||
stream.write( inst->mSize );
|
||||
stream.write( inst->mRenderPriority );
|
||||
}
|
||||
|
||||
// Clear the dirty flag.
|
||||
mIsDirty = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool DecalDataFile::read( Stream &stream )
|
||||
{
|
||||
// NOTE: we are shortcutting by just saving out the DecalInst and
|
||||
// using regular addDecal methods to add them, which will end up
|
||||
// generating the DecalSphere(s) in the process.
|
||||
// It would be more efficient however to just save out all the data
|
||||
// and read it all in with no calculation required.
|
||||
|
||||
// Read our identifier... so we know we're
|
||||
// not reading in pure garbage.
|
||||
char id[4] = { 0 };
|
||||
stream.read( 4, id );
|
||||
if ( dMemcmp( id, "TDDF", 4 ) != 0 )
|
||||
{
|
||||
Con::errorf( "DecalDataFile::read() - This is not a Decal file!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Empty ourselves before we really begin reading.
|
||||
clear();
|
||||
|
||||
// Now the version number.
|
||||
U8 version;
|
||||
stream.read( &version );
|
||||
if ( version != (U8)FILE_VERSION )
|
||||
{
|
||||
Con::errorf( "DecalDataFile::read() - file versions do not match!" );
|
||||
Con::errorf( "You must manually delete the old .decals file before continuing!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read in the lookupNames of the DecalData datablocks and recover the datablock.
|
||||
Vector<DecalData*> allDatablocks;
|
||||
U32 count;
|
||||
stream.read( &count );
|
||||
allDatablocks.setSize( count );
|
||||
for ( U32 i = 0; i < count; i++ )
|
||||
{
|
||||
String lookupName;
|
||||
stream.read( &lookupName );
|
||||
|
||||
DecalData *data = DecalData::findDatablock( lookupName );
|
||||
|
||||
if ( !data )
|
||||
{
|
||||
char name[512];
|
||||
dSprintf(name, 512, "%s_missing", lookupName.c_str());
|
||||
|
||||
DecalData *stubCheck = DecalData::findDatablock( name );
|
||||
if( !stubCheck )
|
||||
{
|
||||
data = new DecalData;
|
||||
data->lookupName = name;
|
||||
data->registerObject(name);
|
||||
Sim::getRootGroup()->addObject( data );
|
||||
data->materialName = "WarningMaterial";
|
||||
data->material = dynamic_cast<Material*>(Sim::findObject("WarningMaterial"));
|
||||
|
||||
Con::errorf( "DecalDataFile::read() - DecalData %s does not exist! Temporarily created %s_missing.", lookupName.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
allDatablocks[ i ] = data;
|
||||
}
|
||||
|
||||
U8 dataIndex;
|
||||
DecalData *data;
|
||||
|
||||
// Now read all the DecalInstance(s).
|
||||
stream.read( &count );
|
||||
for ( U32 i = 0; i < count; i++ )
|
||||
{
|
||||
DecalInstance *inst = _allocateInstance();
|
||||
|
||||
stream.read( &dataIndex );
|
||||
mathRead( stream, &inst->mPosition );
|
||||
mathRead( stream, &inst->mNormal );
|
||||
mathRead( stream, &inst->mTangent );
|
||||
stream.read( &inst->mTextureRectIdx );
|
||||
stream.read( &inst->mSize );
|
||||
stream.read( &inst->mRenderPriority );
|
||||
|
||||
inst->mVisibility = 1.0f;
|
||||
inst->mFlags = PermanentDecal | SaveDecal | ClipDecal;
|
||||
inst->mCreateTime = Sim::getCurrentTime();
|
||||
inst->mVerts = NULL;
|
||||
inst->mIndices = NULL;
|
||||
inst->mVertCount = 0;
|
||||
inst->mIndxCount = 0;
|
||||
|
||||
data = allDatablocks[ dataIndex ];
|
||||
|
||||
if ( data )
|
||||
{
|
||||
inst->mDataBlock = data;
|
||||
|
||||
_addDecalToSpheres( inst );
|
||||
|
||||
// onload set instances should get added to the appropriate vec
|
||||
inst->mId = gDecalManager->mDecalInstanceVec.size();
|
||||
gDecalManager->mDecalInstanceVec.push_back(inst);
|
||||
}
|
||||
else
|
||||
{
|
||||
_freeInstance( inst );
|
||||
Con::errorf( "DecalDataFile::read - cannot find DecalData for DecalInstance read from disk." );
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the dirty flag.
|
||||
mIsDirty = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DecalInstance* DecalDataFile::addDecal( const Point3F& pos, const Point3F& normal, const Point3F& tangent,
|
||||
DecalData* decalData, F32 decalScale, S32 decalTexIndex, U8 flags )
|
||||
{
|
||||
DecalInstance* newDecal = _allocateInstance();
|
||||
|
||||
newDecal->mRenderPriority = 0;
|
||||
newDecal->mCustomTex = NULL;
|
||||
newDecal->mId = -1;
|
||||
|
||||
newDecal->mPosition = pos;
|
||||
newDecal->mNormal = normal;
|
||||
newDecal->mTangent = tangent;
|
||||
|
||||
newDecal->mSize = decalData->size * decalScale;
|
||||
|
||||
newDecal->mDataBlock = decalData;
|
||||
|
||||
S32 frame = newDecal->mDataBlock->frame;
|
||||
// randomize the frame if the flag is set. this number is used directly below us
|
||||
// when calculating render coords
|
||||
if ( decalData->randomize )
|
||||
frame = gRandGen.randI();
|
||||
|
||||
frame %= getMax( decalData->texCoordCount, 0 ) + 1;
|
||||
|
||||
newDecal->mTextureRectIdx = frame;
|
||||
|
||||
newDecal->mVisibility = 1.0f;
|
||||
|
||||
newDecal->mLastAlpha = -1.0f;
|
||||
|
||||
newDecal->mCreateTime = Sim::getCurrentTime();
|
||||
|
||||
newDecal->mVerts = NULL;
|
||||
newDecal->mIndices = NULL;
|
||||
newDecal->mVertCount = 0;
|
||||
newDecal->mIndxCount = 0;
|
||||
|
||||
newDecal->mFlags = flags;
|
||||
newDecal->mFlags |= ClipDecal;
|
||||
|
||||
_addDecalToSpheres( newDecal );
|
||||
|
||||
return newDecal;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void DecalDataFile::_addDecalToSpheres( DecalInstance* inst )
|
||||
{
|
||||
// First try the sphere we have last inserted an item into, if there is one.
|
||||
// Given a good spatial locality of insertions, this is a reasonable first
|
||||
// guess as a good candidate.
|
||||
|
||||
if( mSphereWithLastInsertion && mSphereWithLastInsertion->tryAddItem( inst ) )
|
||||
return;
|
||||
|
||||
// Otherwise, go through the list and try to find an existing sphere that meets
|
||||
// our tolerances.
|
||||
|
||||
for( U32 i = 0; i < mSphereList.size(); i++ )
|
||||
{
|
||||
DecalSphere* sphere = mSphereList[i];
|
||||
|
||||
if( sphere == mSphereWithLastInsertion )
|
||||
continue;
|
||||
|
||||
if( sphere->tryAddItem( inst ) )
|
||||
{
|
||||
mSphereWithLastInsertion = sphere;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Didn't find a suitable existing sphere, so create a new one.
|
||||
|
||||
DecalSphere* sphere = new DecalSphere( inst->mPosition, inst->mSize / 2.f );
|
||||
|
||||
mSphereList.push_back( sphere );
|
||||
mSphereWithLastInsertion = sphere;
|
||||
|
||||
sphere->mItems.push_back( inst );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void DecalDataFile::removeDecal( DecalInstance *inst )
|
||||
{
|
||||
if( !_removeDecalFromSpheres( inst ) )
|
||||
return;
|
||||
|
||||
_freeInstance( inst );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool DecalDataFile::_removeDecalFromSpheres( DecalInstance *inst )
|
||||
{
|
||||
for( U32 i = 0; i < mSphereList.size(); i++ )
|
||||
{
|
||||
DecalSphere* sphere = mSphereList[ i ];
|
||||
Vector< DecalInstance* > &items = sphere->mItems;
|
||||
|
||||
// Try to remove the instance from the list of this sphere.
|
||||
// If that fails, the instance doesn't belong to this sphere
|
||||
// so continue.
|
||||
|
||||
if( !items.remove( inst ) )
|
||||
continue;
|
||||
|
||||
// If the sphere is now empty, remove it. Otherwise, update
|
||||
// it's bounds.
|
||||
|
||||
if( items.empty() )
|
||||
{
|
||||
if( mSphereWithLastInsertion == sphere )
|
||||
mSphereWithLastInsertion = NULL;
|
||||
|
||||
delete sphere;
|
||||
mSphereList.erase( i );
|
||||
}
|
||||
else
|
||||
sphere->updateWorldSphere();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void DecalDataFile::notifyDecalModified( DecalInstance *inst )
|
||||
{
|
||||
_removeDecalFromSpheres( inst );
|
||||
_addDecalToSpheres( inst );
|
||||
}
|
||||
133
Engine/source/T3D/decal/decalDataFile.h
Normal file
133
Engine/source/T3D/decal/decalDataFile.h
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _DECALDATAFILE_H_
|
||||
#define _DECALDATAFILE_H_
|
||||
|
||||
#ifndef _DATACHUNKER_H_
|
||||
#include "core/dataChunker.h"
|
||||
#endif
|
||||
|
||||
#ifndef _TVECTOR_H_
|
||||
#include "core/util/tVector.h"
|
||||
#endif
|
||||
|
||||
#ifndef _DECALSPHERE_H_
|
||||
#include "T3D/decal/decalSphere.h"
|
||||
#endif
|
||||
|
||||
|
||||
class Stream;
|
||||
class DecalData;
|
||||
|
||||
|
||||
|
||||
/// This is the data file for decals.
|
||||
/// Not intended to be used directly, do your work with decals
|
||||
/// via the DecalManager.
|
||||
class DecalDataFile
|
||||
{
|
||||
protected:
|
||||
|
||||
enum { FILE_VERSION = 5 };
|
||||
|
||||
/// Set to true if the file is dirty and
|
||||
/// needs to be saved before being destroyed.
|
||||
bool mIsDirty;
|
||||
|
||||
/// @name Memory Management
|
||||
/// @{
|
||||
|
||||
/// Allocator for DecalInstances.
|
||||
FreeListChunker< DecalInstance > mChunker;
|
||||
|
||||
/// Allocate a new, uninitialized DecalInstance.
|
||||
DecalInstance* _allocateInstance() { return mChunker.alloc(); }
|
||||
|
||||
/// Free the memory of the given DecalInstance.
|
||||
void _freeInstance( DecalInstance *decal ) { mChunker.free( decal ); }
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Instance Management
|
||||
/// @{
|
||||
|
||||
/// The decal sphere that we have last insert an item into. This sphere
|
||||
/// is most likely to be a good candidate for the next insertion so
|
||||
/// test this sphere first.
|
||||
DecalSphere* mSphereWithLastInsertion;
|
||||
|
||||
/// List of bounding sphere shapes that contain and organize
|
||||
/// DecalInstances for optimized culling and lookup.
|
||||
Vector< DecalSphere* > mSphereList;
|
||||
|
||||
/// Add the given decal to the sphere list.
|
||||
void _addDecalToSpheres( DecalInstance *inst );
|
||||
|
||||
/// Remove the decal from the sphere list.
|
||||
bool _removeDecalFromSpheres( DecalInstance *inst );
|
||||
|
||||
/// @}
|
||||
|
||||
public:
|
||||
|
||||
DecalDataFile();
|
||||
virtual ~DecalDataFile();
|
||||
|
||||
Vector< DecalSphere* >& getSphereList() { return mSphereList; }
|
||||
const Vector< DecalSphere* >& getSphereList() const { return mSphereList; }
|
||||
|
||||
/// Return true if the decal data has been modified since the last save or load.
|
||||
bool isDirty() const { return mIsDirty; }
|
||||
|
||||
/// Deletes all the data and resets the
|
||||
/// file to an empty state.
|
||||
void clear();
|
||||
|
||||
/// @name I/O
|
||||
/// @{
|
||||
|
||||
/// Write the decal data to the given stream.
|
||||
bool write( Stream& stream );
|
||||
|
||||
/// Read the decal data from the given stream.
|
||||
bool read( Stream& stream );
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Decal Management
|
||||
/// @{
|
||||
|
||||
/// Create a new decal in this file using the given data.
|
||||
DecalInstance* addDecal( const Point3F& pos, const Point3F& normal, const Point3F& tangent,
|
||||
DecalData* decalData, F32 decalScale, S32 decalTexIndex, U8 flags );
|
||||
|
||||
/// Remove a decal from the file.
|
||||
void removeDecal( DecalInstance *inst );
|
||||
|
||||
/// Let the file know that the data of the given decal has changed.
|
||||
void notifyDecalModified( DecalInstance *inst );
|
||||
|
||||
/// @}
|
||||
};
|
||||
|
||||
#endif // _DECALDATAFILE_H_
|
||||
73
Engine/source/T3D/decal/decalInstance.cpp
Normal file
73
Engine/source/T3D/decal/decalInstance.cpp
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 "T3D/decal/decalInstance.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
|
||||
void DecalInstance::getWorldMatrix( MatrixF *outMat, bool flip )
|
||||
{
|
||||
outMat->setPosition( mPosition );
|
||||
|
||||
Point3F fvec;
|
||||
mCross( mNormal, mTangent, &fvec );
|
||||
|
||||
outMat->setColumn( 0, mTangent );
|
||||
outMat->setColumn( 1, fvec );
|
||||
outMat->setColumn( 2, mNormal );
|
||||
}
|
||||
|
||||
F32 DecalInstance::calcPixelSize( U32 viewportHeight, const Point3F &cameraPos, F32 worldToScreenScaleY ) const
|
||||
{
|
||||
// If fadeStartPixelSize is set less than zero this is interpreted to mean
|
||||
// pixelSize based fading is disabled and the decal always renders.
|
||||
// Returning a value of F32_MAX should be treated by the caller as
|
||||
// meaning "big enough to render at normal quality, dont LOD me.".
|
||||
if ( mDataBlock->fadeStartPixelSize < 0.0f )
|
||||
return F32_MAX;
|
||||
|
||||
// This is an approximation since mSize is actually the xyz size of the
|
||||
// cube we use to clip geometry for the decal. In this case we are assuming
|
||||
// it is appropriate to use the radius of the sphere 'inscribed' in that
|
||||
// cube as the equivalent of mShape->radius for purposes of calculating
|
||||
// the pixelScale ( see TSShapeInstance::setDetailFromDistance ).
|
||||
const F32 radius = mSize * 0.5f;
|
||||
|
||||
// Approximate distance to the decal.
|
||||
const F32 distance = ( cameraPos - mPosition ).len() - radius;
|
||||
|
||||
// We are inside the decal's volume. There is no useful pixelSize for us
|
||||
// to return, it is essentially the entire screen.
|
||||
if ( distance <= 0.0f )
|
||||
return F32_MAX;
|
||||
|
||||
// Lod is relative to a viewport with a heigh of 300. Could prescale this into decalSize...
|
||||
const F32 pixelScale = viewportHeight / 300.0f;
|
||||
|
||||
// Inline of SceneState::projectRadius.
|
||||
const F32 pixelSize = mSize / distance * worldToScreenScaleY * pixelScale;
|
||||
|
||||
// Optionally scale pixelSize by a detail adjust value here...
|
||||
// eg. pixelSize *= TSDetailAdjust...
|
||||
|
||||
return pixelSize;
|
||||
}
|
||||
93
Engine/source/T3D/decal/decalInstance.h
Normal file
93
Engine/source/T3D/decal/decalInstance.h
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _DECALINSTANCE_H_
|
||||
#define _DECALINSTANCE_H_
|
||||
|
||||
#ifndef _GFXVERTEXBUFFER_H_
|
||||
#include "gfx/gfxVertexBuffer.h"
|
||||
#endif
|
||||
|
||||
#ifndef _DECALDATA_H_
|
||||
#include "T3D/decal/decalData.h"
|
||||
#endif
|
||||
|
||||
struct DecalVertex;
|
||||
class SceneRenderState;
|
||||
|
||||
/// DecalInstance represents a rendering decal in the scene.
|
||||
/// You should not allocate this yourself, add new decals to the scene
|
||||
/// via the DecalManager.
|
||||
/// All data is public, change it if you wish, but be sure to inform
|
||||
/// the DecalManager.
|
||||
class DecalInstance
|
||||
{
|
||||
public:
|
||||
|
||||
DecalData *mDataBlock;
|
||||
|
||||
Point3F mPosition;
|
||||
Point3F mNormal;
|
||||
Point3F mTangent;
|
||||
F32 mRotAroundNormal;
|
||||
F32 mSize;
|
||||
|
||||
U32 mCreateTime;
|
||||
F32 mVisibility;
|
||||
|
||||
F32 mLastAlpha;
|
||||
|
||||
U32 mTextureRectIdx;
|
||||
|
||||
DecalVertex *mVerts;
|
||||
U16 *mIndices;
|
||||
|
||||
U32 mVertCount;
|
||||
U32 mIndxCount;
|
||||
|
||||
U8 mFlags;
|
||||
|
||||
U8 mRenderPriority;
|
||||
|
||||
S32 mId;
|
||||
|
||||
GFXTexHandle *mCustomTex;
|
||||
|
||||
void getWorldMatrix( MatrixF *outMat, bool flip = false );
|
||||
|
||||
Box3F getWorldBox() const
|
||||
{
|
||||
return Box3F( mPosition - Point3F( mSize / 2.f ), mPosition + Point3F( mSize / 2.f ) );
|
||||
}
|
||||
|
||||
U8 getRenderPriority() const
|
||||
{
|
||||
return mRenderPriority == 0 ? mDataBlock->renderPriority : mRenderPriority;
|
||||
}
|
||||
|
||||
/// Calculates the size of this decal onscreen in pixels, used for LOD.
|
||||
F32 calcPixelSize( U32 viewportHeight, const Point3F &cameraPos, F32 worldToScreenScaleY ) const;
|
||||
|
||||
DecalInstance() : mId(-1) {}
|
||||
};
|
||||
|
||||
#endif // _DECALINSTANCE_H_
|
||||
1707
Engine/source/T3D/decal/decalManager.cpp
Normal file
1707
Engine/source/T3D/decal/decalManager.cpp
Normal file
File diff suppressed because it is too large
Load diff
278
Engine/source/T3D/decal/decalManager.h
Normal file
278
Engine/source/T3D/decal/decalManager.h
Normal file
|
|
@ -0,0 +1,278 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _DECALMANAGER_H_
|
||||
#define _DECALMANAGER_H_
|
||||
|
||||
#ifndef _SCENEOBJECT_H_
|
||||
#include "scene/sceneObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MATHUTIL_FRUSTUM_H_
|
||||
#include "math/util/frustum.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GFXPRIMITIVEBUFFER_H_
|
||||
#include "gfx/gfxPrimitiveBuffer.h"
|
||||
#endif
|
||||
|
||||
#ifndef _GFXDEVICE_H_
|
||||
#include "gfx/gfxDevice.h"
|
||||
#endif
|
||||
|
||||
#ifndef _CLIPPEDPOLYLIST_H_
|
||||
#include "collision/clippedPolyList.h"
|
||||
#endif
|
||||
|
||||
#ifndef _DECALDATAFILE_H_
|
||||
#include "decalDataFile.h"
|
||||
#endif
|
||||
|
||||
#ifndef __RESOURCE_H__
|
||||
#include "core/resource.h"
|
||||
#endif
|
||||
|
||||
#ifndef _DECALINSTANCE_H_
|
||||
#include "decalInstance.h"
|
||||
#endif
|
||||
|
||||
#ifndef _TSIGNAL_H_
|
||||
#include "core/util/tSignal.h"
|
||||
#endif
|
||||
|
||||
#ifndef _DATACHUNKER_H_
|
||||
#include "core/dataChunker.h"
|
||||
#endif
|
||||
|
||||
|
||||
//#define DECALMANAGER_DEBUG
|
||||
|
||||
|
||||
struct ObjectRenderInst;
|
||||
class Material;
|
||||
|
||||
|
||||
enum DecalFlags
|
||||
{
|
||||
PermanentDecal = 1 << 0,
|
||||
SaveDecal = 1 << 1,
|
||||
ClipDecal = 1 << 2,
|
||||
CustomDecal = 1 << 3 // DecalManager will not attempt to clip or remove this decal
|
||||
// it is managed by someone else.
|
||||
};
|
||||
|
||||
|
||||
/// Manage decals in the scene.
|
||||
class DecalManager : public SceneObject
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SceneObject Parent;
|
||||
|
||||
// [rene, 11-Mar-11] This vector is very poorly managed; the logic is spread all over the place
|
||||
Vector<DecalInstance *> mDecalInstanceVec;
|
||||
|
||||
protected:
|
||||
|
||||
/// The clipper we keep around between decal updates
|
||||
/// to avoid excessive memory allocations.
|
||||
ClippedPolyList mClipper;
|
||||
|
||||
Vector<DecalInstance*> mDecalQueue;
|
||||
|
||||
StringTableEntry mDataFileName;
|
||||
Resource<DecalDataFile> mData;
|
||||
|
||||
Signal< void() > mClearDataSignal;
|
||||
|
||||
Vector< GFXVertexBufferHandle<DecalVertex>* > mVBs;
|
||||
Vector< GFXPrimitiveBufferHandle* > mPBs;
|
||||
|
||||
Vector< GFXVertexBufferHandle<DecalVertex>* > mVBPool;
|
||||
Vector< GFXPrimitiveBufferHandle* > mPBPool;
|
||||
|
||||
FreeListChunkerUntyped *mChunkers[3];
|
||||
|
||||
#ifdef DECALMANAGER_DEBUG
|
||||
Vector<PlaneF> mDebugPlanes;
|
||||
#endif
|
||||
|
||||
bool mDirty;
|
||||
|
||||
struct DecalBatch
|
||||
{
|
||||
U32 startDecal;
|
||||
U32 decalCount;
|
||||
U32 iCount;
|
||||
U32 vCount;
|
||||
U8 priority;
|
||||
Material *mat;
|
||||
BaseMatInstance *matInst;
|
||||
bool dynamic;
|
||||
};
|
||||
|
||||
/// Whether to render visualizations for debugging in the editor.
|
||||
static bool smDebugRender;
|
||||
|
||||
static bool smDecalsOn;
|
||||
static F32 smDecalLifeTimeScale;
|
||||
static bool smPoolBuffers;
|
||||
static const U32 smMaxVerts;
|
||||
static const U32 smMaxIndices;
|
||||
|
||||
// Assume that a class is already given for the object:
|
||||
// Point with coordinates {float x, y;}
|
||||
//===================================================================
|
||||
|
||||
// isLeft(): tests if a point is Left|On|Right of an infinite line.
|
||||
// Input: three points P0, P1, and P2
|
||||
// Return: >0 for P2 left of the line through P0 and P1
|
||||
// =0 for P2 on the line
|
||||
// <0 for P2 right of the line
|
||||
// See: the January 2001 Algorithm on Area of Triangles
|
||||
inline F32 isLeft( const Point3F &P0, const Point3F &P1, const Point3F &P2 )
|
||||
{
|
||||
return (P1.x - P0.x)*(P2.y - P0.y) - (P2.x - P0.x)*(P1.y - P0.y);
|
||||
}
|
||||
|
||||
U32 _generateConvexHull( const Vector<Point3F> &points, Vector<Point3F> *outPoints );
|
||||
|
||||
// Rendering
|
||||
void prepRenderImage( SceneRenderState *state );
|
||||
|
||||
void _generateWindingOrder( const Point3F &cornerPoint, Vector<Point3F> *sortPoints );
|
||||
|
||||
// Helpers for creating and deleting the vert and index arrays
|
||||
// held by DecalInstance.
|
||||
void _allocBuffers( DecalInstance *inst );
|
||||
void _freeBuffers( DecalInstance *inst );
|
||||
void _freePools();
|
||||
|
||||
/// Returns index used to index into the correct sized FreeListChunker for
|
||||
/// allocating vertex and index arrays.
|
||||
S32 _getSizeClass( DecalInstance *inst ) const;
|
||||
|
||||
// Hide this from Doxygen
|
||||
/// @cond
|
||||
bool _handleGFXEvent(GFXDevice::GFXDeviceEventType event);
|
||||
/// @endcond
|
||||
|
||||
void _renderDecalSpheres( ObjectRenderInst* inst, SceneRenderState* state, BaseMatInstance* overrideMat );
|
||||
|
||||
///
|
||||
void _handleZoningChangedEvent( SceneZoneSpaceManager* zoneManager );
|
||||
|
||||
bool _createDataFile();
|
||||
|
||||
// SceneObject.
|
||||
virtual bool onSceneAdd();
|
||||
virtual void onSceneRemove(); public:
|
||||
|
||||
public:
|
||||
|
||||
DecalManager();
|
||||
~DecalManager();
|
||||
|
||||
/// @name Decal Addition
|
||||
/// @{
|
||||
|
||||
/// Adds a decal using a normal and a rotation.
|
||||
///
|
||||
/// @param pos The 3d position for the decal center.
|
||||
/// @param normal The decal up vector.
|
||||
/// @param rotAroundNormal The decal rotation around the normal.
|
||||
/// @param decalData The datablock which defines this decal.
|
||||
/// @param decalScale A scalar for adjusting the default size of the decal.
|
||||
/// @param decalTexIndex Selects the texture coord index within the decal
|
||||
/// data to use. If it is less than zero then a random
|
||||
/// coord is selected.
|
||||
/// @param flags The decal flags. @see DecalFlags
|
||||
///
|
||||
DecalInstance* addDecal( const Point3F &pos,
|
||||
const Point3F &normal,
|
||||
F32 rotAroundNormal,
|
||||
DecalData *decalData,
|
||||
F32 decalScale = 1.0f,
|
||||
S32 decalTexIndex = 0,
|
||||
U8 flags = 0x000 );
|
||||
|
||||
/// Adds a decal using a normal and a tangent.
|
||||
///
|
||||
/// @param pos The 3d position for the decal center.
|
||||
/// @param normal The decal up vector.
|
||||
/// @param tanget The decal right vector.
|
||||
/// @param decalData The datablock which defines this decal.
|
||||
/// @param decalScale A scalar for adjusting the default size of the decal.
|
||||
/// @param decalTexIndex Selects the texture coord index within the decal
|
||||
/// data to use. If it is less than zero then a random
|
||||
/// coord is selected.
|
||||
/// @param flags The decal flags. @see DecalFlags
|
||||
///
|
||||
DecalInstance* addDecal( const Point3F &pos,
|
||||
const Point3F &normal,
|
||||
const Point3F &tangent,
|
||||
DecalData *decalData,
|
||||
F32 decalScale = 1.0f,
|
||||
S32 decalTexIndex = 0,
|
||||
U8 flags = 0 );
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Decal Removal
|
||||
/// @{
|
||||
|
||||
void removeDecal( DecalInstance *inst );
|
||||
|
||||
/// @}
|
||||
|
||||
DecalInstance* getDecal( S32 id );
|
||||
|
||||
DecalInstance* getClosestDecal( const Point3F &pos );
|
||||
|
||||
/// Return the closest DecalInstance hit by a ray.
|
||||
DecalInstance* raycast( const Point3F &start, const Point3F &end, bool savedDecalsOnly = true );
|
||||
|
||||
//void dataDeleted( DecalData *data );
|
||||
|
||||
void saveDecals( const UTF8 *fileName );
|
||||
bool loadDecals( const UTF8 *fileName );
|
||||
void clearData();
|
||||
|
||||
/// Returns true if changes have been made since the last load/save
|
||||
bool isDirty() const { return mDirty; }
|
||||
|
||||
bool clipDecal( DecalInstance *decal, Vector<Point3F> *edgeVerts = NULL, const Point2F *clipDepth = NULL );
|
||||
|
||||
void notifyDecalModified( DecalInstance *inst );
|
||||
|
||||
Signal< void() >& getClearDataSignal() { return mClearDataSignal; }
|
||||
|
||||
Resource<DecalDataFile> getDecalDataFile() { return mData; }
|
||||
|
||||
// SimObject.
|
||||
DECLARE_CONOBJECT( DecalManager );
|
||||
static void consoleInit();
|
||||
};
|
||||
|
||||
extern DecalManager* gDecalManager;
|
||||
|
||||
#endif // _DECALMANAGER_H_
|
||||
109
Engine/source/T3D/decal/decalSphere.cpp
Normal file
109
Engine/source/T3D/decal/decalSphere.cpp
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 "T3D/decal/decalSphere.h"
|
||||
|
||||
#include "scene/zones/sceneZoneSpaceManager.h"
|
||||
#include "T3D/decal/decalInstance.h"
|
||||
|
||||
|
||||
F32 DecalSphere::smDistanceTolerance = 30.0f;
|
||||
F32 DecalSphere::smRadiusTolerance = 40.0f;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool DecalSphere::tryAddItem( DecalInstance* inst )
|
||||
{
|
||||
// If we are further away from the center than our tolerance
|
||||
// allows, don't use this sphere.
|
||||
//
|
||||
// Note that we take the distance from the nearest point on the
|
||||
// bounding sphere rather than the distance to the center of the
|
||||
// decal. This takes decal sizes into account and generally works
|
||||
// better.
|
||||
|
||||
const F32 distCenterToCenter = ( mWorldSphere.center - inst->mPosition ).len();
|
||||
const F32 distBoundsToCenter = distCenterToCenter - inst->mSize / 2.f;
|
||||
|
||||
if( distBoundsToCenter > smDistanceTolerance )
|
||||
return false;
|
||||
|
||||
// Also, if adding the current decal to the sphere would make
|
||||
// it larger than our radius tolerance, don't use it.
|
||||
|
||||
const F32 newRadius = distCenterToCenter + inst->mSize / 2.f + 0.5f;
|
||||
if( newRadius > mWorldSphere.radius && newRadius > smRadiusTolerance )
|
||||
return false;
|
||||
|
||||
// Otherwise, go with this sphere and add the item to it.
|
||||
|
||||
mItems.push_back( inst );
|
||||
|
||||
// Update the sphere bounds, if necessary.
|
||||
|
||||
if( newRadius > mWorldSphere.radius )
|
||||
updateWorldSphere();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void DecalSphere::updateWorldSphere()
|
||||
{
|
||||
AssertFatal( mItems.size() >= 1, "DecalSphere::updateWorldSphere - Sphere is empty!" );
|
||||
|
||||
Box3F aabb( mItems[ 0 ]->getWorldBox() );
|
||||
|
||||
const U32 numItems = mItems.size();
|
||||
for( U32 i = 1; i < numItems; ++ i )
|
||||
aabb.intersect( mItems[ i ]->getWorldBox() );
|
||||
|
||||
mWorldSphere = aabb.getBoundingSphere();
|
||||
|
||||
// Clear the zoning data so that it gets recomputed.
|
||||
mZones.clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void DecalSphere::updateZoning( SceneZoneSpaceManager* zoneManager )
|
||||
{
|
||||
mZones.clear();
|
||||
|
||||
// If there's only a single zone in the world, it must be the
|
||||
// outdoor zone, so there's no point maintaining zoning information
|
||||
// on all the decalspheres.
|
||||
|
||||
if( zoneManager->getNumZones() == 1 )
|
||||
return;
|
||||
|
||||
// Otherwise query the scene graph for all zones that intersect with the
|
||||
// AABB around our world sphere.
|
||||
|
||||
Box3F aabb( mWorldSphere.radius );
|
||||
aabb.setCenter( mWorldSphere.center );
|
||||
|
||||
zoneManager->findZones( aabb, mZones );
|
||||
}
|
||||
83
Engine/source/T3D/decal/decalSphere.h
Normal file
83
Engine/source/T3D/decal/decalSphere.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _DECALSPHERE_H_
|
||||
#define _DECALSPHERE_H_
|
||||
|
||||
#ifndef _TVECTOR_H_
|
||||
#include "core/util/tVector.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MSPHERE_H_
|
||||
#include "math/mSphere.h"
|
||||
#endif
|
||||
|
||||
|
||||
class DecalInstance;
|
||||
class SceneZoneSpaceManager;
|
||||
|
||||
|
||||
/// A bounding sphere in world space and a list of DecalInstance(s)
|
||||
/// contained by it. DecalInstance(s) are organized/binned in this fashion
|
||||
/// as a lookup and culling optimization.
|
||||
class DecalSphere
|
||||
{
|
||||
public:
|
||||
|
||||
static F32 smDistanceTolerance;
|
||||
static F32 smRadiusTolerance;
|
||||
|
||||
DecalSphere()
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mItems );
|
||||
VECTOR_SET_ASSOCIATION( mZones );
|
||||
}
|
||||
DecalSphere( const Point3F &position, F32 radius )
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mItems );
|
||||
VECTOR_SET_ASSOCIATION( mZones );
|
||||
|
||||
mWorldSphere.center = position;
|
||||
mWorldSphere.radius = radius;
|
||||
}
|
||||
|
||||
/// Recompute #mWorldSphere from the current instance list.
|
||||
void updateWorldSphere();
|
||||
|
||||
/// Recompute the zoning information from the current bounds.
|
||||
void updateZoning( SceneZoneSpaceManager* zoneManager );
|
||||
|
||||
/// Decal instances in this sphere.
|
||||
Vector< DecalInstance* > mItems;
|
||||
|
||||
/// Zones that intersect with this sphere. If this is empty, the zoning
|
||||
/// state of the sphere is uninitialized.
|
||||
Vector< U32 > mZones;
|
||||
|
||||
/// World-space sphere corresponding to this DecalSphere.
|
||||
SphereF mWorldSphere;
|
||||
|
||||
///
|
||||
bool tryAddItem( DecalInstance* inst );
|
||||
};
|
||||
|
||||
#endif // !_DECALSPHERE_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue