secondlife/viewer#2421: Do not calculate and store silhouette edges for nearly every geometric prim with a corner
parent
5c16ae1375
commit
f23f28c8f9
|
|
@ -2710,7 +2710,7 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
|
|||
}
|
||||
|
||||
|
||||
bool LLVolume::isMeshAssetLoaded()
|
||||
bool LLVolume::isMeshAssetLoaded() const
|
||||
{
|
||||
return mIsMeshAssetLoaded;
|
||||
}
|
||||
|
|
@ -2733,7 +2733,7 @@ void LLVolume::setMeshAssetUnavaliable(bool unavaliable)
|
|||
}
|
||||
}
|
||||
|
||||
bool LLVolume::isMeshAssetUnavaliable()
|
||||
bool LLVolume::isMeshAssetUnavaliable() const
|
||||
{
|
||||
return mIsMeshAssetUnavaliable;
|
||||
}
|
||||
|
|
@ -3730,6 +3730,207 @@ S32 LLVolume::getNumTriangles(S32* vcount) const
|
|||
return triangle_count;
|
||||
}
|
||||
|
||||
void LLVolumeFace::generateSilhouetteEdge(const LLVolume* volume, std::vector<S32>& edge) const
|
||||
{
|
||||
llassert(edge.empty()); // edge is supposed to be a scratch array
|
||||
|
||||
if (volume->isMeshAssetLoaded()) { return; }
|
||||
|
||||
if (mTypeMask & CAP_MASK)
|
||||
{
|
||||
// Logic copied from LLVolumeFace::createCap - indicates a face created via
|
||||
// createUnCutCubeCap.
|
||||
if (!(mTypeMask & HOLLOW_MASK) &&
|
||||
!(mTypeMask & OPEN_MASK) &&
|
||||
((volume->getParams().getPathParams().getBegin()==0.0f)&&
|
||||
(volume->getParams().getPathParams().getEnd()==1.0f))&&
|
||||
(volume->getParams().getProfileParams().getCurveType()==LL_PCODE_PROFILE_SQUARE &&
|
||||
volume->getParams().getPathParams().getCurveType()==LL_PCODE_PATH_LINE)
|
||||
)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("llvfgse - CAP_MASK");
|
||||
|
||||
const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile;
|
||||
S32 grid_size = (profile.size()-1)/4;
|
||||
edge.resize(mNumIndices);
|
||||
llassert(edge.size() == 6*grid_size*grid_size);
|
||||
|
||||
S32 cur_edge = 0;
|
||||
for(S32 gx = 0;gx<grid_size;gx++)
|
||||
{
|
||||
for(S32 gy = 0;gy<grid_size;gy++)
|
||||
{
|
||||
if (mTypeMask & TOP_MASK)
|
||||
{
|
||||
|
||||
S32 edge_value = grid_size * 2 * gy + gx * 2;
|
||||
|
||||
if (gx > 0)
|
||||
{
|
||||
edge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
edge[cur_edge++] = -1; // Mark face to higlight it
|
||||
}
|
||||
|
||||
if (gy < grid_size - 1)
|
||||
{
|
||||
edge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
edge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
edge[cur_edge++] = edge_value;
|
||||
|
||||
if (gx < grid_size - 1)
|
||||
{
|
||||
edge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
edge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
if (gy > 0)
|
||||
{
|
||||
edge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
edge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
edge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 edge_value = grid_size * 2 * gy + gx * 2;
|
||||
|
||||
if (gy > 0)
|
||||
{
|
||||
edge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
edge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
if (gx < grid_size - 1)
|
||||
{
|
||||
edge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
edge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
edge[cur_edge++] = edge_value;
|
||||
|
||||
if (gy < grid_size - 1)
|
||||
{
|
||||
edge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
edge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
if (gx > 0)
|
||||
{
|
||||
edge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
edge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
edge[cur_edge++] = edge_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((mTypeMask & END_MASK) || (mTypeMask & SIDE_MASK))
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("llvfgse - END_MASK or SIDE_MASK");
|
||||
|
||||
edge.resize(mNumIndices);
|
||||
llassert(edge.size() == 6*(mNumS-1)*(mNumT-1));
|
||||
|
||||
S32 cur_edge = 0;
|
||||
const bool flat_face = mTypeMask & FLAT_MASK;
|
||||
for (S32 t = 0; t < (mNumT-1); t++)
|
||||
{
|
||||
for (S32 s = 0; s < (mNumS-1); s++)
|
||||
{
|
||||
// bottom left/top right neighbor face
|
||||
edge[cur_edge++] = (mNumS-1)*2*t+s*2+1;
|
||||
|
||||
if (t < mNumT-2)
|
||||
{ // top right/top left neighbor face
|
||||
edge[cur_edge++] = (mNumS-1)*2*(t+1)+s*2+1;
|
||||
}
|
||||
else if (mNumT <= 3 || volume->getPath().isOpen())
|
||||
{ // no neighbor
|
||||
edge[cur_edge++] = -1;
|
||||
}
|
||||
else
|
||||
{ // wrap on T
|
||||
edge[cur_edge++] = s*2+1;
|
||||
}
|
||||
|
||||
if (s > 0)
|
||||
{ // top left/bottom left neighbor face
|
||||
edge[cur_edge++] = (mNumS-1)*2*t+s*2-1;
|
||||
}
|
||||
else if (flat_face || volume->getProfile().isOpen())
|
||||
{ // no neighbor
|
||||
edge[cur_edge++] = -1;
|
||||
}
|
||||
else
|
||||
{ // wrap on S
|
||||
edge[cur_edge++] = (mNumS-1)*2*t+(mNumS-2)*2+1;
|
||||
}
|
||||
|
||||
if (t > 0)
|
||||
{ // bottom left/bottom right neighbor face
|
||||
edge[cur_edge++] = (mNumS-1)*2*(t-1)+s*2;
|
||||
}
|
||||
else if (mNumT <= 3 || volume->getPath().isOpen())
|
||||
{ // no neighbor
|
||||
edge[cur_edge++] = -1;
|
||||
}
|
||||
else
|
||||
{ // wrap on T
|
||||
edge[cur_edge++] = (mNumS-1)*2*(mNumT-2)+s*2;
|
||||
}
|
||||
|
||||
if (s < mNumS-2)
|
||||
{ // bottom right/top right neighbor face
|
||||
edge[cur_edge++] = (mNumS-1)*2*t+(s+1)*2;
|
||||
}
|
||||
else if (flat_face || volume->getProfile().isOpen())
|
||||
{ // no neighbor
|
||||
edge[cur_edge++] = -1;
|
||||
}
|
||||
else
|
||||
{ // wrap on S
|
||||
edge[cur_edge++] = (mNumS-1)*2*t;
|
||||
}
|
||||
|
||||
// top right/bottom left neighbor face
|
||||
edge[cur_edge++] = (mNumS-1)*2*t+s*2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_ERRS() << "Unknown/uninitialized face type!" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// generateSilhouetteVertices()
|
||||
|
|
@ -3761,6 +3962,13 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
|
|||
}
|
||||
|
||||
S32 cur_index = 0;
|
||||
// Scratch array for per-face silhouette edge information. This also has a
|
||||
// lot of dev-only debug information that we might not care about anymore.
|
||||
// (see DEBUG_SILHOUETTE_EDGE_MAP)
|
||||
// *TODO: Consider removing the debug associated with
|
||||
// DEBUG_SILHOUETTE_EDGE_MAP, and remove its associated computational
|
||||
// overhead in generateSilhouetteEdge.
|
||||
std::vector<S32> edge;
|
||||
//for each face
|
||||
for (face_list_t::iterator iter = mVolumeFaces.begin();
|
||||
iter != mVolumeFaces.end(); ++iter)
|
||||
|
|
@ -3768,7 +3976,16 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
|
|||
LLVolumeFace& face = *iter;
|
||||
|
||||
if (!(face_mask & (0x1 << cur_index++)) ||
|
||||
face.mNumIndices == 0 || face.mEdge.empty())
|
||||
face.mNumIndices == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Attempt to generate "edge" info for this silhouette, which is used
|
||||
// for some prims. If the edge array remains empty, then this
|
||||
// silhouette generation method is not supported for this face.
|
||||
edge.clear();
|
||||
face.generateSilhouetteEdge(this, edge);
|
||||
if (edge.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -3782,7 +3999,7 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
|
|||
{
|
||||
for (S32 k = 0; k < 3; k++)
|
||||
{
|
||||
S32 index = face.mEdge[j * 3 + k];
|
||||
S32 index = edge[j * 3 + k];
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
|
|
@ -3834,7 +4051,7 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
|
|||
|
||||
//for each edge
|
||||
for (S32 k = 0; k < 3; k++) {
|
||||
S32 nIndex = face.mEdge[j*3+k];
|
||||
S32 nIndex = edge[j*3+k];
|
||||
if (nIndex <= -1) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -3949,7 +4166,7 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
|
|||
// *FIX IF NEEDED: this does not deal with neighboring degenerate faces
|
||||
for (S32 k = 0; k < 3; k++)
|
||||
{
|
||||
S32 index = face.mEdge[j*3+k];
|
||||
S32 index = edge[j*3+k];
|
||||
if (index != -1)
|
||||
{
|
||||
fFacing[j] = fFacing[index];
|
||||
|
|
@ -3961,10 +4178,10 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
|
|||
|
||||
//for each edge
|
||||
for (S32 k = 0; k < 3; k++) {
|
||||
S32 index = face.mEdge[j*3+k];
|
||||
S32 index = edge[j*3+k];
|
||||
if (index != -1 && fFacing[index] == (AWAY | TOWARDS)) {
|
||||
//our neighbor is degenerate, make him face our direction
|
||||
fFacing[face.mEdge[j*3+k]] = fFacing[j];
|
||||
fFacing[edge[j*3+k]] = fFacing[j];
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -5775,30 +5992,16 @@ bool LLVolumeFace::createUnCutCubeCap(LLVolume* volume, bool partial_build)
|
|||
|
||||
if (!partial_build)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("llvfcuccm - generate indices");
|
||||
|
||||
resizeIndices(grid_size*grid_size*6);
|
||||
if (!volume->isMeshAssetLoaded())
|
||||
{
|
||||
S32 size = grid_size * grid_size * 6;
|
||||
try
|
||||
{
|
||||
mEdge.resize(size);
|
||||
}
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
LL_WARNS("LLVOLUME") << "Resize of mEdge to " << size << " failed" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
U16* out = mIndices;
|
||||
|
||||
S32 idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0};
|
||||
|
||||
int cur_edge = 0;
|
||||
|
||||
for(S32 gx = 0;gx<grid_size;gx++)
|
||||
{
|
||||
|
||||
for(S32 gy = 0;gy<grid_size;gy++)
|
||||
{
|
||||
if (mTypeMask & TOP_MASK)
|
||||
|
|
@ -5808,47 +6011,6 @@ bool LLVolumeFace::createUnCutCubeCap(LLVolume* volume, bool partial_build)
|
|||
*out++ = ((gy*(grid_size+1))+gx+idxs[i]);
|
||||
}
|
||||
|
||||
S32 edge_value = grid_size * 2 * gy + gx * 2;
|
||||
|
||||
if (gx > 0)
|
||||
{
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEdge[cur_edge++] = -1; // Mark face to higlight it
|
||||
}
|
||||
|
||||
if (gy < grid_size - 1)
|
||||
{
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEdge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
|
||||
if (gx < grid_size - 1)
|
||||
{
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEdge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
if (gy > 0)
|
||||
{
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEdge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -5856,48 +6018,6 @@ bool LLVolumeFace::createUnCutCubeCap(LLVolume* volume, bool partial_build)
|
|||
{
|
||||
*out++ = ((gy*(grid_size+1))+gx+idxs[i]);
|
||||
}
|
||||
|
||||
S32 edge_value = grid_size * 2 * gy + gx * 2;
|
||||
|
||||
if (gy > 0)
|
||||
{
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEdge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
if (gx < grid_size - 1)
|
||||
{
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEdge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
|
||||
if (gy < grid_size - 1)
|
||||
{
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEdge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
if (gx > 0)
|
||||
{
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEdge[cur_edge++] = -1;
|
||||
}
|
||||
|
||||
mEdge[cur_edge++] = edge_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6377,6 +6497,8 @@ void LLVolumeFace::createTangents()
|
|||
|
||||
void LLVolumeFace::resizeVertices(S32 num_verts)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
|
||||
|
||||
ll_aligned_free<64>(mPositions);
|
||||
//DO NOT free mNormals and mTexCoords as they are part of mPositions buffer
|
||||
ll_aligned_free_16(mTangents);
|
||||
|
|
@ -6499,6 +6621,8 @@ void LLVolumeFace::allocateJointIndices(S32 num_verts)
|
|||
|
||||
void LLVolumeFace::resizeIndices(S32 num_indices)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
|
||||
|
||||
ll_aligned_free_16(mIndices);
|
||||
llassert(num_indices % 3 == 0);
|
||||
|
||||
|
|
@ -6591,19 +6715,6 @@ bool LLVolumeFace::createSide(LLVolume* volume, bool partial_build)
|
|||
{
|
||||
resizeVertices(num_vertices);
|
||||
resizeIndices(num_indices);
|
||||
|
||||
if (!volume->isMeshAssetLoaded())
|
||||
{
|
||||
try
|
||||
{
|
||||
mEdge.resize(num_indices);
|
||||
}
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
LL_WARNS("LLVOLUME") << "Resize of mEdge to " << num_indices << " failed" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LL_CHECK_MEMORY
|
||||
|
|
@ -6618,6 +6729,7 @@ bool LLVolumeFace::createSide(LLVolume* volume, bool partial_build)
|
|||
bool test = (mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2;
|
||||
|
||||
// Copy the vertices into the array
|
||||
{ LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("llvfcs - copy verts");
|
||||
for (t = mBeginT; t < end_t; t++)
|
||||
{
|
||||
tt = path_data[t].mTexT;
|
||||
|
|
@ -6702,6 +6814,7 @@ bool LLVolumeFace::createSide(LLVolume* volume, bool partial_build)
|
|||
cur_vertex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
LL_CHECK_MEMORY
|
||||
|
||||
mCenter->clear();
|
||||
|
|
@ -6755,11 +6868,11 @@ bool LLVolumeFace::createSide(LLVolume* volume, bool partial_build)
|
|||
mCenter->mul(0.5f);
|
||||
|
||||
S32 cur_index = 0;
|
||||
S32 cur_edge = 0;
|
||||
bool flat_face = mTypeMask & FLAT_MASK;
|
||||
|
||||
if (!partial_build)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("llvfcs - generate indices");
|
||||
|
||||
// Now we generate the indices.
|
||||
for (t = 0; t < (mNumT-1); t++)
|
||||
{
|
||||
|
|
@ -6771,64 +6884,6 @@ bool LLVolumeFace::createSide(LLVolume* volume, bool partial_build)
|
|||
mIndices[cur_index++] = s + mNumS*t; //bottom left
|
||||
mIndices[cur_index++] = s+1 + mNumS*t; //bottom right
|
||||
mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right
|
||||
|
||||
// bottom left/top right neighbor face
|
||||
mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1;
|
||||
|
||||
if (t < mNumT-2)
|
||||
{ // top right/top left neighbor face
|
||||
mEdge[cur_edge++] = (mNumS-1)*2*(t+1)+s*2+1;
|
||||
}
|
||||
else if (mNumT <= 3 || volume->getPath().isOpen())
|
||||
{ // no neighbor
|
||||
mEdge[cur_edge++] = -1;
|
||||
}
|
||||
else
|
||||
{ // wrap on T
|
||||
mEdge[cur_edge++] = s*2+1;
|
||||
}
|
||||
|
||||
if (s > 0)
|
||||
{ // top left/bottom left neighbor face
|
||||
mEdge[cur_edge++] = (mNumS-1)*2*t+s*2-1;
|
||||
}
|
||||
else if (flat_face || volume->getProfile().isOpen())
|
||||
{ // no neighbor
|
||||
mEdge[cur_edge++] = -1;
|
||||
}
|
||||
else
|
||||
{ // wrap on S
|
||||
mEdge[cur_edge++] = (mNumS-1)*2*t+(mNumS-2)*2+1;
|
||||
}
|
||||
|
||||
if (t > 0)
|
||||
{ // bottom left/bottom right neighbor face
|
||||
mEdge[cur_edge++] = (mNumS-1)*2*(t-1)+s*2;
|
||||
}
|
||||
else if (mNumT <= 3 || volume->getPath().isOpen())
|
||||
{ // no neighbor
|
||||
mEdge[cur_edge++] = -1;
|
||||
}
|
||||
else
|
||||
{ // wrap on T
|
||||
mEdge[cur_edge++] = (mNumS-1)*2*(mNumT-2)+s*2;
|
||||
}
|
||||
|
||||
if (s < mNumS-2)
|
||||
{ // bottom right/top right neighbor face
|
||||
mEdge[cur_edge++] = (mNumS-1)*2*t+(s+1)*2;
|
||||
}
|
||||
else if (flat_face || volume->getProfile().isOpen())
|
||||
{ // no neighbor
|
||||
mEdge[cur_edge++] = -1;
|
||||
}
|
||||
else
|
||||
{ // wrap on S
|
||||
mEdge[cur_edge++] = (mNumS-1)*2*t;
|
||||
}
|
||||
|
||||
// top right/bottom left neighbor face
|
||||
mEdge[cur_edge++] = (mNumS-1)*2*t+s*2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -918,6 +918,15 @@ public:
|
|||
// Get a reference to the octree, which may be null
|
||||
const LLVolumeOctree* getOctree() const;
|
||||
|
||||
// Part of silhouette generation (used by selection outlines)
|
||||
// Populates the provided edge array with numbers corresponding to
|
||||
// *partial* logic of whether a particular index should be rendered
|
||||
// as a silhouette edge. -1 indicates the index should be rendered as a
|
||||
// silhouette edge. See generateSilhouetteVertices for the full logic.
|
||||
// Silhouette edges can only be generated for some types of prims. If a
|
||||
// silhouette edge cannot be generated, the edge array will be left empty.
|
||||
void generateSilhouetteEdge(const LLVolume* volume, std::vector<S32>& edge) const;
|
||||
|
||||
enum
|
||||
{
|
||||
SINGLE_MASK = 0x0001,
|
||||
|
|
@ -963,8 +972,6 @@ public:
|
|||
// indexes for mPositions/mNormals/mTexCoords
|
||||
U16* mIndices;
|
||||
|
||||
std::vector<S32> mEdge;
|
||||
|
||||
//list of skin weights for rigged volumes
|
||||
// format is mWeights[vertex_index].mV[influence] = <joint_index>.<weight>
|
||||
// mWeights.size() should be empty or match mVertices.size()
|
||||
|
|
@ -1113,9 +1120,9 @@ private:
|
|||
|
||||
public:
|
||||
virtual void setMeshAssetLoaded(bool loaded);
|
||||
virtual bool isMeshAssetLoaded();
|
||||
virtual bool isMeshAssetLoaded() const;
|
||||
virtual void setMeshAssetUnavaliable(bool unavaliable);
|
||||
virtual bool isMeshAssetUnavaliable();
|
||||
virtual bool isMeshAssetUnavaliable() const;
|
||||
|
||||
protected:
|
||||
bool mUnique;
|
||||
|
|
|
|||
Loading…
Reference in New Issue