1 | /*
|
---|
2 | -----------------------------------------------------------------------------
|
---|
3 | This source file is part of the GameTools Project
|
---|
4 | http://www.gametools.org
|
---|
5 |
|
---|
6 | Author: Martin Szydlowski
|
---|
7 | -----------------------------------------------------------------------------
|
---|
8 | */
|
---|
9 |
|
---|
10 | #include "OgreBvHierarchySceneNode.h"
|
---|
11 | #include "OgreBvHierarchySceneManager.h"
|
---|
12 |
|
---|
13 | #include <OgreStringConverter.h>
|
---|
14 | #include <OgreLogManager.h>
|
---|
15 |
|
---|
16 | namespace Ogre
|
---|
17 | {
|
---|
18 | // TRIVIA: this function is _not_ called for nodes which did not change since the last frame
|
---|
19 | // only exception: the root node ... it's aabb should be null however, so we don't care
|
---|
20 | void BvHierarchySceneNode::_updateBounds(void)
|
---|
21 | {
|
---|
22 | // Reset bounds first
|
---|
23 | mWorldAABB.setNull();
|
---|
24 |
|
---|
25 | // Update bounds from own attached objects
|
---|
26 | ObjectMap::iterator i;
|
---|
27 | for (i = mObjectsByName.begin(); i != mObjectsByName.end(); ++i)
|
---|
28 | {
|
---|
29 | // Merge world bounds of each object
|
---|
30 | mWorldAABB.merge(i->second->getWorldBoundingBox(true));
|
---|
31 | }
|
---|
32 |
|
---|
33 | if (!mWorldAABB.isNull())
|
---|
34 | {
|
---|
35 | static_cast<BvHierarchySceneManager *>(mCreator)->_updateNode(this);
|
---|
36 | }
|
---|
37 | }
|
---|
38 |
|
---|
39 | void BvHierarchySceneNode::computeScene(BvhPlaneEventList& events, AxisAlignedBox& aabb, int& nObjects, bool includeChildren)
|
---|
40 | {
|
---|
41 | /**************************************************************************************/
|
---|
42 | /* HACK: do not include camera node, FUCKS UP world AABB really BAD, dunno why */
|
---|
43 | /* TODO: find a generic solution where MOVABLE nodes are NOT INSERTED into the BvHierarchy */
|
---|
44 | /**************************************************************************************/
|
---|
45 | //if (mName == "PlayerCamNode")
|
---|
46 | // return;
|
---|
47 |
|
---|
48 | // first compute nodes AABB
|
---|
49 | mWorldAABB.setNull();
|
---|
50 | // Update bounds from own attached objects
|
---|
51 | ObjectMap::iterator i;
|
---|
52 | for (i = mObjectsByName.begin(); i != mObjectsByName.end(); ++i)
|
---|
53 | {
|
---|
54 | // ignore objects with no actual geometry like frustums & lights
|
---|
55 | if (getExcludedMovables().find(i->second->getMovableType()) == getExcludedMovables().end())
|
---|
56 | {
|
---|
57 | //LogManager::getSingleton().getLog(BvHierarchy_LOGNAME)->logMessage("Adding movable type " + i->second->getMovableType() + " to BvHierarchy");
|
---|
58 | // Merge world bounds of each object
|
---|
59 | mWorldAABB.merge(i->second->getWorldBoundingBox(true));
|
---|
60 | }
|
---|
61 | }
|
---|
62 |
|
---|
63 | // create information for BvHierarchy/SAH
|
---|
64 | if (!mWorldAABB.isNull())
|
---|
65 | {
|
---|
66 | // merge aabb with global AABB
|
---|
67 | aabb.merge(mWorldAABB);
|
---|
68 |
|
---|
69 | // increase object count
|
---|
70 | nObjects++;
|
---|
71 |
|
---|
72 | // generate events
|
---|
73 | BvhPlaneEvent::Dimension axes[] =
|
---|
74 | {BvhPlaneEvent::PED_X, BvhPlaneEvent::PED_Y, BvhPlaneEvent::PED_Z};
|
---|
75 | Vector3 min = mWorldAABB.getMinimum();
|
---|
76 | Vector3 max = mWorldAABB.getMaximum();
|
---|
77 | for (int i = 0; i < 3; i++)
|
---|
78 | {
|
---|
79 | // 1-D and 2-D objects
|
---|
80 | if (min[i] == max[i])
|
---|
81 | {
|
---|
82 | //e = new BvhPlaneEvent(this, min, axes[i], BvhPlaneEvent::PET_ON);
|
---|
83 | //sceneinfo.events.push_back(*e);
|
---|
84 | events.push_back(BvhPlaneEvent(this, min, axes[i], BvhPlaneEvent::PET_ON));
|
---|
85 | }
|
---|
86 | else
|
---|
87 | {
|
---|
88 | //e = new BvhPlaneEvent(this, min, axes[i], BvhPlaneEvent::PET_START);
|
---|
89 | //sceneinfo.events.push_back(*e);
|
---|
90 | //e = new BvhPlaneEvent(this, max, axes[i], BvhPlaneEvent::PET_END);
|
---|
91 | //sceneinfo.events.push_back(*e);
|
---|
92 | events.push_back(BvhPlaneEvent(this, min, axes[i], BvhPlaneEvent::PET_START));
|
---|
93 | events.push_back(BvhPlaneEvent(this, max, axes[i], BvhPlaneEvent::PET_END));
|
---|
94 | }
|
---|
95 | }
|
---|
96 | }
|
---|
97 |
|
---|
98 | // Merge with children
|
---|
99 | if (includeChildren)
|
---|
100 | {
|
---|
101 | ChildNodeMap::iterator child;
|
---|
102 | for (child = mChildren.begin(); child != mChildren.end(); ++child)
|
---|
103 | {
|
---|
104 | BvHierarchySceneNode* sceneChild = static_cast<BvHierarchySceneNode*>(child->second);
|
---|
105 | sceneChild->computeScene(events, aabb, nObjects);
|
---|
106 | }
|
---|
107 | }
|
---|
108 | }
|
---|
109 |
|
---|
110 | //void BvHierarchySceneNode::_findVisibleObjects(Camera* cam, RenderQueue* queue,
|
---|
111 | // bool includeChildren, bool displayNodes, bool onlyShadowCasters)
|
---|
112 | void BvHierarchySceneNode::queueObjects(Camera* cam, RenderQueue* queue, bool onlyShadowCasters)
|
---|
113 | {
|
---|
114 | //SceneNode::_findVisibleObjects(cam, queue, includeChildren, displayNodes, onlyShadowCasters);
|
---|
115 |
|
---|
116 | // Add all entities
|
---|
117 | ObjectMap::iterator iobj;
|
---|
118 | ObjectMap::iterator iobjend = mObjectsByName.end();
|
---|
119 | for (iobj = mObjectsByName.begin(); iobj != iobjend; ++iobj)
|
---|
120 | {
|
---|
121 | // Tell attached objects about camera position (incase any extra processing they want to do)
|
---|
122 | iobj->second->_notifyCurrentCamera(cam);
|
---|
123 | if (iobj->second->isVisible() &&
|
---|
124 | (!onlyShadowCasters || iobj->second->getCastShadows()))
|
---|
125 | {
|
---|
126 | iobj->second->_updateRenderQueue(queue);
|
---|
127 | }
|
---|
128 | }
|
---|
129 |
|
---|
130 | // Check if the bounding box should be shown.
|
---|
131 | // See if our flag is set or if the scene manager flag is set.
|
---|
132 | if (mShowBoundingBox || (mCreator && mCreator->getShowBoundingBoxes()))
|
---|
133 | {
|
---|
134 | _addBoundingBoxToQueue(queue);
|
---|
135 | }
|
---|
136 | }
|
---|
137 |
|
---|
138 | void BvHierarchySceneNode::getGeometryList(GeometryVector *geometryList)
|
---|
139 | {
|
---|
140 | SceneNode::ObjectIterator objIt = getAttachedObjectIterator();
|
---|
141 |
|
---|
142 | while (objIt.hasMoreElements())
|
---|
143 | {
|
---|
144 | MovableObject *movable = objIt.getNext();
|
---|
145 |
|
---|
146 | // we are interested only in the entities, i.e., instances of geometry
|
---|
147 | if (movable->getMovableType() == "Entity")
|
---|
148 | {
|
---|
149 | Entity *ent = static_cast<Entity *>(movable);
|
---|
150 | geometryList->push_back(ent);
|
---|
151 | }
|
---|
152 | }
|
---|
153 | }
|
---|
154 |
|
---|
155 | // recalculate the world aabb
|
---|
156 | AxisAlignedBox BvHierarchySceneNode::getBoundingBox(void) const
|
---|
157 | {
|
---|
158 | return mWorldAABB;
|
---|
159 | }
|
---|
160 |
|
---|
161 | BvHierarchySceneNode::StringSet& BvHierarchySceneNode::getExcludedMovables(void)
|
---|
162 | {
|
---|
163 | static StringSet sExluded;
|
---|
164 |
|
---|
165 | // initialise once
|
---|
166 | if (sExluded.empty())
|
---|
167 | {
|
---|
168 | sExluded.insert("Camera");
|
---|
169 | sExluded.insert("Frustum");
|
---|
170 | sExluded.insert("Light");
|
---|
171 | }
|
---|
172 |
|
---|
173 | return sExluded;
|
---|
174 | }
|
---|
175 |
|
---|
176 | // DEBUG
|
---|
177 | String BvHierarchySceneNode::dumpToString(void)
|
---|
178 | {
|
---|
179 | String objects;
|
---|
180 | // Add all entities
|
---|
181 | ObjectMap::iterator iobj = mObjectsByName.begin();
|
---|
182 | ObjectMap::iterator iobjend = mObjectsByName.end();
|
---|
183 | while (iobj != iobjend)
|
---|
184 | {
|
---|
185 | objects += " " + iobj->second->getName();
|
---|
186 | iobj++;
|
---|
187 | }
|
---|
188 | objects += " Attached to " + StringConverter::toString(mLeaves.size()) + " KdLeaves.";
|
---|
189 | return objects;
|
---|
190 | }
|
---|
191 | } |
---|