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

Revision 751, 16.9 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(iBillboardGroup).x);
185                //uvMapMin->ToElement()->SetAttribute("x",sUvMapMinX.c_str());
186                //Ogre::String sUvMapMinY = Ogre::StringConverter::toString(this->getBillboardUVMapMin(iBillboardGroup).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(iBillboardGroup).x);
191                //uvMapMax->ToElement()->SetAttribute("x",suvMapMaxX.c_str());
192                //Ogre::String suvMapMaxY = Ogre::StringConverter::toString(this->getBillboardUVMapMax(iBillboardGroup).y);
193                //uvMapMax->ToElement()->SetAttribute("y",suvMapMaxY.c_str());
194
195                uvMapMin = billboardNode->ToElement()->InsertEndChild(TiXmlElement("uvMapMin"))->ToElement();
196                Ogre::String sUvMapMinX = Ogre::StringConverter::toString(this->getBillboardUVMapMin(0).x);
197                uvMapMin->ToElement()->SetAttribute("x",sUvMapMinX.c_str());
198                Ogre::String sUvMapMinY = Ogre::StringConverter::toString(this->getBillboardUVMapMin(0).y);
199                uvMapMin->ToElement()->SetAttribute("y",sUvMapMinY.c_str());
200
201                uvMapMax = billboardNode->ToElement()->InsertEndChild(TiXmlElement("uvMapMax"))->ToElement();
202                Ogre::String suvMapMaxX = Ogre::StringConverter::toString(this->getBillboardUVMapMax(0).x);
203                uvMapMax->ToElement()->SetAttribute("x",suvMapMaxX.c_str());
204                Ogre::String suvMapMaxY = Ogre::StringConverter::toString(this->getBillboardUVMapMax(0).y);
205                uvMapMax->ToElement()->SetAttribute("y",suvMapMaxY.c_str());
206        }
207
208        leavesNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("leaves"))->ToElement();
209        Ogre::String sLeaves = Ogre::StringConverter::toString(entityCluster->getNumEntitiesClusterData());
210        leavesNode->ToElement()->SetAttribute("count",sLeaves.c_str());
211       
212        for (unsigned int iLeaf = 0; iLeaf < entityCluster->getNumEntitiesClusterData(); iLeaf++)
213        {
214                LeafKMeansClusterData *leafKMeansClusterData = (LeafKMeansClusterData*)entityCluster->getEntityClusterData(iLeaf).get();
215                Leaf *leaf = (Leaf*)leafKMeansClusterData->getEntity().get();
216                leafNode = leavesNode->ToElement()->InsertEndChild(TiXmlElement("leaf"))->ToElement();
217                Ogre::String sLeaf = Ogre::StringConverter::toString(leaf->getEntityHandle());
218                leafNode->ToElement()->SetAttribute("id",sLeaf.c_str());
219        }
220}
221
222void BillboardKMeansClusterData::generateBillboardBoundingQuad()
223{       
224        Ogre::Vector3 normal = getNormal();
225        Ogre::Vector3 planePosition;
226        float d = getD();
227
228        normal.normalise();
229
230        if ((abs(normal[0] > abs(normal[1])) && (abs(normal[0] > abs(normal[2])))))
231        {
232                planePosition[0] = -d / normal[0];
233                planePosition[1] = 0;
234                planePosition[2] = 0;
235        }
236        else if ((abs(normal[1] > abs(normal[0])) && (abs(normal[1] > abs(normal[2])))))
237        {
238                planePosition[0] = 0;
239                planePosition[1] = -d / normal[1];
240                planePosition[2] = 0;
241        }
242        else
243        {
244                planePosition[0] = 0;
245                planePosition[1] = 0;
246                planePosition[2] = -d / normal[2];
247        }
248       
249        mAxisX = normal.perpendicular();
250        mAxisX.normalise();
251        mAxisY = normal.crossProduct(mAxisX);   
252        mAxisY.normalise();
253        mAxisZ = normal;
254
255        Ogre::Matrix4 coordPlane;
256        Ogre::Matrix4 constCoord;
257        Ogre::Matrix4 invMCoordPlane;
258
259        coordPlane[0][0] = mAxisX.x;
260        coordPlane[0][1] = mAxisX.y;
261        coordPlane[0][2] = mAxisX.z;
262        coordPlane[0][3] = 0.0f;
263        coordPlane[1][0] = mAxisY.x;
264        coordPlane[1][1] = mAxisY.y;
265        coordPlane[1][2] = mAxisY.z;
266        coordPlane[1][3] = 0.0f;
267        coordPlane[2][0] = mAxisZ.x;
268        coordPlane[2][1] = mAxisZ.y;
269        coordPlane[2][2] = mAxisZ.z;
270        coordPlane[2][3] = 0.0f;
271        coordPlane[3][0] = planePosition.x;
272        coordPlane[3][1] = planePosition.y;
273        coordPlane[3][2] = planePosition.z;
274        coordPlane[3][3] = 1.0f;
275
276        invMCoordPlane = coordPlane.inverse();
277
278        constCoord[0][0] = 1.0f;
279        constCoord[0][1] = 0.0f;
280        constCoord[0][2] = 0.0f;
281        constCoord[0][3] = 0.0f;
282        constCoord[1][0] = 0.0f;
283        constCoord[1][1] = 1.0f;
284        constCoord[1][2] = 0.0f;
285        constCoord[1][3] = 0.0f;
286        constCoord[2][0] = 0.0f;
287        constCoord[2][1] = 0.0f;
288        constCoord[2][2] = 0.0f;
289        constCoord[2][3] = 0.0f;
290        constCoord[3][0] = 0.0f;
291        constCoord[3][1] = 0.0f;
292        constCoord[3][2] = 0.0f;
293        constCoord[3][3] = 1.0f;
294
295        float xMax = -FLT_MAX;
296        float xMin = FLT_MAX;
297        float yMax = -FLT_MAX;
298        float yMin = FLT_MAX;
299
300        Ogre::Vector3 vXmax;
301        Ogre::Vector3 vXmin;
302        Ogre::Vector3 vYmax;
303        Ogre::Vector3 vYmin;
304
305        BBC::EntityClusterPtr entityCluster = getEntityCluster();
306        BBC::EntityPtr entity = entityCluster->getEntity();
307
308        for (unsigned int iVertex = 0; iVertex < entity->getSubEntity(0)->getNumVertices(); iVertex++)
309        {                               
310                Ogre::Vector3 position = entity->getSubEntity(0)->getPosition(iVertex);
311                Ogre::Vector4 projPointP1d4 =  Ogre::Vector4(position.x,position.y,position.z,1.0f) * invMCoordPlane * constCoord * coordPlane;
312       
313                // The point projected in the plane
314                Ogre::Vector3 projPointP1(projPointP1d4.x,projPointP1d4.y,projPointP1d4.z);
315
316                float v1 = normal.dotProduct(planePosition);
317                float v2 = normal.dotProduct(position);
318                float t = v1 - v2;
319                projPointP1 = position + (normal * t);
320
321                float x1 = mAxisX.dotProduct(projPointP1 - planePosition);
322                float y1 = mAxisY.dotProduct(projPointP1 - planePosition);
323                float z1 = mAxisZ.dotProduct(projPointP1 - planePosition);             
324               
325                if (x1 > xMax)
326                {
327                        xMax = x1;
328                        vXmax = projPointP1;
329                }
330                if (x1 < xMin)
331                {
332                        xMin = x1;
333                        vXmin = projPointP1;
334                }
335                if (y1 > yMax)
336                {
337                        yMax = y1;
338                        vYmax = projPointP1;
339                }
340                if (y1 < yMin)
341                {
342                        yMin = y1;
343                        vYmin = projPointP1;
344                }               
345        }
346       
347        for (unsigned int iLeaf = 0; iLeaf < entityCluster->getNumEntitiesClusterData(); iLeaf++)
348        {
349                LeafKMeansClusterData *leafKMeansClusterData = (LeafKMeansClusterData*)entityCluster->getEntityClusterData(iLeaf).get();
350                Leaf *leaf = (Leaf*)leafKMeansClusterData->getEntity().get();           
351
352                Ogre::Vector3 position = leaf->getPosition();
353                Ogre::Vector4 projPointP1d4 =  Ogre::Vector4(position.x,position.y,position.z,1.0f) * invMCoordPlane * constCoord * coordPlane;
354               
355                // The point projected in the plane
356                Ogre::Vector3 projPointP1(projPointP1d4.x,projPointP1d4.y,projPointP1d4.z);
357
358                leaf->setPosition(projPointP1);
359        }
360
361        Ogre::Vector3 aP;
362        Ogre::Vector3 bP;
363        Ogre::Vector3 pP;
364        Ogre::Vector3 abV;
365        Ogre::Vector3 apV;
366        Ogre::Vector3 dProdV;
367        float aLength;
368        float abLength;
369        float dist;
370        Ogre::Vector3 intersectP;
371
372        aP = vYmin;
373        bP = vYmin + mAxisX;
374        pP = vXmin;
375        abV = bP - aP;
376        apV = pP - aP;
377        dProdV = abV.crossProduct(apV);
378        aLength = dProdV.length();
379        abLength = abV.length();
380        dist = aLength / abLength;
381        mBillboardCorners[QUAD_TOP_LEFT] = pP + (mAxisY * (-dist));
382
383        aP = vYmax;
384        bP = vYmax + mAxisX;
385        pP = vXmax;
386        abV = bP - aP;
387        apV = pP - aP;
388        dProdV = abV.crossProduct(apV);
389        aLength = dProdV.length();
390        abLength = abV.length();
391        dist = aLength / abLength;
392        mBillboardCorners[QUAD_BOTTOM_RIGHT] = pP + (mAxisY * dist);
393
394        aP = vXmax;
395        bP = vXmax + mAxisY;
396        pP = vYmin;
397        abV = bP - aP;
398        apV = pP - aP;
399        dProdV = abV.crossProduct(apV);
400        aLength = dProdV.length();
401        abLength = abV.length();
402        dist = aLength / abLength;
403        mBillboardCorners[QUAD_BOTTOM_LEFT] = pP + (mAxisX * dist);
404
405        Ogre::Vector3 vDirWidth = mBillboardCorners[QUAD_BOTTOM_LEFT] - mBillboardCorners[QUAD_BOTTOM_RIGHT];
406        float distWidth = vDirWidth.length();
407        mBillboardCorners[QUAD_TOP_RIGHT] = mBillboardCorners[QUAD_TOP_LEFT] + (mAxisY * distWidth);
408}
409
410}
Note: See TracBrowser for help on using the repository browser.