/////////////////////////////////////////////////////////////////////////////// // // ## ###### // ###### ### // ## ############### Shark 3D Engine (www.shark3d.com) // ########## # # # // ######## Copyright (c) 1996-2006 Spinor GmbH. // ######### # # # All rights reserved. // ## ########## // ## // /////////////////////////////////////////////////////////////////////////////// //@cpp #include "gtp_shader_focusedprojmat.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(gtp_Shader_FocusedProjMat) 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 gtp_Shader_FocusedProjMat::gtp_Shader_FocusedProjMat() { } void gtp_Shader_FocusedProjMat::SetupInit( s3d_CUtilMsgHandler *MsgHandler, s3d_CUtilStr_cr Info, s3d_CCompSuppl *FetchSuppl, s3d_CUtilSnkChunk *Param) { m_Data = S3D_SYS_NEW gtp_Shader_FocusedProjMatData; 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_FocusedProjMatVarInfo, m_Data->m_FocusedProjMatVarAtom, m_ShaderEnv->m_AtomMgr, SnkExtract, "destmat_var", true); /*@{ @declare{shader.param}{eng_shader_special.envmap.mesh_var}{$ [str]} @}*/ s3d_CUtilSnkExtractUtil::ExtractAtom( m_Data->m_MeshVarInfo, m_Data->m_MeshVarAtom, m_ShaderEnv->m_AtomMgr, SnkExtract, "mesh_var", true); s3d_CUtilSnkExtractUtil::ExtractAtom( m_Data->m_CenterPointVarInfo, m_Data->m_CenterPointVarAtom, m_ShaderEnv->m_AtomMgr, SnkExtract, "centerpoint_var", true); SnkExtract.CheckForUnknown(); } void gtp_Shader_FocusedProjMat::SetupDone() { } s3d_CUtilStr gtp_Shader_FocusedProjMat::GetInfo() { return m_Data->m_Info; } void gtp_Shader_FocusedProjMat::RegisterNotif(s3d_CUtilNotifRecip *Recip) { } s3d_CEngShaderGfxPtr gtp_Shader_FocusedProjMat::FindShaderGfx( s3d_CUtilNotifGather *NotifGather, s3d_CEngGfxCtx *GfxCtx) { if(!m_ShaderEnv) return 0; gtp_Shader_FocusedProjMatGfxPtr ShaderGfx; gtp_Shader_FocusedProjMatGfxTree::CNode *Pos = s3d_UtilTreeSortedGetStart(m_ShaderGfxTree, GfxCtx); if(s3d_UtilTreeIsEqualAt(Pos, GfxCtx)) ShaderGfx = Pos->m_Data.m_Val; else { ShaderGfx = S3D_SYS_NEW gtp_Shader_FocusedProjMatGfx( m_ShaderEnv, GfxCtx, m_Data); gtp_Shader_FocusedProjMatGfxTree::CNode *Node = ShaderGfx->GetNode(); m_ShaderGfxTree.InsertBefore(Pos, Node); } return ShaderGfx.Get(); } /////////////////////////////////////////////////////////////////////////////// gtp_Shader_FocusedProjMatGfx::gtp_Shader_FocusedProjMatGfx( s3d_CEngShaderEnv *ShaderEnv, s3d_CEngGfxCtx *GfxCtx, gtp_Shader_FocusedProjMatData *Data) { m_Node.m_Data.m_Key = GfxCtx; m_Node.m_Data.m_Val = this; m_ShaderEnv = ShaderEnv; m_Data = Data; } gtp_Shader_FocusedProjMatGfxTree::CNode * gtp_Shader_FocusedProjMatGfx::GetNode() { return &m_Node; } void gtp_Shader_FocusedProjMatGfx::RegisterNotif( s3d_CUtilNotifRecip *Recip) { } void gtp_Shader_FocusedProjMatGfx::ExtractGfx() { m_Node.Extract(); } bool gtp_Shader_FocusedProjMatGfx::IsValid() { return true; } void gtp_Shader_FocusedProjMatGfx::LinkCollect( s3d_CUtilAtomSet &VarAtomSet) { s3d_CDrvUtilVarUtil::LinkCollect( VarAtomSet, m_Data->m_FocusedProjMatVarAtom); s3d_CDrvUtilVarUtil::LinkCollect( VarAtomSet, m_Data->m_CenterPointVarAtom); s3d_CDrvUtilVarUtil::LinkCollect( VarAtomSet, m_Data->m_MeshVarAtom); } void gtp_Shader_FocusedProjMatGfx::LinkAppoint( s3d_CDrvVarDecl *VarDecl) { s3d_CDrvUtilVarUtil::LinkAppoint( m_FocusedProjMatVarSlot.m_Val, VarDecl, m_Data->m_FocusedProjMatVarAtom); s3d_CDrvUtilVarUtil::LinkAppoint( m_CenterPointVarSlot.m_Val, VarDecl, m_Data->m_CenterPointVarAtom); s3d_CDrvUtilVarUtil::LinkAppoint( m_MeshVarSlot.m_Val, VarDecl, m_Data->m_MeshVarAtom); } s3d_CEngShaderInstPtr gtp_Shader_FocusedProjMatGfx::CreateShaderInst( s3d_CEngShaderHead *Head) { return S3D_SYS_NEW gtp_Shader_FocusedProjMatInst( m_ShaderEnv, this); } /////////////////////////////////////////////////////////////////////////////// gtp_Shader_FocusedProjMatInst::gtp_Shader_FocusedProjMatInst( s3d_CEngShaderEnv *ShaderEnv, gtp_Shader_FocusedProjMatGfx *ShaderGfx) { m_ShaderEnv = ShaderEnv; m_ShaderGfx = ShaderGfx; } void gtp_Shader_FocusedProjMatInst::RegisterNotif( s3d_CUtilNotifRecip *Recip) { } void gtp_Shader_FocusedProjMatInst::SetShaderCtx( s3d_CEngShaderCtx *ShaderCtx) { } void gtp_Shader_FocusedProjMatInst::SetGfxState(s3d_CEngGfxState *GfxState) { } void gtp_Shader_FocusedProjMatInst::SetPos(s3d_CEngPos *Pos) { m_Pos = Pos; } void gtp_Shader_FocusedProjMatInst::SetModel(s3d_CEngModel *Model) { } void gtp_Shader_FocusedProjMatInst::ArrangeCollect( s3d_CUtilMemPool *MemPool, s3d_CEngShaderScopeArray &ScopeArray) { } void gtp_Shader_FocusedProjMatInst::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 gtp_Shader_FocusedProjMatInst::ArrangePerform( s3d_CUtilMemPool *MemPool, s3d_CEngShaderScopeArray_cr ScopeArray) { } void gtp_Shader_FocusedProjMatInst::ArrangeFeedback( s3d_CUtilMemPool *MemPool, s3d_CEngShaderScopeArray_cr ScopeArray) { } void gtp_Shader_FocusedProjMatInst::ArrangeGather( s3d_CEngShaderExecArray &ExecArray) { gtp_Shader_FocusedProjMatData *Data = m_ShaderGfx->m_Data; s3d_CEngUtilShaderUtil::ArrangeGather( ExecArray, Data->m_MethodArray, this); } void gtp_Shader_FocusedProjMatInst::ShaderExecPerform( s3d_CEngShaderScope *Scope, s3d_CUtilAtom *Method, s3d_CEngGfxTaskArray &TaskArray) { gtp_Shader_FocusedProjMatGfx *ShaderGfx = m_ShaderGfx; gtp_Shader_FocusedProjMatData *Data = ShaderGfx->m_Data; SetVars(m_ShaderEnv->m_MemPool, Scope); } void gtp_Shader_FocusedProjMatInst::SetVars( s3d_CUtilMemPool *MemPool, s3d_CEngShaderScope *Scope) { gtp_Shader_FocusedProjMatGfx *ShaderGfx = m_ShaderGfx; gtp_Shader_FocusedProjMatData *Data = ShaderGfx->m_Data; s3d_CDrvVarSlot ProjMatVarSlot = ShaderGfx->m_FocusedProjMatVarSlot; if(ProjMatVarSlot >= 0) { s3d_CEngGfxPortion *Portion = Scope->m_Portion; if(Portion) { s3d_CEngGfxCam *Cam = &Portion->m_Cam; s3d_CEngGfxVarMesh *MeshVar = s3d_EngGfxVarFetchWaryMesh( m_ShaderEnv->m_MsgHandler, Scope->m_Info, Scope->m_VarBlk, m_ShaderGfx->m_MeshVarSlot.m_Val); if(!MeshVar) return; s3d_CDrvVarVec4f *CenterPointVar = s3d_DrvVarFetchWaryVec4f( m_ShaderEnv->m_MsgHandler, Data->m_CenterPointVarInfo.GetChars(), Scope->m_VarBlk, ShaderGfx->m_CenterPointVarSlot.m_Val); if(!CenterPointVar) return; s3d_CUtilTranslQuatf viewToWorld = Cam->m_Transf; s3d_CUtilTranslQuatf modelToView = MeshVar->m_Val.m_ViewTransf; s3d_CUtilVec3f BoundCen = MeshVar->m_Val.m_MeshCompos.m_BoundCen; s3d_CUtilVec3f BoundCenView = modelToView.ApplyToPoint(BoundCen); s3d_CUtilVec3f BoundExt = MeshVar->m_Val.m_MeshCompos.m_BoundExt; s3d_CUtilVec3f CenterPositionView = s3d_CUtilVec3f(CenterPointVar->m_Val.m_x, CenterPointVar->m_Val.m_y, CenterPointVar->m_Val.m_z); s3d_CUtilVec3f DirView = (BoundCenView - CenterPositionView); float d = DirView.GetLen(); float r = BoundExt.GetLen(); DirView = DirView.GetNormalized(); if(d < 1.5 * r) { d = 1.5 * r; CenterPositionView = BoundCenView - DirView * d; } float NearPlane = d - r; float FarPlane = d + r; float cotanFov = 1.0 / s3d_SysTan(s3d_SysAsin(r / d)); float Q = FarPlane / (FarPlane - NearPlane); s3d_CUtilMat4x4f lightProjMat(cotanFov, 0, 0, 0, 0, cotanFov, 0, 0, 0, 0, Q, -Q*NearPlane, 0, 0, 1, 0); //float tanFov = s3d_SysTan(s3d_SysAsin(r / d)); //s3d_CUtilMat4x4f lightProjMat = s3d_CEngUtilMathUtil::CalcProjPersp( tanFov, tanFov, 0, 0, NearPlane, FarPlane); /*CenterPositionView = BoundCenView - DirView * r; s3d_CUtilMat4x4f lightProjMat(1.0 / r, 0, 0, 0, 0, 1.0 / r, 0, 0, 0, 0, 0.5 / r, 0, 0, 0, 0, 1);*/ s3d_CUtilMat4x4f worldToViewMatIT = s3d_CUtilGeof::GetMapOfTransf3(viewToWorld); worldToViewMatIT = worldToViewMatIT.GetTransp(); s3d_CUtilVec4f upView4 = worldToViewMatIT * s3d_CUtilVec4f(0,0,-1,1); s3d_CUtilVec3f upView(upView4.m_x, upView4.m_y, upView4.m_z); upView = upView.GetNormalized(); s3d_CUtilVec3f rightView = upView^DirView; rightView = rightView.GetNormalized(); upView = DirView^rightView; upView = upView.GetNormalized(); s3d_CUtilMat4x4f viewToLightViewMatRot(rightView.m_x, rightView.m_y, rightView.m_z, 0, upView.m_x, upView.m_y, upView.m_z, 0, DirView.m_x, DirView.m_y, DirView.m_z, 0, 0, 0, 0, 1); s3d_CUtilMat4x4f viewToLightViewMatTransl(1, 0, 0, -CenterPositionView.m_x, 0, 1, 0, -CenterPositionView.m_y, 0, 0, 1, -CenterPositionView.m_z, 0, 0, 0, 1); s3d_CUtilMat4x4f viewToLightViewMat = viewToLightViewMatRot * viewToLightViewMatTransl; s3d_CUtilMat4x4f FinalMat = lightProjMat * viewToLightViewMat; s3d_CUtilVec4f temp = FinalMat * s3d_CUtilVec4f(1,0,0,1); s3d_CDrvVarMat4x4f *FinalMatVar = new(MemPool) s3d_CDrvVarMat4x4f; FinalMatVar->m_Val = FinalMat; s3d_DrvVarSet(Scope->m_VarBlk, ProjMatVarSlot, FinalMatVar); } } } ///////////////////////////////////////////////////////////////////////////////