void EntityList::sort(Camera& cam, const bool do_reflect) { /// @author ZZ /// @details This function orders the entity list based on distance from camera, /// which is needed for reflections to properly clip themselves. /// Order from closest to farthest assert(list.size() <= CAPACITY); Vector3f vcam; mat_getCamForward(cam.getViewMatrix(), vcam); // Figure the distance of each. size_t count = 0; for (size_t i = 0; i < list.size(); ++i) { Vector3f vtmp; if (ParticleRef::Invalid == list[i].iprt && ObjectRef::Invalid != list[i].iobj) { Vector3f pos_tmp; ObjectRef iobj = list[i].iobj; if (do_reflect) { pos_tmp = mat_getTranslate(_currentModule->getObjectHandler().get(iobj)->inst.getReflectionMatrix()); } else { pos_tmp = mat_getTranslate(_currentModule->getObjectHandler().get(iobj)->inst.getMatrix()); } vtmp = pos_tmp - cam.getPosition(); } else if (ObjectRef::Invalid == list[i].iobj && list[i].iprt != ParticleRef::Invalid) { ParticleRef iprt = list[i].iprt; if (do_reflect) { vtmp = ParticleHandler::get()[iprt]->inst.pos - cam.getPosition(); } else { vtmp = ParticleHandler::get()[iprt]->inst.ref_pos - cam.getPosition(); } } else { continue; } // If theangle between this vector and the camera vector is greater than 90 degrees, // then set the distance to positive infinity. float dist = vtmp.dot(vcam); if (dist > 0) { list[count].iobj = list[i].iobj; list[count].iprt = list[i].iprt; list[count].dist = dist; count++; } } // use qsort to sort the list in-place if (count > 1) { std::sort(list.begin(), list.end(), Compare()); } }
gfx_rv EntityList::sort(Camera& cam, const bool do_reflect) { /// @author ZZ /// @details This function orders the entity list based on distance from camera, /// which is needed for reflections to properly clip themselves. /// Order from closest to farthest if (_size >= CAPACITY) { throw std::logic_error("invalid entity list size"); } Vector3f vcam; mat_getCamForward(cam.getViewMatrix(), vcam); // Figure the distance of each. size_t count = 0; for (size_t i = 0; i < _size; ++i) { Vector3f vtmp; if (INVALID_PRT_REF == _lst[i].iprt && INVALID_CHR_REF != _lst[i].ichr) { Vector3f pos_tmp; CHR_REF iobj = _lst[i].ichr; if (do_reflect) { pos_tmp = mat_getTranslate(_currentModule->getObjectHandler().get(iobj)->inst.ref.matrix); } else { pos_tmp = mat_getTranslate(_currentModule->getObjectHandler().get(iobj)->inst.matrix); } vtmp = pos_tmp - cam.getPosition(); } else if (INVALID_CHR_REF == _lst[i].ichr && _lst[i].iprt != INVALID_PRT_REF) { PRT_REF iprt = _lst[i].iprt; if (do_reflect) { vtmp = ParticleHandler::get()[iprt]->inst.pos - cam.getPosition(); } else { vtmp = ParticleHandler::get()[iprt]->inst.ref_pos - cam.getPosition(); } } else { continue; } float dist = vtmp.dot(vcam); if (dist > 0) { _lst[count].ichr = _lst[i].ichr; _lst[count].iprt = _lst[i].iprt; _lst[count].dist = dist; count++; } } _size = count; // use qsort to sort the list in-place if (_size > 1) { qsort(_lst, _size, sizeof(element_t), element_t::cmp); } return gfx_success; }