[699] | 1 | |
---|
| 2 | #include "LBBCBillboardKdTreeClusterData.h" |
---|
| 3 | |
---|
| 4 | namespace LBBC { |
---|
| 5 | |
---|
| 6 | BillboardKdTreeClusterData::BillboardKdTreeClusterData() { |
---|
| 7 | } |
---|
| 8 | |
---|
| 9 | BillboardKdTreeClusterData::~BillboardKdTreeClusterData() { |
---|
| 10 | } |
---|
| 11 | |
---|
| 12 | void BillboardKdTreeClusterData::readBillboardClusterData(TiXmlNode *parentNode) |
---|
| 13 | { |
---|
| 14 | |
---|
| 15 | } |
---|
| 16 | |
---|
| 17 | void 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 | |
---|
| 125 | void 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 | } |
---|