~ubuntu-branches/debian/sid/ember/sid

« back to all changes in this revision

Viewing changes to src/components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeRaySceneQuery.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michael Koch
  • Date: 2009-07-23 07:46:40 UTC
  • Revision ID: james.westby@ubuntu.com-20090723074640-wh0ukzis0kda36qv
Tags: upstream-0.5.6
ImportĀ upstreamĀ versionĀ 0.5.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
OgrePagingLandScapeRaySceneQuery.cpp  -  description
 
3
-------------------
 
4
begin                : Fri Sep 10 2003
 
5
copyright            : (C) 2003-2006 by Jose A Milan && Tuan Kuranes
 
6
email                : spoke2@supercable.es && tuan.kuranes@free.fr
 
7
***************************************************************************/
 
8
 
 
9
/***************************************************************************
 
10
*                                                                         *
 
11
*   This program is free software; you can redistribute it and/or modify  *
 
12
*   it under the terms of the GNU Lesser General Public License as        *
 
13
*   published by the Free Software Foundation; either version 2 of the    *
 
14
*   License, or (at your option) any later version.                       *
 
15
*                                                                         *
 
16
***************************************************************************/
 
17
 
 
18
#include "OgrePagingLandScapePrecompiledHeaders.h"
 
19
 
 
20
#include "OgreEntity.h"
 
21
 
 
22
#include "OgreVector3.h"
 
23
#include "OgreColourValue.h"
 
24
 
 
25
#include "OgreSceneManager.h"
 
26
#include "OgrePagingLandScapeOctreeSceneManager.h"
 
27
 
 
28
#include "OgrePagingLandScapeOptions.h"
 
29
#include "OgrePagingLandScapeSceneManager.h"
 
30
#include "OgrePagingLandScapeData2DManager.h"
 
31
#include "OgrePagingLandScapeRaySceneQuery.h"
 
32
 
 
33
namespace Ogre
 
34
{
 
35
 
 
36
//----------------------------------------------------------------------------
 
37
// This function return the vertex interpolated height.
 
38
// Supplied by Praetor. Thanks a lot. ]:)
 
39
void PagingLandScapeRaySceneQuery::execute(RaySceneQueryListener* listener) 
 
40
 
41
        ///Ember start
 
42
        ///Make sure that there really is some world geometry first
 
43
    if ((static_cast<PagingLandScapeSceneManager*>(mParentSceneMgr)->mWorldGeomIsSetup) && (getQueryTypeMask() & SceneManager::WORLD_GEOMETRY_TYPE_MASK))
 
44
        ///Ember end
 
45
        {
 
46
                mWorldFrag.fragmentType = SceneQuery::WFT_SINGLE_INTERSECTION;
 
47
 
 
48
                const Vector3& dir(mRay.getDirection());
 
49
                const Vector3& origin(mRay.getOrigin());
 
50
 
 
51
                PagingLandScapeSceneManager* mSceneMgr = static_cast<PagingLandScapeSceneManager*>(mParentSceneMgr);
 
52
                if (mWorldFragmentType & WFT_SINGLE_INTERSECTION)
 
53
                {
 
54
                        if (dir == Vector3::UNIT_Y || 
 
55
                                dir == Vector3::NEGATIVE_UNIT_Y)
 
56
                        {
 
57
                                Real height;
 
58
                                if (mSceneMgr->getOptions()->queryNoInterpolation)
 
59
                                        height = mSceneMgr->getData2DManager()->getWorldHeight(origin.x, origin.z);
 
60
                                else
 
61
                                        height = mSceneMgr->getData2DManager()->getInterpolatedWorldHeight(origin.x, origin.z);
 
62
 
 
63
                                mWorldFrag.singleIntersection.x = origin.x;
 
64
                                mWorldFrag.singleIntersection.z = origin.z;
 
65
                                mWorldFrag.singleIntersection.y = height;
 
66
 
 
67
                                mWorldFrag.singleIntersection += mSceneMgr->getOptions()->position; //consider terrain offset
 
68
 
 
69
                                listener->queryResult(&mWorldFrag, (Math::Abs(mWorldFrag.singleIntersection.y - origin.y)));
 
70
                                return;
 
71
                        }
 
72
                        else if (mSceneMgr->intersectSegmentTerrain(
 
73
                                        origin, 
 
74
                                        dir * mSceneMgr->getOptions()->queryResolutionFactor, 
 
75
                                        &mWorldFrag.singleIntersection))
 
76
                        {
 
77
                listener->queryResult(&mWorldFrag, (mWorldFrag.singleIntersection - origin).length());
 
78
                ///Ember start
 
79
                PagingLandScapeOctreeRaySceneQuery::execute(listener);
 
80
                ///Ember end
 
81
                return;
 
82
                        }
 
83
                }
 
84
                else
 
85
                {
 
86
                        // multiple terrain intersection
 
87
                        const Vector3 raydir (mRay.getDirection());
 
88
                        const Vector3 raymove (raydir * mSceneMgr->getOptions()->queryResolutionFactor);
 
89
                        const Real distmove = mSceneMgr->getOptions()->queryResolutionFactor;
 
90
                        const Real maxHeight = mSceneMgr->getData2DManager()->getMaxHeight ();
 
91
                        const Real MaxTerrainX = mSceneMgr->getOptions()->maxScaledX;
 
92
                        const Real MaxTerrainZ = mSceneMgr->getOptions()->maxScaledZ;
 
93
 
 
94
                        Vector3 ray (mRay.getOrigin());
 
95
                        Real dist = 0.0f;
 
96
 
 
97
                        // while ray is inside or ray is outside but raydir going inside
 
98
                        while ((ray.y < 0 && raydir.y > 0) || 
 
99
                                (ray.y > maxHeight    && raydir.y < 0) || 
 
100
                                (ray.x < -MaxTerrainX && raydir.x > 0) || 
 
101
                                (ray.x > MaxTerrainX  && raydir.x < 0) || 
 
102
                                (ray.z < -MaxTerrainZ && raydir.z > 0) || 
 
103
                                (ray.z > MaxTerrainZ  && raydir.z < 0)) 
 
104
                        {
 
105
                                ray += raymove;
 
106
                                dist += distmove;
 
107
                                if (ray.y < maxHeight)// no need to do complex tests
 
108
                                {
 
109
                                        const Vector3 land (getHeightAt(ray));
 
110
                                        if (ray.y < land.y)
 
111
                                        {
 
112
                                                WorldFragment* frag = new WorldFragment();
 
113
                                                //fragmentList.push_back(frag);
 
114
 
 
115
                                                frag->fragmentType = SceneQuery::WFT_SINGLE_INTERSECTION; 
 
116
                                                frag->singleIntersection = land;
 
117
 
 
118
                                                if (!listener->queryResult(frag,  dist))
 
119
                                                        return;
 
120
                                        }
 
121
                                }
 
122
                        } 
 
123
                }
 
124
 
 
125
        }
 
126
    // if anything else is queried, ask underlying Octree Scene Manager.
 
127
    PagingLandScapeOctreeRaySceneQuery::execute(listener);
 
128
 
129
//----------------------------------------------------------------------------
 
130
Vector3 PagingLandScapeRaySceneQuery::getHeightAt(const Vector3& origin) const
 
131
{
 
132
 
 
133
    PagingLandScapeSceneManager * mSceneMgr = static_cast<PagingLandScapeSceneManager*>(mParentSceneMgr);
 
134
        return Vector3(origin.x, mSceneMgr->getData2DManager()->getInterpolatedWorldHeight(origin.x, origin.z), origin.z);
 
135
 
 
136
}
 
137
 
 
138
} // namespace Ogre