108 const Quaternion &orientation,
109 const Vector3 &scale,
110 const Ogre::ColourValue &color)
112 const MeshPtr &mesh = ent->getMesh();
118 for (uint32 i = 0; i < ent->getNumSubEntities(); ++i)
121 SubEntity *subEntity = ent->getSubEntity(i);
122 SubMesh *subMesh = subEntity->getSubMesh();
125 if (subMesh->vertexData == NULL)
126 OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
"SubMesh vertex data not found!",
"BatchedGeometry::addEntity()");
131 TSubBatchMap::iterator batchIter =
m_mapSubBatch.find(formatStr);
133 batch = batchIter->second;
136 batch =
new SubBatch(
this, subEntity);
137 m_mapSubBatch.insert(std::pair<String, SubBatch*>(formatStr, batch));
141 batch->
addSubEntity(subEntity, position, orientation, scale, color);
145 Matrix4 mat(orientation);
147 AxisAlignedBox entBounds = ent->getBoundingBox();
148 entBounds.transform(mat);
152 m_boundsAAB.setMinimum(entBounds.getMinimum() + position);
153 m_boundsAAB.setMaximum(entBounds.getMaximum() + position);
160 min.makeFloor(entBounds.getMinimum() + position);
161 max.makeCeil(entBounds.getMaximum() + position);
173 switch (id->indexBuffer->getType()) {
174 case HardwareIndexBuffer::IT_16BIT:
176 uint16 *data = (uint16*)id->indexBuffer->lock(id->indexStart *
sizeof(uint16),
177 id->indexCount *
sizeof(uint16), HardwareBuffer::HBL_READ_ONLY);
179 for (i = 0; i <
id->indexCount; i++) {
180 uint16 index = data[i];
181 if (ibmap.find(index) == ibmap.end())
185 uint32 size = (uint32)(ibmap.size());
189 count = (uint32)ibmap.size();
190 id->indexBuffer->unlock();
194 case HardwareIndexBuffer::IT_32BIT:
196 uint32 *data = (uint32*)id->indexBuffer->lock(id->indexStart *
sizeof(uint32),
197 id->indexCount *
sizeof(uint32), HardwareBuffer::HBL_READ_ONLY);
199 for (i = 0; i <
id->indexCount; i++) {
200 uint32 index = data[i];
201 if (ibmap.find(index) == ibmap.end())
205 uint32 size = (uint32)(ibmap.size());
209 count = (uint32)ibmap.size();
210 id->indexBuffer->unlock();
215 throw new Ogre::Exception(0,
"Unknown index buffer type",
"Converter.cpp::CountVertices");
227 if (!mesh || !mesh->sharedVertexData)
230 Mesh::SubMeshIterator subMeshIterator = mesh->getSubMeshIterator();
233 VertexData *oldVertexData = mesh->sharedVertexData;
235 while (subMeshIterator.hasMoreElements()) {
236 SubMesh *subMesh = subMeshIterator.getNext();
239 IndexData *indexData = subMesh->indexData;
240 HardwareIndexBufferSharedPtr ib = indexData->indexBuffer;
243 std::map<uint32, uint32> indicesMap;
244 VertexData *newVertexData =
new VertexData();
247 newVertexData->vertexDeclaration = oldVertexData->vertexDeclaration->clone();
250 uint32 buffersCount = (uint32)oldVertexData->vertexBufferBinding->getBufferCount();
251 for (uint32 bufferIndex = 0; bufferIndex < buffersCount; bufferIndex++) {
254 HardwareVertexBufferSharedPtr oldVertexBuffer = oldVertexData->vertexBufferBinding->getBuffer(bufferIndex);
255 size_t vertexSize = oldVertexBuffer->getVertexSize();
256 uint8 *oldLock = (uint8*)oldVertexBuffer->lock(0, oldVertexData->vertexCount * vertexSize, HardwareBuffer::HBL_READ_ONLY);
259 HardwareVertexBufferSharedPtr newVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer(
260 vertexSize, newVertexData->vertexCount, oldVertexBuffer->getUsage(), oldVertexBuffer->hasShadowBuffer());
261 uint8 *newLock = (uint8*)newVertexBuffer->lock(0, newVertexData->vertexCount * vertexSize, HardwareBuffer::HBL_NORMAL);
264 std::map<uint32, uint32>::iterator i, iend = indicesMap.end();
265 for (i = indicesMap.begin(); i != iend; i++) {
266 memcpy(newLock + vertexSize * i->second, oldLock + vertexSize * i->first, vertexSize);
270 oldVertexBuffer->unlock();
271 newVertexBuffer->unlock();
274 newVertexData->vertexBufferBinding->setBinding(bufferIndex, newVertexBuffer);
278 switch (indexData->indexBuffer->getType()) {
279 case HardwareIndexBuffer::IT_16BIT:
281 uint16 *data = (uint16*)indexData->indexBuffer->lock(indexData->indexStart *
sizeof(uint16),
282 indexData->indexCount *
sizeof(uint16), HardwareBuffer::HBL_NORMAL);
284 for (uint32 i = 0; i < indexData->indexCount; i++) {
285 data[i] = (uint16)indicesMap[data[i]];
288 indexData->indexBuffer->unlock();
292 case HardwareIndexBuffer::IT_32BIT:
294 uint32 *data = (uint32*)indexData->indexBuffer->lock(indexData->indexStart *
sizeof(uint32),
295 indexData->indexCount *
sizeof(uint32), HardwareBuffer::HBL_NORMAL);
297 for (uint32 i = 0; i < indexData->indexCount; i++) {
298 data[i] = (uint32)indicesMap[data[i]];
301 indexData->indexBuffer->unlock();
306 throw new Ogre::Exception(0,
"Unknown index buffer type",
"Converter.cpp::CountVertices");
311 subMesh->useSharedVertices =
false;
312 subMesh->vertexData = newVertexData;
316 delete mesh->sharedVertexData;
317 mesh->sharedVertexData = NULL;
474m_pBestTechnique (NULL),
478m_RequireVertexColors (false),
480m_pParentGeom (parent)
485 const Ogre::MaterialPtr &parentMaterial = ent->getMaterial();
487 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
"Empty parent material");
494 Ogre::String newName = parentMaterial->getName() +
"_Batched";
495 m_ptrMaterial = Ogre::static_pointer_cast<Material>(MaterialManager::getSingleton().getByName(newName, parentMaterial->getGroup()));
505 const VertexElement* blendIndices =
m_pVertexData->vertexDeclaration->findElementBySemantic(VES_BLEND_INDICES);
506 const VertexElement* blendWeights =
m_pVertexData->vertexDeclaration->findElementBySemantic(VES_BLEND_WEIGHTS);
507 if (blendIndices && blendWeights)
510 assert(blendIndices->getSource() == blendWeights->getSource()
511 &&
"Blend indices and weights should be in the same buffer");
512 assert(blendIndices->getSize() + blendWeights->getSize() ==
m_pVertexData->vertexBufferBinding->getBuffer(blendIndices->getSource())->getVertexSize()
513 &&
"Blend indices and blend buffers should have buffer to themselves!");
516 m_pVertexData->vertexBufferBinding->unsetBinding(blendIndices->getSource());
517 m_pVertexData->vertexDeclaration->removeElement(VES_BLEND_INDICES);
518 m_pVertexData->vertexDeclaration->removeElement(VES_BLEND_WEIGHTS);
582 HardwareIndexBuffer::IndexType srcIndexType = m_pSubMesh->indexData->indexBuffer->getType();
583 HardwareIndexBuffer::IndexType destIndexType =
584 m_pVertexData->vertexCount > 0xFFFF || srcIndexType == HardwareIndexBuffer::IT_32BIT ?
585 HardwareIndexBuffer::IT_32BIT : HardwareIndexBuffer::IT_16BIT;
588 m_pIndexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(
589 destIndexType, m_pIndexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
592 uint32 *indexBuffer32;
593 uint16 *indexBuffer16;
594 if (destIndexType == HardwareIndexBuffer::IT_32BIT)
595 indexBuffer32 =
static_cast<uint32*
>(m_pIndexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD));
597 indexBuffer16 =
static_cast<uint16*
>(m_pIndexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD));
600 std::vector<uchar*> vertexBuffers;
601 std::vector<VertexDeclaration::VertexElementList> vertexBufferElements;
603 VertexBufferBinding *vertBinding = m_pVertexData->vertexBufferBinding;
604 VertexDeclaration *vertDecl = m_pVertexData->vertexDeclaration;
606 for (Ogre::ushort i = 0; i < vertBinding->getBufferCount(); ++i)
608 HardwareVertexBufferSharedPtr buffer = HardwareBufferManager::getSingleton().createVertexBuffer(
609 vertDecl->getVertexSize(i), m_pVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
610 vertBinding->setBinding(i, buffer);
612 vertexBuffers.push_back(
static_cast<uchar*
>(buffer->lock(HardwareBuffer::HBL_DISCARD)));
613 vertexBufferElements.push_back(vertDecl->findElementsBySource(i));
617 if (m_RequireVertexColors)
619 if (!m_pVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE))
621 Ogre::ushort i = (Ogre::ushort)vertBinding->getBufferCount();
622 vertDecl->addElement(i, 0, VET_COLOUR, VES_DIFFUSE);
624 HardwareVertexBufferSharedPtr buffer = HardwareBufferManager::getSingleton().createVertexBuffer(
625 vertDecl->getVertexSize(i), m_pVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
626 vertBinding->setBinding(i, buffer);
628 vertexBuffers.push_back(
static_cast<uchar*
>(buffer->lock(HardwareBuffer::HBL_DISCARD)));
629 vertexBufferElements.push_back(vertDecl->findElementsBySource(i));
632 m_ptrMaterial->getTechnique(0)->getPass(0)->setVertexColourTracking(TVC_AMBIENT);
636 size_t indexOffset = 0;
637 for (
size_t iMesh = 0, cntMeshes = m_queueMesh.size(); iMesh < cntMeshes; ++iMesh)
639 const QueuedMesh &queuedMesh = m_queueMesh[iMesh];
642 if (queuedMesh.
orientation == Ogre::Quaternion::IDENTITY)
643 _buildIdentiryOrientation(queuedMesh, m_pParentGeom->m_vecCenter, vertexBufferElements, vertexBuffers, m_pVertexData);
645 _buildFullTransform(queuedMesh, m_pParentGeom->m_vecCenter, vertexBufferElements, vertexBuffers, m_pVertexData);
648 Ogre::IndexData *sourceIndexData = queuedMesh.
subMesh->indexData;
650 if (srcIndexType == HardwareIndexBuffer::IT_32BIT)
652 sourceIndexData->indexBuffer->readData(
653 sourceIndexData->indexStart *
sizeof(uint32),
654 sourceIndexData->indexCount *
sizeof(uint32), indexBuffer32);
655 uint32 *updateEnd = indexBuffer32 + sourceIndexData->indexCount;
658 while (indexBuffer32 != updateEnd)
659 *indexBuffer32++ += indexOffset;
663 if (destIndexType == HardwareIndexBuffer::IT_32BIT)
666 std::vector<uint16> tmp(sourceIndexData->indexCount);
668 sourceIndexData->indexBuffer->readData(sourceIndexData->indexStart*
sizeof(uint16), tmp.size(), tmp.data());
669 uint16 *source = tmp.data();
670 uint16 *sourceEnd = source + sourceIndexData->indexCount;
673 while (source != sourceEnd)
674 *indexBuffer32++ = (*source++ + indexOffset);
678 sourceIndexData->indexBuffer->readData(
679 sourceIndexData->indexStart *
sizeof(uint16),
680 sourceIndexData->indexCount *
sizeof(uint16), indexBuffer16);
681 uint16 *updateEnd = indexBuffer16 + sourceIndexData->indexCount;
684 while (indexBuffer16 != updateEnd)
685 *indexBuffer16++ += indexOffset;
687 indexOffset += queuedMesh.
subMesh->vertexData->vertexCount;
693 m_pIndexData->indexBuffer->unlock();
694 for (Ogre::ushort i = 0; i < vertBinding->getBufferCount(); ++i)
695 vertBinding->getBuffer(i)->unlock();
705 const Ogre::Vector3 &parentGeomCenter,
706 const std::vector<VertexDeclaration::VertexElementList> &vertexBufferElements,
707 std::vector<Ogre::uchar*> &vertexBuffers,
708 Ogre::VertexData *dstVertexData)
710 const VertexData *sourceVertexData = queuedMesh.
subMesh->vertexData;
711 Ogre::Vector3 v3AddBatchPosition = queuedMesh.
position - parentGeomCenter;
714 VertexBufferBinding *sourceBinds = sourceVertexData->vertexBufferBinding;
715 VertexBufferBinding *destBinds = dstVertexData->vertexBufferBinding;
717 std::vector<uchar> shadowBuf;
720 for (
unsigned short ibuffer = 0, bufCnt = destBinds->getBufferCount(); ibuffer < bufCnt; ++ibuffer)
722 if (ibuffer < sourceBinds->getBufferCount())
725 const HardwareVertexBufferSharedPtr &sourceBuffer = sourceBinds->getBuffer(ibuffer);
727 shadowBuf.resize(sourceBuffer->getSizeInBytes());
728 sourceBuffer->readData(0, sourceBuffer->getSizeInBytes(), shadowBuf.data());
729 uchar *sourceBase = shadowBuf.data();
731 uchar *destBase = vertexBuffers[ibuffer];
733 const VertexDeclaration::VertexElementList &elems = vertexBufferElements[ibuffer];
734 VertexDeclaration::VertexElementList::const_iterator iBegin = elems.begin(), iEnd = elems.end();
735 float *sourcePtr = 0, *destPtr = 0;
736 size_t sourceVertexBuffer = sourceBuffer->getVertexSize();
739 for (
size_t v = 0, vertexCounter = sourceVertexData->vertexCount; v < vertexCounter; ++v)
742 VertexDeclaration::VertexElementList::const_iterator it = iBegin;
745 const VertexElement &elem = *it;
746 elem.baseVertexPointerToElement(sourceBase, &sourcePtr);
747 elem.baseVertexPointerToElement(destBase, &destPtr);
749 switch (elem.getSemantic())
753 Vector3 tmp(sourcePtr[0], sourcePtr[1], sourcePtr[2]);
754 tmp *= queuedMesh.
scale;
755 tmp += v3AddBatchPosition;
757 destPtr[0] = (float)tmp.x; destPtr[1] = (float)tmp.y; destPtr[2] = (float)tmp.z;
766 destPtr[0] = sourcePtr[0];
767 destPtr[1] = sourcePtr[1];
768 destPtr[2] = sourcePtr[2];
774 uint32 tmpColor = *((uint32*)sourcePtr++);
775 uint8 tmpR =
static_cast<uint8
>(((tmpColor) & 0xFF) * queuedMesh.
color.r);
776 uint8 tmpG =
static_cast<uint8
>(((tmpColor >> 8) & 0xFF) * queuedMesh.
color.g);
777 uint8 tmpB =
static_cast<uint8
>(((tmpColor >> 16) & 0xFF) * queuedMesh.
color.b);
780 *((uint32*)destPtr) = tmpR | (tmpG << 8) | (tmpB << 16) | (0xFF << 24);
795 destBase += sourceVertexBuffer;
796 sourceBase += sourceVertexBuffer;
799 vertexBuffers[ibuffer] = destBase;
803 size_t bufferNumber = destBinds->getBufferCount()-1;
806 uint32 *startPtr = (uint32*)vertexBuffers[bufferNumber];
807 uint32 *endPtr = startPtr + sourceVertexData->vertexCount;
810 uint8 tmpR =
static_cast<uint8
>(queuedMesh.
color.r * 255);
811 uint8 tmpG =
static_cast<uint8
>(queuedMesh.
color.g * 255);
812 uint8 tmpB =
static_cast<uint8
>(queuedMesh.
color.b * 255);
813 uint32 tmpColor = tmpR | (tmpG << 8) | (tmpB << 16) | (0xFF << 24);
816 while (startPtr < endPtr)
817 *startPtr++ = tmpColor;
819 vertexBuffers[bufferNumber] +=
sizeof(uint32) * sourceVertexData->vertexCount;
829 const Ogre::Vector3 &parentGeomCenter,
830 const std::vector<VertexDeclaration::VertexElementList> &vertexBufferElements,
831 std::vector<Ogre::uchar*> &vertexBuffers,
832 Ogre::VertexData *dstVertexData)
834 const VertexData *sourceVertexData = queuedMesh.
subMesh->vertexData;
836 Ogre::Matrix3 m3MeshOrientation;
837 queuedMesh.
orientation.ToRotationMatrix(m3MeshOrientation);
838 const Ogre::Real *mat = m3MeshOrientation[0];
839 Ogre::Vector3 v3AddBatchPosition = queuedMesh.
position - parentGeomCenter;
840 const Ogre::Vector3 &scale = queuedMesh.
scale;
843 VertexBufferBinding *sourceBinds = sourceVertexData->vertexBufferBinding;
844 VertexBufferBinding *destBinds = dstVertexData->vertexBufferBinding;
846 std::vector<uchar> shadowBuf;
849 for (
unsigned short ibuffer = 0, bufCnt = destBinds->getBufferCount(); ibuffer < bufCnt; ++ibuffer)
851 if (ibuffer < sourceBinds->getBufferCount())
854 const HardwareVertexBufferSharedPtr &sourceBuffer = sourceBinds->getBuffer(ibuffer);
855 shadowBuf.resize(sourceBuffer->getSizeInBytes());
856 sourceBuffer->readData(0, sourceBuffer->getSizeInBytes(), shadowBuf.data());
857 uchar *sourceBase = shadowBuf.data();
860 uchar *destBase = vertexBuffers[ibuffer];
863 const VertexDeclaration::VertexElementList &elems = vertexBufferElements[ibuffer];
864 VertexDeclaration::VertexElementList::const_iterator iBegin = elems.begin(), iEnd = elems.end();
865 float *sourcePtr = 0, *destPtr = 0;
866 size_t sourceVertexSize = sourceBuffer->getVertexSize();
869 for (
size_t v = 0, vertexCounter = sourceVertexData->vertexCount; v < vertexCounter; ++v)
871 VertexDeclaration::VertexElementList::const_iterator it = iBegin;
875 const VertexElement &elem = *it;
876 elem.baseVertexPointerToElement(sourceBase, &sourcePtr);
877 elem.baseVertexPointerToElement(destBase, &destPtr);
879 switch (elem.getSemantic())
883 Vector3 tmp(sourcePtr[0] * scale.x, sourcePtr[1] * scale.x, sourcePtr[2] * scale.x);
884 tmp = m3MeshOrientation*tmp;
885 tmp += v3AddBatchPosition;
886 destPtr[0] = (float)tmp.x;
887 destPtr[1] = (float)tmp.y;
888 destPtr[2] = (float)tmp.z;
897 destPtr[0] = float(mat[0] * sourcePtr[0] + mat[1] * sourcePtr[1] + mat[2] * sourcePtr[2]);
898 destPtr[1] = float(mat[3] * sourcePtr[0] + mat[4] * sourcePtr[1] + mat[5] * sourcePtr[2]);
899 destPtr[2] = float(mat[6] * sourcePtr[0] + mat[7] * sourcePtr[1] + mat[8] * sourcePtr[2]);
905 uint32 tmpColor = *((uint32*)sourcePtr);
906 uint8 tmpR =
static_cast<uint8
>(((tmpColor) & 0xFF) * queuedMesh.
color.r);
907 uint8 tmpG =
static_cast<uint8
>(((tmpColor >> 8) & 0xFF) * queuedMesh.
color.g);
908 uint8 tmpB =
static_cast<uint8
>(((tmpColor >> 16) & 0xFF) * queuedMesh.
color.b);
912 *((uint32*)destPtr) = tmpR | (tmpG << 8) | (tmpB << 16) | (0xFF << 24);
926 destBase += sourceVertexSize;
927 sourceBase += sourceVertexSize;
931 vertexBuffers[ibuffer] = destBase;
935 size_t bufferNumber = destBinds->getBufferCount()-1;
938 uint32 *startPtr = (uint32*)vertexBuffers[bufferNumber];
939 uint32 *endPtr = startPtr + sourceVertexData->vertexCount;
942 uint8 tmpR =
static_cast<uint8
>(queuedMesh.
color.r * 255);
943 uint8 tmpG =
static_cast<uint8
>(queuedMesh.
color.g * 255);
944 uint8 tmpB =
static_cast<uint8
>(queuedMesh.
color.b * 255);
945 uint32 tmpColor = tmpR | (tmpG << 8) | (tmpB << 16) | (0xFF << 24);
948 while (startPtr < endPtr)
949 *startPtr++ = tmpColor;
951 vertexBuffers[bufferNumber] +=
sizeof(uint32) * sourceVertexData->vertexCount;