void CToyUtil::CalculateVisibleAreas() { AABB aabbExpand(Vector(-m_flNeighborDistance, -m_flNeighborDistance, -m_flNeighborDistance)/2, Vector(m_flNeighborDistance, m_flNeighborDistance, m_flNeighborDistance)/2); // First auto-detect neighbors. Naive O(n(n-1)/2) distance check. for (size_t i = 0; i < m_asSceneAreas.size(); i++) { // We can skip j <= i since we add neighbors reciprocally for (size_t j = i+1; j < m_asSceneAreas.size(); j++) { // Instead of finding the actual distance, just expand each box by m_flNeighborDistance/2 in every direction and test intersection. It's easier! AABB aabbBounds1 = m_asSceneAreas[i].m_aabbArea + aabbExpand; AABB aabbBounds2 = m_asSceneAreas[j].m_aabbArea + aabbExpand; if (aabbBounds1.Intersects(aabbBounds2)) { AddSceneAreaNeighbor(i, j); AddSceneAreaNeighbor(j, i); continue; } } } for (size_t i = 0; i < m_asSceneAreas.size(); i++) { for (size_t j = 0; j < m_asSceneAreas[i].m_aiNeighboringAreas.size(); j++) { size_t iNeighbor = m_asSceneAreas[i].m_aiNeighboringAreas[j]; // I can always see my neighbors AddSceneAreaVisible(i, iNeighbor); AddSceneAreaVisible(iNeighbor, i); AddVisibleNeighbors(i, iNeighbor); } } }
uint32_t render(const float* _mtxView, const float* _eye, uint32_t _first, uint32_t _max, ParticleSort* _outSort, PosColorTexCoord0Vertex* _outVertices) { bx::EaseFn easeRgba = s_easeFunc[m_uniforms.m_easeRgba]; bx::EaseFn easePos = s_easeFunc[m_uniforms.m_easePos]; bx::EaseFn easeBlend = s_easeFunc[m_uniforms.m_easeBlend]; bx::EaseFn easeScale = s_easeFunc[m_uniforms.m_easeScale]; Aabb aabb = { { bx::huge, bx::huge, bx::huge }, { -bx::huge, -bx::huge, -bx::huge }, }; for (uint32_t jj = 0, num = m_num, current = _first ; jj < num && current < _max ; ++jj, ++current ) { const Particle& particle = m_particles[jj]; const float ttPos = easePos(particle.life); const float ttScale = easeScale(particle.life); const float ttBlend = bx::fsaturate(easeBlend(particle.life) ); const float ttRgba = bx::fsaturate(easeRgba(particle.life) ); float p0[3]; bx::vec3Lerp(p0, particle.start, particle.end[0], ttPos); float p1[3]; bx::vec3Lerp(p1, particle.end[0], particle.end[1], ttPos); float pos[3]; bx::vec3Lerp(pos, p0, p1, ttPos); ParticleSort& sort = _outSort[current]; float tmp[3]; bx::vec3Sub(tmp, _eye, pos); sort.dist = bx::fsqrt(bx::vec3Dot(tmp, tmp) ); sort.idx = current; uint32_t idx = uint32_t(ttRgba*4); float ttmod = bx::fmod(ttRgba, 0.25f)/0.25f; uint32_t rgbaStart = particle.rgba[idx]; uint32_t rgbaEnd = particle.rgba[idx+1]; float rr = bx::flerp( ( (uint8_t*)&rgbaStart)[0], ( (uint8_t*)&rgbaEnd)[0], ttmod)/255.0f; float gg = bx::flerp( ( (uint8_t*)&rgbaStart)[1], ( (uint8_t*)&rgbaEnd)[1], ttmod)/255.0f; float bb = bx::flerp( ( (uint8_t*)&rgbaStart)[2], ( (uint8_t*)&rgbaEnd)[2], ttmod)/255.0f; float aa = bx::flerp( ( (uint8_t*)&rgbaStart)[3], ( (uint8_t*)&rgbaEnd)[3], ttmod)/255.0f; float blend = bx::flerp(particle.blendStart, particle.blendEnd, ttBlend); float scale = bx::flerp(particle.scaleStart, particle.scaleEnd, ttScale); uint32_t abgr = toAbgr(rr, gg, bb, aa); float udir[3] = { _mtxView[0]*scale, _mtxView[4]*scale, _mtxView[8]*scale }; float vdir[3] = { _mtxView[1]*scale, _mtxView[5]*scale, _mtxView[9]*scale }; PosColorTexCoord0Vertex* vertex = &_outVertices[current*4]; bx::vec3Sub(tmp, pos, udir); bx::vec3Sub(&vertex->m_x, tmp, vdir); aabbExpand(aabb, &vertex->m_x); vertex->m_abgr = abgr; vertex->m_u = 0.0f; vertex->m_v = 0.0f; vertex->m_blend = blend; ++vertex; bx::vec3Add(tmp, pos, udir); bx::vec3Sub(&vertex->m_x, tmp, vdir); aabbExpand(aabb, &vertex->m_x); vertex->m_abgr = abgr; vertex->m_u = 1.0f; vertex->m_v = 0.0f; vertex->m_blend = blend; ++vertex; bx::vec3Add(tmp, pos, udir); bx::vec3Add(&vertex->m_x, tmp, vdir); aabbExpand(aabb, &vertex->m_x); vertex->m_abgr = abgr; vertex->m_u = 1.0f; vertex->m_v = 1.0f; vertex->m_blend = blend; ++vertex; bx::vec3Sub(tmp, pos, udir); bx::vec3Add(&vertex->m_x, tmp, vdir); aabbExpand(aabb, &vertex->m_x); vertex->m_abgr = abgr; vertex->m_u = 0.0f; vertex->m_v = 1.0f; vertex->m_blend = blend; ++vertex; } m_aabb = aabb; return m_num; }