LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp) { LLFace *face; face = new LLFace(this, mVObjp); face->setTEOffset(mFaces.size()); face->setTexture(texturep); face->setNormalMap(normalp); face->setSpecularMap(specularp); face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep)); mFaces.push_back(face); if (isState(UNLIT)) { face->setState(LLFace::FULLBRIGHT); } return face; }
LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerImage *texturep) { LLMemType mt(LLMemType::MTYPE_DRAWABLE); LLFace *face; face = new LLFace(this, mVObjp); face->setTEOffset(mFaces.size()); face->setTexture(texturep); face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep)); mFaces.push_back(face); if (isState(UNLIT)) { face->setState(LLFace::FULLBRIGHT); } return face; }
LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep) { LLMemType mt(LLMemType::MTYPE_DRAWABLE); LLFace *face = new LLFace(this, mVObjp); if (!face) llerrs << "Allocating new Face: " << mFaces.size() << llendl; if (face) { mFaces.push_back(face); if (poolp) { face->setPool(poolp, texturep); } if (isState(UNLIT)) { face->setState(LLFace::FULLBRIGHT); } } return face; }
LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep) { LLFace *face; { LLFastTimer t(FTM_ALLOCATE_FACE); face = new LLFace(this, mVObjp); } face->setTEOffset(mFaces.size()); face->setTexture(texturep); face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep)); mFaces.push_back(face); if (isState(UNLIT)) { face->setState(LLFace::FULLBRIGHT); } return face; }
void LLParticlePartition::getGeometry(LLSpatialGroup* group) { LLFastTimer ftm(FTM_REBUILD_PARTICLE_GEOM); std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater()); U32 index_count = 0; U32 vertex_count = 0; group->clearDrawMap(); LLVertexBuffer* buffer = group->mVertexBuffer; LLStrider<U16> indicesp; LLStrider<LLVector4a> verticesp; LLStrider<LLVector3> normalsp; LLStrider<LLVector2> texcoordsp; LLStrider<LLColor4U> colorsp; LLStrider<LLColor4U> emissivep; buffer->getVertexStrider(verticesp); buffer->getNormalStrider(normalsp); buffer->getColorStrider(colorsp); buffer->getEmissiveStrider(emissivep); LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass]; for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i) { LLFace* facep = *i; LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject(); if (!facep->isState(LLFace::PARTICLE)) { //set the indices of this face S32 idx = LLVOPartGroup::findAvailableVBSlot(); if (idx >= 0) { facep->setGeomIndex(idx*4); facep->setIndicesIndex(idx*6); facep->setVertexBuffer(LLVOPartGroup::sVB); facep->setPoolType(LLDrawPool::POOL_ALPHA); facep->setState(LLFace::PARTICLE); } else { continue; //out of space in particle buffer } } S32 geom_idx = (S32) facep->getGeomIndex(); LLStrider<U16> cur_idx = indicesp + facep->getIndicesStart(); LLStrider<LLVector4a> cur_vert = verticesp + geom_idx; LLStrider<LLVector3> cur_norm = normalsp + geom_idx; LLStrider<LLVector2> cur_tc = texcoordsp + geom_idx; LLStrider<LLColor4U> cur_col = colorsp + geom_idx; LLStrider<LLColor4U> cur_glow = emissivep + geom_idx; LLColor4U* start_glow = cur_glow.get(); object->getGeometry(facep->getTEOffset(), cur_vert, cur_norm, cur_tc, cur_col, cur_glow, cur_idx); BOOL has_glow = FALSE; if (cur_glow.get() != start_glow) { has_glow = TRUE; } llassert(facep->getGeomCount() == 4); llassert(facep->getIndicesCount() == 6); vertex_count += facep->getGeomCount(); index_count += facep->getIndicesCount(); S32 idx = draw_vec.size()-1; BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); F32 vsize = facep->getVirtualSize(); bool batched = false; U32 bf_src = LLRender::BF_SOURCE_ALPHA; U32 bf_dst = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; object->getBlendFunc(facep->getTEOffset(), bf_src, bf_dst); if (idx >= 0) { LLDrawInfo* info = draw_vec[idx]; if (info->mTexture == facep->getTexture() && info->mHasGlow == has_glow && info->mFullbright == fullbright && info->mBlendFuncDst == bf_dst && info->mBlendFuncSrc == bf_src) { if (draw_vec[idx]->mEnd == facep->getGeomIndex()-1) { batched = true; info->mCount += facep->getIndicesCount(); info->mEnd += facep->getGeomCount(); info->mVSize = llmax(draw_vec[idx]->mVSize, vsize); } else if (draw_vec[idx]->mStart == facep->getGeomIndex()+facep->getGeomCount()+1) { batched = true; info->mCount += facep->getIndicesCount(); info->mStart -= facep->getGeomCount(); info->mOffset = facep->getIndicesStart(); info->mVSize = llmax(draw_vec[idx]->mVSize, vsize); } } } if (!batched) { U32 start = facep->getGeomIndex(); U32 end = start + facep->getGeomCount()-1; U32 offset = facep->getIndicesStart(); U32 count = facep->getIndicesCount(); LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), //facep->getTexture(), buffer, fullbright); const LLVector4a* bounds = group->getBounds(); info->mExtents[0] = bounds[0]; info->mExtents[1] = bounds[1]; info->mVSize = vsize; info->mBlendFuncDst = bf_dst; info->mBlendFuncSrc = bf_src; info->mHasGlow = has_glow; info->mParticle = TRUE; draw_vec.push_back(info); //for alpha sorting facep->setDrawInfo(info); } if(facep->getGeomCount() > 0) { buffer->validateRange(facep->getGeomIndex(), facep->getGeomIndex() + facep->getGeomCount() - 1, facep->getIndicesCount(), facep->getIndicesStart()); } } mFaceList.clear(); }
BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) { LLFastTimer ftm(FTM_UPDATE_PARTICLES); dirtySpatialGroup(); S32 num_parts = mViewerPartGroupp->getCount(); LLFace *facep; LLSpatialGroup* group = drawable->getSpatialGroup(); if (!group && num_parts) { drawable->movePartition(); group = drawable->getSpatialGroup(); } if (group && group->isVisible()) { dirtySpatialGroup(TRUE); } if (!num_parts) { if (group && drawable->getNumFaces()) { group->setState(LLSpatialGroup::GEOM_DIRTY); } drawable->setNumFaces(0, NULL, getTEImage(0)); return TRUE; } if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES))) { return TRUE; } if (num_parts > drawable->getNumFaces()) { drawable->setNumFacesFast(num_parts+num_parts/4, NULL, getTEImage(0)); } F32 tot_area = 0; F32 max_area = LLViewerPartSim::getMaxPartCount() * MAX_PARTICLE_AREA_SCALE; F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio(); pixel_meter_ratio *= pixel_meter_ratio; LLViewerPartSim::checkParticleCount(mViewerPartGroupp->mParticles.size()) ; S32 count=0; mDepth = 0.f; S32 i = 0 ; LLVector3 camera_agent = getCameraPosition(); F32 max_scale = 0.f; for (i = 0 ; i < (S32)mViewerPartGroupp->mParticles.size(); i++) { const LLViewerPart *part = mViewerPartGroupp->mParticles[i]; //remember the largest particle max_scale = llmax(max_scale, part->mScale.mV[0], part->mScale.mV[1]); if (part->mFlags & LLPartData::LL_PART_RIBBON_MASK) { //include ribbon segment length in scale const LLVector3* pos_agent = NULL; if (part->mParent) { pos_agent = &(part->mParent->mPosAgent); } else if (part->mPartSourcep.notNull()) { pos_agent = &(part->mPartSourcep->mPosAgent); } if (pos_agent) { F32 dist = (*pos_agent-part->mPosAgent).length(); max_scale = llmax(max_scale, dist); } } LLVector3 part_pos_agent(part->mPosAgent); LLVector3 at(part_pos_agent - camera_agent); F32 camera_dist_squared = at.lengthSquared(); F32 inv_camera_dist_squared; if (camera_dist_squared > 1.f) inv_camera_dist_squared = 1.f / camera_dist_squared; else inv_camera_dist_squared = 1.f; llassert(llfinite(inv_camera_dist_squared)); llassert(!llisnan(inv_camera_dist_squared)); F32 area = part->mScale.mV[0] * part->mScale.mV[1] * inv_camera_dist_squared; tot_area = llmax(tot_area, area); if (tot_area > max_area) { break; } count++; facep = drawable->getFace(i); if (!facep) { LL_WARNS() << "No face found for index " << i << "!" << LL_ENDL; continue; } facep->setTEOffset(i); const F32 NEAR_PART_DIST_SQ = 5.f*5.f; // Only discard particles > 5 m from the camera const F32 MIN_PART_AREA = .005f*.005f; // only less than 5 mm x 5 mm at 1 m from camera if (camera_dist_squared > NEAR_PART_DIST_SQ && area < MIN_PART_AREA) { facep->setSize(0, 0); continue; } facep->setSize(4, 6); facep->setViewerObject(this); if (part->mFlags & LLPartData::LL_PART_EMISSIVE_MASK) { facep->setState(LLFace::FULLBRIGHT); } else { facep->clearState(LLFace::FULLBRIGHT); } facep->mCenterLocal = part->mPosAgent; facep->setFaceColor(part->mColor); facep->setTexture(part->mImagep); //check if this particle texture is replaced by a parcel media texture. if(part->mImagep.notNull() && part->mImagep->hasParcelMedia()) { part->mImagep->getParcelMedia()->addMediaToFace(facep) ; } mPixelArea = tot_area * pixel_meter_ratio; const F32 area_scale = 10.f; // scale area to increase priority a bit facep->setVirtualSize(mPixelArea*area_scale); } for (i = count; i < drawable->getNumFaces(); i++) { LLFace* facep = drawable->getFace(i); if (!facep) { LL_WARNS() << "No face found for index " << i << "!" << LL_ENDL; continue; } facep->setTEOffset(i); facep->setSize(0, 0); } //record max scale (used to stretch bounding box for visibility culling) mScale.set(max_scale, max_scale, max_scale); mDrawable->movePartition(); return TRUE; }
BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) { LLFastTimer ftm(LLFastTimer::FTM_UPDATE_PARTICLES); dirtySpatialGroup(); S32 num_parts = mViewerPartGroupp->getCount(); LLFace *facep; LLSpatialGroup* group = drawable->getSpatialGroup(); if (!group && num_parts) { drawable->movePartition(); group = drawable->getSpatialGroup(); } if (!num_parts) { if (group && drawable->getNumFaces()) { group->setState(LLSpatialGroup::GEOM_DIRTY); } drawable->setNumFaces(0, NULL, getTEImage(0)); LLPipeline::sCompiles++; return TRUE; } if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES))) { return TRUE; } if (num_parts > drawable->getNumFaces()) { drawable->setNumFacesFast(num_parts+num_parts/4, NULL, getTEImage(0)); } F32 tot_area = 0; F32 max_area = LLViewerPartSim::getMaxPartCount() * MAX_PARTICLE_AREA_SCALE; F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio(); pixel_meter_ratio *= pixel_meter_ratio; LLViewerPartSim::checkParticleCount(mViewerPartGroupp->mParticles.size()) ; S32 count=0; mDepth = 0.f; S32 i = 0 ; LLVector3 camera_agent = getCameraPosition(); for (i = 0 ; i < (S32)mViewerPartGroupp->mParticles.size(); i++) { const LLViewerPart *part = mViewerPartGroupp->mParticles[i]; LLVector3 part_pos_agent(part->mPosAgent); LLVector3 at(part_pos_agent - camera_agent); F32 camera_dist_squared = at.lengthSquared(); F32 inv_camera_dist_squared; if (camera_dist_squared > 1.f) inv_camera_dist_squared = 1.f / camera_dist_squared; else inv_camera_dist_squared = 1.f; F32 area = part->mScale.mV[0] * part->mScale.mV[1] * inv_camera_dist_squared; tot_area = llmax(tot_area, area); if (tot_area > max_area) { break; } count++; facep = drawable->getFace(i); if (!facep) { llwarns << "No face found for index " << i << "!" << llendl; continue; } facep->setTEOffset(i); const F32 NEAR_PART_DIST_SQ = 5.f*5.f; // Only discard particles > 5 m from the camera const F32 MIN_PART_AREA = .005f*.005f; // only less than 5 mm x 5 mm at 1 m from camera if (camera_dist_squared > NEAR_PART_DIST_SQ && area < MIN_PART_AREA) { facep->setSize(0, 0); continue; } facep->setSize(4, 6); facep->setViewerObject(this); if (part->mFlags & LLPartData::LL_PART_EMISSIVE_MASK) { facep->setState(LLFace::FULLBRIGHT); } else { facep->clearState(LLFace::FULLBRIGHT); } facep->mCenterLocal = part->mPosAgent; facep->setFaceColor(part->mColor); facep->setTexture(part->mImagep); mPixelArea = tot_area * pixel_meter_ratio; const F32 area_scale = 10.f; // scale area to increase priority a bit facep->setVirtualSize(mPixelArea*area_scale); } for (i = count; i < drawable->getNumFaces(); i++) { LLFace* facep = drawable->getFace(i); if (!facep) { llwarns << "No face found for index " << i << "!" << llendl; continue; } facep->setTEOffset(i); facep->setSize(0, 0); } mDrawable->movePartition(); LLPipeline::sCompiles++; return TRUE; }
void LLViewerJointAttachment::setupDrawable(LLViewerObject *object) { if (!object->mDrawable) return; if (object->mDrawable->isActive()) { object->mDrawable->makeStatic(FALSE); } object->mDrawable->mXform.setParent(getXform()); // LLViewerJointAttachment::lazyAttach object->mDrawable->makeActive(); LLVector3 current_pos = object->getRenderPosition(); LLQuaternion current_rot = object->getRenderRotation(); LLQuaternion attachment_pt_inv_rot = ~(getWorldRotation()); current_pos -= getWorldPosition(); current_pos.rotVec(attachment_pt_inv_rot); current_rot = current_rot * attachment_pt_inv_rot; object->mDrawable->mXform.setPosition(current_pos); object->mDrawable->mXform.setRotation(current_rot); gPipeline.markMoved(object->mDrawable); gPipeline.markTextured(object->mDrawable); // face may need to change draw pool to/from POOL_HUD object->mDrawable->setState(LLDrawable::USE_BACKLIGHT); if(mIsHUDAttachment) { for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++) { LLFace *face = object->mDrawable->getFace(face_num); if (face) { face->setState(LLFace::HUD_RENDER); } } } LLViewerObject::const_child_list_t& child_list = object->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); iter != child_list.end(); ++iter) { LLViewerObject* childp = *iter; if (childp && childp->mDrawable.notNull()) { childp->mDrawable->setState(LLDrawable::USE_BACKLIGHT); gPipeline.markTextured(childp->mDrawable); // face may need to change draw pool to/from POOL_HUD gPipeline.markMoved(childp->mDrawable); if(mIsHUDAttachment) { for (S32 face_num = 0; face_num < childp->mDrawable->getNumFaces(); face_num++) { LLFace * face = childp->mDrawable->getFace(face_num); if (face) { face->setState(LLFace::HUD_RENDER); } } } } } }
void LLParticlePartition::getGeometry(LLSpatialGroup* group) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); LLFastTimer ftm(FTM_REBUILD_PARTICLE_GEOM); std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater()); U32 index_count = 0; U32 vertex_count = 0; group->clearDrawMap(); LLVertexBuffer* buffer = group->mVertexBuffer; LLStrider<U16> indicesp; LLStrider<LLVector4a> verticesp; LLStrider<LLVector3> normalsp; LLStrider<LLVector2> texcoordsp; LLStrider<LLColor4U> colorsp; buffer->getVertexStrider(verticesp); buffer->getNormalStrider(normalsp); buffer->getColorStrider(colorsp); LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass]; for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i) { LLFace* facep = *i; LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject(); if (!facep->isState(LLFace::PARTICLE)) { //set the indices of this face S32 idx = LLVOPartGroup::findAvailableVBSlot(); if (idx >= 0) { facep->setGeomIndex(idx*4); facep->setIndicesIndex(idx*6); facep->setVertexBuffer(LLVOPartGroup::sVB); facep->setPoolType(LLDrawPool::POOL_ALPHA); facep->setState(LLFace::PARTICLE); } else { continue; //out of space in particle buffer } } S32 geom_idx = (S32) facep->getGeomIndex(); LLStrider<U16> cur_idx = indicesp + facep->getIndicesStart(); LLStrider<LLVector4a> cur_vert = verticesp + geom_idx; LLStrider<LLVector3> cur_norm = normalsp + geom_idx; LLStrider<LLVector2> cur_tc = texcoordsp + geom_idx; LLStrider<LLColor4U> cur_col = colorsp + geom_idx; object->getGeometry(facep->getTEOffset(), cur_vert, cur_norm, cur_tc, cur_col, cur_idx); llassert(facep->getGeomCount() == 4); llassert(facep->getIndicesCount() == 6); vertex_count += facep->getGeomCount(); index_count += facep->getIndicesCount(); S32 idx = draw_vec.size()-1; BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); F32 vsize = facep->getVirtualSize(); bool batched = false; if (idx >= 0 && draw_vec[idx]->mTexture == facep->getTexture() && draw_vec[idx]->mFullbright == fullbright) { if (draw_vec[idx]->mEnd == facep->getGeomIndex()-1) { batched = true; draw_vec[idx]->mCount += facep->getIndicesCount(); draw_vec[idx]->mEnd += facep->getGeomCount(); draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize); } else if (draw_vec[idx]->mStart == facep->getGeomIndex()+facep->getGeomCount()+1) { batched = true; draw_vec[idx]->mCount += facep->getIndicesCount(); draw_vec[idx]->mStart -= facep->getGeomCount(); draw_vec[idx]->mOffset = facep->getIndicesStart(); draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize); } } if (!batched) { U32 start = facep->getGeomIndex(); U32 end = start + facep->getGeomCount()-1; U32 offset = facep->getIndicesStart(); U32 count = facep->getIndicesCount(); LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), //facep->getTexture(), buffer, fullbright); info->mExtents[0] = group->mObjectExtents[0]; info->mExtents[1] = group->mObjectExtents[1]; info->mVSize = vsize; draw_vec.push_back(info); //for alpha sorting facep->setDrawInfo(info); } } mFaceList.clear(); }