void LLSpatialBridge::updateSpatialExtents() { LLSpatialGroup* root = (LLSpatialGroup*) mOctree->getListener(0); { LLFastTimer ftm(LLFastTimer::FTM_CULL_REBOUND); root->rebound(); } LLXformMatrix* mat = mDrawable->getXform(); LLVector3 offset = root->mBounds[0]; LLVector3 size = root->mBounds[1]; LLVector3 center = LLVector3(0,0,0) * mat->getWorldMatrix(); LLQuaternion rotation = LLQuaternion(mat->getWorldMatrix()); offset *= rotation; center += offset; LLVector3 v[4]; //get 4 corners of bounding box v[0] = (size * rotation); v[1] = (LLVector3(-size.mV[0], -size.mV[1], size.mV[2]) * rotation); v[2] = (LLVector3(size.mV[0], -size.mV[1], -size.mV[2]) * rotation); v[3] = (LLVector3(-size.mV[0], size.mV[1], -size.mV[2]) * rotation); LLVector3& newMin = mExtents[0]; LLVector3& newMax = mExtents[1]; newMin = newMax = center; for (U32 i = 0; i < 4; i++) { for (U32 j = 0; j < 3; j++) { F32 delta = fabsf(v[i].mV[j]); F32 min = center.mV[j] - delta; F32 max = center.mV[j] + delta; if (min < newMin.mV[j]) { newMin.mV[j] = min; } if (max > newMax.mV[j]) { newMax.mV[j] = max; } } } LLVector3 diagonal = newMax - newMin; mRadius = diagonal.magVec() * 0.5f; mPositionGroup.setVec((newMin + newMax) * 0.5f); updateBinRadius(); }
void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results, BOOL for_select) { if (!gPipeline.hasRenderType(mDrawableType)) { return; } //HACK don't draw attachments for avatars that haven't been visible in more than a frame LLViewerObject *vobj = mDrawable->getVObj(); if (vobj && vobj->isAttachment() && !vobj->isHUDAttachment()) { LLDrawable* av; LLDrawable* parent = mDrawable->getParent(); if (parent) { LLViewerObject* objparent = parent->getVObj(); av = objparent->mDrawable; LLSpatialGroup* group = av->getSpatialGroup(); BOOL impostor = FALSE; BOOL loaded = FALSE; if (objparent->isAvatar()) { LLVOAvatar* avatarp = (LLVOAvatar*) objparent; if (avatarp->isVisible()) { impostor = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isImpostor(); loaded = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isFullyLoaded(); } else { return; } } if (!group || LLDrawable::getCurrentFrame() - av->mVisible > 1 || impostor || !loaded) { return; } } } LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); group->rebound(); LLVector4a center; center.setAdd(mExtents[0], mExtents[1]); center.mul(0.5f); LLVector4a size; size.setSub(mExtents[1], mExtents[0]); size.mul(0.5f); if ((LLPipeline::sShadowRender && camera_in.AABBInFrustum(center, size)) || LLPipeline::sImpostorRender || (camera_in.AABBInFrustumNoFarClip(center, size) && AABBSphereIntersect(mExtents[0], mExtents[1], camera_in.getOrigin(), camera_in.mFrustumCornerDist))) { if (!LLPipeline::sImpostorRender && !LLPipeline::sShadowRender && LLPipeline::calcPixelArea(center, size, camera_in) < FORCE_INVISIBLE_AREA) { return; } LLDrawable::setVisible(camera_in); if (for_select) { results->push_back(mDrawable); if (mDrawable->getVObj()) { LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); iter != child_list.end(); iter++) { LLViewerObject* child = *iter; LLDrawable* drawable = child->mDrawable; results->push_back(drawable); } } } else { LLCamera trans_camera = transformCamera(camera_in); LLOctreeMarkNotCulled culler(&trans_camera); culler.traverse(mOctree); } } }
void LLSpatialBridge::updateSpatialExtents() { LLSpatialGroup* root = (LLSpatialGroup*) mOctree->getListener(0); { LLFastTimer ftm(FTM_CULL_REBOUND); root->rebound(); } LLVector4a offset; LLVector4a size = root->mBounds[1]; //VECTORIZE THIS LLMatrix4a mat; mat.loadu(mDrawable->getXform()->getWorldMatrix()); LLVector4a t; t.splat(0.f); LLVector4a center; mat.affineTransform(t, center); mat.rotate(root->mBounds[0], offset); center.add(offset); LLVector4a v[4]; //get 4 corners of bounding box mat.rotate(size,v[0]); LLVector4a scale; scale.set(-1.f, -1.f, 1.f); scale.mul(size); mat.rotate(scale, v[1]); scale.set(1.f, -1.f, -1.f); scale.mul(size); mat.rotate(scale, v[2]); scale.set(-1.f, 1.f, -1.f); scale.mul(size); mat.rotate(scale, v[3]); LLVector4a& newMin = mExtents[0]; LLVector4a& newMax = mExtents[1]; newMin = newMax = center; for (U32 i = 0; i < 4; i++) { LLVector4a delta; delta.setAbs(v[i]); LLVector4a min; min.setSub(center, delta); LLVector4a max; max.setAdd(center, delta); newMin.setMin(newMin, min); newMax.setMax(newMax, max); } LLVector4a diagonal; diagonal.setSub(newMax, newMin); mRadius = diagonal.getLength3().getF32() * 0.5f; mPositionGroup.setAdd(newMin,newMax); mPositionGroup.mul(0.5f); updateBinRadius(); }