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

Revision 745, 15.4 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
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       
213        Ogre::Vector3 normal = getNormal();
214        Ogre::Vector3 planePosition;
215        float d = getD();
216
217        normal.normalise();
218
219        if ((abs(normal[0] > abs(normal[1])) && (abs(normal[0] > abs(normal[2])))))
220        {
221                planePosition[0] = -d / normal[0];
222                planePosition[1] = 0;
223                planePosition[2] = 0;
224        }
225        else if ((abs(normal[1] > abs(normal[0])) && (abs(normal[1] > abs(normal[2])))))
226        {
227                planePosition[0] = 0;
228                planePosition[1] = -d / normal[1];
229                planePosition[2] = 0;
230        }
231        else
232        {
233                planePosition[0] = 0;
234                planePosition[1] = 0;
235                planePosition[2] = -d / normal[2];
236        }
237       
238        mAxisX = normal.perpendicular();
239        mAxisX.normalise();
240        mAxisY = normal.crossProduct(mAxisX);   
241        mAxisY.normalise();
242        mAxisZ = normal;
243
244        Ogre::Matrix4 coordPlane;
245        Ogre::Matrix4 constCoord;
246        Ogre::Matrix4 invMCoordPlane;
247
248        coordPlane[0][0] = mAxisX.x;
249        coordPlane[0][1] = mAxisX.y;
250        coordPlane[0][2] = mAxisX.z;
251        coordPlane[0][3] = 0.0f;
252        coordPlane[1][0] = mAxisY.x;
253        coordPlane[1][1] = mAxisY.y;
254        coordPlane[1][2] = mAxisY.z;
255        coordPlane[1][3] = 0.0f;
256        coordPlane[2][0] = mAxisZ.x;
257        coordPlane[2][1] = mAxisZ.y;
258        coordPlane[2][2] = mAxisZ.z;
259        coordPlane[2][3] = 0.0f;
260        coordPlane[3][0] = planePosition.x;
261        coordPlane[3][1] = planePosition.y;
262        coordPlane[3][2] = planePosition.z;
263        coordPlane[3][3] = 1.0f;
264
265        invMCoordPlane = coordPlane.inverse();
266
267        constCoord[0][0] = 1.0f;
268        constCoord[0][1] = 0.0f;
269        constCoord[0][2] = 0.0f;
270        constCoord[0][3] = 0.0f;
271        constCoord[1][0] = 0.0f;
272        constCoord[1][1] = 1.0f;
273        constCoord[1][2] = 0.0f;
274        constCoord[1][3] = 0.0f;
275        constCoord[2][0] = 0.0f;
276        constCoord[2][1] = 0.0f;
277        constCoord[2][2] = 0.0f;
278        constCoord[2][3] = 0.0f;
279        constCoord[3][0] = 0.0f;
280        constCoord[3][1] = 0.0f;
281        constCoord[3][2] = 0.0f;
282        constCoord[3][3] = 1.0f;
283
284        float xMax = -FLT_MAX;
285        float xMin = FLT_MAX;
286        float yMax = -FLT_MAX;
287        float yMin = FLT_MAX;
288
289        Ogre::Vector3 vXmax;
290        Ogre::Vector3 vXmin;
291        Ogre::Vector3 vYmax;
292        Ogre::Vector3 vYmin;
293
294        BBC::EntityClusterPtr entityCluster = getEntityCluster();
295        BBC::EntityPtr entity = entityCluster->getEntity();
296
297        for (unsigned int iVertex = 0; iVertex < entity->getSubEntity(0)->getNumVertices(); iVertex++)
298        {                               
299                Ogre::Vector3 position = entity->getSubEntity(0)->getPosition(iVertex);
300                Ogre::Vector4 projPointP1d4 =  Ogre::Vector4(position.x,position.y,position.z,1.0f) * invMCoordPlane * constCoord * coordPlane;
301       
302                // The point projected in the plane
303                Ogre::Vector3 projPointP1(projPointP1d4.x,projPointP1d4.y,projPointP1d4.z);
304
305                float v1 = normal.dotProduct(planePosition);
306                float v2 = normal.dotProduct(position);
307                float t = v1 - v2;
308                projPointP1 = position + (normal * t);
309
310                float x1 = mAxisX.dotProduct(projPointP1 - planePosition);
311                float y1 = mAxisY.dotProduct(projPointP1 - planePosition);
312                float z1 = mAxisZ.dotProduct(projPointP1 - planePosition);             
313               
314                if (x1 > xMax)
315                {
316                        xMax = x1;
317                        vXmax = projPointP1;
318                }
319                if (x1 < xMin)
320                {
321                        xMin = x1;
322                        vXmin = projPointP1;
323                }
324                if (y1 > yMax)
325                {
326                        yMax = y1;
327                        vYmax = projPointP1;
328                }
329                if (y1 < yMin)
330                {
331                        yMin = y1;
332                        vYmin = projPointP1;
333                }               
334        }
335
336        Ogre::Vector3 aP;
337        Ogre::Vector3 bP;
338        Ogre::Vector3 pP;
339        Ogre::Vector3 abV;
340        Ogre::Vector3 apV;
341        Ogre::Vector3 dProdV;
342        float aLength;
343        float abLength;
344        float dist;
345        Ogre::Vector3 intersectP;
346
347        aP = vYmin;
348        bP = vYmin + mAxisX;
349        pP = vXmin;
350        abV = bP - aP;
351        apV = pP - aP;
352        dProdV = abV.crossProduct(apV);
353        aLength = dProdV.length();
354        abLength = abV.length();
355        dist = aLength / abLength;
356        mBillboardCorners[QUAD_TOP_LEFT] = pP + (mAxisY * (-dist));
357
358        aP = vYmax;
359        bP = vYmax + mAxisX;
360        pP = vXmax;
361        abV = bP - aP;
362        apV = pP - aP;
363        dProdV = abV.crossProduct(apV);
364        aLength = dProdV.length();
365        abLength = abV.length();
366        dist = aLength / abLength;
367        mBillboardCorners[QUAD_BOTTOM_RIGHT] = pP + (mAxisY * dist);
368
369        aP = vXmax;
370        bP = vXmax + mAxisY;
371        pP = vYmin;
372        abV = bP - aP;
373        apV = pP - aP;
374        dProdV = abV.crossProduct(apV);
375        aLength = dProdV.length();
376        abLength = abV.length();
377        dist = aLength / abLength;
378        mBillboardCorners[QUAD_BOTTOM_LEFT] = pP + (mAxisX * dist);
379
380        Ogre::Vector3 vDirWidth = mBillboardCorners[QUAD_BOTTOM_LEFT] - mBillboardCorners[QUAD_BOTTOM_RIGHT];
381        float distWidth = vDirWidth.length();
382        mBillboardCorners[QUAD_TOP_RIGHT] = mBillboardCorners[QUAD_TOP_LEFT] + (mAxisY * distWidth);
383}
384
385}
Note: See TracBrowser for help on using the repository browser.