#include "BBCBillboardCloud.h" namespace BBC { BillboardCloud::BillboardCloud() { //mEntity = new Entity(); mEntity = 0; } BillboardCloud::~BillboardCloud() { } void BillboardCloud::clearBillboardCloud() { Ogre::LogManager::getSingleton().logMessage("Before Num.Billboards:" + Ogre::StringConverter::toString(this->getNumBillboards())); while (this->getNumBillboardGroups() > 0) { this->removeBillboardGroup(this->getNumBillboardGroups()-1); } while (this->getNumBillboards() > 0) { this->removeBillboard(this->getNumBillboards()-1); } Ogre::LogManager::getSingleton().logMessage("After Num.Billboards:" + Ogre::StringConverter::toString(this->getNumBillboards())); } 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(BillboardPtr value) { value->setBillboardHandle((unsigned int)(mBillboardList.size())); mBillboardList.push_back(value); } void BillboardCloud::removeBillboard(unsigned int value) { BillboardPtr billboard = mBillboardList[value]; mBillboardList.erase(mBillboardList.begin() + value); } BillboardPtr BillboardCloud::getBillboard(unsigned int value) { return mBillboardList[value]; } EntityPtr BillboardCloud::getEntity() { return mEntity; } EntityPtr BillboardCloud::getEntityGrouped() { return mEntityGrouped; } void BillboardCloud::setEntityGrouped(EntityPtr value) { mEntityGrouped = value; } void BillboardCloud::setEntity(EntityPtr value) { mEntity = value; } void BillboardCloud::generateBillboardCloud(bool mergeBillboards) { mEntity = EntityPtr(new Entity()); unsigned int numGeneratedBillboardClouds = 0; bool mergeBillboardCloudTexCoordGenerated = false; for (unsigned int iBillboard = 0; iBillboard < getNumBillboards(); iBillboard++) { BillboardPtr billboard = this->getBillboard(iBillboard); EntityClusterPtr entityCluster = billboard->getBillboardClusterData()->getEntityCluster(); if (entityCluster->getNumEntitiesClusterData() > 0) { SubEntityPtr subEntity; if (mergeBillboards) { subEntity = mEntity->getSubEntity(0); if (!mergeBillboardCloudTexCoordGenerated) { subEntity->enableVertexColors(true); mergeBillboardCloudTexCoordGenerated = true; } 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->enableVertexColors(true); //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(); vFaceA2.position = billboard->getBillboardClusterData()->getQuadTopRightCorner(); vFaceA3.position = billboard->getBillboardClusterData()->getQuadBottomRightCorner(); vFaceA1.normal = billboard->getBillboardClusterData()->getNormal(); vFaceA2.normal = billboard->getBillboardClusterData()->getNormal(); vFaceA3.normal = billboard->getBillboardClusterData()->getNormal(); vFaceA1.colour = Ogre::ColourValue(1.0 , 0.0, 0.0, 0.0).getAsARGB(); vFaceA2.colour = Ogre::ColourValue(0.0, 0.0, 0.0, 0.0).getAsARGB(); vFaceA3.colour = Ogre::ColourValue(0.0, 1.0 ,0.0, 0.0).getAsARGB(); // Face B of the billboard quad UniqueVertex vFaceB1,vFaceB2,vFaceB3; vFaceB1.position = billboard->getBillboardClusterData()->getQuadBottomRightCorner(); vFaceB2.position = billboard->getBillboardClusterData()->getQuadBottomLeftCorner(); vFaceB3.position = billboard->getBillboardClusterData()->getQuadTopLeftCorner(); vFaceB1.normal = billboard->getBillboardClusterData()->getNormal(); vFaceB2.normal = billboard->getBillboardClusterData()->getNormal(); vFaceB3.normal = billboard->getBillboardClusterData()->getNormal(); vFaceB1.colour = Ogre::ColourValue(0.0, 1.0 ,0.0, 0.0).getAsARGB(); vFaceB2.colour = Ogre::ColourValue(1.0, 1.0, 0.0, 0.0).getAsARGB(); vFaceB3.colour = Ogre::ColourValue(1.0, 0.0, 0.0, 0.0).getAsARGB(); 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) { for (unsigned int iSubEntity = 0; iSubEntity < mEntity->getNumSubEntities(); iSubEntity++) { mEntity->getSubEntity(iSubEntity)->removeTextureCoordSet(); } while (getNumBillboardGroups() > 0) { BillboardGroupPtr billboardGroup = getBillboardGroup(getNumBillboardGroups()-1); removeBillboardGroup(getNumBillboardGroups()-1); } unsigned int iBillboardGroup; for (iBillboardGroup = 0; iBillboardGroup < numberGroups; iBillboardGroup++) { BillboardGroupPtr billboardGroup = BillboardGroupPtr( new BillboardGroup() ); addBillboardGroup(billboardGroup); } unsigned int numGeneratedBillboardClouds = 0; for (unsigned int iBillboard = 0; iBillboard < getNumBillboards(); iBillboard++) { BillboardPtr billboard = this->getBillboard(iBillboard); EntityClusterPtr entityCluster = billboard->getBillboardClusterData()->getEntityCluster(); if (entityCluster->getNumEntitiesClusterData() > 0) { for (unsigned int iBillboardGroup = 0; iBillboardGroup < billboard->getBillboardClusterData()->getNumUVMapGroups(); iBillboardGroup++) { billboard->getBillboardClusterData()->removeBillboardUVMapMax(iBillboardGroup); billboard->getBillboardClusterData()->removeBillboardUVMapMin(iBillboardGroup); } 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++) { BillboardPtr billboard = this->getBillboard(iBillboard); EntityClusterPtr 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() { SubEntityPtr subEntityGroup; SubEntityPtr subEntity; EntityPtr entity = EntityPtr(new Entity()); unsigned int numGeneratedBillboardClouds = 0; for (unsigned int iBillboardGroup = 0; iBillboardGroup < this->getNumBillboardGroups(); iBillboardGroup++) { if (iBillboardGroup > 0) { entity->createSubEntity(); } subEntityGroup = entity->getSubEntity(iBillboardGroup); BillboardGroupPtr billboardGroup = this->getBillboardGroup(iBillboardGroup); for (unsigned int iBillboard = 0; iBillboard < billboardGroup->getNumBillboards(); iBillboard++) { unsigned int billboardHandle = billboardGroup->getBillboardHandle(iBillboard); BillboardPtr billboard = this->getBillboard(billboardHandle); BillboardClusterData *billboardClusterData = billboard->getBillboardClusterData().get(); if (billboardClusterData != NULL) { EntityClusterPtr entityCluster = billboardClusterData->getEntityCluster(); if (entityCluster->getNumEntitiesClusterData() > 0) { subEntity = mEntity->getSubEntity(numGeneratedBillboardClouds); while (subEntityGroup->getNumTexCoordSets() < subEntity->getNumTexCoordSets()) { subEntityGroup->addTextureCoordSet(subEntity->getTexCoordDimensions(subEntityGroup->getNumTexCoordSets())); } subEntityGroup->enableVertexColors(subEntity->hasVertexColors()); 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(); vFaceA2.position = billboard->getBillboardClusterData()->getQuadTopRightCorner(); vFaceA3.position = billboard->getBillboardClusterData()->getQuadBottomRightCorner(); vFaceA1.normal = billboard->getBillboardClusterData()->getNormal(); vFaceA2.normal = billboard->getBillboardClusterData()->getNormal(); vFaceA3.normal = billboard->getBillboardClusterData()->getNormal(); if (subEntity->hasVertexColors()) { vFaceA1.colour = subEntity->getVertexColor(0); vFaceA2.colour = subEntity->getVertexColor(1); vFaceA3.colour = subEntity->getVertexColor(2); } UniqueVertex vFaceB1,vFaceB2,vFaceB3; // Face B of the billboard quad vFaceB1.position = billboard->getBillboardClusterData()->getQuadBottomRightCorner(); vFaceB2.position = billboard->getBillboardClusterData()->getQuadBottomLeftCorner(); vFaceB3.position = billboard->getBillboardClusterData()->getQuadTopLeftCorner(); vFaceB1.normal = billboard->getBillboardClusterData()->getNormal(); vFaceB2.normal = billboard->getBillboardClusterData()->getNormal(); vFaceB3.normal = billboard->getBillboardClusterData()->getNormal(); if (subEntity->hasVertexColors()) { vFaceB1.colour = subEntity->getVertexColor(3); vFaceB2.colour = subEntity->getVertexColor(4); vFaceB3.colour = subEntity->getVertexColor(5); } 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++; } } } } mEntityGrouped = entity; } unsigned int BillboardCloud::getNumBillboardGroups() { return mBillboardGroupList.size(); } BillboardGroupPtr BillboardCloud::getBillboardGroup(unsigned int iBillboardGroup) { return mBillboardGroupList[iBillboardGroup]; } void BillboardCloud::addBillboardGroup(BillboardGroupPtr value) { mBillboardGroupList.push_back(value); } void BillboardCloud::removeBillboardGroup(unsigned int value) { BillboardGroupPtr billboardGroup = mBillboardGroupList[value]; mBillboardGroupList.erase(mBillboardGroupList.begin() + value); } }