| 142 | } |
| 143 | |
| 144 | std::shared_ptr<Visual> MeshFactory::CreateTriangle(uint32_t numSamples, |
| 145 | float xExtent, float yExtent) |
| 146 | { |
| 147 | // Quantities derived from inputs. |
| 148 | float inv = 1.0f / (static_cast<float>(numSamples) - 1.0f); |
| 149 | uint32_t numVertices = numSamples * (numSamples + 1) / 2; |
| 150 | uint32_t numTriangles = (numSamples - 1) * (numSamples - 1); |
| 151 | |
| 152 | // Generate geometry. |
| 153 | auto vbuffer = CreateVBuffer(numVertices); |
| 154 | if (!vbuffer) |
| 155 | { |
| 156 | return nullptr; |
| 157 | } |
| 158 | |
| 159 | Vector3<float> pos{}; |
| 160 | Vector3<float> nor{ 0.0f, 0.0f, 1.0f }; |
| 161 | Vector3<float> tan{ 1.0f, 0.0f, 0.0f }; |
| 162 | Vector3<float> bit{ 0.0f, 1.0f, 0.0f }; // = Cross(nor,tan) |
| 163 | Vector2<float> tcd{}; |
| 164 | pos[2] = 0.0f; |
| 165 | for (uint32_t i1 = 0, i = 0; i1 < numSamples; ++i1) |
| 166 | { |
| 167 | tcd[1] = i1 * inv; |
| 168 | pos[1] = tcd[1] * yExtent; |
| 169 | for (uint32_t i0 = 0; i0 + i1 < numSamples; ++i0, ++i) |
| 170 | { |
| 171 | tcd[0] = i0 * inv; |
| 172 | pos[0] = tcd[0] * xExtent; |
| 173 | |
| 174 | SetPosition(i, pos); |
| 175 | SetNormal(i, nor); |
| 176 | SetTangent(i, tan); |
| 177 | SetBitangent(i, bit); |
| 178 | SetTCoord(i, tcd); |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | // Generate indices. |
| 183 | auto ibuffer = CreateIBuffer(numTriangles); |
| 184 | if (!ibuffer) |
| 185 | { |
| 186 | return nullptr; |
| 187 | } |
| 188 | |
| 189 | int32_t y0 = 0, y1 = numSamples; |
| 190 | uint32_t t = 0; |
| 191 | for (uint32_t i1 = 0; i1 < numSamples - 2; ++i1) |
| 192 | { |
| 193 | int32_t bot0 = y0, bot1 = bot0 + 1, top0 = y1, top1 = y1 + 1; |
| 194 | for (uint32_t i0 = 0; i0 + i1 < numSamples - 2; ++i0) |
| 195 | { |
| 196 | ibuffer->SetTriangle(t++, bot0, bot1, top0); |
| 197 | ibuffer->SetTriangle(t++, bot1, top1, top0); |
| 198 | bot0 = bot1++; |
| 199 | top0 = top1++; |
| 200 | } |
| 201 | ibuffer->SetTriangle(t++, bot0, bot1, top0); |
no test coverage detected