source: GTP/trunk/App/Demos/Illum/Shark3D/version164x12u/IllumDemo/src/gtp_shader/gtp_shader_opticsutil.cpp @ 2196

Revision 2196, 9.5 KB checked in by szirmay, 17 years ago (diff)
Line 
1///////////////////////////////////////////////////////////////////////////////
2//
3//      ##  ######
4//       ######  ###
5//  ## ###############        Shark 3D Engine (www.shark3d.com)
6//   ########## # # #
7//    ########                Copyright (c) 1996-2006 Spinor GmbH.
8//   ######### # # #          All rights reserved.
9//  ##   ##########
10//      ##
11//
12///////////////////////////////////////////////////////////////////////////////
13
14//@cpp
15
16#include "gtp_shader_opticsutil.h"
17#include "../../../util/math/util_geo_types.h"
18
19///////////////////////////////////////////////////////////////////////////////
20
21bool gtp_ShaderOpticsUtil::CalcViewNormalDist(
22        s3d_CUtilVec3f &ViewNormal, float &ViewDist,
23        s3d_CUtilTranslQuatf_cr ViewTransf)
24{
25    if(ViewTransf.m_Quat == 0)
26        return false;
27
28    // Clip plane is local z-plane.
29    s3d_CUtilVec3f LocalNormal = s3d_CUtilVec3f(0, 0, 1);
30
31    // Clip plane in view coordinates. Plane equation is:
32    // Point * ViewNormal + ViewDist = 0.
33    s3d_CUtilMat3x3f TransfMat = ViewTransf.m_Quat.GetMat();
34    ViewNormal = (TransfMat * LocalNormal).GetNormalized();
35    ViewDist = - ViewNormal * ViewTransf.m_Transl;
36
37    // Front side visible?:
38    return ViewDist > 0;
39}
40
41bool gtp_ShaderOpticsUtil::CalcChildCamFull(
42        s3d_CEngGfxCam &ChildCam,
43        void *Exclude,
44        int MaxRecursion, float Coeff, float Precision,
45        bool UseCompactFrustum, s3d_CEngShaderScope *Scope,
46        s3d_CUtilTranslQuatf_cr ViewTransf,
47        s3d_CUtilVec3f_cr ViewNormal, float ViewDist)
48{
49    s3d_CEngGfxPortion *Portion = Scope->m_Portion;
50
51    // Check recursion level:
52    if(Portion->m_Cam.m_Recursion >= MaxRecursion)
53        return false;
54
55    s3d_CUtilTranslQuatf RecTransf = Portion->m_Cam.m_Transf;
56    bool RecReverse = Portion->m_Cam.m_Reverse;
57
58    s3d_CUtilMat4x4f RecProj = Portion->m_Cam.m_Proj;
59
60    s3d_CUtilVec4f RecClipPlane;
61    RecClipPlane.m_x = - ViewNormal.m_x;
62    RecClipPlane.m_y = - ViewNormal.m_y;
63    RecClipPlane.m_z = - ViewNormal.m_z;
64    RecClipPlane.m_w = - ViewDist;
65
66    if(Coeff != 0 && Coeff != 1)
67    {
68        // Calculate extra transformation in view coordinates:
69
70        float Change = Coeff - 1;
71        // (Assuming that normal vector is normalized:)
72        // NewPoint
73        // = Point + Point-To-Plane-Distance * (ViewNormal * Change)
74        // = Point + (Point * ViewNormal + ViewDist) * (ViewNormal * Change)
75        // = (I + ViewNormal (x) ViewNormal * Change) * Point
76        //   + ViewNormal * (ViewDist * Change)
77        // =: ExtraMat * Point + ExtraTransl
78        s3d_CUtilMat3x3f ExtraMat(s3d_CUtilMat3x3f(1)
79                + s3d_CUtilMat3x3f::ByTensorProd(
80                        ViewNormal, ViewNormal * Change));
81        s3d_CUtilVec3f ExtraTransl(ViewNormal * (ViewDist * Change));
82
83        // PartQuat maps the view z into the reflected view z:
84        s3d_CUtilVec3f BeforeDirZ(0, 0, 1);
85        s3d_CUtilVec3f AppliedDirZ = ExtraMat.GetColZ().GetNormalized();
86        s3d_CUtilVec3f DirY(0, 1, 0);
87        s3d_CUtilQuatf PartQuat = s3d_CUtilQuatf::ByPathAlso(
88                        AppliedDirZ, BeforeDirZ, DirY, DirY);
89        // (ExtraTransl, ExtraMat)
90        // := (0, RestMat) x (PartTransl, PartQuat)
91        // = (RestMat * PartTransl, RestMat * PartQuat)
92        s3d_CUtilMat3x3f RestMat = ExtraMat * PartQuat.GetInvMat();
93        s3d_CUtilVec3f PartTransl = RestMat.GetInv() * ExtraTransl;
94        s3d_CUtilTranslQuatf PartTransf(PartTransl, PartQuat);
95
96        // Apply:
97        RecTransf = RecTransf.ConcatInv(PartTransf);
98        RecProj = s3d_CUtilGeof::ConcatMapTranslMat3(RecProj, 0, RestMat);
99        RecClipPlane = RecClipPlane
100            * s3d_CUtilGeof::GetMapOfInvTransf3(PartTransf);
101        if(Coeff < 0)
102        {
103            RecClipPlane = - RecClipPlane;
104            RecReverse = !RecReverse;
105        }
106    }
107
108    if(UseCompactFrustum)
109    {
110        // Use the near clipping plane as mirror clipping plane.
111        //
112        // Clipping plane condition:
113        // -> (NewProj * P).z >= - (NewProj * P).w
114        // -> (NewProj.z? + NewProj.w?) * P >= 0
115        // Only modify Proj.z?
116        // -> (NewProj.z? + Proj.w?) * P >= 0
117        //
118        // Plane:
119        // -> Plane * P >= 0
120        // -> NewProj.z? + NewProj.w? = Plane * Fac
121        // -> NewProj.z? = Plane * Fac - Proj.w?
122        //
123        // Choose far clipping plane to include FarPoint
124        // (typically choose plane dir infinity):
125        // NewProj * FarPoint = ~ (0, 0, 1, 1)
126        // -> NewProj.z? * FarPoint = NewProj.w? * FarPoint
127        // -> [Plane * Fac - Proj.w?] * FarPoint = Proj.w? * FarPoint
128        // -> Fac = (Proj.w? * FarPoint * 2) / (Plane * FarPoint)
129        //
130        // Choose FarPoint at infinity in that way
131        // that the complete old frustum is included.
132        // For this, select one frustum vertex at infinity
133        // depending on the plane slope signs.
134
135        s3d_CUtilVec4f FarPoint(
136                s3d_SysSign(RecClipPlane.m_x),
137                s3d_SysSign(RecClipPlane.m_y),
138                1,
139                0);
140
141        s3d_CUtilVec4f RecProjRowW = RecProj.GetRowW();
142        float PlaneFac = ((RecProjRowW * FarPoint) * 2)
143                        / (RecClipPlane * FarPoint);
144        RecProj.SetRowZ(RecClipPlane * PlaneFac - RecProjRowW);
145        RecClipPlane = 0;
146    }
147   
148    s3d_CUtilVec3f WorldTransl
149        = Portion->m_Cam.m_Transf.ApplyToPoint(ViewTransf.m_Transl);
150
151    // New camera structure:
152    ChildCam = Portion->m_Cam;
153    ChildCam.m_Exclude = Exclude;
154    ChildCam.m_Recursion = Portion->m_Cam.m_Recursion + 1;
155    ChildCam.m_VisibPoint = WorldTransl;
156    ChildCam.m_Transf = RecTransf;
157    ChildCam.m_Proj = RecProj;
158    ChildCam.m_Reverse = RecReverse;
159
160    if(Precision > 0)
161    {
162        ChildCam.m_CullPix *= Precision;
163        ChildCam.m_MeshPix *= Precision;
164        ChildCam.m_VisibMeshPix *= Precision;
165    }
166
167    return true;
168}
169
170bool gtp_ShaderOpticsUtil::CalcChildRange(
171        s3d_CUtilVec3f &SubNeg, s3d_CUtilVec3f &SubPos,
172        s3d_CUtilTranslQuatf_cr ViewTransf,
173        s3d_CUtilVec3f_cr BoundCen, s3d_CUtilVec3f_cr BoundExt,
174        s3d_CEngShaderScope *Scope)
175{
176    s3d_CEngGfxPortion *Portion = Scope->m_Portion;
177
178    // Calculate bounding rectangle in screen coordinates:
179    s3d_CUtilMat3x3f TransfMat = ViewTransf.m_Quat.GetMat();
180    s3d_CUtilVec3f ViewBoundCen = ViewTransf.m_Transl + TransfMat * BoundCen;
181    s3d_CUtilMat3x3f ViewBoundExt = TransfMat.ColGetScaled(BoundExt);
182
183    s3d_CUtilMat4x4f TotalBoundMap =
184            s3d_CUtilGeof::ConcatMapTranslMat3(
185                    Portion->m_Cam.m_Proj, ViewBoundCen, ViewBoundExt);
186    s3d_CUtilVec3f MapMin, MapMax;
187    s3d_CUtilGeof::CalcRangeMapMinusPlusOne3(
188                        MapMin, MapMax, -1, +1, TotalBoundMap);
189    MapMin.m_z = -1; // Keep near plane to avoid problems with linked cam.
190    MapMax.m_z = 1; // Look to infinity.
191    if(MapMin.IsAnyCompGe(MapMax))
192        return false;
193
194    // Calculate new rendering target rectangle:
195    SubNeg = (MapMin + s3d_CUtilVec3f(1)) * 0.5f;
196    SubPos = (MapMax + s3d_CUtilVec3f(1)) * 0.5f;
197
198    return true;
199}
200
201void gtp_ShaderOpticsUtil::SnapChildRange(
202        s3d_CUtilVec3f &SubNeg, s3d_CUtilVec3f &SubPos,
203        int SnapWidth, int SnapHeight)
204{
205    S3D_SYS_ASSERT(SnapWidth > 0 && SnapHeight > 0);
206    float RcpSnapWidth = 1.0f / SnapWidth;
207    float RcpSnapHeight = 1.0f / SnapHeight;
208    SubNeg.m_x = s3d_SysRoundFloor(SubNeg.m_x * SnapWidth) * RcpSnapWidth;
209    SubPos.m_x = s3d_SysRoundCeil(SubPos.m_x * SnapWidth) * RcpSnapWidth;
210    SubNeg.m_y = s3d_SysRoundFloor(SubNeg.m_y * SnapHeight) * RcpSnapHeight;
211    SubPos.m_y = s3d_SysRoundCeil(SubPos.m_y * SnapHeight) * RcpSnapHeight;
212}
213
214void gtp_ShaderOpticsUtil::ApplyRangeToChildCam(
215        s3d_CEngGfxCam &ChildCam, s3d_CUtilMat4x4f &BaseProj,
216        s3d_CUtilVec3f_cr SubNeg, s3d_CUtilVec3f_cr SubPos)
217{
218    s3d_CUtilVec3f SubDelta = SubPos - SubNeg;
219    s3d_CUtilVec3f SubSum = SubPos + SubNeg;
220
221    // Calculate new target matrix:
222    s3d_CUtilVec2f SubNegXY(SubNeg.m_x, SubNeg.m_y);
223    s3d_CUtilVec2f SubDeltaXY(SubDelta.m_x, SubDelta.m_y);
224    ChildCam.m_ViewPane.m_Transl
225            = ChildCam.m_ViewPane.m_Transl
226            + SubNegXY.CompMul(ChildCam.m_ViewPane.m_Scale);
227    ChildCam.m_ViewPane.m_Scale
228            = SubDeltaXY.CompMul(ChildCam.m_ViewPane.m_Scale);
229    float ViewDepthDelta = ChildCam.m_ViewDepthEnd - ChildCam.m_ViewDepthStart;
230    ChildCam.m_ViewDepthStart
231            = ChildCam.m_ViewDepthStart + ViewDepthDelta * SubNeg.m_z;
232
233    // Calculate new projection matrix:
234    s3d_CUtilVec3f ScrScal = s3d_CUtilVec3f(1).CompDiv(SubDelta);
235    s3d_CUtilVec3f ScrOffs = (s3d_CUtilVec3f(1) - SubSum).CompMul(ScrScal);
236    s3d_CUtilMat4x4f ExtraProj = 1;
237    ExtraProj.m_xx = ScrScal.m_x;
238    ExtraProj.m_yy = ScrScal.m_y;
239    ExtraProj.m_zz = ScrScal.m_z;
240    ExtraProj.m_xw = ScrOffs.m_x;
241    ExtraProj.m_yw = ScrOffs.m_y;
242    ExtraProj.m_zw = ScrOffs.m_z;
243    ChildCam.m_Proj = ExtraProj * ChildCam.m_Proj;
244    BaseProj = ExtraProj * BaseProj;
245}
246
247int gtp_ShaderOpticsUtil::RoundToPowerOfTwoDown(int x)
248{
249    x |= (x >> 16);
250    x |= (x >> 8);
251    x |= (x >> 4);
252    x |= (x >> 2);
253    x |= (x >> 1);
254    return x & ~(x >> 1);
255}
256
257int gtp_ShaderOpticsUtil::RoundToPowerOfTwoUp(int x)
258{
259    return RoundToPowerOfTwoDown((x << 1) - 1);
260}
261
262///////////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.