| 239 | } |
| 240 | |
| 241 | void EveEllipseSet::RebuildGeometry( const EveUpdateContext& updateContext ) |
| 242 | { |
| 243 | m_indexCount = 0; |
| 244 | |
| 245 | BoundingSphereInitialize( m_boundingSphere ); |
| 246 | |
| 247 | const unsigned int segmentCount = std::max( 16u, std::min( 512u, m_ribbonSegmentCount ) ); |
| 248 | const unsigned int ellipseCount = static_cast<unsigned int>( m_ellipses.size() ); |
| 249 | const uint32_t vertexCount = ellipseCount * 2u * segmentCount; |
| 250 | const uint32_t indexCount = ellipseCount * 6u * segmentCount; |
| 251 | |
| 252 | if( ellipseCount == 0 ) |
| 253 | { |
| 254 | m_vertexBuffer = Tr2BufferAL(); |
| 255 | m_indexBuffer = Tr2BufferAL(); |
| 256 | m_geometryDirty = false; |
| 257 | return; |
| 258 | } |
| 259 | |
| 260 | TriPoolAllocator* allocator = Tr2Renderer::GetPoolAllocator(); |
| 261 | if( !allocator ) |
| 262 | { |
| 263 | return; |
| 264 | } |
| 265 | |
| 266 | auto vertices = reinterpret_cast<EllipseVertex*>( allocator->Allocate( vertexCount * sizeof( EllipseVertex ) ) ); |
| 267 | auto indices = reinterpret_cast<uint32_t*>( allocator->Allocate( indexCount * sizeof( uint32_t ) ) ); |
| 268 | if( !vertices || !indices ) |
| 269 | { |
| 270 | return; |
| 271 | } |
| 272 | |
| 273 | uint32_t vWrite = 0; |
| 274 | uint32_t iWrite = 0; |
| 275 | |
| 276 | // Screen-space billboard ribbon: store centerline + tangent; VS expands to pixel width at draw time. |
| 277 | for( auto& spec : m_ellipses ) |
| 278 | { |
| 279 | Vector3 semiMajorAxis, semiMinorAxis; |
| 280 | BuildOrbitEllipseAxes( *spec, semiMajorAxis, semiMinorAxis ); |
| 281 | |
| 282 | const Vector3& center = spec->m_center; |
| 283 | const float semiMajor = std::max( spec->m_semiMajor, 1e-4f ); |
| 284 | const float semiMinor = std::max( spec->m_semiMinor, 1e-4f ); |
| 285 | |
| 286 | const uint32_t baseVertexIndex = vWrite; |
| 287 | |
| 288 | for( unsigned int i = 0; i < segmentCount; ++i ) |
| 289 | { |
| 290 | const float angle = ( static_cast<float>( i ) / static_cast<float>( segmentCount ) ) * ( 2.f * TRI_PI ); |
| 291 | const float cosAngle = cosf( angle ); |
| 292 | const float sinAngle = sinf( angle ); |
| 293 | const Vector3 point = center + semiMajorAxis * ( semiMajor * cosAngle ) + semiMinorAxis * ( semiMinor * sinAngle ); |
| 294 | Vector3 tangent = semiMajorAxis * ( -semiMajor * sinAngle ) + semiMinorAxis * ( semiMinor * cosAngle ); |
| 295 | float tangentLength = Length( tangent ); |
| 296 | if( tangentLength < 1e-12f ) |
| 297 | { |
| 298 | tangent = semiMajorAxis; |
nothing calls this directly
no test coverage detected