phoenix-firestorm/indra/newview/llface.h

413 lines
16 KiB
C++

/**
* @file llface.h
* @brief LLFace class definition
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLFACE_H
#define LL_LLFACE_H
#include "llstrider.h"
#include "llrender.h"
#include "v2math.h"
#include "v3math.h"
#include "v4math.h"
#include "m4math.h"
#include "v4coloru.h"
#include "llquaternion.h"
#include "xform.h"
#include "llvertexbuffer.h"
#include "llviewertexture.h"
#include "lldrawable.h"
#include "lljoint.h"
class LLFacePool;
class LLVolume;
class LLViewerTexture;
class LLTextureEntry;
class LLVertexProgram;
class LLViewerTexture;
class LLGeometryManager;
class LLDrawInfo;
class LLMeshSkinInfo;
const F32 MIN_ALPHA_SIZE = 1024.f;
const F32 MIN_TEX_ANIM_SIZE = 512.f;
const U8 FACE_DO_NOT_BATCH_TEXTURES = 255;
class alignas(16) LLFace
{
LL_ALIGN_NEW
public:
LLFace(const LLFace& rhs)
{
*this = rhs;
}
const LLFace& operator=(const LLFace& rhs)
{
LL_ERRS() << "Illegal operation!" << LL_ENDL;
return *this;
}
enum EMasks
{
LIGHT = 0x0001,
GLOBAL = 0x0002,
FULLBRIGHT = 0x0004,
HUD_RENDER = 0x0008,
USE_FACE_COLOR = 0x0010,
TEXTURE_ANIM = 0x0020,
RIGGED = 0x0040,
PARTICLE = 0x0080,
};
public:
LLFace(LLDrawable* drawablep, LLViewerObject* objp)
{
LL_PROFILE_ZONE_SCOPED;
init(drawablep, objp);
}
~LLFace() { destroy(); }
const LLMatrix4& getWorldMatrix() const { return mVObjp->getWorldMatrix(mXform); }
const LLMatrix4& getRenderMatrix() const;
U32 getIndicesCount() const { return mIndicesCount; };
S32 getIndicesStart() const { return mIndicesIndex; };
U16 getGeomCount() const { return mGeomCount; } // vertex count for this face
U16 getGeomIndex() const { return mGeomIndex; } // index into draw pool
U16 getGeomStart() const { return mGeomIndex; } // index into draw pool
void setTextureIndex(U8 index);
U8 getTextureIndex() const { return mTextureIndex; }
void setTexture(U32 ch, LLViewerTexture* tex);
void setTexture(LLViewerTexture* tex) ;
void setDiffuseMap(LLViewerTexture* tex);
void setNormalMap(LLViewerTexture* tex);
void setSpecularMap(LLViewerTexture* tex);
void setAlternateDiffuseMap(LLViewerTexture* tex);
void switchTexture(U32 ch, LLViewerTexture* new_texture);
void dirtyTexture();
LLXformMatrix* getXform() const { return mXform; }
bool hasGeometry() const { return mGeomCount > 0; }
LLVector3 getPositionAgent() const;
LLVector2 surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal);
void getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const;
bool calcAlignedPlanarTE(const LLFace* align_to, LLVector2* st_offset,
LLVector2* st_scale, F32* st_rot, LLRender::eTexIndex map = LLRender::DIFFUSE_MAP) const;
U32 getState() const { return mState; }
void setState(U32 state) { mState |= state; }
void clearState(U32 state) { mState &= ~state; }
bool isState(U32 state) const { return (mState & state) != 0; }
void setVirtualSize(F32 size) { mVSize = size; }
void setPixelArea(F32 area) { mPixelArea = area; }
F32 getVirtualSize() const { return mVSize; }
F32 getPixelArea() const { return mPixelArea; }
S32 getIndexInTex(U32 ch) const { llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); return mIndexInTex[ch]; }
void setIndexInTex(U32 ch, S32 index) { llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); mIndexInTex[ch] = index; }
void setWorldMatrix(const LLMatrix4& mat);
const LLTextureEntry* getTextureEntry() const { return mVObjp->getTE(mTEOffset); }
LLFacePool* getPool() const { return mDrawPoolp; }
U32 getPoolType() const { return mPoolType; }
LLDrawable* getDrawable() const { return mDrawablep; }
LLViewerObject* getViewerObject() const { return mVObjp; }
S32 getLOD() const { return mVObjp.notNull() ? mVObjp->getLOD() : 0; }
void setPoolType(U32 type) { mPoolType = type; }
S32 getTEOffset() const { return mTEOffset; }
LLViewerTexture* getTexture(U32 ch = LLRender::DIFFUSE_MAP) const;
void setViewerObject(LLViewerObject* object);
void setPool(LLFacePool *pool, LLViewerTexture *texturep);
void setPool(LLFacePool* pool);
void setDrawable(LLDrawable *drawable);
void setTEOffset(const S32 te_offset);
void renderIndexed();
void setFaceColor(const LLColor4& color); // override material color
void unsetFaceColor(); // switch back to material color
const LLColor4& getFaceColor() const { return mFaceColor; }
//for volumes
void updateRebuildFlags();
bool canRenderAsMask(); // logic helper
bool getGeometryVolume(const LLVolume& volume,
S32 face_index,
const LLMatrix4& mat_vert,
const LLMatrix3& mat_normal,
U16 index_offset,
bool force_rebuild = false,
bool no_debug_assert = false,
bool rebuild_for_gltf = false);
// For avatar
U16 getGeometryAvatar(
LLStrider<LLVector3> &vertices,
LLStrider<LLVector3> &normals,
LLStrider<LLVector2> &texCoords,
LLStrider<F32> &vertex_weights,
// <FS:Ansariel> Vectorized Weight4Strider and ClothWeightStrider by Drake Arconis
//LLStrider<LLVector4> &clothing_weights);
LLStrider<LLVector4a> &clothing_weights);
// For volumes, etc.
U16 getGeometry(LLStrider<LLVector3> &vertices,
LLStrider<LLVector3> &normals,
LLStrider<LLVector2> &texCoords,
LLStrider<U16> &indices);
S32 getColors(LLStrider<LLColor4U> &colors);
S32 getIndices(LLStrider<U16> &indices);
void setSize(S32 numVertices, S32 num_indices = 0, bool align = false);
bool genVolumeBBoxes(const LLVolume &volume, S32 f,
const LLMatrix4& mat_vert_in, bool global_volume = false);
void init(LLDrawable* drawablep, LLViewerObject* objp);
void destroy();
void update();
void updateCenterAgent(); // Update center when xform has changed.
void renderSelectedUV();
void renderSelected(LLViewerTexture *image, const LLColor4 &color);
void renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wireframe_selection, bool bRenderHiddenSelections, bool shader);
F32 getKey() const { return mDistance; }
S32 getReferenceIndex() const { return mReferenceIndex; }
void setReferenceIndex(const S32 index) { mReferenceIndex = index; }
bool verify(const U32* indices_array = NULL) const;
void printDebugInfo() const;
void setGeomIndex(U16 idx);
void setIndicesIndex(S32 idx);
void setDrawInfo(LLDrawInfo* draw_info);
F32 getTextureVirtualSize() ;
void resetVirtualSize();
void setHasMedia(bool has_media) { mHasMedia = has_media ;}
bool hasMedia() const ;
void setMediaAllowed(bool is_media_allowed) { mIsMediaAllowed = is_media_allowed; }
bool isMediaAllowed() const { return mIsMediaAllowed; }
bool switchTexture() ;
// [SL:KB] - Patch: Render-TextureToggle (Catznip-4.0)
bool isDefaultTexture(U32 nChannel) const;
void setDefaultTexture(U32 nChannel, bool fShowDefault) const;
// [/SL:KB]
//vertex buffer tracking
void setVertexBuffer(LLVertexBuffer* buffer);
void clearVertexBuffer(); //sets mVertexBuffer to NULL
LLVertexBuffer* getVertexBuffer() const { return mVertexBuffer; }
S32 getRiggedIndex(U32 type) const;
// used to preserve draw order of faces that are batched together.
// Allows content creators to manipulate linked sets and face ordering
// for consistent alpha sorting results, particularly for rigged attachments
void setDrawOrderIndex(U32 index) { mDrawOrderIndex = index; }
U32 getDrawOrderIndex() const { return mDrawOrderIndex; }
// return true if this face is in an alpha draw pool
bool isInAlphaPool() const;
public: //aligned members
// bounding box of face in drawable space
LLVector4a mExtents[2];
// cached bounding box of rigged face in world space
// calculated on-demand by LLFace::calcPixelArea and may not be up-to-date
LLVector4a mRiggedExtents[2] = { LLVector4a(0,0,0), LLVector4a(0,0,0) };
private:
friend class LLViewerTextureList;
F32 adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius );
bool calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) ;
public:
static F32 calcImportanceToCamera(F32 to_view_dir, F32 dist);
static F32 adjustPixelArea(F32 importance, F32 pixel_area) ;
public:
LLVector3 mCenterLocal;
LLVector3 mCenterAgent;
LLVector2 mTexExtents[2];
F32 mDistance;
F32 mLastUpdateTime;
F32 mLastSkinTime;
F32 mLastMoveTime;
LLMatrix4* mTextureMatrix;
LLMatrix4* mSpecMapMatrix;
LLMatrix4* mNormalMapMatrix;
LLDrawInfo* mDrawInfo;
LLVOAvatar* mAvatar = nullptr;
LLMeshSkinInfo* mSkinInfo = nullptr;
// return mSkinInfo->mHash or 0 if mSkinInfo is null
U64 getSkinHash();
// true if face was recently in the main camera frustum according to LLViewerTextureList updates
bool mInFrustum = false;
// value of gFrameCount the last time the face was touched by LLViewerTextureList::updateImageDecodePriority
U32 mLastTextureUpdate = 0;
private:
LLPointer<LLVertexBuffer> mVertexBuffer;
LLPointer<LLVertexBuffer> mVertexBufferGLTF;
U32 mState;
LLFacePool* mDrawPoolp;
U32 mPoolType;
LLColor4 mFaceColor; // overrides material color if state |= USE_FACE_COLOR
U16 mGeomCount; // vertex count for this face
U16 mGeomIndex; // starting index into mVertexBuffer's vertex array
U8 mTextureIndex; // index of texture channel to use for pseudo-atlasing
U32 mIndicesCount;
U32 mIndicesIndex; // index into mVertexBuffer's index array
S32 mIndexInTex[LLRender::NUM_TEXTURE_CHANNELS];
LLXformMatrix* mXform;
LLPointer<LLViewerTexture> mTexture[LLRender::NUM_TEXTURE_CHANNELS];
// mDrawablep is not supposed to be null, don't use LLPointer because
// mDrawablep owns LLFace and LLPointer is a good way to either cause a
// memory leak or a 'delete each other' situation if something deletes
// drawable wrongly.
LLDrawable* mDrawablep;
// LLViewerObject technically owns drawable, but also it should be strictly managed
LLPointer<LLViewerObject> mVObjp;
S32 mTEOffset;
S32 mReferenceIndex;
std::vector<S32> mRiggedIndex;
// gFrameTimeSeconds when mPixelArea was last updated
F32 mLastPixelAreaUpdate = 0.f;
// virtual size of face in texture area (mPixelArea adjusted by texture repeats)
// used to determine desired resolution of texture
F32 mVSize;
// pixel area face covers on screen
F32 mPixelArea;
//importance factor, in the range [0, 1.0].
//1.0: the most important.
//based on the distance from the face to the view point and the angle from the face center to the view direction.
F32 mImportanceToCamera ;
F32 mBoundingSphereRadius ;
bool mHasMedia ;
bool mIsMediaAllowed;
U32 mDrawOrderIndex = 0; // see setDrawOrderIndex
// [SL:KB] - Patch: Render-TextureToggle (Catznip-4.0)
mutable bool mShowDiffTexture;
mutable LLPointer<LLViewerTexture> mOrigDiffTexture;
// [/SL:KB]
protected:
static bool sSafeRenderSelect;
public:
struct CompareDistanceGreater
{
bool operator()(const LLFace* const& lhs, const LLFace* const& rhs)
{
return !lhs || (rhs && (lhs->mDistance > rhs->mDistance)); // farthest = first
}
};
struct CompareTexture
{
bool operator()(const LLFace* const& lhs, const LLFace* const& rhs)
{
return lhs->getTexture() < rhs->getTexture();
}
};
struct CompareBatchBreaker
{
bool operator()(const LLFace* const& lhs, const LLFace* const& rhs)
{
const LLTextureEntry* lte = lhs->getTextureEntry();
const LLTextureEntry* rte = rhs->getTextureEntry();
if(lhs->getTexture() != rhs->getTexture())
{
return lhs->getTexture() < rhs->getTexture();
}
else
{
return lte->getBumpShinyFullbright() < rte->getBumpShinyFullbright();
}
}
};
struct CompareTextureAndGeomCount
{
bool operator()(const LLFace* const& lhs, const LLFace* const& rhs)
{
return lhs->getTexture() == rhs->getTexture() ?
lhs->getGeomCount() < rhs->getGeomCount() : //smallest = first
lhs->getTexture() > rhs->getTexture();
}
};
struct CompareTextureAndLOD
{
bool operator()(const LLFace* const& lhs, const LLFace* const& rhs)
{
return lhs->getTexture() == rhs->getTexture() ?
lhs->getLOD() < rhs->getLOD() :
lhs->getTexture() < rhs->getTexture();
}
};
struct CompareTextureAndTime
{
bool operator()(const LLFace* const& lhs, const LLFace* const& rhs)
{
return lhs->getTexture() == rhs->getTexture() ?
lhs->mLastUpdateTime < rhs->mLastUpdateTime :
lhs->getTexture() < rhs->getTexture();
}
};
};
#endif // LL_LLFACE_H