#include "BBCBillboardCloud.h" namespace BBC { BillboardCloud::BillboardCloud() { mEntity = new Entity(); } BillboardCloud::~BillboardCloud() { for (unsigned int iBillboard = 0; iBillboard < getNumBillboards(); iBillboard++) { Billboard *billboard = getBillboard(iBillboard); delete billboard; } for (unsigned int iBillboardGroup = 0; iBillboardGroup < getNumBillboardGroups(); iBillboardGroup++) { BillboardGroup *billboardGroup = getBillboardGroup(iBillboardGroup); delete billboardGroup; } delete mEntity; } std::vector* BillboardCloud::getBillboardList() { return &mBillboardList; } void BillboardCloud::setBillboardList(std::vector &value) { mBillboardList = value; } unsigned int BillboardCloud::getNumBillboards() { return (unsigned int)(mBillboardList.size()); } void BillboardCloud::addBillboard(Billboard *value) { value->setBillboardHandle((unsigned int)(mBillboardList.size())); mBillboardList.push_back(value); } void BillboardCloud::removeBillboard(unsigned int value) { Billboard *billboard = mBillboardList[value]; mBillboardList.erase(mBillboardList.begin() + value); delete billboard; } Billboard* BillboardCloud::getBillboard(unsigned int value) { return mBillboardList[value]; } Entity* BillboardCloud::getEntity() { return mEntity; } void BillboardCloud::setEntity(Entity *value) { mEntity = value; } void BillboardCloud::generateBillboardCloud(bool mergeBillboards) { if (mEntity != NULL) { delete mEntity; mEntity = new Entity(); } unsigned int numGeneratedBillboardClouds = 0; for (unsigned int iBillboard = 0; iBillboard < getNumBillboards(); iBillboard++) { Billboard *billboard = this->getBillboard(iBillboard); EntityCluster *entityCluster = billboard->getBillboardClusterData()->getEntityCluster(); if (entityCluster->getNumEntitiesClusterData() > 0) { SubEntity *subEntity; if (mergeBillboards) { subEntity = mEntity->getSubEntity(0); unsigned int offset = subEntity->getNumFaces() * 3; Ogre::Vector3 indicesA = Ogre::Vector3(offset, offset + 1, offset + 2); subEntity->addFaceVerticesIDs(indicesA); offset = subEntity->getNumFaces()*3; Ogre::Vector3 indicesB = Ogre::Vector3(offset, offset + 1, offset + 2); subEntity->addFaceVerticesIDs(indicesB); } else { // The entity has by default one subentity, if we need more // we have to create them. if (numGeneratedBillboardClouds > 0) { mEntity->createSubEntity(); } Ogre::Vector3 indices = Ogre::Vector3(0,1,2); subEntity = mEntity->getSubEntity(numGeneratedBillboardClouds); subEntity->addTextureCoordSet(2); Ogre::LogManager::getSingleton().logMessage("BBC-SubEntity(" + Ogre::StringConverter::toString(numGeneratedBillboardClouds) + ") - Num.Tex.Coord.Sets:" + Ogre::StringConverter::toString(subEntity->getNumTexCoordSets())); subEntity->addFaceVerticesIDs(indices); subEntity->addFaceVerticesIDs(indices + Ogre::Vector3(3,3,3)); } UniqueVertex vFaceA1,vFaceA2,vFaceA3; // Face A of the billboard quad vFaceA1.position = billboard->getBillboardClusterData()->getQuadTopLeftCorner(); vFaceA1.normal = billboard->getBillboardClusterData()->getNormal(); vFaceA1.uv[0] = Ogre::Vector3(0,0,0); vFaceA2.position = billboard->getBillboardClusterData()->getQuadTopRightCorner(); vFaceA2.normal = billboard->getBillboardClusterData()->getNormal(); vFaceA2.uv[0] = Ogre::Vector3(1,0,0); vFaceA3.position = billboard->getBillboardClusterData()->getQuadBottomRightCorner(); vFaceA3.normal = billboard->getBillboardClusterData()->getNormal(); vFaceA3.uv[0] = Ogre::Vector3(1,1,0); // Face B of the billboard quad UniqueVertex vFaceB1,vFaceB2,vFaceB3; vFaceB1.position = billboard->getBillboardClusterData()->getQuadBottomRightCorner(); vFaceB1.normal = billboard->getBillboardClusterData()->getNormal(); vFaceB1.uv[0] = Ogre::Vector3(1,1,0); vFaceB2.position = billboard->getBillboardClusterData()->getQuadBottomLeftCorner(); vFaceB2.normal = billboard->getBillboardClusterData()->getNormal(); vFaceB2.uv[0] = Ogre::Vector3(0,1,0); vFaceB3.position = billboard->getBillboardClusterData()->getQuadTopLeftCorner(); vFaceB3.normal = billboard->getBillboardClusterData()->getNormal(); vFaceB3.uv[0] = Ogre::Vector3(0,0,0); subEntity->addUniqueVertex(vFaceA1); subEntity->addUniqueVertex(vFaceA2); subEntity->addUniqueVertex(vFaceA3); subEntity->addUniqueVertex(vFaceB1); subEntity->addUniqueVertex(vFaceB2); subEntity->addUniqueVertex(vFaceB3); numGeneratedBillboardClouds++; } } } void BillboardCloud::initializeBillboardCloudGroups(unsigned int numberGroups) { Ogre::LogManager::getSingleton().logMessage("Ini.Num.Billboard Groups:" + Ogre::StringConverter::toString(getNumBillboardGroups())); while (getNumBillboardGroups() > 0) { BillboardGroup *billboardGroup = getBillboardGroup(getNumBillboardGroups()-1); removeBillboardGroup(getNumBillboardGroups()-1); } Ogre::LogManager::getSingleton().logMessage("Clear.Num.Billboard Groups:" + Ogre::StringConverter::toString(getNumBillboardGroups())); unsigned int iBillboardGroup; for (iBillboardGroup = 0; iBillboardGroup < numberGroups; iBillboardGroup++) { BillboardGroup *billboardGroup = new BillboardGroup(); addBillboardGroup(billboardGroup); } Ogre::LogManager::getSingleton().logMessage("New.Num.Billboard Groups:" + Ogre::StringConverter::toString(getNumBillboardGroups())); std::cin.get(); std::cin.get(); unsigned int numGeneratedBillboardClouds = 0; for (unsigned int iBillboard = 0; iBillboard < getNumBillboards(); iBillboard++) { Billboard *billboard = this->getBillboard(iBillboard); EntityCluster *entityCluster = billboard->getBillboardClusterData()->getEntityCluster(); if (entityCluster->getNumEntitiesClusterData() > 0) { numGeneratedBillboardClouds++; } } unsigned int numberBillboardsEachGroup = numGeneratedBillboardClouds / numberGroups; unsigned int numberBillboardsAddedFirstGroup = numGeneratedBillboardClouds % numberGroups; Ogre::LogManager::getSingleton().logMessage("Num.Billboards:" + Ogre::StringConverter::toString(numGeneratedBillboardClouds)); Ogre::LogManager::getSingleton().logMessage("Num.Billboards Each Group:" + Ogre::StringConverter::toString(numberBillboardsEachGroup)); Ogre::LogManager::getSingleton().logMessage("Num.Billboards Added First Group:" + Ogre::StringConverter::toString(numberBillboardsAddedFirstGroup)); iBillboardGroup = 0; unsigned int iBillboardsInGroup = 0; for (unsigned int iBillboard = 0; iBillboard < getNumBillboards(); iBillboard++) { Billboard *billboard = this->getBillboard(iBillboard); EntityCluster *entityCluster = billboard->getBillboardClusterData()->getEntityCluster(); if (entityCluster->getNumEntitiesClusterData() > 0) { if ((iBillboardGroup == 0) && (iBillboardsInGroup < (numberBillboardsEachGroup + numberBillboardsAddedFirstGroup))) { getBillboardGroup(iBillboardGroup)->addBillboardHandle(billboard->getBillboardHandle()); iBillboardsInGroup++; } else { if ((iBillboardGroup > 0) && (iBillboardsInGroup < numberBillboardsEachGroup)) { getBillboardGroup(iBillboardGroup)->addBillboardHandle(billboard->getBillboardHandle()); iBillboardsInGroup++; } else { iBillboardGroup++; iBillboardsInGroup = 0; getBillboardGroup(iBillboardGroup)->addBillboardHandle(billboard->getBillboardHandle()); iBillboardsInGroup++; } } } } } void BillboardCloud::generateBillboardCloudGroups() { SubEntity *subEntityGroup; SubEntity *subEntity; Entity *entity = new Entity(); unsigned int numGeneratedBillboardClouds = 0; for (unsigned int iBillboardGroup = 0; iBillboardGroup < this->getNumBillboardGroups(); iBillboardGroup++) { if (iBillboardGroup > 0) { entity->createSubEntity(); Ogre::LogManager::getSingleton().logMessage("BillboardGroup:" + Ogre::StringConverter::toString(iBillboardGroup) + "--" + Ogre::StringConverter::toString(getBillboardGroup(iBillboardGroup)->getNumBillboards())); } subEntityGroup = entity->getSubEntity(iBillboardGroup); BillboardGroup *billboardGroup = this->getBillboardGroup(iBillboardGroup); Ogre::LogManager::getSingleton().logMessage("BBCG-Num.Billboards:" + Ogre::StringConverter::toString(billboardGroup->getNumBillboards())); std::cin.get(); std::cin.get(); for (unsigned int iBillboard = 0; iBillboard < billboardGroup->getNumBillboards(); iBillboard++) { unsigned int billboardHandle = billboardGroup->getBillboardHandle(iBillboard); Billboard *billboard = this->getBillboard(billboardHandle); EntityCluster *entityCluster = billboard->getBillboardClusterData()->getEntityCluster(); if (entityCluster->getNumEntitiesClusterData() > 0) { subEntity = mEntity->getSubEntity(numGeneratedBillboardClouds); while (subEntityGroup->getNumTexCoordSets() < subEntity->getNumTexCoordSets()) { subEntityGroup->addTextureCoordSet(subEntity->getTexCoordDimensions(subEntityGroup->getNumTexCoordSets())); } unsigned int offset = subEntityGroup->getNumFaces() * 3; Ogre::Vector3 indicesA = Ogre::Vector3(offset, offset + 1, offset + 2); subEntityGroup->addFaceVerticesIDs(indicesA); offset = subEntityGroup->getNumFaces()*3; Ogre::Vector3 indicesB = Ogre::Vector3(offset, offset + 1, offset + 2); subEntityGroup->addFaceVerticesIDs(indicesB); UniqueVertex vFaceA1,vFaceA2,vFaceA3; // Face A of the billboard quad vFaceA1.position = billboard->getBillboardClusterData()->getQuadTopLeftCorner(); vFaceA1.normal = billboard->getBillboardClusterData()->getNormal(); vFaceA2.position = billboard->getBillboardClusterData()->getQuadTopRightCorner(); vFaceA2.normal = billboard->getBillboardClusterData()->getNormal(); vFaceA3.position = billboard->getBillboardClusterData()->getQuadBottomRightCorner(); vFaceA3.normal = billboard->getBillboardClusterData()->getNormal(); // Face B of the billboard quad UniqueVertex vFaceB1,vFaceB2,vFaceB3; vFaceB1.position = billboard->getBillboardClusterData()->getQuadBottomRightCorner(); vFaceB1.normal = billboard->getBillboardClusterData()->getNormal(); vFaceB2.position = billboard->getBillboardClusterData()->getQuadBottomLeftCorner(); vFaceB2.normal = billboard->getBillboardClusterData()->getNormal(); vFaceB3.position = billboard->getBillboardClusterData()->getQuadTopLeftCorner(); vFaceB3.normal = billboard->getBillboardClusterData()->getNormal(); Ogre::LogManager::getSingleton().logMessage("BBCG-SubEntity(" + Ogre::StringConverter::toString(numGeneratedBillboardClouds) + ") - Num.Tex.Coord.Sets:"+ Ogre::StringConverter::toString(subEntity->getNumTexCoordSets())); for (unsigned int iTexCoordSet = 0; iTexCoordSet < subEntityGroup->getNumTexCoordSets(); iTexCoordSet++) { vFaceA1.uv[iTexCoordSet] = subEntity->getUniqueVertex(0).uv[iTexCoordSet]; vFaceA2.uv[iTexCoordSet] = subEntity->getUniqueVertex(1).uv[iTexCoordSet]; vFaceA3.uv[iTexCoordSet] = subEntity->getUniqueVertex(2).uv[iTexCoordSet]; vFaceB1.uv[iTexCoordSet] = subEntity->getUniqueVertex(3).uv[iTexCoordSet]; vFaceB2.uv[iTexCoordSet] = subEntity->getUniqueVertex(4).uv[iTexCoordSet]; vFaceB3.uv[iTexCoordSet] = subEntity->getUniqueVertex(5).uv[iTexCoordSet]; } subEntityGroup->addUniqueVertex(vFaceA1); subEntityGroup->addUniqueVertex(vFaceA2); subEntityGroup->addUniqueVertex(vFaceA3); subEntityGroup->addUniqueVertex(vFaceB1); subEntityGroup->addUniqueVertex(vFaceB2); subEntityGroup->addUniqueVertex(vFaceB3); numGeneratedBillboardClouds++; } } } delete mEntity; mEntity = entity; entity->setSubEntitiesDistinctVertexColours(); } unsigned int BillboardCloud::getNumBillboardGroups() { return mBillboardGroupList.size(); } BillboardGroup* BillboardCloud::getBillboardGroup(unsigned int iBillboardGroup) { return mBillboardGroupList[iBillboardGroup]; } void BillboardCloud::addBillboardGroup(BillboardGroup *value) { mBillboardGroupList.push_back(value); } void BillboardCloud::removeBillboardGroup(unsigned int value) { BillboardGroup *billboardGroup = mBillboardGroupList[value]; mBillboardGroupList.erase(mBillboardGroupList.begin() + value); delete billboardGroup; } }