Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/OgreShadowCameraSetupFocused.cpp @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 22.8 KB
RevLine 
[1]1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2006  Torus Knot Software Ltd
8Copyright (c) 2006 Matthias Fink, netAllied GmbH <matthias.fink@web.de>                                                         
9Also see acknowledgements in Readme.html
10
11This program is free software; you can redistribute it and/or modify it under
12the terms of the GNU Lesser General Public License as published by the Free Software
13Foundation; either version 2 of the License, or (at your option) any later
14version.
15
16This program is distributed in the hope that it will be useful, but WITHOUT
17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
19
20You should have received a copy of the GNU Lesser General Public License along with
21this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22Place - Suite 330, Boston, MA 02111-1307, USA, or go to
23http://www.gnu.org/copyleft/lesser.txt.
24
25You may alternatively use this source under the terms of a specific version of
26the OGRE Unrestricted License provided you have obtained such a license from
27Torus Knot Software Ltd.
28-----------------------------------------------------------------------------
29*/
30
31#include "OgreStableHeaders.h"
32#include "OgreShadowCameraSetupFocused.h"
33#include "OgreRoot.h"
34#include "OgreSceneManager.h"
35#include "OgreCamera.h"
36#include "OgreLight.h"
37#include "OgrePlane.h"
38#include "OgreLogManager.h"
39
40
41namespace Ogre
42{
43        /** transform from normal to light space */
44        const Matrix4 FocusedShadowCameraSetup::msNormalToLightSpace(
45                1,  0,  0,  0,          // x
46                0,  0, -1,  0,          // y
47                0,  1,  0,  0,          // z
48                0,  0,  0,  1); // w
49        /** transform  from light to normal space */
50        const Matrix4 FocusedShadowCameraSetup::msLightSpaceToNormal(
51                1,  0,  0,  0,          // x
52                0,  0,  1,  0,          // y
53                0, -1,  0,  0,          // z
54                0,  0,  0,  1); // w
55
56        FocusedShadowCameraSetup::FocusedShadowCameraSetup(void)
57                : mTempFrustum(new Frustum())
58                , mLightFrustumCamera(new Camera("TEMP LIGHT INTERSECT CAM", NULL))
59                , mLightFrustumCameraCalculated(false)
60                , mUseAggressiveRegion(true)
61        {
62                mTempFrustum->setProjectionType(PT_PERSPECTIVE);
63        }
64        //-----------------------------------------------------------------------
65        FocusedShadowCameraSetup::~FocusedShadowCameraSetup(void)
66        {
67                delete mTempFrustum;
68                delete mLightFrustumCamera;
69        }
70        //-----------------------------------------------------------------------
71        void FocusedShadowCameraSetup::calculateShadowMappingMatrix(const SceneManager& sm,
72                const Camera& cam, const Light& light, Matrix4 *out_view, Matrix4 *out_proj, 
73                Camera *out_cam) const
74        {
75                const Vector3& camDir = cam.getDerivedDirection();
76
77                // get the shadow frustum's far distance
78                Real shadowDist = sm.getShadowFarDistance();
79                if (!shadowDist)
80                {
81                        // need a shadow distance, make one up
82                        shadowDist = cam.getNearClipDistance() * 3000;
83                }
84                Real shadowOffset = shadowDist * sm.getShadowDirLightTextureOffset();
85
86
87                if (light.getType() == Light::LT_DIRECTIONAL)
88                {
89                        // generate view matrix if requested
90                        if (out_view != NULL)
91                        {
92                                *out_view = buildViewMatrix(cam.getDerivedPosition(), 
93                                        -light.getDerivedDirection(), 
94                                        camDir);
95                        }
96
97                        // generate projection matrix if requested
98                        if (out_proj != NULL)
99                        {
100                                *out_proj = Matrix4::IDENTITY;
101                        }
102
103                        // set up camera if requested
104                        if (out_cam != NULL)
105                        {
106                                out_cam->setProjectionType(PT_ORTHOGRAPHIC);
107                                out_cam->setDirection(light.getDerivedDirection());
108                                out_cam->setPosition(cam.getDerivedPosition());
109                                out_cam->setFOVy(Degree(90));
110                                out_cam->setNearClipDistance(shadowOffset);
111                        }
112                }
113                else if (light.getType() == Light::LT_POINT)
114                {
115                        // target analogue to the default shadow textures
116                        // Calculate look at position
117                        // We want to look at a spot shadowOffset away from near plane
118                        // 0.5 is a little too close for angles
119                        Vector3 target = cam.getDerivedPosition() + 
120                                (cam.getDerivedDirection() * shadowOffset);
121                        Vector3 lightDir = target - light.getDerivedPosition();
122                        lightDir.normalise();
123
124                        // generate view matrix if requested
125                        if (out_view != NULL)
126                        {
127                                *out_view = buildViewMatrix(light.getDerivedPosition(), 
128                                        lightDir, 
129                                        camDir);
130                        }
131
132                        // generate projection matrix if requested
133                        if (out_proj != NULL)
134                        {
135                                // set FOV to 120 degrees
136                                mTempFrustum->setFOVy(Degree(120));
137
138                                // set near clip distance like the camera
139                                mTempFrustum->setNearClipDistance(cam.getNearClipDistance());
140
141                                *out_proj = mTempFrustum->getProjectionMatrix();
142                        }
143
144                        // set up camera if requested
145                        if (out_cam != NULL)
146                        {
147                                out_cam->setProjectionType(PT_PERSPECTIVE);
148                                out_cam->setDirection(lightDir);
149                                out_cam->setPosition(light.getDerivedPosition());
150                                out_cam->setFOVy(Degree(120));
151                                out_cam->setNearClipDistance(cam.getNearClipDistance());
152                        }
153                }
154                else if (light.getType() == Light::LT_SPOTLIGHT)
155                {
156                        // generate view matrix if requested
157                        if (out_view != NULL)
158                        {
159                                *out_view = buildViewMatrix(light.getDerivedPosition(), 
160                                        light.getDerivedDirection(), 
161                                        camDir);
162                        }
163
164                        // generate projection matrix if requested
165                        if (out_proj != NULL)
166                        {
167                                // set FOV slightly larger than spotlight range
168                                mTempFrustum->setFOVy(light.getSpotlightOuterAngle() * 1.2);
169
170                                // set near clip distance like the camera
171                                mTempFrustum->setNearClipDistance(cam.getNearClipDistance());
172
173                                *out_proj = mTempFrustum->getProjectionMatrix();
174                        }
175
176                        // set up camera if requested
177                        if (out_cam != NULL)
178                        {
179                                out_cam->setProjectionType(PT_PERSPECTIVE);
180                                out_cam->setDirection(light.getDerivedDirection());
181                                out_cam->setPosition(light.getDerivedPosition());
182                                out_cam->setFOVy(light.getSpotlightOuterAngle() * 1.2);
183                                out_cam->setNearClipDistance(cam.getNearClipDistance());
184                        }
185                }
186        }
187        //-----------------------------------------------------------------------
188        void FocusedShadowCameraSetup::calculateB(const SceneManager& sm, const Camera& cam, 
189                const Light& light, const AxisAlignedBox& sceneBB, PointListBody *out_bodyB) const
190        {
191                OgreAssert(out_bodyB != NULL, "bodyB vertex list is NULL");
192
193                /// perform convex intersection of the form B = ((V \cap S) + l) \cap S \cap L
194
195                // get V
196                mBodyB.define(cam);
197
198                if (light.getType() != Light::LT_DIRECTIONAL)
199                {
200                        // clip bodyB with sceneBB
201                        /* Note, Matthias' original code states this:
202                        "The procedure ((V \cap S) + l) \cap S \cap L (Wimmer et al.) leads in some
203                        cases to disappearing shadows. Valid parts of the scene are clipped, so shadows
204                        are partly incomplete. The cause may be the     transformation into light space that
205                        is only done for the corner points which may not contain the whole scene afterwards
206                        any more. So we fall back to the method of Stamminger et al. (V + l) \cap S \cap L
207                        which does not show these anomalies."
208
209                        .. leading to the commenting out of the below clip. However, ift makes a major
210                        difference to the quality of the focus, and so far I haven't noticed
211                        the clipping issues described. Intuitively I would have thought that
212                        any clipping issue would be due to the findCastersForLight not being
213                        quite right, since if the sceneBB includes those there is no reason for
214                        this clip instruction to omit a genuine shadow caster.
215
216                        I have made this a user option since the quality effect is major and
217                        the clipping problem only seems to occur in some specific cases.
218                        */
219                        if (mUseAggressiveRegion)
220                                mBodyB.clip(sceneBB);
221
222                        // form a convex hull of bodyB with the light position
223                        mBodyB.extend(light.getDerivedPosition());
224
225                        // clip bodyB with sceneBB
226                        mBodyB.clip(sceneBB);
227
228                        // clip with the light frustum
229                        // set up light camera to clip with the resulting frustum planes
230                        if (!mLightFrustumCameraCalculated)
231                        {
232                                calculateShadowMappingMatrix(sm, cam, light, NULL, NULL, mLightFrustumCamera);
233                                mLightFrustumCameraCalculated = true;
234                        }
235                        mBodyB.clip(*mLightFrustumCamera);
236
237                        // extract bodyB vertices
238                        out_bodyB->build(mBodyB);
239
240                }
241                else
242                {
243                        // clip bodyB with sceneBB
244                        mBodyB.clip(sceneBB);
245
246                        // Also clip based on shadow far distance if appropriate
247                        Real farDist = sm.getShadowFarDistance();
248                        if (farDist)
249                        {
250                                Vector3 pointOnPlane = cam.getDerivedPosition() + 
251                                        (cam.getDerivedDirection() * farDist);
252                                Plane p(cam.getDerivedDirection(), pointOnPlane);
253                                mBodyB.clip(p);
254                        }
255
256                        // Extrude the intersection bodyB into the inverted light direction and store
257                        // the info in the point list.
258                        // The sceneBB holds the maximum extent of the extrusion.
259                        out_bodyB->buildAndIncludeDirection(mBodyB, 
260                                sceneBB, 
261                                -light.getDerivedDirection());
262                }
263        }
264
265        //-----------------------------------------------------------------------
266        void FocusedShadowCameraSetup::calculateLVS(const SceneManager& sm, const Camera& cam, 
267                const Light& light, const AxisAlignedBox& sceneBB, PointListBody *out_LVS) const
268        {
269                ConvexBody bodyLVS;
270
271                // init body with view frustum
272                bodyLVS.define(cam);
273
274                // clip the body with the light frustum (point + spot)
275                // for a directional light the space of the intersected
276                // view frustum and sceneBB is always lighted and in front
277                // of the viewer.
278                if (light.getType() != Light::LT_DIRECTIONAL)
279                {
280                        // clip with the light frustum
281                        // set up light camera to clip the resulting frustum
282                        if (!mLightFrustumCameraCalculated)
283                        {
284                                calculateShadowMappingMatrix(sm, cam, light, NULL, NULL, mLightFrustumCamera);
285                                mLightFrustumCameraCalculated = true;
286                        }
287                        bodyLVS.clip(*mLightFrustumCamera);
288                }
289
290                // clip the body with the scene bounding box
291                bodyLVS.clip(sceneBB);
292
293                // extract bodyLVS vertices
294                out_LVS->build(bodyLVS);
295        }
296        //-----------------------------------------------------------------------
297        Vector3 FocusedShadowCameraSetup::getLSProjViewDir(const Matrix4& lightSpace, 
298                const Camera& cam, const PointListBody& bodyLVS) const
299        {
300                // goal is to construct a view direction
301                // because parallel lines are not parallel any more after perspective projection we have to transform
302                // a ray to point us the viewing direction
303
304                // fetch a point near the camera
305                const Vector3 e_world = getNearCameraPoint_ws(cam.getViewMatrix(), bodyLVS);
306
307                // plus the direction results in a second point
308                const Vector3 b_world = e_world + cam.getDerivedDirection();
309
310                // transformation into light space
311                const Vector3 e_ls = lightSpace * e_world;
312                const Vector3 b_ls = lightSpace * b_world;
313
314                // calculate the projection direction, which is the subtraction of
315                // b_ls from e_ls. The y component is set to 0 to project the view
316                // direction into the shadow map plane.
317                Vector3 projectionDir(b_ls - e_ls);
318                projectionDir.y = 0;
319                projectionDir.normalise();
320
321                return projectionDir;
322        }
323        //-----------------------------------------------------------------------
324        Vector3 FocusedShadowCameraSetup::getNearCameraPoint_ws(const Matrix4& viewMatrix, 
325                const PointListBody& bodyLVS) const
326        {
327                if (bodyLVS.getPointCount() == 0)
328                        return Vector3(0,0,0);
329
330                Vector3 nearEye = viewMatrix * bodyLVS.getPoint(0),     // for comparison
331                        nearWorld = bodyLVS.getPoint(0);                                // represents the final point
332
333                // store the vertex with the highest z-value which is the nearest point
334                for (size_t i = 1; i < bodyLVS.getPointCount(); ++i)
335                {
336                        const Vector3& vWorld = bodyLVS.getPoint(i);
337
338                        // comparison is done from the viewer
339                        Vector3 vEye = viewMatrix * vWorld;
340
341                        if (vEye.z > nearEye.z)
342                        {
343                                nearEye         = vEye;
344                                nearWorld       = vWorld;
345                        }
346                }
347
348                return nearWorld;
349        }
350        //-----------------------------------------------------------------------
351        Matrix4 FocusedShadowCameraSetup::transformToUnitCube(const Matrix4& m, 
352                const PointListBody& body) const
353        {
354                // map the transformed body AAB points to the unit cube (-1/-1/-1) / (+1/+1/+1) corners
355                AxisAlignedBox aab_trans;
356
357                for (size_t i = 0; i < body.getPointCount(); ++i)
358                {
359                        aab_trans.merge(m * body.getPoint(i));
360                }
361
362                Vector3 vMin, vMax;
363
364                vMin = aab_trans.getMinimum();
365                vMax = aab_trans.getMaximum();
366
367                const Vector3 trans(-(vMax.x + vMin.x) / (vMax.x - vMin.x),
368                        -(vMax.y + vMin.y) / (vMax.y - vMin.y),
369                        -(vMax.z + vMin.z) / (vMax.z - vMin.z));
370
371                const Vector3 scale(2 / (vMax.x - vMin.x),
372                        2 / (vMax.y - vMin.y),
373                        2 / (vMax.z - vMin.z));
374
375                Matrix4 mOut(Matrix4::IDENTITY);
376                mOut.setTrans(trans);
377                mOut.setScale(scale);
378
379                return mOut;
380        }
381        //-----------------------------------------------------------------------
382        Matrix4 FocusedShadowCameraSetup::buildViewMatrix(const Vector3& pos, const Vector3& dir, 
383                const Vector3& up) const
384        {
385                Vector3 xN = dir.crossProduct(up);
386                xN.normalise();
387                Vector3 upN = xN.crossProduct(dir);
388                upN.normalise();
389
390                Matrix4 m(xN.x,         xN.y,           xN.z,           -xN.dotProduct(pos),
391                        upN.x,          upN.y,          upN.z,          -upN.dotProduct(pos),
392                        -dir.x,         -dir.y, -dir.z, dir.dotProduct(pos),
393                        0.0,                    0.0,            0.0,            1.0
394                        );
395
396                return m;
397        }
398        //-----------------------------------------------------------------------
399        void FocusedShadowCameraSetup::getShadowCamera (const SceneManager *sm, const Camera *cam, 
400                const Viewport *vp, const Light *light, Camera *texCam) const
401        {
402                // check availability - viewport not needed
403                OgreAssert(sm != NULL, "SceneManager is NULL");
404                OgreAssert(cam != NULL, "Camera (viewer) is NULL");
405                OgreAssert(light != NULL, "Light is NULL");
406                OgreAssert(texCam != NULL, "Camera (texture) is NULL");
407                mLightFrustumCameraCalculated = false;
408
409                // calculate standard shadow mapping matrix
410                Matrix4 LView, LProj;
411                calculateShadowMappingMatrix(*sm, *cam, *light, &LView, &LProj, NULL);
412
413                // build scene bounding box
414                const VisibleObjectsBoundsInfo& visInfo = sm->getShadowCasterBoundsInfo(light);
415                AxisAlignedBox sceneBB = visInfo.aabb;
416                sceneBB.merge(sm->getVisibleObjectsBoundsInfo(cam).aabb);
417                sceneBB.merge(cam->getDerivedPosition());
418
419                // in case the sceneBB is empty (e.g. nothing visible to the cam) simply
420                // return the standard shadow mapping matrix
421                if (sceneBB.isNull())
422                {
423                        texCam->setCustomViewMatrix(true, LView);
424                        texCam->setCustomProjectionMatrix(true, LProj);
425                        return;
426                }
427
428                // calculate the intersection body B
429                mPointListBodyB.reset();
430                calculateB(*sm, *cam, *light, sceneBB, &mPointListBodyB);
431
432                // in case the bodyB is empty (e.g. nothing visible to the light or the cam)
433                // simply return the standard shadow mapping matrix
434                if (mPointListBodyB.getPointCount() == 0)
435                {
436                        texCam->setCustomViewMatrix(true, LView);
437                        texCam->setCustomProjectionMatrix(true, LProj);
438                        return;
439                }
440
441                // transform to light space: y -> -z, z -> y
442                LProj = msNormalToLightSpace * LProj;
443
444                // calculate LVS so it does not need to be calculated twice
445                // calculate the body L \cap V \cap S to make sure all returned points are in
446                // front of the camera
447                mPointListBodyLVS.reset();
448                calculateLVS(*sm, *cam, *light, sceneBB, &mPointListBodyLVS);
449
450                // fetch the viewing direction
451                const Vector3 viewDir = getLSProjViewDir(LProj * LView, *cam, mPointListBodyLVS);
452
453                // The light space will be rotated in such a way, that the projected light view
454                // always points upwards, so the up-vector is the y-axis (we already prepared the
455                // light space for this usage).The transformation matrix is set up with the
456                // following parameters:
457                // - position is the origin
458                // - the view direction is the calculated viewDir
459                // - the up vector is the y-axis
460                LProj = buildViewMatrix(Vector3::ZERO, viewDir, Vector3::UNIT_Y) * LProj;
461
462                // map bodyB to unit cube
463                LProj = transformToUnitCube(LProj * LView, mPointListBodyB) * LProj;
464
465                // transform from light space to normal space: y -> z, z -> -y
466                LProj = msLightSpaceToNormal * LProj;
467
468                // set the two custom matrices
469                texCam->setCustomViewMatrix(true, LView);
470                texCam->setCustomProjectionMatrix(true, LProj);
471        }
472
473        //---------------------------------------------------------------------
474        //---------------------------------------------------------------------
475        //-----------------------------------------------------------------------
476        FocusedShadowCameraSetup::PointListBody::PointListBody()
477        {
478                // Preallocate some space
479                mBodyPoints.reserve(12);
480        }
481        //-----------------------------------------------------------------------
482        FocusedShadowCameraSetup::PointListBody::PointListBody(const ConvexBody& body)
483        {
484                build(body);
485        }
486        //-----------------------------------------------------------------------
487        FocusedShadowCameraSetup::PointListBody::~PointListBody()
488        {
489        }
490        //-----------------------------------------------------------------------
491        void FocusedShadowCameraSetup::PointListBody::merge(const PointListBody& plb)
492        {
493                size_t size = plb.getPointCount();
494                for (size_t i = 0; i < size; ++i)
495                {
496                        this->addPoint(plb.getPoint(i));
497                }
498        }
499        //-----------------------------------------------------------------------
500        void FocusedShadowCameraSetup::PointListBody::build(const ConvexBody& body, bool filterDuplicates)
501        {
502                // erase list
503                mBodyPoints.clear();
504
505                // Try to reserve a representative amount of memory
506                mBodyPoints.reserve(body.getPolygonCount() * 6);
507
508                // build new list
509                for (size_t i = 0; i < body.getPolygonCount(); ++i)
510                {
511                        for (size_t j = 0; j < body.getVertexCount(i); ++j)
512                        {
513                                const Vector3 &vInsert = body.getVertex(i, j);
514
515                                // duplicates allowed?
516                                if (filterDuplicates)
517                                {
518                                        bool bPresent = false;
519
520                                        for(Polygon::VertexList::iterator vit = mBodyPoints.begin();
521                                                vit != mBodyPoints.end(); ++vit)
522                                        {
523                                                const Vector3& v = *vit;
524
525                                                if (vInsert.positionEquals(v))
526                                                {
527                                                        bPresent = true;
528                                                        break;
529                                                }
530                                        }
531
532                                        if (bPresent == false)
533                                        {
534                                                mBodyPoints.push_back(body.getVertex(i, j));
535                                        }
536                                }
537
538                                // else insert directly
539                                else
540                                {
541                                        mBodyPoints.push_back(body.getVertex(i, j));
542                                }
543                        }
544                }
545
546                // update AAB
547                // no points altered, so take body AAB
548                mAAB = body.getAABB();
549        }
550        //-----------------------------------------------------------------------
551        void FocusedShadowCameraSetup::PointListBody::buildAndIncludeDirection(
552                const ConvexBody& body, const AxisAlignedBox& aabMax, const Vector3& dir)
553        {
554                // reset point list
555                this->reset();
556
557                // intersect the rays formed by the points in the list with the given direction and
558                // insert them into the list
559
560                // min/max aab points for comparison
561                const Vector3& min = aabMax.getMinimum();
562                const Vector3& max = aabMax.getMaximum();
563
564                // assemble the clipping planes
565                Plane pl[6];
566
567                // front
568                pl[0].redefine(Vector3::UNIT_Z, max);
569                // back
570                pl[1].redefine(Vector3::NEGATIVE_UNIT_Z, min);
571                // left
572                pl[2].redefine(Vector3::NEGATIVE_UNIT_X, min);
573                // right
574                pl[3].redefine(Vector3::UNIT_X, max);
575                // bottom
576                pl[4].redefine(Vector3::NEGATIVE_UNIT_Y, min);
577                // top
578                pl[5].redefine(Vector3::UNIT_Y, max);
579
580
581                const size_t polyCount = body.getPolygonCount();
582                for (size_t iPoly = 0; iPoly < polyCount; ++iPoly)
583                {
584
585                        // store the old inserted point and plane info
586                        // if the currently processed point hits a different plane than the previous point an
587                        // intersection point is calculated that lies on the two planes' intersection edge
588
589                        // fetch current polygon
590                        const Polygon& p = body.getPolygon(iPoly);
591
592                        size_t pointCount = p.getVertexCount();
593                        for (size_t iPoint = 0; iPoint < pointCount ; ++iPoint)
594                        {
595                                // base point
596                                const Vector3& pt = p.getVertex(iPoint);
597
598                                // add the base point
599                                this->addPoint(pt);
600
601                                // intersection ray
602                                Ray ray(pt, dir);
603
604                                // intersect with each plane
605                                for (size_t iPlane = 0; iPlane < 6; ++iPlane)
606                                {
607                                        std::pair< bool, Real > intersect = ray.intersects(pl[ iPlane ]);
608
609                                        const Vector3 ptIntersect = ray.getPoint(intersect.second);
610
611                                        // intersection point must exist (first) and the point distance must be greater than null (second)
612                                        // in case of distance null the intersection point equals the base point
613                                        if (intersect.first && intersect.second > 0)
614                                        {
615                                                if (ptIntersect.x < max.x + 1e-3f && ptIntersect.x > min.x - 1e-3f && 
616                                                        ptIntersect.y < max.y + 1e-3f && ptIntersect.y > min.y - 1e-3f && 
617                                                        ptIntersect.z < max.z + 1e-3f && ptIntersect.z > min.z - 1e-3f)
618                                                {
619                                                        // in case the point lies on the boundary, continue and see if there is another plane that intersects
620                                                        if (pt.positionEquals(ptIntersect))
621                                                        {
622                                                                continue;
623                                                        }
624
625                                                        // add intersection point
626                                                        this->addPoint(ptIntersect);
627                                                }
628
629                                        } // if: intersection available
630
631                                } // for: plane intersection
632
633                        } // for: polygon point iteration
634
635                } // for: polygon iteration
636        }
637        //-----------------------------------------------------------------------
638        const AxisAlignedBox& FocusedShadowCameraSetup::PointListBody::getAAB(void) const
639        {
640                return mAAB;
641        }
642        //-----------------------------------------------------------------------       
643        void FocusedShadowCameraSetup::PointListBody::addPoint(const Vector3& point)
644        {
645                // dont check for doubles, simply add
646                mBodyPoints.push_back(point);
647
648                // update AAB
649                mAAB.merge(point);
650        }
651        //-----------------------------------------------------------------------
652        void FocusedShadowCameraSetup::PointListBody::addAAB(const AxisAlignedBox& aab)
653        {
654                const Vector3& min = aab.getMinimum();
655                const Vector3& max = aab.getMaximum();
656
657                Vector3 currentVertex = min;
658                // min min min
659                addPoint(currentVertex);
660
661                // min min max
662                currentVertex.z = max.z;
663                addPoint(currentVertex);
664
665                // min max max
666                currentVertex.y = max.y;
667                addPoint(currentVertex);
668
669                // min max min
670                currentVertex.z = min.z;
671                addPoint(currentVertex);
672
673                // max max min
674                currentVertex.x = max.x;
675                addPoint(currentVertex);
676
677                // max max max
678                currentVertex.z = max.z;
679                addPoint(currentVertex);
680
681                // max min max
682                currentVertex.y = min.y;
683                addPoint(currentVertex);
684
685                // max min min
686                currentVertex.z = min.z;
687                addPoint(currentVertex); 
688
689        }
690        //-----------------------------------------------------------------------       
691        const Vector3& FocusedShadowCameraSetup::PointListBody::getPoint(size_t cnt) const
692        {
693                OgreAssert(cnt >= 0 && cnt < getPointCount(), "Search position out of range");
694
695                return mBodyPoints[ cnt ];
696        }
697        //-----------------------------------------------------------------------       
698        size_t FocusedShadowCameraSetup::PointListBody::getPointCount(void) const
699        {
700                return mBodyPoints.size();
701        }
702        //-----------------------------------------------------------------------       
703        void FocusedShadowCameraSetup::PointListBody::reset(void)
704        {
705                mBodyPoints.clear();
706                mAAB.setNull();
707        }
708
709}
710
711
Note: See TracBrowser for help on using the repository browser.