Files
SingularityViewer/indra/newview/llpolymesh.h
Aleric Inglewood 10af185abc Add Advanced --> Character --> Meshes and morphs...
Allows to save the .llm of all mesh objects, and
all morphs of each as .obj (Wavefront OBJ File),
for import in, for example, blender.

You can also load .obj files, but of course they
will only affect what you see locally.
2011-05-16 19:03:48 +02:00

464 lines
13 KiB
C++

/**
* @file llpolymesh.h
* @brief Implementation of LLPolyMesh class
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLPOLYMESH_H
#define LL_LLPOLYMESH_H
#include <string>
#include <map>
#include "llstl.h"
#include "v3math.h"
#include "v2math.h"
#include "llquaternion.h"
#include "llpolymorph.h"
#include "lljoint.h"
//#include "lldarray.h"
class LLSkinJoint;
class LLVOAvatar;
//#define USE_STRIPS // Use tri-strips for rendering.
//-----------------------------------------------------------------------------
// LLPolyFace
// A set of 4 vertex indices.
// An LLPolyFace can represent either a triangle or quad.
// If the last index is -1, it's a triangle.
//-----------------------------------------------------------------------------
typedef S32 LLPolyFace[3];
//struct PrimitiveGroup;
//-----------------------------------------------------------------------------
// LLPolyMesh
// A polyhedra consisting of any number of triangles and quads.
// All instances contain a set of faces, and optionally may include
// faces grouped into named face sets.
//-----------------------------------------------------------------------------
class LLPolyMorphTarget;
class LLPolyMeshSharedData
{
friend class LLPolyMesh;
private:
// transform data
LLVector3 mPosition;
LLQuaternion mRotation;
LLVector3 mScale;
// vertex data
S32 mNumVertices;
LLVector3 *mBaseCoords;
LLVector3 *mBaseNormals;
LLVector3 *mBaseBinormals;
LLVector2 *mTexCoords;
LLVector2 *mDetailTexCoords;
F32 *mWeights;
BOOL mHasWeights;
BOOL mHasDetailTexCoords;
// face data
S32 mNumFaces;
LLPolyFace *mFaces;
// face set data
U32 mNumJointNames;
std::string* mJointNames;
// morph targets
typedef std::set<LLPolyMorphData*> morphdata_list_t;
morphdata_list_t mMorphData;
std::map<S32, S32> mSharedVerts;
LLPolyMeshSharedData* mReferenceData;
S32 mLastIndexOffset;
public:
// Temporarily...
// Triangle indices
U32 mNumTriangleIndices;
U32 *mTriangleIndices;
public:
LLPolyMeshSharedData();
~LLPolyMeshSharedData();
private:
void setupLOD(LLPolyMeshSharedData* reference_data);
// Frees all mesh memory resources
void freeMeshData();
void setPosition( const LLVector3 &pos ) { mPosition = pos; }
void setRotation( const LLQuaternion &rot ) { mRotation = rot; }
void setScale( const LLVector3 &scale ) { mScale = scale; }
BOOL allocateVertexData( U32 numVertices );
BOOL allocateFaceData( U32 numFaces );
BOOL allocateJointNames( U32 numJointNames );
// Retrieve the number of KB of memory used by this instance
U32 getNumKB();
// Load mesh data from file
BOOL loadMesh( const std::string& fileName );
public:
void genIndices(S32 offset);
const LLVector2 &getUVs(U32 index);
const S32 *getSharedVert(S32 vert);
BOOL isLOD() { return (mReferenceData != NULL); }
};
class LLJointRenderData
{
public:
LLJointRenderData(const LLMatrix4* world_matrix, LLSkinJoint* skin_joint) : mWorldMatrix(world_matrix), mSkinJoint(skin_joint) {}
~LLJointRenderData(){}
const LLMatrix4* mWorldMatrix;
LLSkinJoint* mSkinJoint;
};
class LLPolyMesh
{
public:
// Constructor
LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_mesh);
// Destructor
~LLPolyMesh();
// Requests a mesh by name.
// If the mesh already exists in the global mesh table, it is returned,
// otherwise it is loaded from file, added to the table, and returned.
static LLPolyMesh *getMesh( const std::string &name, LLPolyMesh* reference_mesh = NULL);
// Saves the mesh information as a binary Linden Lab Mesh file.
BOOL saveLLM(LLFILE *fp);
// Saves the mesh information as an OBJ file.
BOOL saveOBJ(LLFILE *fp);
// Loads new mesh information from an OBJ file.
BOOL loadOBJ(LLFILE *fp);
// Copies the current mesh to the base mesh.
BOOL setSharedFromCurrent();
// Gets the name of the mesh corresponding to the shared data
static const std::string* getSharedMeshName(LLPolyMeshSharedData* shared);
// Requests mesh data by name. Returns null if not found.
static LLPolyMeshSharedData *getMeshData( const std::string &name );
// Frees all loaded meshes.
// This should only be called once you know there are no outstanding
// references to these objects. Generally, upon exit of the application.
static void freeAllMeshes();
//--------------------------------------------------------------------
// Transform Data Access
//--------------------------------------------------------------------
// Get position
const LLVector3 &getPosition() {
llassert (mSharedData);
return mSharedData->mPosition;
}
// Get rotation
const LLQuaternion &getRotation() {
llassert (mSharedData);
return mSharedData->mRotation;
}
// Get scale
const LLVector3 &getScale() {
llassert (mSharedData);
return mSharedData->mScale;
}
//--------------------------------------------------------------------
// Vertex Data Access
//--------------------------------------------------------------------
// Get number of vertices
U32 getNumVertices() {
llassert (mSharedData);
return mSharedData->mNumVertices;
}
// Returns whether or not the mesh has detail texture coords
BOOL hasDetailTexCoords() {
llassert (mSharedData);
return mSharedData->mHasDetailTexCoords;
}
// Returns whether or not the mesh has vertex weights
BOOL hasWeights() const{
llassert (mSharedData);
return mSharedData->mHasWeights;
}
// Get coords
const LLVector3 *getCoords() const{
return mCoords;
}
// non const version
LLVector3 *getWritableCoords();
// Get normals
const LLVector3 *getNormals() const{
return mNormals;
}
// Get normals
const LLVector3 *getBinormals() const{
return mBinormals;
}
// Get base mesh normals
const LLVector3 *getBaseNormals() const{
llassert(mSharedData);
return mSharedData->mBaseNormals;
}
// Get base mesh normals
const LLVector3 *getBaseBinormals() const{
llassert(mSharedData);
return mSharedData->mBaseBinormals;
}
// intermediate morphed normals and output normals
LLVector3 *getWritableNormals();
LLVector3 *getScaledNormals();
LLVector3 *getWritableBinormals();
LLVector3 *getScaledBinormals();
// Get texCoords
const LLVector2 *getTexCoords() const {
return mTexCoords;
}
// non const version
LLVector2 *getWritableTexCoords();
// Get detailTexCoords
const LLVector2 *getDetailTexCoords() const {
llassert (mSharedData);
return mSharedData->mDetailTexCoords;
}
// Get weights
const F32 *getWeights() const {
llassert (mSharedData);
return mSharedData->mWeights;
}
F32 *getWritableWeights() const;
LLVector4 *getWritableClothingWeights();
const LLVector4 *getClothingWeights()
{
return mClothingWeights;
}
//--------------------------------------------------------------------
// Face Data Access
//--------------------------------------------------------------------
// Get number of faces
S32 getNumFaces() {
llassert (mSharedData);
return mSharedData->mNumFaces;
}
// Get faces
LLPolyFace *getFaces() {
llassert (mSharedData);
return mSharedData->mFaces;
}
U32 getNumJointNames() {
llassert (mSharedData);
return mSharedData->mNumJointNames;
}
std::string *getJointNames() {
llassert (mSharedData);
return mSharedData->mJointNames;
}
typedef std::map<std::string,LLPolyMorphData*> morph_list_t;
static void getMorphList (const std::string& mesh_name, morph_list_t* morph_list);
LLPolyMorphData* getMorphData(const std::string& morph_name);
// void removeMorphData(LLPolyMorphData *morph_target);
// void deleteAllMorphData();
LLPolyMeshSharedData *getSharedData() const;
LLPolyMesh *getReferenceMesh() { return mReferenceMesh ? mReferenceMesh : this; }
// Get indices
U32* getIndices() { return mSharedData ? mSharedData->mTriangleIndices : NULL; }
BOOL isLOD() { return mSharedData && mSharedData->isLOD(); }
void setAvatar(LLVOAvatar* avatarp) { mAvatarp = avatarp; }
LLVOAvatar* getAvatar() { return mAvatarp; }
LLDynamicArray<LLJointRenderData*> mJointRenderData;
U32 mFaceVertexOffset;
U32 mFaceVertexCount;
U32 mFaceIndexOffset;
U32 mFaceIndexCount;
U32 mCurVertexCount;
// Dumps diagnostic information about the global mesh table
static void dumpDiagInfo(void*);
private:
void initializeForMorph();
protected:
// mesh data shared across all instances of a given mesh
LLPolyMeshSharedData *mSharedData;
// Single array of floats for allocation / deletion
F32 *mVertexData;
// deformed vertices (resulting from application of morph targets)
LLVector3 *mCoords;
// deformed normals (resulting from application of morph targets)
LLVector3 *mScaledNormals;
// output normals (after normalization)
LLVector3 *mNormals;
// deformed binormals (resulting from application of morph targets)
LLVector3 *mScaledBinormals;
// output binormals (after normalization)
LLVector3 *mBinormals;
// weight values that mark verts as clothing/skin
LLVector4 *mClothingWeights;
// output texture coordinates
LLVector2 *mTexCoords;
LLPolyMesh *mReferenceMesh;
// global mesh list
typedef std::map<std::string, LLPolyMeshSharedData*> LLPolyMeshSharedDataTable;
static LLPolyMeshSharedDataTable sGlobalSharedMeshList;
// Backlink only; don't make this an LLPointer.
LLVOAvatar* mAvatarp;
};
//-----------------------------------------------------------------------------
// LLPolySkeletalDeformationInfo
// Shared information for LLPolySkeletalDeformations
//-----------------------------------------------------------------------------
struct LLPolySkeletalBoneInfo
{
LLPolySkeletalBoneInfo(std::string &name, LLVector3 &scale, LLVector3 &pos, BOOL haspos)
: mBoneName(name),
mScaleDeformation(scale),
mPositionDeformation(pos),
mHasPositionDeformation(haspos) {}
std::string mBoneName;
LLVector3 mScaleDeformation;
LLVector3 mPositionDeformation;
BOOL mHasPositionDeformation;
};
class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo
{
friend class LLPolySkeletalDistortion;
public:
LLPolySkeletalDistortionInfo();
/*virtual*/ ~LLPolySkeletalDistortionInfo() {};
/*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
protected:
typedef std::vector<LLPolySkeletalBoneInfo> bone_info_list_t;
bone_info_list_t mBoneInfoList;
};
//-----------------------------------------------------------------------------
// LLPolySkeletalDeformation
// A set of joint scale data for deforming the avatar mesh
//-----------------------------------------------------------------------------
class LLPolySkeletalDistortion : public LLViewerVisualParam
{
public:
LLPolySkeletalDistortion(LLVOAvatar *avatarp);
~LLPolySkeletalDistortion();
// Special: These functions are overridden by child classes
LLPolySkeletalDistortionInfo* getInfo() const { return (LLPolySkeletalDistortionInfo*)mInfo; }
// This sets mInfo and calls initialization functions
BOOL setInfo(LLPolySkeletalDistortionInfo *info);
// LLVisualParam Virtual functions
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
/*virtual*/ void apply( ESex sex );
// LLViewerVisualParam Virtual functions
/*virtual*/ F32 getTotalDistortion() { return 0.1f; }
/*virtual*/ const LLVector3& getAvgDistortion() { return mDefaultVec; }
/*virtual*/ F32 getMaxDistortion() { return 0.1f; }
/*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector3(0.001f, 0.001f, 0.001f);}
/*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;};
/*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;};
protected:
typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;
joint_vec_map_t mJointScales;
joint_vec_map_t mJointOffsets;
LLVector3 mDefaultVec;
// Backlink only; don't make this an LLPointer.
LLVOAvatar *mAvatar;
};
#endif // LL_LLPOLYMESH_H