void LLDrawable::updateDistance(LLCamera& camera, bool force_update) { if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) { llwarns << "Attempted to update distance for non-world camera." << llendl; return; } //switch LOD with the spatial group to avoid artifacts //LLSpatialGroup* sg = getSpatialGroup(); LLVector3 pos; //if (!sg || sg->changeLOD()) { LLVOVolume* volume = getVOVolume(); if (volume) { if (getSpatialGroup()) { pos.set(getPositionGroup().getF32ptr()); } else { pos = getPositionAgent(); } if (isState(LLDrawable::HAS_ALPHA)) { for (S32 i = 0; i < getNumFaces(); i++) { LLFace* facep = getFace(i); if (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA) { LLVector4a box; box.setSub(facep->mExtents[1], facep->mExtents[0]); box.mul(0.25f); LLVector3 v = (facep->mCenterLocal-camera.getOrigin()); const LLVector3& at = camera.getAtAxis(); for (U32 j = 0; j < 3; j++) { v.mV[j] -= box[j] * at.mV[j]; } facep->mDistance = v * camera.getAtAxis(); } } } } else { pos = LLVector3(getPositionGroup().getF32ptr()); } pos -= camera.getOrigin(); mDistanceWRTCamera = llround(pos.magVec(), 0.01f); mVObjp->updateLOD(); } }
void LLDrawable::updateDistance(LLCamera& camera, bool force_update) { //switch LOD with the spatial group to avoid artifacts //LLSpatialGroup* sg = getSpatialGroup(); LLVector3 pos; //if (!sg || sg->changeLOD()) { LLVOVolume* volume = getVOVolume(); if (volume) { volume->updateRelativeXform(); pos = volume->getRelativeXform().getTranslation(); if (isStatic()) { pos += volume->getRegion()->getOriginAgent(); } if (isState(LLDrawable::HAS_ALPHA)) { for (S32 i = 0; i < getNumFaces(); i++) { LLFace* facep = getFace(i); if (facep->getPoolType() == LLDrawPool::POOL_ALPHA) { LLVector3 box = (facep->mExtents[1] - facep->mExtents[0]) * 0.25f; LLVector3 v = (facep->mCenterLocal-camera.getOrigin()); const LLVector3& at = camera.getAtAxis(); for (U32 j = 0; j < 3; j++) { v.mV[j] -= box.mV[j] * at.mV[j]; } facep->mDistance = v * camera.getAtAxis(); } } } } else { pos = LLVector3(getPositionGroup()); } pos -= camera.getOrigin(); mDistanceWRTCamera = llround(pos.magVec(), 0.01f); mVObjp->updateLOD(); } }
LLCamera LLSpatialBridge::transformCamera(LLCamera& camera) { LLCamera ret = camera; LLXformMatrix* mat = mDrawable->getXform(); LLVector3 center = LLVector3(0,0,0) * mat->getWorldMatrix(); LLQuaternion rotation = LLQuaternion(mat->getWorldMatrix()); LLVector3 delta = ret.getOrigin() - center; LLQuaternion rot = ~mat->getRotation(); delta *= rot; LLVector3 lookAt = ret.getAtAxis(); LLVector3 up_axis = ret.getUpAxis(); LLVector3 left_axis = ret.getLeftAxis(); lookAt *= rot; up_axis *= rot; left_axis *= rot; if (!delta.isFinite()) { delta.clearVec(); } ret.setOrigin(delta); ret.setAxes(lookAt, left_axis, up_axis); return ret; }
LLCamera LLSpatialBridge::transformCamera(LLCamera& camera) { LLCamera ret = camera; LLXformMatrix* mat = mDrawable->getXform(); const LLVector4a& center = mat->getWorldMatrix().getRow<3>(); LLQuaternion2 invRot; invRot.setConjugate( LLQuaternion2(mat->getRotation()) ); LLVector4a delta; delta.load3(ret.getOrigin().mV); delta.sub(center); LLVector4a lookAt; lookAt.load3(ret.getAtAxis().mV); LLVector4a up_axis; up_axis.load3(ret.getUpAxis().mV); LLVector4a left_axis; left_axis.load3(ret.getLeftAxis().mV); delta.setRotated(invRot, delta); lookAt.setRotated(invRot, lookAt); up_axis.setRotated(invRot, up_axis); left_axis.setRotated(invRot, left_axis); if (!delta.isFinite3()) { delta.clear(); } ret.setOrigin(LLVector3(delta.getF32ptr())); ret.setAxes(LLVector3(lookAt.getF32ptr()), LLVector3(left_axis.getF32ptr()), LLVector3(up_axis.getF32ptr())); return ret; }
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); } } }
//static void LLViewerCamera::updateFrustumPlanes(LLCamera& camera, BOOL ortho, BOOL zflip, BOOL no_hacks) { GLint* viewport = (GLint*) gGLViewport; GLdouble* model = gGLModelView; GLdouble* proj = gGLProjection; GLdouble objX,objY,objZ; LLVector3 frust[8]; if (no_hacks) { gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); frust[4].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); frust[5].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); frust[6].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); frust[7].setVec((F32)objX,(F32)objY,(F32)objZ); } else if (zflip) { gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); frust[4].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); frust[5].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); frust[6].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); frust[7].setVec((F32)objX,(F32)objY,(F32)objZ); for (U32 i = 0; i < 4; i++) { frust[i+4] = frust[i+4]-frust[i]; frust[i+4].normVec(); frust[i+4] = frust[i] + frust[i+4]*camera.getFar(); } } else { gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); if (ortho) { LLVector3 far_shift = camera.getAtAxis()*camera.getFar()*2.f; for (U32 i = 0; i < 4; i++) { frust[i+4] = frust[i] + far_shift; } } else { for (U32 i = 0; i < 4; i++) { LLVector3 vec = frust[i] - camera.getOrigin(); vec.normVec(); frust[i+4] = camera.getOrigin() + vec*camera.getFar(); } } } camera.calcAgentFrustumPlanes(frust); }
//static void LLViewerCamera::updateFrustumPlanes(LLCamera& camera, BOOL ortho, BOOL zflip, BOOL no_hacks) { LLVector3 frust[8]; LLRect view_port(gGLViewport[0],gGLViewport[1]+gGLViewport[3],gGLViewport[0]+gGLViewport[2],gGLViewport[1]); if (no_hacks) { gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mBottom,0.f),gGLModelView,gGLProjection,view_port,frust[0]); gGL.unprojectf(LLVector3(view_port.mRight,view_port.mBottom,0.f),gGLModelView,gGLProjection,view_port,frust[1]); gGL.unprojectf(LLVector3(view_port.mRight,view_port.mTop,0.f),gGLModelView,gGLProjection,view_port,frust[2]); gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mTop,0.f),gGLModelView,gGLProjection,view_port,frust[3]); gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mBottom,1.f),gGLModelView,gGLProjection,view_port,frust[4]); gGL.unprojectf(LLVector3(view_port.mRight,view_port.mBottom,1.f),gGLModelView,gGLProjection,view_port,frust[5]); gGL.unprojectf(LLVector3(view_port.mRight,view_port.mTop,1.f),gGLModelView,gGLProjection,view_port,frust[6]); gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mTop,1.f),gGLModelView,gGLProjection,view_port,frust[7]); } else if (zflip) { gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mTop,0.f),gGLModelView,gGLProjection,view_port,frust[0]); gGL.unprojectf(LLVector3(view_port.mRight,view_port.mTop,0.f),gGLModelView,gGLProjection,view_port,frust[1]); gGL.unprojectf(LLVector3(view_port.mRight,view_port.mBottom,0.f),gGLModelView,gGLProjection,view_port,frust[2]); gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mBottom,0.f),gGLModelView,gGLProjection,view_port,frust[3]); gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mTop,1.f),gGLModelView,gGLProjection,view_port,frust[4]); gGL.unprojectf(LLVector3(view_port.mRight,view_port.mTop,1.f),gGLModelView,gGLProjection,view_port,frust[5]); gGL.unprojectf(LLVector3(view_port.mRight,view_port.mBottom,1.f),gGLModelView,gGLProjection,view_port,frust[6]); gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mBottom,1.f),gGLModelView,gGLProjection,view_port,frust[7]); for (U32 i = 0; i < 4; i++) { frust[i+4] = frust[i+4]-frust[i]; frust[i+4].normVec(); frust[i+4] = frust[i] + frust[i+4]*camera.getFar(); } } else { gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mBottom,0.f),gGLModelView,gGLProjection,view_port,frust[0]); gGL.unprojectf(LLVector3(view_port.mRight,view_port.mBottom,0.f),gGLModelView,gGLProjection,view_port,frust[1]); gGL.unprojectf(LLVector3(view_port.mRight,view_port.mTop,0.f),gGLModelView,gGLProjection,view_port,frust[2]); gGL.unprojectf(LLVector3(view_port.mLeft,view_port.mTop,0.f),gGLModelView,gGLProjection,view_port,frust[3]); if (ortho) { LLVector3 far_shift = camera.getAtAxis()*camera.getFar()*2.f; for (U32 i = 0; i < 4; i++) { frust[i+4] = frust[i] + far_shift; } } else { for (U32 i = 0; i < 4; i++) { LLVector3 vec = frust[i] - camera.getOrigin(); vec.normVec(); frust[i+4] = camera.getOrigin() + vec*camera.getFar(); } } } camera.calcAgentFrustumPlanes(frust); }