2018-09-17 03:15:07 +00:00
//-----------------------------------------------------------------------------
// 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 "T3D/lighting/reflectionProbe.h"
# include "math/mathIO.h"
# include "scene/sceneRenderState.h"
# include "console/consoleTypes.h"
# include "core/stream/bitStream.h"
# include "materials/baseMatInstance.h"
# include "console/engineAPI.h"
# include "gfx/gfxDrawUtil.h"
# include "gfx/gfxDebugEvent.h"
# include "gfx/gfxTransformSaver.h"
# include "math/mathUtils.h"
# include "gfx/bitmap/gBitmap.h"
# include "core/stream/fileStream.h"
# include "core/fileObject.h"
# include "core/resourceManager.h"
2019-08-19 06:14:34 +00:00
# include "console/simPersistID.h"
2018-09-17 03:15:07 +00:00
# include "T3D/gameFunctions.h"
# include "postFx/postEffect.h"
# include "renderInstance/renderProbeMgr.h"
2019-01-26 08:05:18 +00:00
# include "renderInstance/renderProbeMgr.h"
2018-09-17 03:15:07 +00:00
# include "math/util/sphereMesh.h"
# include "materials/materialManager.h"
# include "math/util/matrixSet.h"
# include "gfx/bitmap/cubemapSaver.h"
# include "materials/materialFeatureTypes.h"
# include "gfx/gfxTextureManager.h"
# include "T3D/lighting/IBLUtilities.h"
2019-02-13 06:37:50 +00:00
# include "scene/reflector.h"
2018-09-17 03:15:07 +00:00
extern bool gEditingMission ;
extern ColorI gCanvasClearColor ;
bool ReflectionProbe : : smRenderPreviewProbes = true ;
IMPLEMENT_CO_NETOBJECT_V1 ( ReflectionProbe ) ;
ConsoleDocClass ( ReflectionProbe ,
" @brief An example scene object which renders a mesh. \n \n "
" This class implements a basic SceneObject that can exist in the world at a "
" 3D position and render itself. There are several valid ways to render an "
" object in Torque. This class implements the preferred rendering method which "
" is to submit a MeshRenderInst along with a Material, vertex buffer, "
" primitive buffer, and transform and allow the RenderMeshMgr handle the "
" actual setup and rendering for you. \n \n "
" See the C++ code for implementation details. \n \n "
" @ingroup Examples \n " ) ;
ImplementEnumType ( ReflectProbeType ,
" Type of mesh data available in a shape. \n "
" @ingroup gameObjects " )
2022-02-12 21:53:40 +00:00
{ ReflectionProbe : : ProbeInfo : : Sphere , " Sphere " , " Sphere shaped " } ,
{ ReflectionProbe : : ProbeInfo : : Box , " Box " , " Box shape " }
2018-09-17 03:15:07 +00:00
EndImplementEnumType ;
ImplementEnumType ( ReflectionModeEnum ,
" Type of mesh data available in a shape. \n "
" @ingroup gameObjects " )
{ ReflectionProbe : : NoReflection , " No Reflections " , " This probe does not provide any local reflection data " } ,
{ ReflectionProbe : : StaticCubemap , " Static Cubemap " , " Uses a static CubemapData " } ,
{ ReflectionProbe : : BakedCubemap , " Baked Cubemap " , " Uses a cubemap baked from the probe's current position " } ,
2020-10-19 05:53:09 +00:00
//{ ReflectionProbe::DynamicCubemap, "Dynamic Cubemap", "Uses a cubemap baked from the probe's current position, updated at a set rate" },
2018-09-17 03:15:07 +00:00
EndImplementEnumType ;
//-----------------------------------------------------------------------------
// Object setup and teardown
//-----------------------------------------------------------------------------
2020-10-19 05:53:09 +00:00
ReflectionProbe : : ReflectionProbe ( )
2018-09-17 03:15:07 +00:00
{
// Flag this object so that it will always
// be sent across the network to clients
mNetFlags . set ( Ghostable | ScopeAlways ) ;
mTypeMask = LightObjectType | MarkerObjectType ;
2022-02-12 21:53:40 +00:00
mProbeShapeType = ProbeInfo : : Box ;
2018-09-17 03:15:07 +00:00
mReflectionModeType = BakedCubemap ;
mEnabled = true ;
2020-10-19 05:53:09 +00:00
mBakeReflections = false ;
2019-06-04 05:21:52 +00:00
mCubemapDirty = false ;
2018-09-17 03:15:07 +00:00
mRadius = 10 ;
2019-03-02 10:48:07 +00:00
mObjScale = Point3F : : One * 10 ;
2019-02-19 14:58:02 +00:00
mProbeRefScale = Point3F : : One * 10 ;
2018-09-17 03:15:07 +00:00
2018-12-05 10:01:58 +00:00
mUseHDRCaptures = true ;
2018-10-26 06:19:14 +00:00
2021-07-31 22:04:31 +00:00
mCubemapName = StringTable - > EmptyString ( ) ;
2018-09-17 06:52:18 +00:00
mStaticCubemap = NULL ;
2018-09-17 03:15:07 +00:00
mProbeUniqueID = " " ;
2022-06-13 17:38:08 +00:00
# ifdef TORQUE_TOOLS
2018-09-17 03:15:07 +00:00
mEditorShapeInst = NULL ;
mEditorShape = NULL ;
2022-06-13 17:38:08 +00:00
# endif
2020-10-19 05:53:09 +00:00
mRefreshRateMS = 200 ;
2018-09-17 03:15:07 +00:00
mDynamicLastBakeMS = 0 ;
mResourcesCreated = false ;
mPrefilterSize = 64 ;
2020-10-19 05:53:09 +00:00
mPrefilterMipLevels = mLog2 ( F32 ( mPrefilterSize ) ) ;
2018-09-17 06:52:18 +00:00
mPrefilterMap = nullptr ;
mIrridianceMap = nullptr ;
2019-02-19 14:58:02 +00:00
mProbeRefOffset = Point3F : : Zero ;
2018-09-17 06:52:18 +00:00
mEditPosOffset = false ;
2018-11-19 07:18:09 +00:00
2018-11-21 05:53:02 +00:00
mCaptureMask = REFLECTION_PROBE_CAPTURE_TYPEMASK ;
2018-09-17 03:15:07 +00:00
}
ReflectionProbe : : ~ ReflectionProbe ( )
{
2022-06-13 17:38:08 +00:00
# ifdef TORQUE_TOOLS
2018-09-17 03:15:07 +00:00
if ( mEditorShapeInst )
SAFE_DELETE ( mEditorShapeInst ) ;
2022-06-13 17:38:08 +00:00
# endif
2019-06-05 05:07:46 +00:00
if ( mReflectionModeType = = StaticCubemap & & mStaticCubemap )
2018-09-17 06:52:18 +00:00
mStaticCubemap - > deleteObject ( ) ;
2018-09-17 03:15:07 +00:00
}
//-----------------------------------------------------------------------------
// Object Editing
//-----------------------------------------------------------------------------
void ReflectionProbe : : initPersistFields ( )
{
addGroup ( " Rendering " ) ;
addProtectedField ( " enabled " , TypeBool , Offset ( mEnabled , ReflectionProbe ) ,
2020-10-19 05:53:09 +00:00
& _setEnabled , & defaultProtectedGetFn , " Is the probe enabled or not " ) ;
2018-09-17 06:52:18 +00:00
endGroup ( " Rendering " ) ;
2018-09-17 03:15:07 +00:00
addGroup ( " Reflection " ) ;
2019-03-02 10:48:07 +00:00
addProtectedField ( " radius " , TypeF32 , Offset ( mRadius , ReflectionProbe ) , & _setRadius , & defaultProtectedGetFn ,
" The name of the material used to render the mesh. " ) ;
addProtectedField ( " EditPosOffset " , TypeBool , Offset ( mEditPosOffset , ReflectionProbe ) ,
& _toggleEditPosOffset , & defaultProtectedGetFn , " Toggle Edit Pos Offset Mode " , AbstractClassRep : : FieldFlags : : FIELD_ComponentInspectors ) ;
2020-10-19 05:53:09 +00:00
addField ( " refOffset " , TypePoint3F , Offset ( mProbeRefOffset , ReflectionProbe ) , " The reference positional offset for the probe. This is used for adjusting the perceived center and area of influence. \n Helpful in adjusting parallax issues " ) ;
addField ( " refScale " , TypePoint3F , Offset ( mProbeRefScale , ReflectionProbe ) , " The reference scale for the probe. This is used for adjusting the perceived center and area of influence. \n Helpful in adjusting parallax issues " ) ;
2019-03-02 10:48:07 +00:00
addProtectedField ( " ReflectionMode " , TypeReflectionModeEnum , Offset ( mReflectionModeType , ReflectionProbe ) , & _setReflectionMode , & defaultProtectedGetFn ,
2020-10-19 05:53:09 +00:00
" Used to dictate what sort of cubemap the probes use when using IBL. " ) ;
2018-09-17 03:15:07 +00:00
2020-10-19 05:53:09 +00:00
addField ( " StaticCubemap " , TypeCubemapName , Offset ( mCubemapName , ReflectionProbe ) , " This is used when a static cubemap is used. The name of the cubemap is looked up and loaded for the IBL calculations. " ) ;
2018-09-17 03:15:07 +00:00
2020-10-19 05:53:09 +00:00
//addField("DynamicReflectionRefreshMS", TypeS32, Offset(mRefreshRateMS, ReflectionProbe), "How often the dynamic cubemap is refreshed in milliseconds. Only works when the ReflectionMode is set to DynamicCubemap.");
2020-09-11 07:13:05 +00:00
2020-10-19 05:53:09 +00:00
addProtectedField ( " Bake " , TypeBool , Offset ( mBakeReflections , ReflectionProbe ) ,
& _doBake , & defaultProtectedGetFn , " Bake Probe Reflections " , AbstractClassRep : : FieldFlags : : FIELD_ComponentInspectors ) ;
2018-09-17 03:15:07 +00:00
endGroup ( " Reflection " ) ;
2019-01-26 08:05:18 +00:00
Con : : addVariable ( " $Light::renderReflectionProbes " , TypeBool , & RenderProbeMgr : : smRenderReflectionProbes ,
2018-09-17 03:15:07 +00:00
" Toggles rendering of light frustums when the light is selected in the editor. \n \n "
" @note Only works for shadow mapped lights. \n \n "
" @ingroup Lighting " ) ;
Con : : addVariable ( " $Light::renderPreviewProbes " , TypeBool , & ReflectionProbe : : smRenderPreviewProbes ,
" Toggles rendering of light frustums when the light is selected in the editor. \n \n "
" @note Only works for shadow mapped lights. \n \n "
" @ingroup Lighting " ) ;
// SceneObject already handles exposing the transform
Parent : : initPersistFields ( ) ;
}
void ReflectionProbe : : inspectPostApply ( )
{
Parent : : inspectPostApply ( ) ;
mDirty = true ;
2019-11-22 07:30:49 +00:00
bool liveUpdates = Con : : getBoolVariable ( " $Probes::liveUpdates " , false ) ;
if ( liveUpdates )
{
bake ( ) ;
}
2018-09-17 03:15:07 +00:00
// Flag the network mask to send the updates
// to the client object
setMaskBits ( - 1 ) ;
}
bool ReflectionProbe : : _setEnabled ( void * object , const char * index , const char * data )
{
ReflectionProbe * probe = reinterpret_cast < ReflectionProbe * > ( object ) ;
probe - > mEnabled = dAtob ( data ) ;
2019-06-05 05:07:46 +00:00
probe - > setMaskBits ( EnabledMask ) ;
2018-09-17 03:15:07 +00:00
return true ;
}
bool ReflectionProbe : : _doBake ( void * object , const char * index , const char * data )
{
ReflectionProbe * probe = reinterpret_cast < ReflectionProbe * > ( object ) ;
2019-03-02 10:48:07 +00:00
probe - > bake ( ) ;
2019-06-05 05:07:46 +00:00
probe - > setMaskBits ( StaticDataMask ) ;
2018-09-17 06:52:18 +00:00
return false ;
}
bool ReflectionProbe : : _toggleEditPosOffset ( void * object , const char * index , const char * data )
{
ReflectionProbe * probe = reinterpret_cast < ReflectionProbe * > ( object ) ;
probe - > mEditPosOffset = ! probe - > mEditPosOffset ;
2018-09-17 03:15:07 +00:00
return false ;
}
2019-03-02 10:48:07 +00:00
bool ReflectionProbe : : _setRadius ( void * object , const char * index , const char * data )
{
ReflectionProbe * probe = reinterpret_cast < ReflectionProbe * > ( object ) ;
2022-02-12 21:53:40 +00:00
if ( probe - > mProbeShapeType ! = ProbeInfo : : Sphere )
2019-03-02 10:48:07 +00:00
return false ;
probe - > mObjScale = Point3F ( probe - > mRadius , probe - > mRadius , probe - > mRadius ) ;
2019-06-05 05:07:46 +00:00
probe - > setMaskBits ( StaticDataMask ) ;
2019-03-02 10:48:07 +00:00
return true ;
}
bool ReflectionProbe : : _setReflectionMode ( void * object , const char * index , const char * data )
{
ReflectionProbe * probe = reinterpret_cast < ReflectionProbe * > ( object ) ;
2020-10-03 22:00:01 +00:00
if ( ! String : : compare ( data , " Static Cubemap " ) )
2019-03-02 10:48:07 +00:00
{
probe - > mReflectionModeType = StaticCubemap ;
}
2020-10-03 22:00:01 +00:00
else if ( ! String : : compare ( data , " Baked Cubemap " ) )
2019-03-02 10:48:07 +00:00
{
//Clear our cubemap if we changed it to be baked, just for cleanliness
probe - > mReflectionModeType = BakedCubemap ;
2021-07-31 22:04:31 +00:00
probe - > mCubemapName = StringTable - > EmptyString ( ) ;
2019-03-02 10:48:07 +00:00
}
2019-06-05 05:07:46 +00:00
probe - > setMaskBits ( StaticDataMask ) ;
2019-03-02 10:48:07 +00:00
return true ;
}
2018-09-17 03:15:07 +00:00
bool ReflectionProbe : : onAdd ( )
{
if ( ! Parent : : onAdd ( ) )
return false ;
2018-09-17 06:52:18 +00:00
mEditPosOffset = false ;
2019-03-02 10:48:07 +00:00
mObjBox . minExtents . set ( - 0.5 , - 0.5 , - 0.5 ) ;
mObjBox . maxExtents . set ( 0.5 , 0.5 , 0.5 ) ;
2018-09-17 03:15:07 +00:00
// Skip our transform... it just dirties mask bits.
Parent : : setTransform ( mObjToWorld ) ;
resetWorldBox ( ) ;
// Add this object to the scene
addToScene ( ) ;
if ( isServerObject ( ) )
{
if ( ! mPersistentId )
mPersistentId = getOrCreatePersistentId ( ) ;
2022-02-12 21:53:40 +00:00
mProbeUniqueID = mPersistentId - > getUUID ( ) . toString ( ) ;
2018-09-17 03:15:07 +00:00
}
// Refresh this object's material (if any)
if ( isClientObject ( ) )
2018-09-17 06:52:18 +00:00
{
2020-10-30 04:27:07 +00:00
if ( ! mResourcesCreated & & ! createClientResources ( ) )
2019-06-04 05:21:52 +00:00
return false ;
2018-09-17 06:52:18 +00:00
updateProbeParams ( ) ;
}
2018-09-17 03:15:07 +00:00
setMaskBits ( - 1 ) ;
return true ;
}
void ReflectionProbe : : onRemove ( )
{
2019-02-17 09:47:40 +00:00
if ( isClientObject ( ) )
{
2022-02-12 21:53:40 +00:00
PROBEMGR - > unregisterProbe ( & mProbeInfo ) ;
2019-02-17 09:47:40 +00:00
}
2019-06-04 05:21:52 +00:00
2018-09-17 03:15:07 +00:00
// Remove this object from the scene
removeFromScene ( ) ;
Parent : : onRemove ( ) ;
}
2018-12-10 06:46:28 +00:00
void ReflectionProbe : : handleDeleteAction ( )
2018-12-07 06:30:08 +00:00
{
//we're deleting it?
//Then we need to clear out the processed cubemaps(if we have them)
2019-06-04 05:21:52 +00:00
if ( mReflectionModeType ! = StaticCubemap )
2018-12-07 06:30:08 +00:00
{
2019-06-04 05:21:52 +00:00
String prefilPath = getPrefilterMapPath ( ) ;
2022-06-13 16:02:58 +00:00
if ( Torque : : FS : : IsFile ( prefilPath ) )
2019-06-04 05:21:52 +00:00
{
2022-06-13 16:02:58 +00:00
Torque : : FS : : Remove ( prefilPath ) ;
2019-06-04 05:21:52 +00:00
}
2018-12-07 06:30:08 +00:00
2019-06-04 05:21:52 +00:00
String irrPath = getIrradianceMapPath ( ) ;
2022-06-13 16:02:58 +00:00
if ( Torque : : FS : : IsFile ( irrPath ) )
2019-06-04 05:21:52 +00:00
{
2022-06-13 16:02:58 +00:00
Torque : : FS : : Remove ( irrPath ) ;
2019-06-04 05:21:52 +00:00
}
2018-12-07 06:30:08 +00:00
}
2018-12-10 06:46:28 +00:00
Parent : : handleDeleteAction ( ) ;
2018-12-07 06:30:08 +00:00
}
2018-09-17 03:15:07 +00:00
void ReflectionProbe : : setTransform ( const MatrixF & mat )
{
// Let SceneObject handle all of the matrix manipulation
2018-09-17 06:52:18 +00:00
if ( ! mEditPosOffset )
2019-06-05 05:07:46 +00:00
{
2018-09-17 06:52:18 +00:00
Parent : : setTransform ( mat ) ;
2019-06-05 05:07:46 +00:00
setMaskBits ( TransformMask ) ;
}
2018-09-17 06:52:18 +00:00
else
2019-06-05 05:07:46 +00:00
{
2019-02-19 14:58:02 +00:00
mProbeRefOffset = mat . getPosition ( ) ;
2019-06-05 05:07:46 +00:00
setMaskBits ( StaticDataMask ) ;
}
2018-09-17 03:15:07 +00:00
mDirty = true ;
}
2019-03-02 10:48:07 +00:00
const MatrixF & ReflectionProbe : : getTransform ( ) const
{
if ( ! mEditPosOffset )
return mObjToWorld ;
else
{
MatrixF transformMat = MatrixF : : Identity ;
transformMat . setPosition ( mProbeRefOffset ) ;
return transformMat ;
}
}
void ReflectionProbe : : setScale ( const VectorF & scale )
{
if ( ! mEditPosOffset )
2019-06-05 05:07:46 +00:00
{
2019-03-02 10:48:07 +00:00
Parent : : setScale ( scale ) ;
2019-06-05 05:07:46 +00:00
setMaskBits ( TransformMask ) ;
}
2019-03-02 10:48:07 +00:00
else
2019-06-05 05:07:46 +00:00
{
2019-03-02 10:48:07 +00:00
mProbeRefScale = scale ;
2019-06-05 05:07:46 +00:00
setMaskBits ( StaticDataMask ) ;
}
2019-03-02 10:48:07 +00:00
mDirty = true ;
}
const VectorF & ReflectionProbe : : getScale ( ) const
{
if ( ! mEditPosOffset )
return mObjScale ;
else
return mProbeRefScale ;
}
bool ReflectionProbe : : writeField ( StringTableEntry fieldname , const char * value )
{
if ( fieldname = = StringTable - > insert ( " Bake " ) | | fieldname = = StringTable - > insert ( " EditPosOffset " ) )
return false ;
return Parent : : writeField ( fieldname , value ) ;
}
2018-09-17 03:15:07 +00:00
U32 ReflectionProbe : : packUpdate ( NetConnection * conn , U32 mask , BitStream * stream )
{
// Allow the Parent to get a crack at writing its info
U32 retMask = Parent : : packUpdate ( conn , mask , stream ) ;
// Write our transform information
if ( stream - > writeFlag ( mask & TransformMask ) )
{
2019-03-02 10:48:07 +00:00
stream - > writeFlag ( mEditPosOffset ) ;
mathWrite ( * stream , mObjToWorld ) ;
mathWrite ( * stream , mObjScale ) ;
2019-02-19 14:58:02 +00:00
mathWrite ( * stream , mProbeRefOffset ) ;
mathWrite ( * stream , mProbeRefScale ) ;
2018-09-17 03:15:07 +00:00
}
2019-06-04 05:21:52 +00:00
if ( stream - > writeFlag ( mask & StaticDataMask ) )
2018-09-17 03:15:07 +00:00
{
stream - > write ( ( U32 ) mProbeShapeType ) ;
stream - > write ( mRadius ) ;
stream - > write ( mProbeUniqueID ) ;
2019-06-04 05:21:52 +00:00
stream - > write ( ( U32 ) mReflectionModeType ) ;
2021-07-19 06:07:08 +00:00
stream - > writeString ( mCubemapName ) ;
2018-09-17 03:15:07 +00:00
}
if ( stream - > writeFlag ( mask & EnabledMask ) )
{
stream - > writeFlag ( mEnabled ) ;
}
return retMask ;
}
void ReflectionProbe : : unpackUpdate ( NetConnection * conn , BitStream * stream )
{
// Let the Parent read any info it sent
Parent : : unpackUpdate ( conn , stream ) ;
if ( stream - > readFlag ( ) ) // TransformMask
{
2019-03-02 10:48:07 +00:00
mEditPosOffset = stream - > readFlag ( ) ;
2018-09-17 03:15:07 +00:00
mathRead ( * stream , & mObjToWorld ) ;
mathRead ( * stream , & mObjScale ) ;
2019-03-02 10:48:07 +00:00
Parent : : setTransform ( mObjToWorld ) ;
resetWorldBox ( ) ;
2018-09-17 06:52:18 +00:00
2019-02-19 14:58:02 +00:00
mathRead ( * stream , & mProbeRefOffset ) ;
2020-10-19 05:53:09 +00:00
mathRead ( * stream , & mProbeRefScale ) ;
2019-03-26 04:17:53 +00:00
mDirty = true ;
2018-09-17 03:15:07 +00:00
}
2019-06-04 05:21:52 +00:00
if ( stream - > readFlag ( ) ) // StaticDataMask
2018-09-17 03:15:07 +00:00
{
2022-02-12 21:53:40 +00:00
U32 shapeType = ProbeInfo : : Sphere ;
2018-09-17 03:15:07 +00:00
stream - > read ( & shapeType ) ;
2022-02-12 21:53:40 +00:00
mProbeShapeType = ( ProbeInfo : : ProbeShapeType ) shapeType ;
2018-09-17 03:15:07 +00:00
stream - > read ( & mRadius ) ;
2019-03-26 04:17:53 +00:00
2018-09-17 03:15:07 +00:00
stream - > read ( & mProbeUniqueID ) ;
2019-03-26 04:17:53 +00:00
2019-06-04 05:21:52 +00:00
U32 oldReflectModeType = mReflectionModeType ;
2018-09-17 03:15:07 +00:00
U32 reflectModeType = BakedCubemap ;
stream - > read ( & reflectModeType ) ;
mReflectionModeType = ( ReflectionModeType ) reflectModeType ;
2021-07-19 06:07:08 +00:00
StringTableEntry oldCubemapName = mCubemapName ;
mCubemapName = stream - > readSTString ( ) ;
2019-06-04 05:21:52 +00:00
if ( oldReflectModeType ! = mReflectionModeType | | oldCubemapName ! = mCubemapName )
mCubemapDirty = true ;
2019-03-26 04:17:53 +00:00
mDirty = true ;
2018-09-17 03:15:07 +00:00
}
2019-06-04 05:21:52 +00:00
if ( stream - > readFlag ( ) ) // EnabledMask
2018-09-17 03:15:07 +00:00
{
2019-06-04 05:21:52 +00:00
mEnabled = stream - > readFlag ( ) ;
2018-12-07 06:30:08 +00:00
2019-03-26 04:17:53 +00:00
mDirty = true ;
2018-09-17 03:15:07 +00:00
}
}
//-----------------------------------------------------------------------------
// Object Rendering
//-----------------------------------------------------------------------------
void ReflectionProbe : : updateProbeParams ( )
{
2022-02-12 21:53:40 +00:00
mProbeInfo . mObject = this ;
2020-10-30 04:27:07 +00:00
if ( ! mResourcesCreated )
{
if ( ! createClientResources ( ) )
return ;
}
2020-10-19 05:53:09 +00:00
mProbeInfo . mIsEnabled = mEnabled ;
2019-06-05 05:07:46 +00:00
2020-10-19 05:53:09 +00:00
mProbeInfo . mProbeShapeType = mProbeShapeType ;
2018-09-17 03:15:07 +00:00
2022-02-12 21:53:40 +00:00
if ( mProbeShapeType = = ProbeInfo : : Sphere )
2019-03-02 10:48:07 +00:00
mObjScale . set ( mRadius , mRadius , mRadius ) ;
2018-09-17 03:15:07 +00:00
2019-06-04 05:21:52 +00:00
Box3F bounds ;
2019-03-18 05:14:06 +00:00
2022-02-12 21:53:40 +00:00
if ( mProbeShapeType = = ProbeInfo : : Skylight )
2019-06-04 05:21:52 +00:00
{
2020-10-19 05:53:09 +00:00
mProbeInfo . mPosition = Point3F : : Zero ;
mProbeInfo . mTransform = MatrixF : : Identity ;
2018-09-17 03:15:07 +00:00
2019-06-04 05:21:52 +00:00
F32 visDist = gClientSceneGraph - > getVisibleDistance ( ) ;
Box3F skylightBounds = Box3F ( visDist * 2 ) ;
2018-09-17 03:15:07 +00:00
2019-06-04 05:21:52 +00:00
skylightBounds . setCenter ( Point3F : : Zero ) ;
2018-09-17 06:52:18 +00:00
2019-06-04 05:21:52 +00:00
bounds = skylightBounds ;
2018-10-07 22:32:23 +00:00
2019-06-04 05:21:52 +00:00
setGlobalBounds ( ) ;
2018-09-17 03:15:07 +00:00
2020-10-19 05:53:09 +00:00
mProbeInfo . mScore = 10000.0f ;
2019-06-04 05:21:52 +00:00
}
else
{
MatrixF transform = getTransform ( ) ;
2020-10-19 05:53:09 +00:00
mProbeInfo . mPosition = getPosition ( ) ;
2018-12-10 06:46:28 +00:00
2019-06-04 05:21:52 +00:00
transform . scale ( getScale ( ) ) ;
2020-10-19 05:53:09 +00:00
mProbeInfo . mTransform = transform . inverse ( ) ;
2018-12-07 06:30:08 +00:00
2019-06-04 05:21:52 +00:00
bounds = mWorldBox ;
2018-09-17 03:15:07 +00:00
2020-10-19 05:53:09 +00:00
mProbeInfo . mScore = 1 ;
2018-12-07 06:30:08 +00:00
}
2018-10-26 06:19:14 +00:00
2019-06-04 05:21:52 +00:00
// Skip our transform... it just dirties mask bits.
Parent : : setTransform ( mObjToWorld ) ;
2018-10-26 06:19:14 +00:00
2019-06-04 05:21:52 +00:00
resetWorldBox ( ) ;
2018-12-10 06:46:28 +00:00
2020-10-19 05:53:09 +00:00
mProbeInfo . mBounds = bounds ;
mProbeInfo . mExtents = getScale ( ) ;
mProbeInfo . mRadius = mRadius ;
2018-12-07 06:30:08 +00:00
2020-10-19 05:53:09 +00:00
mProbeInfo . mProbeRefOffset = mProbeRefOffset ;
mProbeInfo . mProbeRefScale = mProbeRefScale ;
2018-12-07 06:30:08 +00:00
2020-10-19 05:53:09 +00:00
mProbeInfo . mDirty = true ;
2018-10-26 06:19:14 +00:00
2019-06-04 05:21:52 +00:00
if ( mCubemapDirty )
{
if ( mReflectionModeType = = StaticCubemap )
processStaticCubemap ( ) ;
2019-06-05 05:07:46 +00:00
else if ( mReflectionModeType = = BakedCubemap )
processBakedCubemap ( ) ;
2019-06-04 05:21:52 +00:00
else
processDynamicCubemap ( ) ;
}
2018-12-07 06:30:08 +00:00
}
2018-10-26 06:19:14 +00:00
2019-06-04 05:21:52 +00:00
void ReflectionProbe : : processDynamicCubemap ( )
2018-12-07 06:30:08 +00:00
{
2020-10-19 05:53:09 +00:00
2019-06-04 05:21:52 +00:00
}
2019-06-05 05:07:46 +00:00
void ReflectionProbe : : processBakedCubemap ( )
{
2022-02-12 21:53:40 +00:00
//mProbeInfo.mIsEnabled = false;
2019-06-05 05:07:46 +00:00
if ( ( mReflectionModeType ! = BakedCubemap ) | | mProbeUniqueID . isEmpty ( ) )
return ;
String irrPath = getIrradianceMapPath ( ) ;
if ( Platform : : isFile ( irrPath ) )
{
mIrridianceMap - > setCubemapFile ( FileName ( irrPath ) ) ;
mIrridianceMap - > updateFaces ( ) ;
}
2020-10-19 05:53:09 +00:00
if ( mIrridianceMap = = nullptr | | mIrridianceMap - > mCubemap . isNull ( ) )
2019-06-05 05:07:46 +00:00
{
Con : : errorf ( " ReflectionProbe::processDynamicCubemap() - Unable to load baked irradiance map at %s " , getIrradianceMapPath ( ) . c_str ( ) ) ;
return ;
}
String prefilPath = getPrefilterMapPath ( ) ;
if ( Platform : : isFile ( prefilPath ) )
{
mPrefilterMap - > setCubemapFile ( FileName ( prefilPath ) ) ;
mPrefilterMap - > updateFaces ( ) ;
}
2020-10-19 05:53:09 +00:00
if ( mPrefilterMap = = nullptr | | mPrefilterMap - > mCubemap . isNull ( ) )
2019-06-05 05:07:46 +00:00
{
Con : : errorf ( " ReflectionProbe::processDynamicCubemap() - Unable to load baked prefilter map at %s " , getPrefilterMapPath ( ) . c_str ( ) ) ;
return ;
}
2020-10-19 05:53:09 +00:00
mProbeInfo . mPrefilterCubemap = mPrefilterMap - > mCubemap ;
mProbeInfo . mIrradianceCubemap = mIrridianceMap - > mCubemap ;
2019-06-05 05:07:46 +00:00
2020-10-19 05:53:09 +00:00
if ( mEnabled & & mProbeInfo . mPrefilterCubemap - > isInitialized ( ) & & mProbeInfo . mIrradianceCubemap - > isInitialized ( ) )
2019-06-05 05:07:46 +00:00
{
2022-02-12 21:53:40 +00:00
//mProbeInfo.mIsEnabled = true;
2019-06-05 05:07:46 +00:00
2019-06-13 05:37:12 +00:00
mCubemapDirty = false ;
2019-06-05 05:07:46 +00:00
//Update the probe manager with our new texture!
2020-10-19 05:53:09 +00:00
PROBEMGR - > updateProbeTexture ( & mProbeInfo ) ;
//now, cleanup
mProbeInfo . mPrefilterCubemap . free ( ) ;
mProbeInfo . mIrradianceCubemap . free ( ) ;
2019-06-05 05:07:46 +00:00
}
2022-02-12 21:53:40 +00:00
else
{
//if we failed, disable
mProbeInfo . mIsEnabled = false ;
}
2019-06-05 05:07:46 +00:00
}
2019-06-04 05:21:52 +00:00
void ReflectionProbe : : processStaticCubemap ( )
{
2020-10-19 05:53:09 +00:00
mProbeInfo . mIsEnabled = false ;
2019-06-04 05:21:52 +00:00
String path = Con : : getVariable ( " $pref::ReflectionProbes::CurrentLevelPath " , " levels/ " ) ;
char irradFileName [ 256 ] ;
2021-07-19 06:07:08 +00:00
dSprintf ( irradFileName , 256 , " %s%s_Irradiance.dds " , path . c_str ( ) , mCubemapName ) ;
2019-06-04 05:21:52 +00:00
if ( Platform : : isFile ( irradFileName ) )
{
mIrridianceMap - > setCubemapFile ( FileName ( irradFileName ) ) ;
2020-09-19 23:25:10 +00:00
mIrridianceMap - > updateFaces ( ) ;
2019-06-04 05:21:52 +00:00
}
2020-10-19 05:53:09 +00:00
if ( mIrridianceMap = = nullptr | | mIrridianceMap - > mCubemap . isNull ( ) )
{
Con : : errorf ( " ReflectionProbe::processStaticCubemap() - Unable to load baked irradiance map at %s " , irradFileName ) ;
return ;
}
2019-06-04 05:21:52 +00:00
char prefilterFileName [ 256 ] ;
2021-07-19 06:07:08 +00:00
dSprintf ( prefilterFileName , 256 , " %s%s_Prefilter.dds " , path . c_str ( ) , mCubemapName ) ;
2019-06-04 05:21:52 +00:00
if ( Platform : : isFile ( prefilterFileName ) )
{
mPrefilterMap - > setCubemapFile ( FileName ( prefilterFileName ) ) ;
2020-09-19 23:25:10 +00:00
mPrefilterMap - > updateFaces ( ) ;
2019-06-04 05:21:52 +00:00
}
2020-10-19 05:53:09 +00:00
if ( mPrefilterMap = = nullptr | | mPrefilterMap - > mCubemap . isNull ( ) )
{
Con : : errorf ( " ReflectionProbe::processStaticCubemap() - Unable to load baked prefilter map at %s " , prefilterFileName ) ;
return ;
}
2019-06-04 05:21:52 +00:00
if ( ! Platform : : isFile ( prefilterFileName ) | | ! Platform : : isFile ( irradFileName ) )
{
//If we are missing either of the files, just re-run the bake
Sim : : findObject ( mCubemapName , mStaticCubemap ) ;
if ( ! mStaticCubemap )
{
Con : : errorf ( " ReflectionProbe::updateMaterial() - unable to find static cubemap file! " ) ;
return ;
}
if ( mStaticCubemap - > mCubemap = = nullptr )
{
mStaticCubemap - > createMap ( ) ;
mStaticCubemap - > updateFaces ( ) ;
}
if ( mUseHDRCaptures )
{
mIrridianceMap - > mCubemap - > initDynamic ( mPrefilterSize , GFXFormatR16G16B16A16F ) ;
mPrefilterMap - > mCubemap - > initDynamic ( mPrefilterSize , GFXFormatR16G16B16A16F ) ;
}
else
{
mIrridianceMap - > mCubemap - > initDynamic ( mPrefilterSize , GFXFormatR8G8B8A8 ) ;
mPrefilterMap - > mCubemap - > initDynamic ( mPrefilterSize , GFXFormatR8G8B8A8 ) ;
}
GFXTextureTargetRef renderTarget = GFX - > allocRenderToTextureTarget ( false ) ;
IBLUtilities : : GenerateIrradianceMap ( renderTarget , mStaticCubemap - > mCubemap , mIrridianceMap - > mCubemap ) ;
IBLUtilities : : GeneratePrefilterMap ( renderTarget , mStaticCubemap - > mCubemap , mPrefilterMipLevels , mPrefilterMap - > mCubemap ) ;
IBLUtilities : : SaveCubeMap ( irradFileName , mIrridianceMap - > mCubemap ) ;
IBLUtilities : : SaveCubeMap ( prefilterFileName , mPrefilterMap - > mCubemap ) ;
}
2020-10-19 05:53:09 +00:00
if ( ( mIrridianceMap ! = nullptr | | ! mIrridianceMap - > mCubemap . isNull ( ) ) & & ( mPrefilterMap ! = nullptr | | ! mPrefilterMap - > mCubemap . isNull ( ) ) )
2019-06-04 05:21:52 +00:00
{
2020-10-19 05:53:09 +00:00
mProbeInfo . mPrefilterCubemap = mPrefilterMap - > mCubemap ;
mProbeInfo . mIrradianceCubemap = mIrridianceMap - > mCubemap ;
2019-06-04 05:21:52 +00:00
}
2020-10-19 05:53:09 +00:00
if ( mEnabled & & mProbeInfo . mPrefilterCubemap - > isInitialized ( ) & & mProbeInfo . mIrradianceCubemap - > isInitialized ( ) )
2019-06-05 05:07:46 +00:00
{
2020-10-19 05:53:09 +00:00
mProbeInfo . mIsEnabled = true ;
2019-06-04 05:21:52 +00:00
2019-06-13 05:37:12 +00:00
mCubemapDirty = false ;
2019-06-05 05:07:46 +00:00
//Update the probe manager with our new texture!
2020-10-19 05:53:09 +00:00
PROBEMGR - > updateProbeTexture ( & mProbeInfo ) ;
2019-06-05 05:07:46 +00:00
}
2018-09-17 03:15:07 +00:00
}
bool ReflectionProbe : : createClientResources ( )
{
2020-10-19 05:53:09 +00:00
PROBEMGR - > registerProbe ( & mProbeInfo ) ;
2019-06-04 05:21:52 +00:00
2020-10-19 05:53:09 +00:00
mProbeInfo . mIsEnabled = false ;
2018-09-17 03:15:07 +00:00
//irridiance resources
2018-09-17 06:52:18 +00:00
if ( ! mIrridianceMap )
{
mIrridianceMap = new CubemapData ( ) ;
mIrridianceMap - > registerObject ( ) ;
2018-09-17 03:15:07 +00:00
2018-09-17 06:52:18 +00:00
mIrridianceMap - > createMap ( ) ;
}
2018-09-17 03:15:07 +00:00
2018-09-17 06:52:18 +00:00
//
if ( ! mPrefilterMap )
{
mPrefilterMap = new CubemapData ( ) ;
mPrefilterMap - > registerObject ( ) ;
2018-09-17 03:15:07 +00:00
2018-09-17 06:52:18 +00:00
mPrefilterMap - > createMap ( ) ;
}
2018-09-17 03:15:07 +00:00
2018-09-17 06:52:18 +00:00
mResourcesCreated = true ;
2019-06-04 05:21:52 +00:00
mCubemapDirty = true ;
2018-09-17 06:52:18 +00:00
return true ;
}
2019-03-25 05:06:08 +00:00
String ReflectionProbe : : getPrefilterMapPath ( )
{
if ( mProbeUniqueID . isEmpty ( ) )
{
Con : : errorf ( " ReflectionProbe::getPrefilterMapPath() - We don't have a set output path or persistant id, so no valid path can be provided! " ) ;
return " " ;
}
String path = Con : : getVariable ( " $pref::ReflectionProbes::CurrentLevelPath " , " levels/ " ) ;
char fileName [ 256 ] ;
dSprintf ( fileName , 256 , " %s%s_Prefilter.dds " , path . c_str ( ) , mProbeUniqueID . c_str ( ) ) ;
return fileName ;
}
String ReflectionProbe : : getIrradianceMapPath ( )
{
if ( mProbeUniqueID . isEmpty ( ) )
{
Con : : errorf ( " ReflectionProbe::getIrradianceMapPath() - We don't have a set output path or persistant id, so no valid path can be provided! " ) ;
return " " ;
}
String path = Con : : getVariable ( " $pref::ReflectionProbes::CurrentLevelPath " , " levels/ " ) ;
char fileName [ 256 ] ;
dSprintf ( fileName , 256 , " %s%s_Irradiance.dds " , path . c_str ( ) , mProbeUniqueID . c_str ( ) ) ;
return fileName ;
}
void ReflectionProbe : : bake ( )
{
2020-10-19 05:53:09 +00:00
if ( mReflectionModeType ! = BakedCubemap )
2019-03-25 05:06:08 +00:00
return ;
2020-10-19 05:53:09 +00:00
PROBEMGR - > bakeProbe ( this ) ;
2019-03-25 05:06:08 +00:00
2019-07-11 04:41:55 +00:00
setMaskBits ( - 1 ) ;
2019-03-25 05:06:08 +00:00
}
2019-06-04 05:21:52 +00:00
2019-03-25 05:06:08 +00:00
//-----------------------------------------------------------------------------
//Rendering of editing/debug stuff
//-----------------------------------------------------------------------------
2020-10-19 05:53:09 +00:00
void ReflectionProbe : : createEditorResources ( )
2018-09-17 06:52:18 +00:00
{
2020-10-19 05:53:09 +00:00
# ifdef TORQUE_TOOLS
2019-03-25 05:06:08 +00:00
// Clean up our previous shape
if ( mEditorShapeInst )
SAFE_DELETE ( mEditorShapeInst ) ;
mEditorShape = NULL ;
2021-12-24 23:26:45 +00:00
String shapeFile = " tools/resources/previewSphereShape.dae " ;
2019-03-25 05:06:08 +00:00
// Attempt to get the resource from the ResourceManager
mEditorShape = ResourceManager : : get ( ) . load ( shapeFile ) ;
if ( mEditorShape )
{
mEditorShapeInst = new TSShapeInstance ( mEditorShape , isClientObject ( ) ) ;
}
2020-10-19 05:53:09 +00:00
# endif
2018-09-17 03:15:07 +00:00
}
void ReflectionProbe : : prepRenderImage ( SceneRenderState * state )
{
2022-08-28 22:24:59 +00:00
if ( ! mEnabled | | ( ! RenderProbeMgr : : smRenderReflectionProbes & & ! dStrcmp ( Con : : getVariable ( " $Probes::Capturing " , " 0 " ) , " 1 " ) ) )
2018-09-17 03:15:07 +00:00
return ;
Point3F distVec = getRenderPosition ( ) - state - > getCameraPosition ( ) ;
F32 dist = distVec . len ( ) ;
//Culling distance. Can be adjusted for performance options considerations via the scalar
2022-02-12 21:53:40 +00:00
if ( dist > RenderProbeMgr : : smMaxProbeDrawDistance * Con : : getFloatVariable ( " $pref::GI::ProbeDrawDistScale " , 1.0 ) )
2018-11-25 18:35:02 +00:00
{
2022-02-12 21:53:40 +00:00
mProbeInfo . mScore = RenderProbeMgr : : smMaxProbeDrawDistance ;
2018-11-28 07:51:52 +00:00
return ;
2018-11-25 18:35:02 +00:00
}
2018-09-17 03:15:07 +00:00
if ( mReflectionModeType = = DynamicCubemap & & mRefreshRateMS < ( Platform : : getRealMilliseconds ( ) - mDynamicLastBakeMS ) )
{
2020-10-19 05:53:09 +00:00
bake ( ) ;
2018-09-17 03:15:07 +00:00
mDynamicLastBakeMS = Platform : : getRealMilliseconds ( ) ;
}
//Submit our probe to actually do the probe action
// Get a handy pointer to our RenderPassmanager
//RenderPassManager *renderPass = state->getRenderPass();
//Update our score based on our radius, distance
2020-10-19 05:53:09 +00:00
mProbeInfo . mScore = mMax ( dist , 1.0f ) ;
2018-09-17 03:15:07 +00:00
Point3F vect = distVec ;
vect . normalizeSafe ( ) ;
2020-10-19 05:53:09 +00:00
//mProbeInfo.mScore *= mMax(mAbs(mDot(vect, state->getCameraTransform().getForwardVector())),0.001f);
2018-09-17 03:15:07 +00:00
2022-02-12 21:53:40 +00:00
PROBEMGR - > submitProbe ( & mProbeInfo ) ;
2018-09-17 03:15:07 +00:00
2020-10-19 05:53:09 +00:00
# ifdef TORQUE_TOOLS
2019-06-04 05:21:52 +00:00
if ( ReflectionProbe : : smRenderPreviewProbes & & gEditingMission & & mPrefilterMap ! = nullptr )
2018-09-17 03:15:07 +00:00
{
2019-06-04 05:21:52 +00:00
if ( ! mEditorShapeInst )
2020-10-19 05:53:09 +00:00
createEditorResources ( ) ;
2019-06-04 05:21:52 +00:00
2018-09-17 03:15:07 +00:00
GFXTransformSaver saver ;
// Calculate the distance of this object from the camera
Point3F cameraOffset ;
getRenderTransform ( ) . getColumn ( 3 , & cameraOffset ) ;
cameraOffset - = state - > getDiffuseCameraPosition ( ) ;
2018-11-28 07:51:52 +00:00
dist = cameraOffset . len ( ) ;
2018-09-17 03:15:07 +00:00
if ( dist < 0.01f )
dist = 0.01f ;
// Set up the LOD for the shape
F32 invScale = ( 1.0f / getMax ( getMax ( mObjScale . x , mObjScale . y ) , mObjScale . z ) ) ;
mEditorShapeInst - > setDetailFromDistance ( state , dist * invScale ) ;
// Make sure we have a valid level of detail
if ( mEditorShapeInst - > getCurrentDetail ( ) < 0 )
return ;
BaseMatInstance * probePrevMat = mEditorShapeInst - > getMaterialList ( ) - > getMaterialInst ( 0 ) ;
setPreviewMatParameters ( state , probePrevMat ) ;
// GFXTransformSaver is a handy helper class that restores
// the current GFX matrices to their original values when
// it goes out of scope at the end of the function
// Set up our TS render state
TSRenderState rdata ;
rdata . setSceneState ( state ) ;
rdata . setFadeOverride ( 1.0f ) ;
if ( mReflectionModeType ! = DynamicCubemap )
2018-09-17 06:52:18 +00:00
rdata . setCubemap ( mPrefilterMap - > mCubemap ) ;
2018-09-17 03:15:07 +00:00
else
rdata . setCubemap ( mDynamicCubemap ) ;
// We might have some forward lit materials
// so pass down a query to gather lights.
LightQuery query ;
query . init ( getWorldSphere ( ) ) ;
rdata . setLightQuery ( & query ) ;
// Set the world matrix to the objects render transform
MatrixF mat = getRenderTransform ( ) ;
GFX - > setWorldMatrix ( mat ) ;
// Animate the the shape
mEditorShapeInst - > animate ( ) ;
// Allow the shape to submit the RenderInst(s) for itself
mEditorShapeInst - > render ( rdata ) ;
saver . restore ( ) ;
}
2020-10-19 05:53:09 +00:00
// If the probe is selected or probe visualization
2018-09-17 03:15:07 +00:00
// is enabled then register the callback.
const bool isSelectedInEditor = ( gEditingMission & & isSelected ( ) ) ;
if ( isSelectedInEditor )
{
ObjectRenderInst * ri = state - > getRenderPass ( ) - > allocInst < ObjectRenderInst > ( ) ;
ri - > renderDelegate . bind ( this , & ReflectionProbe : : _onRenderViz ) ;
ri - > type = RenderPassManager : : RIT_Editor ;
state - > getRenderPass ( ) - > addInst ( ri ) ;
}
2020-10-19 05:53:09 +00:00
# endif
2018-09-17 03:15:07 +00:00
}
void ReflectionProbe : : _onRenderViz ( ObjectRenderInst * ri ,
SceneRenderState * state ,
BaseMatInstance * overrideMat )
{
2019-01-26 08:05:18 +00:00
if ( ! RenderProbeMgr : : smRenderReflectionProbes )
2018-09-17 03:15:07 +00:00
return ;
GFXDrawUtil * draw = GFX - > getDrawUtil ( ) ;
GFXStateBlockDesc desc ;
desc . setZReadWrite ( true , false ) ;
desc . setCullMode ( GFXCullNone ) ;
desc . setBlend ( true ) ;
2019-10-20 07:47:15 +00:00
//desc.fillMode = GFXFillWireframe;
2018-09-17 03:15:07 +00:00
// Base the sphere color on the light color.
2019-02-19 19:58:29 +00:00
ColorI color = ColorI ( 255 , 0 , 255 , 63 ) ;
2018-09-17 03:15:07 +00:00
2019-03-02 10:48:07 +00:00
const MatrixF worldToObjectXfm = mObjToWorld ;
2022-02-12 21:53:40 +00:00
if ( mProbeShapeType = = ProbeInfo : : Sphere )
2018-09-17 03:15:07 +00:00
{
draw - > drawSphere ( desc , mRadius , getPosition ( ) , color ) ;
}
else
{
2019-03-02 10:48:07 +00:00
Point3F tscl = worldToObjectXfm . getScale ( ) ;
Box3F projCube ( - mObjScale / 2 , mObjScale / 2 ) ;
2019-02-19 14:58:02 +00:00
projCube . setCenter ( getPosition ( ) ) ;
draw - > drawCube ( desc , projCube , color , & worldToObjectXfm ) ;
2018-09-17 03:15:07 +00:00
}
2019-03-02 10:48:07 +00:00
Point3F renderPos = getRenderTransform ( ) . getPosition ( ) ;
Box3F refCube = Box3F ( - mProbeRefScale / 2 , mProbeRefScale / 2 ) ;
refCube . setCenter ( renderPos + mProbeRefOffset ) ;
2019-02-19 19:58:29 +00:00
color = ColorI ( 0 , 255 , 255 , 63 ) ;
2019-02-19 14:58:02 +00:00
draw - > drawCube ( desc , refCube , color , & worldToObjectXfm ) ;
2018-09-17 03:15:07 +00:00
}
void ReflectionProbe : : setPreviewMatParameters ( SceneRenderState * renderState , BaseMatInstance * mat )
{
if ( ! mat - > getFeatures ( ) . hasFeature ( MFT_isDeferred ) )
return ;
//Set up the params
MaterialParameters * matParams = mat - > getMaterialParameters ( ) ;
//Get the deferred render target
NamedTexTarget * deferredTexTarget = NamedTexTarget : : find ( " deferred " ) ;
GFXTextureObject * deferredTexObject = deferredTexTarget - > getTexture ( ) ;
if ( ! deferredTexObject )
return ;
GFX - > setTexture ( 0 , deferredTexObject ) ;
//Set the cubemap
2018-09-17 06:52:18 +00:00
GFX - > setCubeTexture ( 1 , mPrefilterMap - > mCubemap ) ;
2018-09-17 03:15:07 +00:00
//Set the invViewMat
MatrixSet & matrixSet = renderState - > getRenderPass ( ) - > getMatrixSet ( ) ;
const MatrixF & worldToCameraXfm = matrixSet . getWorldToCamera ( ) ;
MaterialParameterHandle * invViewMat = mat - > getMaterialParameterHandle ( " $invViewMat " ) ;
matParams - > setSafe ( invViewMat , worldToCameraXfm ) ;
}
2018-09-17 06:52:18 +00:00
DefineEngineMethod ( ReflectionProbe , postApply , void , ( ) , ,
" A utility method for forcing a network update. \n " )
2018-09-17 03:15:07 +00:00
{
2018-09-17 06:52:18 +00:00
object - > inspectPostApply ( ) ;
2018-09-17 03:15:07 +00:00
}
2019-02-14 06:35:22 +00:00
DefineEngineMethod ( ReflectionProbe , Bake , void , ( ) , ,
2020-10-19 05:53:09 +00:00
" @brief Bakes the cubemaps for a reflection probe \n \n . " )
2018-09-17 03:15:07 +00:00
{
2018-09-17 06:52:18 +00:00
ReflectionProbe * clientProbe = ( ReflectionProbe * ) object - > getClientObject ( ) ;
if ( clientProbe )
{
2019-02-14 06:35:22 +00:00
clientProbe - > bake ( ) ;
2018-09-17 06:52:18 +00:00
}
2019-06-03 07:47:30 +00:00
}