| 90 | } |
| 91 | |
| 92 | void RawData::ToModelData(ModelData& modelData) const |
| 93 | { |
| 94 | // Generate lightmap UVs (single chart for the whole mesh) |
| 95 | { |
| 96 | // Every surface has custom lightmap scale so we have to try to pack all triangles into |
| 97 | // single rectangle using fast rectangle pack algorithm. Rectangle size can be calculated from |
| 98 | // all triangles surfaces area with margins. |
| 99 | |
| 100 | // Sum the area for the atlas surfaces |
| 101 | float areaSum = 0; |
| 102 | for (int32 slotIndex = 0; slotIndex < Slots.Count(); slotIndex++) |
| 103 | { |
| 104 | auto& slot = Slots[slotIndex]; |
| 105 | for (int32 i = 0; i < slot->Surfaces.Count(); i++) |
| 106 | { |
| 107 | auto& surface = slot->Surfaces[i]; |
| 108 | areaSum += surface.Size.MulValues(); |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | // Insert only non-empty surfaces |
| 113 | if (areaSum > ZeroTolerance) |
| 114 | { |
| 115 | // Pack all surfaces into atlas |
| 116 | float atlasSize = Math::Sqrt(areaSum) * 1.02f; |
| 117 | int32 triesLeft = 10; |
| 118 | while (triesLeft--) |
| 119 | { |
| 120 | bool failed = false; |
| 121 | const float chartsPadding = (8.0f / 1024.0f) * atlasSize; |
| 122 | LightmapUVsPacker packer(atlasSize, chartsPadding); |
| 123 | for (int32 slotIndex = 0; slotIndex < Slots.Count(); slotIndex++) |
| 124 | { |
| 125 | auto& slot = Slots[slotIndex]; |
| 126 | for (int32 i = 0; i < slot->Surfaces.Count(); i++) |
| 127 | { |
| 128 | auto& surface = slot->Surfaces[i]; |
| 129 | if (packer.Insert(&surface) == nullptr) |
| 130 | { |
| 131 | // Failed to insert surface, increase atlas size and try again |
| 132 | atlasSize *= 1.5f; |
| 133 | failed = true; |
| 134 | break; |
| 135 | } |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | if (!failed) |
| 140 | break; |
| 141 | } |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | // Transfer data (use 1-1 mesh-material slot linkage) |
| 146 | modelData.MinScreenSize = 0.0f; |
| 147 | modelData.LODs.Resize(1); |
| 148 | modelData.LODs[0].Meshes.Resize(Slots.Count()); |
| 149 | modelData.Materials.Resize(Slots.Count()); |