source: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCBillboardKdTreeClusterData.cpp @ 699

Revision 699, 10.7 KB checked in by igarcia, 18 years ago (diff)
Line 
1
2#include "LBBCBillboardKdTreeClusterData.h"
3
4namespace LBBC {
5
6BillboardKdTreeClusterData::BillboardKdTreeClusterData() {
7}
8
9BillboardKdTreeClusterData::~BillboardKdTreeClusterData() {
10}
11
12void BillboardKdTreeClusterData::readBillboardClusterData(TiXmlNode *parentNode)
13{
14
15}
16
17void BillboardKdTreeClusterData::writeBillboardClusterData(TiXmlNode *parentNode)
18{
19        BBC::EntityCluster *entityCluster = getEntityCluster();
20        Ogre::Vector3 normal = getNormal();
21        normal.normalise();
22
23        float d = 0;
24        for (unsigned int iLeaf = 0; iLeaf < entityCluster->getNumEntitiesClusterData(); iLeaf++)
25        {
26                LeafKdTreeClusterData *leafKdTreeClusterData = (LeafKdTreeClusterData*)entityCluster->getEntityClusterData(iLeaf);
27                Leaf *leaf = (Leaf*)leafKdTreeClusterData->getEntity();
28                d = d + leaf->getPosition().dotProduct(normal);
29        }       
30        d = - d / entityCluster->getNumEntitiesClusterData();
31       
32        TiXmlNode *billboardNode;
33        TiXmlNode *coord4dNode;
34        TiXmlNode *quadTopRightCornerNode;
35        TiXmlNode *quadTopLeftCornerNode;
36        TiXmlNode *quadBottomRightCornerNode;
37        TiXmlNode *quadBottomLeftCornerNode;
38        TiXmlNode *axisXNode;
39        TiXmlNode *axisYNode;
40        TiXmlNode *axisZNode;
41        TiXmlNode *leavesNode;
42        TiXmlNode *leafNode;
43        billboardNode = parentNode->ToElement()->InsertEndChild(TiXmlElement("billboard"))->ToElement();
44
45        coord4dNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("coord4d"))->ToElement();
46        Ogre::String sNX = Ogre::StringConverter::toString(normal.x);
47        coord4dNode->ToElement()->SetAttribute("nx",sNX.c_str());
48        Ogre::String sNY = Ogre::StringConverter::toString(normal.y);
49        coord4dNode->ToElement()->SetAttribute("ny",sNY.c_str());
50        Ogre::String sNZ = Ogre::StringConverter::toString(normal.z);
51        coord4dNode->ToElement()->SetAttribute("nz",sNZ.c_str());
52        Ogre::String sD = Ogre::StringConverter::toString(d);
53        coord4dNode->ToElement()->SetAttribute("d",sD.c_str());
54       
55        quadTopLeftCornerNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("topLeft"))->ToElement();
56        Ogre::String sTLX = Ogre::StringConverter::toString(getQuadTopLeftCorner().x);
57        quadTopLeftCornerNode->ToElement()->SetAttribute("x",sTLX.c_str());
58        Ogre::String sTLY = Ogre::StringConverter::toString(getQuadTopLeftCorner().y);
59        quadTopLeftCornerNode->ToElement()->SetAttribute("y",sTLY.c_str());
60        Ogre::String sTLZ = Ogre::StringConverter::toString(getQuadTopLeftCorner().z);
61        quadTopLeftCornerNode->ToElement()->SetAttribute("z",sTLZ.c_str());     
62
63        quadTopRightCornerNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("topRight"))->ToElement();
64        Ogre::String sTRX = Ogre::StringConverter::toString(getQuadTopRightCorner().x);
65        quadTopRightCornerNode->ToElement()->SetAttribute("x",sTRX.c_str());
66        Ogre::String sTRY = Ogre::StringConverter::toString(getQuadTopRightCorner().y);
67        quadTopRightCornerNode->ToElement()->SetAttribute("y",sTRY.c_str());
68        Ogre::String sTRZ = Ogre::StringConverter::toString(getQuadTopRightCorner().z);
69        quadTopRightCornerNode->ToElement()->SetAttribute("z",sTRZ.c_str());   
70
71        quadBottomRightCornerNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("bottomRight"))->ToElement();
72        Ogre::String sBRX = Ogre::StringConverter::toString(getQuadBottomRightCorner().x);
73        quadBottomRightCornerNode->ToElement()->SetAttribute("x",sBRX.c_str());
74        Ogre::String sBRY = Ogre::StringConverter::toString(getQuadBottomRightCorner().y);
75        quadBottomRightCornerNode->ToElement()->SetAttribute("y",sBRY.c_str());
76        Ogre::String sBRZ = Ogre::StringConverter::toString(getQuadBottomRightCorner().z);
77        quadBottomRightCornerNode->ToElement()->SetAttribute("z",sBRZ.c_str());
78
79        quadBottomLeftCornerNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("bottomLeft"))->ToElement();
80        Ogre::String sBLX = Ogre::StringConverter::toString(getQuadBottomLeftCorner().x);
81        quadBottomLeftCornerNode->ToElement()->SetAttribute("x",sBLX.c_str());
82        Ogre::String sBLY = Ogre::StringConverter::toString(getQuadBottomLeftCorner().y);
83        quadBottomLeftCornerNode->ToElement()->SetAttribute("y",sBLY.c_str());
84        Ogre::String sBLZ = Ogre::StringConverter::toString(getQuadBottomLeftCorner().z);
85        quadBottomLeftCornerNode->ToElement()->SetAttribute("z",sBLZ.c_str()); 
86
87        axisYNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("axisX"))->ToElement();
88        Ogre::String sAXX = Ogre::StringConverter::toString(getAxisX().x);
89        axisYNode->ToElement()->SetAttribute("x",sAXX.c_str());
90        Ogre::String sAXY = Ogre::StringConverter::toString(getAxisX().y);
91        axisYNode->ToElement()->SetAttribute("y",sAXY.c_str());
92        Ogre::String sAXZ = Ogre::StringConverter::toString(getAxisX().z);
93        axisYNode->ToElement()->SetAttribute("z",sAXZ.c_str());
94
95        axisYNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("axisY"))->ToElement();
96        Ogre::String sAYX = Ogre::StringConverter::toString(getAxisY().x);
97        axisYNode->ToElement()->SetAttribute("x",sAYX.c_str());
98        Ogre::String sAYY = Ogre::StringConverter::toString(getAxisY().y);
99        axisYNode->ToElement()->SetAttribute("y",sAYY.c_str());
100        Ogre::String sAYZ = Ogre::StringConverter::toString(getAxisY().z);
101        axisYNode->ToElement()->SetAttribute("z",sAYZ.c_str());
102
103        axisZNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("axisZ"))->ToElement();
104        Ogre::String sAZX = Ogre::StringConverter::toString(getAxisZ().x);
105        axisZNode->ToElement()->SetAttribute("x",sAZX.c_str());
106        Ogre::String sAZY = Ogre::StringConverter::toString(getAxisZ().y);
107        axisZNode->ToElement()->SetAttribute("y",sAZY.c_str());
108        Ogre::String sAZZ = Ogre::StringConverter::toString(getAxisZ().z);
109        axisZNode->ToElement()->SetAttribute("z",sAZZ.c_str());
110
111        leavesNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("leaves"))->ToElement();
112        Ogre::String sLeaves = Ogre::StringConverter::toString(entityCluster->getNumEntitiesClusterData());
113        leavesNode->ToElement()->SetAttribute("count",sLeaves.c_str());
114       
115        for (unsigned int iLeaf = 0; iLeaf < entityCluster->getNumEntitiesClusterData(); iLeaf++)
116        {
117                LeafKdTreeClusterData *leafKdTreeClusterData = (LeafKdTreeClusterData*)entityCluster->getEntityClusterData(iLeaf);
118                Leaf *leaf = (Leaf*)leafKdTreeClusterData->getEntity();
119                leafNode = leavesNode->ToElement()->InsertEndChild(TiXmlElement("leaf"))->ToElement();
120                Ogre::String sLeaf = Ogre::StringConverter::toString(leaf->getEntityHandle());
121                leafNode->ToElement()->SetAttribute("id",sLeaf.c_str());
122        }
123}
124
125void BillboardKdTreeClusterData::generateBillboardBoundingQuad()
126{
127       
128        Ogre::Vector3 normal = getNormal();
129        Ogre::Vector3 planePosition;
130        float d = getD();
131
132        normal.normalise();
133
134        if ((abs(normal[0] > abs(normal[1])) && (abs(normal[0] > abs(normal[2])))))
135        {
136                planePosition[0] = -d / normal[0];
137                planePosition[1] = 0;
138                planePosition[2] = 0;
139        }
140        else if ((abs(normal[1] > abs(normal[0])) && (abs(normal[1] > abs(normal[2])))))
141        {
142                planePosition[0] = 0;
143                planePosition[1] = -d / normal[1];
144                planePosition[2] = 0;
145        }
146        else
147        {
148                planePosition[0] = 0;
149                planePosition[1] = 0;
150                planePosition[2] = -d / normal[2];
151        }
152       
153        mAxisX = normal.perpendicular();
154        mAxisX.normalise();
155        mAxisY = normal.crossProduct(mAxisX);   
156        mAxisY.normalise();
157        mAxisZ = normal;
158
159        Ogre::Matrix4 coordPlane;
160        Ogre::Matrix4 constCoord;
161        Ogre::Matrix4 invMCoordPlane;
162
163        coordPlane[0][0] = mAxisX.x;
164        coordPlane[0][1] = mAxisX.y;
165        coordPlane[0][2] = mAxisX.z;
166        coordPlane[0][3] = 0.0f;
167        coordPlane[1][0] = mAxisY.x;
168        coordPlane[1][1] = mAxisY.y;
169        coordPlane[1][2] = mAxisY.z;
170        coordPlane[1][3] = 0.0f;
171        coordPlane[2][0] = mAxisZ.x;
172        coordPlane[2][1] = mAxisZ.y;
173        coordPlane[2][2] = mAxisZ.z;
174        coordPlane[2][3] = 0.0f;
175        coordPlane[3][0] = planePosition.x;
176        coordPlane[3][1] = planePosition.y;
177        coordPlane[3][2] = planePosition.z;
178        coordPlane[3][3] = 1.0f;
179
180        invMCoordPlane = coordPlane.inverse();
181
182        constCoord[0][0] = 1.0f;
183        constCoord[0][1] = 0.0f;
184        constCoord[0][2] = 0.0f;
185        constCoord[0][3] = 0.0f;
186        constCoord[1][0] = 0.0f;
187        constCoord[1][1] = 1.0f;
188        constCoord[1][2] = 0.0f;
189        constCoord[1][3] = 0.0f;
190        constCoord[2][0] = 0.0f;
191        constCoord[2][1] = 0.0f;
192        constCoord[2][2] = 0.0f;
193        constCoord[2][3] = 0.0f;
194        constCoord[3][0] = 0.0f;
195        constCoord[3][1] = 0.0f;
196        constCoord[3][2] = 0.0f;
197        constCoord[3][3] = 1.0f;
198
199        float xMax = -FLT_MAX;
200        float xMin = FLT_MAX;
201        float yMax = -FLT_MAX;
202        float yMin = FLT_MAX;
203
204        Ogre::Vector3 vXmax;
205        Ogre::Vector3 vXmin;
206        Ogre::Vector3 vYmax;
207        Ogre::Vector3 vYmin;
208
209        BBC::EntityCluster *entityCluster = getEntityCluster();
210        BBC::Entity *entity = entityCluster->getEntity();
211
212        for (unsigned int iVertex = 0; iVertex < entity->getSubEntity(0)->getNumVertices(); iVertex++)
213        {                               
214                Ogre::Vector3 position = entity->getSubEntity(0)->getPosition(iVertex);
215                Ogre::Vector4 projPointP1d4 =  Ogre::Vector4(position.x,position.y,position.z,1.0f) * invMCoordPlane * constCoord * coordPlane;
216       
217                // The point projected in the plane
218                Ogre::Vector3 projPointP1(projPointP1d4.x,projPointP1d4.y,projPointP1d4.z);
219
220                float v1 = normal.dotProduct(planePosition);
221                float v2 = normal.dotProduct(position);
222                float t = v1 - v2;
223                projPointP1 = position + (normal * t);
224
225                float x1 = mAxisX.dotProduct(projPointP1 - planePosition);
226                float y1 = mAxisY.dotProduct(projPointP1 - planePosition);
227                float z1 = mAxisZ.dotProduct(projPointP1 - planePosition);             
228               
229                if (x1 > xMax)
230                {
231                        xMax = x1;
232                        vXmax = projPointP1;
233                }
234                if (x1 < xMin)
235                {
236                        xMin = x1;
237                        vXmin = projPointP1;
238                }
239                if (y1 > yMax)
240                {
241                        yMax = y1;
242                        vYmax = projPointP1;
243                }
244                if (y1 < yMin)
245                {
246                        yMin = y1;
247                        vYmin = projPointP1;
248                }               
249        }
250
251        Ogre::Vector3 aP;
252        Ogre::Vector3 bP;
253        Ogre::Vector3 pP;
254        Ogre::Vector3 abV;
255        Ogre::Vector3 apV;
256        Ogre::Vector3 dProdV;
257        float aLength;
258        float abLength;
259        float dist;
260        Ogre::Vector3 intersectP;
261
262        aP = vYmin;
263        bP = vYmin + mAxisX;
264        pP = vXmin;
265        abV = bP - aP;
266        apV = pP - aP;
267        dProdV = abV.crossProduct(apV);
268        aLength = dProdV.length();
269        abLength = abV.length();
270        dist = aLength / abLength;
271        mBillboardCorners[QUAD_TOP_LEFT] = pP + (mAxisY * (-dist));
272
273        aP = vYmax;
274        bP = vYmax + mAxisX;
275        pP = vXmax;
276        abV = bP - aP;
277        apV = pP - aP;
278        dProdV = abV.crossProduct(apV);
279        aLength = dProdV.length();
280        abLength = abV.length();
281        dist = aLength / abLength;
282        mBillboardCorners[QUAD_BOTTOM_RIGHT] = pP + (mAxisY * dist);
283
284        aP = vXmax;
285        bP = vXmax + mAxisY;
286        pP = vYmin;
287        abV = bP - aP;
288        apV = pP - aP;
289        dProdV = abV.crossProduct(apV);
290        aLength = dProdV.length();
291        abLength = abV.length();
292        dist = aLength / abLength;
293        mBillboardCorners[QUAD_BOTTOM_LEFT] = pP + (mAxisX * dist);
294
295        Ogre::Vector3 vDirWidth = mBillboardCorners[QUAD_BOTTOM_LEFT] - mBillboardCorners[QUAD_BOTTOM_RIGHT];
296        float distWidth = vDirWidth.length();
297        mBillboardCorners[QUAD_TOP_RIGHT] = mBillboardCorners[QUAD_TOP_LEFT] + (mAxisY * distWidth);
298}
299
300}
Note: See TracBrowser for help on using the repository browser.