source: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCBillboardKMeansClusterData.cpp @ 786

Revision 786, 16.0 KB checked in by igarcia, 18 years ago (diff)
Line 
1
2#include "LBBCBillboardKMeansClusterData.h"
3
4namespace LBBC {
5
6BillboardKMeansClusterData::BillboardKMeansClusterData() {
7}
8
9BillboardKMeansClusterData::~BillboardKMeansClusterData() {
10}
11
12void BillboardKMeansClusterData::readBillboardClusterData(TiXmlNode *billboardNode, int iBillboardGroup)
13{
14        TiXmlNode *coord4dNode = billboardNode->FirstChild("coord4d");
15        Ogre::Vector3 normal;
16        normal[0] = Ogre::StringConverter::parseReal(coord4dNode->ToElement()->Attribute("nx"));
17        normal[1] = Ogre::StringConverter::parseReal(coord4dNode->ToElement()->Attribute("ny"));
18        normal[2] = Ogre::StringConverter::parseReal(coord4dNode->ToElement()->Attribute("nz"));
19        this->setNormal(normal);
20
21        TiXmlNode *topLeftNode = billboardNode->FirstChild("topLeft"); 
22        Ogre::Vector3 topLeft;
23        topLeft[0] = Ogre::StringConverter::parseReal(topLeftNode->ToElement()->Attribute("x"));
24        topLeft[1] = Ogre::StringConverter::parseReal(topLeftNode->ToElement()->Attribute("y"));
25        topLeft[2] = Ogre::StringConverter::parseReal(topLeftNode->ToElement()->Attribute("z"));
26        this->setQuadTopLeftCorner(topLeft);
27
28        TiXmlNode *topRightNode = billboardNode->FirstChild("topRight");       
29        Ogre::Vector3 topRight;
30        topRight[0] = Ogre::StringConverter::parseReal(topRightNode->ToElement()->Attribute("x"));
31        topRight[1] = Ogre::StringConverter::parseReal(topRightNode->ToElement()->Attribute("y"));
32        topRight[2] = Ogre::StringConverter::parseReal(topRightNode->ToElement()->Attribute("z"));
33        this->setQuadTopRightCorner(topRight);
34
35        TiXmlNode *bottomRightNode = billboardNode->FirstChild("bottomRight"); 
36        Ogre::Vector3 bottomRight;
37        bottomRight[0] = Ogre::StringConverter::parseReal(bottomRightNode->ToElement()->Attribute("x"));
38        bottomRight[1] = Ogre::StringConverter::parseReal(bottomRightNode->ToElement()->Attribute("y"));
39        bottomRight[2] = Ogre::StringConverter::parseReal(bottomRightNode->ToElement()->Attribute("z"));
40        this->setQuadBottomRightCorner(bottomRight);
41
42        TiXmlNode *bottomLeftNode = billboardNode->FirstChild("bottomLeft");   
43        Ogre::Vector3 bottomLeft;
44        bottomLeft[0] = Ogre::StringConverter::parseReal(bottomLeftNode->ToElement()->Attribute("x"));
45        bottomLeft[1] = Ogre::StringConverter::parseReal(bottomLeftNode->ToElement()->Attribute("y"));
46        bottomLeft[2] = Ogre::StringConverter::parseReal(bottomLeftNode->ToElement()->Attribute("z"));
47        this->setQuadBottomLeftCorner(bottomLeft);
48
49        TiXmlNode *axisXNode = billboardNode->FirstChild("axisX");     
50        Ogre::Vector3 axisX;
51        axisX[0] = Ogre::StringConverter::parseReal(axisXNode->ToElement()->Attribute("x"));
52        axisX[1] = Ogre::StringConverter::parseReal(axisXNode->ToElement()->Attribute("y"));
53        axisX[2] = Ogre::StringConverter::parseReal(axisXNode->ToElement()->Attribute("z"));
54        this->setAxisX(axisX);
55
56        TiXmlNode *axisYNode = billboardNode->FirstChild("axisY");     
57        Ogre::Vector3 axisY;
58        axisY[0] = Ogre::StringConverter::parseReal(axisYNode->ToElement()->Attribute("x"));
59        axisY[1] = Ogre::StringConverter::parseReal(axisYNode->ToElement()->Attribute("y"));
60        axisY[2] = Ogre::StringConverter::parseReal(axisYNode->ToElement()->Attribute("z"));
61        this->setAxisY(axisY);
62
63        TiXmlNode *axisZNode = billboardNode->FirstChild("axisZ");     
64        Ogre::Vector3 axisZ;
65        axisZ[0] = Ogre::StringConverter::parseReal(axisZNode->ToElement()->Attribute("x"));
66        axisZ[1] = Ogre::StringConverter::parseReal(axisZNode->ToElement()->Attribute("y"));
67        axisZ[2] = Ogre::StringConverter::parseReal(axisZNode->ToElement()->Attribute("z"));
68        this->setAxisZ(axisZ);
69
70        if (iBillboardGroup >= 0)
71        {
72                TiXmlNode *uvMapMinNode = billboardNode->FirstChild("uvMapMin");       
73                Ogre::Vector2 uvMapMin;
74                uvMapMin[0] = Ogre::StringConverter::parseReal(uvMapMinNode->ToElement()->Attribute("x"));
75                uvMapMin[1] = Ogre::StringConverter::parseReal(uvMapMinNode->ToElement()->Attribute("y"));
76                this->addBillboardUVMapMin(uvMapMin);
77
78                TiXmlNode *uvMapMaxNode = billboardNode->FirstChild("uvMapMax");       
79                Ogre::Vector2 uvMapMax;
80                uvMapMax[0] = Ogre::StringConverter::parseReal(uvMapMaxNode->ToElement()->Attribute("x"));
81                uvMapMax[1] = Ogre::StringConverter::parseReal(uvMapMaxNode->ToElement()->Attribute("y"));
82                this->addBillboardUVMapMax(uvMapMax);
83        }
84}
85
86void BillboardKMeansClusterData::writeBillboardClusterData(TiXmlNode *parentNode, int iBillboardGroup)
87{
88        BBC::EntityClusterPtr entityCluster = getEntityCluster();
89        Ogre::Vector3 normal = getNormal();
90        normal.normalise();
91
92        float d = 0;
93        for (unsigned int iLeaf = 0; iLeaf < entityCluster->getNumEntitiesClusterData(); iLeaf++)
94        {
95                LeafKMeansClusterData *leafKMeansClusterData = (LeafKMeansClusterData*)entityCluster->getEntityClusterData(iLeaf).get();
96                Leaf *leaf = (Leaf*)leafKMeansClusterData->getEntity().get();
97                d = d + leaf->getPosition().dotProduct(normal);
98        }       
99        d = - d / entityCluster->getNumEntitiesClusterData();
100       
101        TiXmlNode *billboardNode;
102        TiXmlNode *coord4dNode;
103        TiXmlNode *uvMapMin;
104        TiXmlNode *uvMapMax;
105        TiXmlNode *quadTopRightCornerNode;
106        TiXmlNode *quadTopLeftCornerNode;
107        TiXmlNode *quadBottomRightCornerNode;
108        TiXmlNode *quadBottomLeftCornerNode;
109        TiXmlNode *axisYNode;
110        TiXmlNode *axisZNode;
111        TiXmlNode *leavesNode;
112        TiXmlNode *leafNode;
113        billboardNode = parentNode->ToElement()->InsertEndChild(TiXmlElement("billboard"))->ToElement();
114
115        coord4dNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("coord4d"))->ToElement();
116        Ogre::String sNX = Ogre::StringConverter::toString(normal.x);
117        coord4dNode->ToElement()->SetAttribute("nx",sNX.c_str());
118        Ogre::String sNY = Ogre::StringConverter::toString(normal.y);
119        coord4dNode->ToElement()->SetAttribute("ny",sNY.c_str());
120        Ogre::String sNZ = Ogre::StringConverter::toString(normal.z);
121        coord4dNode->ToElement()->SetAttribute("nz",sNZ.c_str());
122        Ogre::String sD = Ogre::StringConverter::toString(d);
123        coord4dNode->ToElement()->SetAttribute("d",sD.c_str());
124       
125        quadTopLeftCornerNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("topLeft"))->ToElement();
126        Ogre::String sTLX = Ogre::StringConverter::toString(getQuadTopLeftCorner().x);
127        quadTopLeftCornerNode->ToElement()->SetAttribute("x",sTLX.c_str());
128        Ogre::String sTLY = Ogre::StringConverter::toString(getQuadTopLeftCorner().y);
129        quadTopLeftCornerNode->ToElement()->SetAttribute("y",sTLY.c_str());
130        Ogre::String sTLZ = Ogre::StringConverter::toString(getQuadTopLeftCorner().z);
131        quadTopLeftCornerNode->ToElement()->SetAttribute("z",sTLZ.c_str());     
132
133        quadTopRightCornerNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("topRight"))->ToElement();
134        Ogre::String sTRX = Ogre::StringConverter::toString(getQuadTopRightCorner().x);
135        quadTopRightCornerNode->ToElement()->SetAttribute("x",sTRX.c_str());
136        Ogre::String sTRY = Ogre::StringConverter::toString(getQuadTopRightCorner().y);
137        quadTopRightCornerNode->ToElement()->SetAttribute("y",sTRY.c_str());
138        Ogre::String sTRZ = Ogre::StringConverter::toString(getQuadTopRightCorner().z);
139        quadTopRightCornerNode->ToElement()->SetAttribute("z",sTRZ.c_str());   
140
141        quadBottomRightCornerNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("bottomRight"))->ToElement();
142        Ogre::String sBRX = Ogre::StringConverter::toString(getQuadBottomRightCorner().x);
143        quadBottomRightCornerNode->ToElement()->SetAttribute("x",sBRX.c_str());
144        Ogre::String sBRY = Ogre::StringConverter::toString(getQuadBottomRightCorner().y);
145        quadBottomRightCornerNode->ToElement()->SetAttribute("y",sBRY.c_str());
146        Ogre::String sBRZ = Ogre::StringConverter::toString(getQuadBottomRightCorner().z);
147        quadBottomRightCornerNode->ToElement()->SetAttribute("z",sBRZ.c_str());
148
149        quadBottomLeftCornerNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("bottomLeft"))->ToElement();
150        Ogre::String sBLX = Ogre::StringConverter::toString(getQuadBottomLeftCorner().x);
151        quadBottomLeftCornerNode->ToElement()->SetAttribute("x",sBLX.c_str());
152        Ogre::String sBLY = Ogre::StringConverter::toString(getQuadBottomLeftCorner().y);
153        quadBottomLeftCornerNode->ToElement()->SetAttribute("y",sBLY.c_str());
154        Ogre::String sBLZ = Ogre::StringConverter::toString(getQuadBottomLeftCorner().z);
155        quadBottomLeftCornerNode->ToElement()->SetAttribute("z",sBLZ.c_str()); 
156
157        axisYNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("axisX"))->ToElement();
158        Ogre::String sAXX = Ogre::StringConverter::toString(getAxisX().x);
159        axisYNode->ToElement()->SetAttribute("x",sAXX.c_str());
160        Ogre::String sAXY = Ogre::StringConverter::toString(getAxisX().y);
161        axisYNode->ToElement()->SetAttribute("y",sAXY.c_str());
162        Ogre::String sAXZ = Ogre::StringConverter::toString(getAxisX().z);
163        axisYNode->ToElement()->SetAttribute("z",sAXZ.c_str());
164
165        axisYNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("axisY"))->ToElement();
166        Ogre::String sAYX = Ogre::StringConverter::toString(getAxisY().x);
167        axisYNode->ToElement()->SetAttribute("x",sAYX.c_str());
168        Ogre::String sAYY = Ogre::StringConverter::toString(getAxisY().y);
169        axisYNode->ToElement()->SetAttribute("y",sAYY.c_str());
170        Ogre::String sAYZ = Ogre::StringConverter::toString(getAxisY().z);
171        axisYNode->ToElement()->SetAttribute("z",sAYZ.c_str());
172
173        axisZNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("axisZ"))->ToElement();
174        Ogre::String sAZX = Ogre::StringConverter::toString(getAxisZ().x);
175        axisZNode->ToElement()->SetAttribute("x",sAZX.c_str());
176        Ogre::String sAZY = Ogre::StringConverter::toString(getAxisZ().y);
177        axisZNode->ToElement()->SetAttribute("y",sAZY.c_str());
178        Ogre::String sAZZ = Ogre::StringConverter::toString(getAxisZ().z);
179        axisZNode->ToElement()->SetAttribute("z",sAZZ.c_str());
180
181        if (iBillboardGroup >= 0)
182        {               
183                uvMapMin = billboardNode->ToElement()->InsertEndChild(TiXmlElement("uvMapMin"))->ToElement();
184                Ogre::String sUvMapMinX = Ogre::StringConverter::toString(this->getBillboardUVMapMin(0).x);
185                uvMapMin->ToElement()->SetAttribute("x",sUvMapMinX.c_str());
186                Ogre::String sUvMapMinY = Ogre::StringConverter::toString(this->getBillboardUVMapMin(0).y);
187                uvMapMin->ToElement()->SetAttribute("y",sUvMapMinY.c_str());
188
189                uvMapMax = billboardNode->ToElement()->InsertEndChild(TiXmlElement("uvMapMax"))->ToElement();
190                Ogre::String suvMapMaxX = Ogre::StringConverter::toString(this->getBillboardUVMapMax(0).x);
191                uvMapMax->ToElement()->SetAttribute("x",suvMapMaxX.c_str());
192                Ogre::String suvMapMaxY = Ogre::StringConverter::toString(this->getBillboardUVMapMax(0).y);
193                uvMapMax->ToElement()->SetAttribute("y",suvMapMaxY.c_str());
194        }
195
196        leavesNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("leaves"))->ToElement();
197        Ogre::String sLeaves = Ogre::StringConverter::toString(entityCluster->getNumEntitiesClusterData());
198        leavesNode->ToElement()->SetAttribute("count",sLeaves.c_str());
199       
200        for (unsigned int iLeaf = 0; iLeaf < entityCluster->getNumEntitiesClusterData(); iLeaf++)
201        {
202                LeafKMeansClusterData *leafKMeansClusterData = (LeafKMeansClusterData*)entityCluster->getEntityClusterData(iLeaf).get();
203                Leaf *leaf = (Leaf*)leafKMeansClusterData->getEntity().get();
204                leafNode = leavesNode->ToElement()->InsertEndChild(TiXmlElement("leaf"))->ToElement();
205                Ogre::String sLeaf = Ogre::StringConverter::toString(leaf->getEntityHandle());
206                leafNode->ToElement()->SetAttribute("id",sLeaf.c_str());
207        }
208}
209
210void BillboardKMeansClusterData::generateBillboardBoundingQuad()
211{       
212        Ogre::Vector3 normal = getNormal();
213        Ogre::Vector3 planePosition;
214        float d = getD();
215
216        normal.normalise();
217
218        if ((abs(normal[0] > abs(normal[1])) && (abs(normal[0] > abs(normal[2])))))
219        {
220                planePosition[0] = -d / normal[0];
221                planePosition[1] = 0;
222                planePosition[2] = 0;
223        }
224        else if ((abs(normal[1] > abs(normal[0])) && (abs(normal[1] > abs(normal[2])))))
225        {
226                planePosition[0] = 0;
227                planePosition[1] = -d / normal[1];
228                planePosition[2] = 0;
229        }
230        else
231        {
232                planePosition[0] = 0;
233                planePosition[1] = 0;
234                planePosition[2] = -d / normal[2];
235        }
236       
237        mAxisX = normal.perpendicular();
238        mAxisX.normalise();
239        mAxisY = normal.crossProduct(mAxisX);   
240        mAxisY.normalise();
241        mAxisZ = normal;
242
243        Ogre::Matrix4 coordPlane;
244        Ogre::Matrix4 constCoord;
245        Ogre::Matrix4 invMCoordPlane;
246
247        coordPlane[0][0] = mAxisX.x;
248        coordPlane[0][1] = mAxisX.y;
249        coordPlane[0][2] = mAxisX.z;
250        coordPlane[0][3] = 0.0f;
251        coordPlane[1][0] = mAxisY.x;
252        coordPlane[1][1] = mAxisY.y;
253        coordPlane[1][2] = mAxisY.z;
254        coordPlane[1][3] = 0.0f;
255        coordPlane[2][0] = mAxisZ.x;
256        coordPlane[2][1] = mAxisZ.y;
257        coordPlane[2][2] = mAxisZ.z;
258        coordPlane[2][3] = 0.0f;
259        coordPlane[3][0] = planePosition.x;
260        coordPlane[3][1] = planePosition.y;
261        coordPlane[3][2] = planePosition.z;
262        coordPlane[3][3] = 1.0f;
263
264        invMCoordPlane = coordPlane.inverse();
265
266        constCoord[0][0] = 1.0f;
267        constCoord[0][1] = 0.0f;
268        constCoord[0][2] = 0.0f;
269        constCoord[0][3] = 0.0f;
270        constCoord[1][0] = 0.0f;
271        constCoord[1][1] = 1.0f;
272        constCoord[1][2] = 0.0f;
273        constCoord[1][3] = 0.0f;
274        constCoord[2][0] = 0.0f;
275        constCoord[2][1] = 0.0f;
276        constCoord[2][2] = 0.0f;
277        constCoord[2][3] = 0.0f;
278        constCoord[3][0] = 0.0f;
279        constCoord[3][1] = 0.0f;
280        constCoord[3][2] = 0.0f;
281        constCoord[3][3] = 1.0f;
282
283        float xMax = -FLT_MAX;
284        float xMin = FLT_MAX;
285        float yMax = -FLT_MAX;
286        float yMin = FLT_MAX;
287
288        Ogre::Vector3 vXmax;
289        Ogre::Vector3 vXmin;
290        Ogre::Vector3 vYmax;
291        Ogre::Vector3 vYmin;
292
293        BBC::EntityClusterPtr entityCluster = getEntityCluster();
294        BBC::EntityPtr entity = entityCluster->getEntity();
295
296        for (unsigned int iVertex = 0; iVertex < entity->getSubEntity(0)->getNumVertices(); iVertex++)
297        {                               
298                Ogre::Vector3 position = entity->getSubEntity(0)->getPosition(iVertex);
299                Ogre::Vector4 projPointP1d4 =  Ogre::Vector4(position.x,position.y,position.z,1.0f) * invMCoordPlane * constCoord * coordPlane;
300       
301                // The point projected in the plane
302                Ogre::Vector3 projPointP1(projPointP1d4.x,projPointP1d4.y,projPointP1d4.z);
303
304                float v1 = normal.dotProduct(planePosition);
305                float v2 = normal.dotProduct(position);
306                float t = v1 - v2;
307                projPointP1 = position + (normal * t);
308
309                float x1 = mAxisX.dotProduct(projPointP1 - planePosition);
310                float y1 = mAxisY.dotProduct(projPointP1 - planePosition);
311                float z1 = mAxisZ.dotProduct(projPointP1 - planePosition);             
312               
313                if (x1 > xMax)
314                {
315                        xMax = x1;
316                        vXmax = projPointP1;
317                }
318                if (x1 < xMin)
319                {
320                        xMin = x1;
321                        vXmin = projPointP1;
322                }
323                if (y1 > yMax)
324                {
325                        yMax = y1;
326                        vYmax = projPointP1;
327                }
328                if (y1 < yMin)
329                {
330                        yMin = y1;
331                        vYmin = projPointP1;
332                }               
333        }
334       
335        for (unsigned int iLeaf = 0; iLeaf < entityCluster->getNumEntitiesClusterData(); iLeaf++)
336        {
337                LeafKMeansClusterData *leafKMeansClusterData = (LeafKMeansClusterData*)entityCluster->getEntityClusterData(iLeaf).get();
338                Leaf *leaf = (Leaf*)leafKMeansClusterData->getEntity().get();           
339
340                Ogre::Vector3 position = leaf->getPosition();
341                Ogre::Vector4 projPointP1d4 =  Ogre::Vector4(position.x,position.y,position.z,1.0f) * invMCoordPlane * constCoord * coordPlane;
342               
343                // The point projected in the plane
344                Ogre::Vector3 projPointP1(projPointP1d4.x,projPointP1d4.y,projPointP1d4.z);
345
346                leaf->setPosition(projPointP1);
347        }
348
349        Ogre::Vector3 aP;
350        Ogre::Vector3 bP;
351        Ogre::Vector3 pP;
352        Ogre::Vector3 abV;
353        Ogre::Vector3 apV;
354        Ogre::Vector3 dProdV;
355        float aLength;
356        float abLength;
357        float dist;
358        Ogre::Vector3 intersectP;
359
360        aP = vYmin;
361        bP = vYmin + mAxisX;
362        pP = vXmin;
363        abV = bP - aP;
364        apV = pP - aP;
365        dProdV = abV.crossProduct(apV);
366        aLength = dProdV.length();
367        abLength = abV.length();
368        dist = aLength / abLength;
369        mBillboardCorners[QUAD_TOP_LEFT] = pP + (mAxisY * (-dist));
370
371        aP = vYmax;
372        bP = vYmax + mAxisX;
373        pP = vXmax;
374        abV = bP - aP;
375        apV = pP - aP;
376        dProdV = abV.crossProduct(apV);
377        aLength = dProdV.length();
378        abLength = abV.length();
379        dist = aLength / abLength;
380        mBillboardCorners[QUAD_BOTTOM_RIGHT] = pP + (mAxisY * dist);
381
382        aP = vXmax;
383        bP = vXmax + mAxisY;
384        pP = vYmin;
385        abV = bP - aP;
386        apV = pP - aP;
387        dProdV = abV.crossProduct(apV);
388        aLength = dProdV.length();
389        abLength = abV.length();
390        dist = aLength / abLength;
391        mBillboardCorners[QUAD_BOTTOM_LEFT] = pP + (mAxisX * dist);
392
393        Ogre::Vector3 vDirWidth = mBillboardCorners[QUAD_BOTTOM_LEFT] - mBillboardCorners[QUAD_BOTTOM_RIGHT];
394        float distWidth = vDirWidth.length();
395        mBillboardCorners[QUAD_TOP_RIGHT] = mBillboardCorners[QUAD_TOP_LEFT] + (mAxisY * distWidth);
396}
397
398}
Note: See TracBrowser for help on using the repository browser.