Fix for copying of tetrahedrons in place of mesh LODs.
Fix for bad tetrahedron bounding box. Bad fix for simultaneous loading of multiple LODs.master
parent
5f44d4398a
commit
62233f2246
|
|
@ -1676,6 +1676,7 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge
|
|||
mFaceMask = 0x0;
|
||||
mDetail = detail;
|
||||
mSculptLevel = -2;
|
||||
mIsTetrahedron = FALSE;
|
||||
mLODScaleBias.setVec(1,1,1);
|
||||
|
||||
// set defaults
|
||||
|
|
@ -1905,7 +1906,7 @@ BOOL LLVolume::createVolumeFacesFromFile(const std::string& file_name)
|
|||
BOOL LLVolume::createVolumeFacesFromStream(std::istream& is)
|
||||
{
|
||||
mSculptLevel = -1; // default is an error occured
|
||||
|
||||
|
||||
LLSD header;
|
||||
{
|
||||
if (!LLSDSerialize::deserialize(header, is, 1024*1024*1024))
|
||||
|
|
@ -2048,6 +2049,11 @@ BOOL LLVolume::createVolumeFacesFromStream(std::istream& is)
|
|||
{
|
||||
U32 face_count = mdl.size();
|
||||
|
||||
if (face_count == 0)
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
}
|
||||
|
||||
mVolumeFaces.resize(face_count);
|
||||
|
||||
for (U32 i = 0; i < face_count; ++i)
|
||||
|
|
@ -2063,8 +2069,9 @@ BOOL LLVolume::createVolumeFacesFromStream(std::istream& is)
|
|||
|
||||
//copy out indices
|
||||
face.mIndices.resize(idx.size()/2);
|
||||
if (idx.empty())
|
||||
if (idx.empty() || face.mIndices.size() < 3)
|
||||
{ //why is there an empty index list?
|
||||
llerrs <<"WTF?" << llendl;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -2150,6 +2157,11 @@ void tetrahedron_set_normal(LLVolumeFace::VertexData* cv)
|
|||
cv[2].mNormal = nrm;
|
||||
}
|
||||
|
||||
BOOL LLVolume::isTetrahedron()
|
||||
{
|
||||
return mIsTetrahedron;
|
||||
}
|
||||
|
||||
void LLVolume::makeTetrahedron()
|
||||
{
|
||||
mVolumeFaces.clear();
|
||||
|
|
@ -2165,6 +2177,9 @@ void LLVolume::makeTetrahedron()
|
|||
LLVector3(x,-x,-x)
|
||||
};
|
||||
|
||||
face.mExtents[0].setVec(-x,-x,-x);
|
||||
face.mExtents[1].setVec(x,x,x);
|
||||
|
||||
LLVolumeFace::VertexData cv[3];
|
||||
|
||||
//set texture coordinates
|
||||
|
|
@ -2225,12 +2240,19 @@ void LLVolume::makeTetrahedron()
|
|||
|
||||
mVolumeFaces.push_back(face);
|
||||
mSculptLevel = 0;
|
||||
mIsTetrahedron = TRUE;
|
||||
}
|
||||
|
||||
void LLVolume::copyVolumeFaces(LLVolume* volume)
|
||||
{
|
||||
if (volume->isTetrahedron())
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
}
|
||||
|
||||
mVolumeFaces = volume->mVolumeFaces;
|
||||
mSculptLevel = 0;
|
||||
mIsTetrahedron = FALSE;
|
||||
}
|
||||
|
||||
S32 const LL_SCULPT_MESH_MAX_FACES = 8;
|
||||
|
|
@ -2615,6 +2637,11 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components,
|
|||
LLMemType m1(LLMemType::MTYPE_VOLUME);
|
||||
U8 sculpt_type = mParams.getSculptType();
|
||||
|
||||
if (sculpt_type & LL_SCULPT_TYPE_MASK == LL_SCULPT_TYPE_MESH)
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
}
|
||||
|
||||
BOOL data_is_empty = FALSE;
|
||||
|
||||
if (sculpt_width == 0 || sculpt_height == 0 || sculpt_components < 3 || sculpt_data == NULL)
|
||||
|
|
|
|||
|
|
@ -904,7 +904,8 @@ public:
|
|||
BOOL isUnique() const { return mUnique; }
|
||||
|
||||
S32 getSculptLevel() const { return mSculptLevel; }
|
||||
|
||||
void setSculptLevel(S32 level) { mSculptLevel = level; }
|
||||
|
||||
S32 *getTriangleIndices(U32 &num_indices) const;
|
||||
|
||||
// returns number of triangle indeces required for path/profile mesh
|
||||
|
|
@ -970,11 +971,13 @@ public:
|
|||
virtual BOOL createVolumeFacesFromFile(const std::string& file_name);
|
||||
virtual BOOL createVolumeFacesFromStream(std::istream& is);
|
||||
virtual void makeTetrahedron();
|
||||
virtual BOOL isTetrahedron();
|
||||
|
||||
protected:
|
||||
BOOL mUnique;
|
||||
F32 mDetail;
|
||||
S32 mSculptLevel;
|
||||
BOOL mIsTetrahedron;
|
||||
|
||||
LLVolumeParams mParams;
|
||||
LLPath *mPathp;
|
||||
|
|
|
|||
|
|
@ -375,6 +375,19 @@ F32 LLVolumeLODGroup::getVolumeScaleFromDetail(const S32 detail)
|
|||
return mDetailScales[detail];
|
||||
}
|
||||
|
||||
S32 LLVolumeLODGroup::getVolumeDetailFromScale(const F32 detail)
|
||||
{
|
||||
for (S32 i = 1; i < 4; i++)
|
||||
{
|
||||
if (mDetailScales[i] > detail)
|
||||
{
|
||||
return i-1;
|
||||
}
|
||||
}
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
F32 LLVolumeLODGroup::dump()
|
||||
{
|
||||
F32 usage = 0.f;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ public:
|
|||
static S32 getDetailFromTan(const F32 tan_angle);
|
||||
static void getDetailProximity(const F32 tan_angle, F32 &to_lower, F32& to_higher);
|
||||
static F32 getVolumeScaleFromDetail(const S32 detail);
|
||||
static S32 getVolumeDetailFromScale(F32 scale);
|
||||
|
||||
LLVolume* refLOD(const S32 detail);
|
||||
BOOL derefLOD(LLVolume *volumep);
|
||||
|
|
|
|||
|
|
@ -163,7 +163,6 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
|
|||
mRelativeXformInvTrans.setIdentity();
|
||||
|
||||
mLOD = MIN_LOD;
|
||||
mMeshSculptLevel = -2;
|
||||
mTextureAnimp = NULL;
|
||||
mVObjRadius = LLVector3(1,1,0.5f).length();
|
||||
mNumFaces = 0;
|
||||
|
|
@ -682,25 +681,7 @@ void LLVOVolume::updateTextureVirtualSize()
|
|||
LLUUID id = sculpt_params->getSculptTexture();
|
||||
U8 sculpt_type = sculpt_params->getSculptType();
|
||||
|
||||
if ((sculpt_type & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
|
||||
// mesh is a mesh
|
||||
{
|
||||
if (mMeshSculptLevel == -2)
|
||||
{
|
||||
// get the asset please
|
||||
gPipeline.loadMesh(this, id);
|
||||
/*gAssetStorage->getAssetData(id, LLAssetType::AT_MESH, (LLGetAssetCallback)NULL, NULL, TRUE);
|
||||
|
||||
if (gAssetStorage->hasLocalAsset(id, LLAssetType::AT_MESH))
|
||||
{
|
||||
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE);
|
||||
mSculptChanged = TRUE;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
// mesh is a sculptie
|
||||
if ((sculpt_type & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH)
|
||||
{
|
||||
mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
|
||||
|
||||
|
|
@ -902,14 +883,10 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms, const S32 detail, bool
|
|||
if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
|
||||
{
|
||||
if (getVolume()->getNumVolumeFaces() == 0)
|
||||
{
|
||||
//mesh is not loaded, request pipeline load this mesh
|
||||
{
|
||||
//load request not yet issued, request pipeline load this mesh
|
||||
LLUUID asset_id = volume_params.getSculptID();
|
||||
gPipeline.loadMesh(this, asset_id, detail);
|
||||
}
|
||||
else
|
||||
{
|
||||
mMeshSculptLevel = 1;
|
||||
gPipeline.loadMesh(this, asset_id, LLVolumeLODGroup::getVolumeDetailFromScale(getVolume()->getDetail()));
|
||||
}
|
||||
}
|
||||
else // otherwise is sculptie
|
||||
|
|
|
|||
|
|
@ -298,7 +298,6 @@ private:
|
|||
LLFrameTimer mTextureUpdateTimer;
|
||||
S32 mLOD;
|
||||
BOOL mLODChanged;
|
||||
S32 mMeshSculptLevel;
|
||||
BOOL mSculptChanged;
|
||||
F32 mSpotLightPriority;
|
||||
LLMatrix4 mRelativeXform;
|
||||
|
|
|
|||
|
|
@ -8913,23 +8913,29 @@ LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups()
|
|||
|
||||
void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail)
|
||||
{
|
||||
|
||||
if (detail < 0 || detail > 4)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
LLMutexLock lock(mMeshMutex);
|
||||
//add volume to list of loading meshes
|
||||
mesh_load_map::iterator iter = mLoadingMeshes.find(mesh_id);
|
||||
if (iter != mLoadingMeshes.end())
|
||||
mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_id);
|
||||
if (iter != mLoadingMeshes[detail].end())
|
||||
{ //request pending for this mesh, append volume id to list
|
||||
iter->second.insert(vobj->getID());
|
||||
return;
|
||||
}
|
||||
|
||||
//first request for this mesh
|
||||
mLoadingMeshes[mesh_id].insert(vobj->getID());
|
||||
mLoadingMeshes[detail][mesh_id].insert(vobj->getID());
|
||||
}
|
||||
|
||||
if (gAssetStorage->hasLocalAsset(mesh_id, LLAssetType::AT_MESH))
|
||||
{ //already have asset, load desired LOD in background
|
||||
mPendingMeshes.push_back(new LLMeshThread(mesh_id, vobj->getVolume()));
|
||||
mPendingMeshes.push_back(new LLMeshThread(mesh_id, vobj->getVolume(), detail));
|
||||
}
|
||||
else
|
||||
{ //fetch asset and load when done
|
||||
|
|
@ -8952,7 +8958,7 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail)
|
|||
for (S32 i = detail-1; i >= 0; --i)
|
||||
{
|
||||
LLVolume* lod = group->refLOD(i);
|
||||
if (lod && lod->getNumVolumeFaces() > 0)
|
||||
if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0)
|
||||
{
|
||||
volume->copyVolumeFaces(lod);
|
||||
group->derefLOD(lod);
|
||||
|
|
@ -8966,7 +8972,7 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail)
|
|||
for (S32 i = detail+1; i < 4; ++i)
|
||||
{
|
||||
LLVolume* lod = group->refLOD(i);
|
||||
if (lod && lod->getNumVolumeFaces() > 0)
|
||||
if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0)
|
||||
{
|
||||
volume->copyVolumeFaces(lod);
|
||||
group->derefLOD(lod);
|
||||
|
|
@ -8976,6 +8982,10 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail)
|
|||
group->derefLOD(lod);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
}
|
||||
|
||||
//nothing found, so make a tetrahedron
|
||||
volume->makeTetrahedron();
|
||||
|
|
@ -8992,12 +9002,22 @@ void LLPipeline::getMeshAssetCallback(LLVFS *vfs,
|
|||
}
|
||||
|
||||
|
||||
LLPipeline::LLMeshThread::LLMeshThread(LLUUID mesh_id, LLVolume* target)
|
||||
LLPipeline::LLMeshThread::LLMeshThread(LLUUID mesh_id, LLVolume* target, S32 detail)
|
||||
: LLThread("mesh_loading_thread")
|
||||
{
|
||||
mMeshID = mesh_id;
|
||||
mVolume = NULL;
|
||||
mDetail = target->getDetail();
|
||||
|
||||
if (detail == -1)
|
||||
{
|
||||
mDetailIndex = LLVolumeLODGroup::getVolumeDetailFromScale(target->getDetail());
|
||||
}
|
||||
else
|
||||
{
|
||||
mDetailIndex = detail;
|
||||
}
|
||||
|
||||
mTargetVolume = target;
|
||||
}
|
||||
|
||||
|
|
@ -9073,6 +9093,10 @@ void LLPipeline::notifyLoadedMeshes()
|
|||
|
||||
for (std::list<LLMeshThread*>::iterator iter = mLoadedMeshes.begin(); iter != mLoadedMeshes.end(); ++iter)
|
||||
{ //for each mesh done loading
|
||||
|
||||
|
||||
|
||||
|
||||
LLMeshThread* mesh = *iter;
|
||||
|
||||
if (!mesh->isStopped())
|
||||
|
|
@ -9081,10 +9105,12 @@ void LLPipeline::notifyLoadedMeshes()
|
|||
continue;
|
||||
}
|
||||
|
||||
//get list of objects waiting to be notified this mesh is loaded
|
||||
mesh_load_map::iterator obj_iter = mLoadingMeshes.find(mesh->mMeshID);
|
||||
S32 detail = mesh->mDetailIndex;
|
||||
|
||||
if (mesh->mVolume && obj_iter != mLoadingMeshes.end())
|
||||
//get list of objects waiting to be notified this mesh is loaded
|
||||
mesh_load_map::iterator obj_iter = mLoadingMeshes[detail].find(mesh->mMeshID);
|
||||
|
||||
if (mesh->mVolume && obj_iter != mLoadingMeshes[detail].end())
|
||||
{
|
||||
//make sure target volume is still valid
|
||||
BOOL valid = FALSE;
|
||||
|
|
@ -9109,6 +9135,10 @@ void LLPipeline::notifyLoadedMeshes()
|
|||
{
|
||||
mesh->mTargetVolume->copyVolumeFaces(mesh->mVolume);
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Mesh loading returned empty volume." << llendl;
|
||||
}
|
||||
|
||||
for (std::set<LLUUID>::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter)
|
||||
{
|
||||
|
|
@ -9120,7 +9150,7 @@ void LLPipeline::notifyLoadedMeshes()
|
|||
}
|
||||
}
|
||||
|
||||
mLoadingMeshes.erase(mesh->mMeshID);
|
||||
mLoadingMeshes[detail].erase(mesh->mMeshID);
|
||||
}
|
||||
|
||||
delete mesh;
|
||||
|
|
|
|||
|
|
@ -676,8 +676,9 @@ public:
|
|||
protected:
|
||||
std::vector<LLFace*> mSelectedFaces;
|
||||
|
||||
|
||||
typedef std::map<LLUUID, std::set<LLUUID> > mesh_load_map;
|
||||
mesh_load_map mLoadingMeshes;
|
||||
mesh_load_map mLoadingMeshes[4];
|
||||
|
||||
LLMutex* mMeshMutex;
|
||||
|
||||
|
|
@ -688,7 +689,8 @@ protected:
|
|||
LLVolume* mTargetVolume;
|
||||
LLUUID mMeshID;
|
||||
F32 mDetail;
|
||||
LLMeshThread(LLUUID mesh_id, LLVolume* target);
|
||||
S32 mDetailIndex;
|
||||
LLMeshThread(LLUUID mesh_id, LLVolume* target, S32 detail = -1);
|
||||
~LLMeshThread();
|
||||
void run();
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue