void CalculateNormals(irr::core::array<video::S3DVertex>& vertices, irr::core::array<u16>& indices) { for (unsigned int i = 0; i < vertices.size(); i++) { vertices[i].Normal = Vector3_Zero; } u32 size = indices.size(); for (unsigned int i = 0; i < size / 3; i++) { int index1 = indices[i * 3]; int index2 = indices[i * 3 + 1]; int index3 = indices[i * 3 + 2]; Vector3 side1 = vertices[index2].Pos - vertices[index1].Pos; Vector3 side2 = vertices[index3].Pos - vertices[index1].Pos; Vector3 normal = side1.crossProduct(side2); vertices[index1].Normal += normal; vertices[index2].Normal += normal; vertices[index3].Normal += normal; } for (unsigned int i = 0; i < vertices.size(); i++) { vertices[i].Normal.normalize(); } }
// Pack rectangles into box with dimensions sizeOfPackxsizeOfPack. Packed outputs new rectangles void CRectPacker::pack(const irr::core::array<irr::core::rect<irr::u32> > &rects, irr::core::array<irr::core::array<SPacked>> &packed, irr::u32 sizeOfPack) { clear(); mPackSize = sizeOfPack; for (int x = 0; x < rects.size(); x++) { SRect addRect; addRect.pos = rects[x]; addRect.id = x; addRect.packed = false; mRects.push_back(addRect); } mRects.sort(); while (mNumPacked < mRects.size()) { SRect empty; empty.id = -1; empty.children[0] = -1; empty.children[1] = -1; empty.pos = irr::core::rect<irr::u32>(0,0,mPackSize,mPackSize); int oldSize = mPacks.size(); mPacks.push_back(empty); mRoots.push_back(oldSize); fill(oldSize); } for (int x = 0; x < mRoots.size(); x++) { irr::core::array<SPacked> arr; packed.push_back(arr); packed[x].clear(); addPackToArray(mRoots[x],packed[x]); } }
// Find a good area to pack rects into. If the area of the rects divided by the area of the nearest power of two calculated is above a certain tolerance, the size is doubled irr::core::dimension2du CMeshCombiner::findOptimalPackingArea(irr::core::array<irr::core::rect<irr::u32> > rectangles) { irr::u32 totalArea = 0; for (int x = 0; x < rectangles.size(); x++) { totalArea += rectangles[x].getArea(); } irr::u32 smallestDimension = ceil(sqrtf(totalArea)); irr::u32 closestPowerOfTwo = pow(2.0f,ceil(logf(smallestDimension)/logf(2))); if ((irr::f32)smallestDimension/(irr::f32)closestPowerOfTwo > mSizingTolerance) closestPowerOfTwo *= 2; return irr::core::dimension2du(closestPowerOfTwo,closestPowerOfTwo); }