/////////////////////////////////////////////////////////////////////////////// // // ## ###### // ###### ### // ## ############### Shark 3D Engine (www.shark3d.com) // ########## # # # // ######## Copyright (c) 1996-2006 Spinor GmbH. // ######### # # # All rights reserved. // ## ########## // ## // /////////////////////////////////////////////////////////////////////////////// //@cpp #include "eng_shader_special_worldmat.h" #include "../../util/eng_util_gfxutil.h" #include "../../util/eng_util_shaderutil.h" #include "../../util/eng_util_mathutil.h" #include "../../../drv/interf/drv_vartypes.h" #include "../../../drv/util/drv_util_varutil.h" #include "../../../util/snk/util_snk_extractutil.h" #include "../../../util/math/util_geo_types.h" /////////////////////////////////////////////////////////////////////////////// /*@{ @declare{shadercomp.class}{eng_shader_special.worldmat}{} Provides a matrix which maps from view coordinates in world coordinates. @p Important warning! Usually, if you need this matrix something is wrong! See @ref{prog_man.shader.coord_systems}. @p @}*/ /////////////////////////////////////////////////////////////////////////////// S3D_UTIL_RTTI_TABLE_DEFINE_BEGIN(s3d_CEngShaderSpecialWorldMat) S3D_UTIL_RTTI_TABLE_DEFINE_BASE(s3d_CEngShader) S3D_UTIL_RTTI_TABLE_DEFINE_BASE(s3d_CCompUtilUniqueBase) S3D_UTIL_RTTI_TABLE_DEFINE_BASE(s3d_CCompSetup) S3D_UTIL_RTTI_TABLE_DEFINE_END s3d_CEngShaderSpecialWorldMat::s3d_CEngShaderSpecialWorldMat() { } void s3d_CEngShaderSpecialWorldMat::SetupInit( s3d_CUtilMsgHandler *MsgHandler, s3d_CUtilStr_cr Info, s3d_CCompSuppl *FetchSuppl, s3d_CUtilSnkChunk *Param) { m_Data = S3D_SYS_NEW s3d_CEngShaderSpecialWorldMatData; s3d_CUtilSnkExtract SnkExtract; SnkExtract.Assign(MsgHandler, Param); m_Data->m_Info = SnkExtract.GetInfo(); /*@{ @declare{shadercomp.param}{eng_shader_special.worldmat.env}{$ [str]} See @ident{comp}{eng_shader_std.group.env}. @}*/ s3d_CUtilStr EnvIdent, EnvInfo; SnkExtract.ExtractStr(EnvInfo, EnvIdent, "env", true); m_ShaderEnv = s3d_CompSupplObjT( MsgHandler, EnvInfo, FetchSuppl, EnvIdent, S3D_GENERAL_INTEROP_INTERF); if(!m_ShaderEnv) return; /*@{ @declare{shadercomp.param}{eng_shader_special.worldmat.methods} {$ [str] .. [str]} See @ref{prog_man.shader.methods}. @}*/ s3d_CUtilSnkExtractUtil::ExtractAtomSortedArray( m_Data->m_MethodArray, m_ShaderEnv->m_AtomMgr, SnkExtract, "methods", true); /*@{ @declare{shadercomp.param} {eng_shader_special.worldmat.worldmat_var}{$ [str]} The variable stores the resulting matrix. The variable is of type mat4x4f. @}*/ s3d_CUtilSnkExtractUtil::ExtractAtom( m_Data->m_WorldMatVarInfo, m_Data->m_WorldMatVarAtom, m_ShaderEnv->m_AtomMgr, SnkExtract, "worldmat_var", true); /*@{ @declare{shadercomp.param} {eng_shader_special.worldmat.inverse}{$ [bool]} Sets if the matrix should be inverted. @}*/ m_Data->m_Inverse = SnkExtract.ExtractBool("inverse", true, false); /*@{ @declare{shadercomp.param} {eng_shader_special.worldmat.transpose}{$ [bool]} Sets if the matrix should be transposed. @}*/ m_Data->m_Transpose = SnkExtract.ExtractBool("transpose", true, false); SnkExtract.CheckForUnknown(); } void s3d_CEngShaderSpecialWorldMat::SetupDone() { } s3d_CUtilStr s3d_CEngShaderSpecialWorldMat::GetInfo() { return m_Data->m_Info; } void s3d_CEngShaderSpecialWorldMat::RegisterNotif(s3d_CUtilNotifRecip *Recip) { } s3d_CEngShaderGfxPtr s3d_CEngShaderSpecialWorldMat::FindShaderGfx( s3d_CUtilNotifGather *NotifGather, s3d_CEngGfxCtx *GfxCtx) { if(!m_ShaderEnv) return 0; s3d_CEngShaderSpecialWorldMatGfxPtr ShaderGfx; s3d_CEngShaderSpecialWorldMatGfxTree::CNode *Pos = s3d_UtilTreeSortedGetStart(m_ShaderGfxTree, GfxCtx); if(s3d_UtilTreeIsEqualAt(Pos, GfxCtx)) ShaderGfx = Pos->m_Data.m_Val; else { ShaderGfx = S3D_SYS_NEW s3d_CEngShaderSpecialWorldMatGfx( m_ShaderEnv, GfxCtx, m_Data); s3d_CEngShaderSpecialWorldMatGfxTree::CNode *Node = ShaderGfx->GetNode(); m_ShaderGfxTree.InsertBefore(Pos, Node); } return ShaderGfx.Get(); } /////////////////////////////////////////////////////////////////////////////// s3d_CEngShaderSpecialWorldMatGfx::s3d_CEngShaderSpecialWorldMatGfx( s3d_CEngShaderEnv *ShaderEnv, s3d_CEngGfxCtx *GfxCtx, s3d_CEngShaderSpecialWorldMatData *Data) { m_Node.m_Data.m_Key = GfxCtx; m_Node.m_Data.m_Val = this; m_ShaderEnv = ShaderEnv; m_Data = Data; } s3d_CEngShaderSpecialWorldMatGfxTree::CNode * s3d_CEngShaderSpecialWorldMatGfx::GetNode() { return &m_Node; } void s3d_CEngShaderSpecialWorldMatGfx::RegisterNotif( s3d_CUtilNotifRecip *Recip) { } void s3d_CEngShaderSpecialWorldMatGfx::ExtractGfx() { m_Node.Extract(); } bool s3d_CEngShaderSpecialWorldMatGfx::IsValid() { return true; } void s3d_CEngShaderSpecialWorldMatGfx::LinkCollect( s3d_CUtilAtomSet &VarAtomSet) { s3d_CDrvUtilVarUtil::LinkCollect( VarAtomSet, m_Data->m_WorldMatVarAtom); } void s3d_CEngShaderSpecialWorldMatGfx::LinkAppoint( s3d_CDrvVarDecl *VarDecl) { s3d_CDrvUtilVarUtil::LinkAppoint( m_WorldMatVarSlot.m_Val, VarDecl, m_Data->m_WorldMatVarAtom); } s3d_CEngShaderInstPtr s3d_CEngShaderSpecialWorldMatGfx::CreateShaderInst( s3d_CEngShaderHead *Head) { return S3D_SYS_NEW s3d_CEngShaderSpecialWorldMatInst( m_ShaderEnv, this); } /////////////////////////////////////////////////////////////////////////////// s3d_CEngShaderSpecialWorldMatInst::s3d_CEngShaderSpecialWorldMatInst( s3d_CEngShaderEnv *ShaderEnv, s3d_CEngShaderSpecialWorldMatGfx *ShaderGfx) { m_ShaderEnv = ShaderEnv; m_ShaderGfx = ShaderGfx; } void s3d_CEngShaderSpecialWorldMatInst::RegisterNotif( s3d_CUtilNotifRecip *Recip) { } void s3d_CEngShaderSpecialWorldMatInst::SetShaderCtx( s3d_CEngShaderCtx *ShaderCtx) { } void s3d_CEngShaderSpecialWorldMatInst::SetGfxState(s3d_CEngGfxState *GfxState) { } void s3d_CEngShaderSpecialWorldMatInst::SetPos(s3d_CEngPos *Pos) { m_Pos = Pos; } void s3d_CEngShaderSpecialWorldMatInst::SetModel(s3d_CEngModel *Model) { } void s3d_CEngShaderSpecialWorldMatInst::ArrangeCollect( s3d_CUtilMemPool *MemPool, s3d_CEngShaderScopeArray &ScopeArray) { } void s3d_CEngShaderSpecialWorldMatInst::ArrangeInit( s3d_CUtilMemPool *MemPool, s3d_CEngShaderScopeArray_cr ScopeArray) { s3d_CSysIntps nScope = ScopeArray.GetCnt(); s3d_CSysIntps iScope; for(iScope = 0; iScope < nScope; iScope++) { s3d_CEngShaderScope *Scope = ScopeArray.GetAt(iScope); SetVars(MemPool, Scope); } } void s3d_CEngShaderSpecialWorldMatInst::ArrangePerform( s3d_CUtilMemPool *MemPool, s3d_CEngShaderScopeArray_cr ScopeArray) { } void s3d_CEngShaderSpecialWorldMatInst::ArrangeFeedback( s3d_CUtilMemPool *MemPool, s3d_CEngShaderScopeArray_cr ScopeArray) { } void s3d_CEngShaderSpecialWorldMatInst::ArrangeGather( s3d_CEngShaderExecArray &ExecArray) { s3d_CEngShaderSpecialWorldMatData *Data = m_ShaderGfx->m_Data; s3d_CEngUtilShaderUtil::ArrangeGather( ExecArray, Data->m_MethodArray, this); } void s3d_CEngShaderSpecialWorldMatInst::ShaderExecPerform( s3d_CEngShaderScope *Scope, s3d_CUtilAtom *Method, s3d_CEngGfxTaskArray &TaskArray) { SetVars(m_ShaderEnv->m_MemPool, Scope); } void s3d_CEngShaderSpecialWorldMatInst::SetVars( s3d_CUtilMemPool *MemPool, s3d_CEngShaderScope *Scope) { s3d_CEngShaderSpecialWorldMatGfx *ShaderGfx = m_ShaderGfx; s3d_CEngShaderSpecialWorldMatData *Data = ShaderGfx->m_Data; s3d_CDrvVarSlot WorldMatVarSlot = ShaderGfx->m_WorldMatVarSlot; if(WorldMatVarSlot >= 0) { s3d_CEngGfxPortion *Portion = Scope->m_Portion; if(Portion) { s3d_CUtilMat4x4f WorldMat; if(!Data->m_Inverse) WorldMat = s3d_CUtilGeof::GetMapOfTransf3(Portion->m_Cam.m_Transf); else WorldMat = s3d_CUtilGeof::GetMapOfInvTransf3(Portion->m_Cam.m_Transf); if(Data->m_Transpose) WorldMat = WorldMat.GetTransp(); s3d_CDrvVarMat4x4f *WorldMatVar = new(MemPool) s3d_CDrvVarMat4x4f; WorldMatVar->m_Val = WorldMat; s3d_DrvVarSet(Scope->m_VarBlk, WorldMatVarSlot, WorldMatVar); } } } ///////////////////////////////////////////////////////////////////////////////