phoenix-firestorm/indra/llprimitive/llmodelloader.h

220 lines
7.8 KiB
C++

/**
* @file llmodelloader.h
* @brief LLModelLoader class definition
*
* $LicenseInfo:firstyear=2004&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_LLMODELLOADER_H
#define LL_LLMODELLOADER_H
#include "llmodel.h"
#include "llthread.h"
#include <boost/function.hpp>
#include <list>
class LLJoint;
typedef std::map<std::string, LLMatrix4> JointTransformMap;
typedef std::map<std::string, LLMatrix4>::iterator JointTransformMapIt;
typedef std::map<std::string, std::string> JointMap;
typedef std::deque<std::string> JointNameSet;
const S32 SLM_SUPPORTED_VERSION = 3;
const S32 NUM_LOD = 4;
const U32 LEGACY_RIG_OK = 0;
const U32 LEGACY_RIG_FLAG_TOO_MANY_JOINTS = 1;
const U32 LEGACY_RIG_FLAG_UNKNOWN_JOINT = 2;
class LLModelLoader : public LLThread
{
public:
typedef std::map<std::string, LLImportMaterial> material_map;
typedef std::vector<LLPointer<LLModel>> model_list;
typedef std::vector<LLModelInstance> model_instance_list;
typedef std::map<LLMatrix4, model_instance_list> scene;
// Callback with loaded model data and loaded LoD
//
typedef boost::function<void (scene&, model_list&, S32, void*)> load_callback_t;
// Function to provide joint lookup by name
// (within preview avi skeleton, for example)
//
typedef boost::function<LLJoint* (const std::string&, void*)> joint_lookup_func_t;
// Func to load and associate material with all it's textures,
// returned value is the number of textures loaded
// intentionally non-const so func can modify material to
// store platform-specific data
//
typedef boost::function<U32 (LLImportMaterial&, void*)> texture_load_func_t;
// Callback to inform client of state changes
// during loading process (errors will be reported
// as state changes here as well)
//
typedef boost::function<void (U32, void*)> state_callback_t;
typedef enum
{
STARTING = 0,
READING_FILE,
CREATING_FACES,
GENERATING_VERTEX_BUFFERS,
GENERATING_LOD,
DONE,
WARNING_BIND_SHAPE_ORIENTATION,
ERROR_PARSING, //basically loading failed
ERROR_MATERIALS_NOT_A_SUBSET, // <FS:Beq/> FIRE-30965 - better error differentiation
ERROR_PASSWORD_REQUIRED,
ERROR_NEED_MORE_MEMORY,
ERROR_INVALID_FILE,
ERROR_LOADER_SETUP,
ERROR_INVALID_PARAMETERS,
ERROR_OUT_OF_RANGE,
ERROR_FILE_VERSION_INVALID,
ERROR_LOD_MODEL_MISMATCH, // <FS:Beq/> clean up and improve error reporting
ERROR_HIGH_LOD_MODEL_MISSING, // <FS:Beq/> clean up and improve error reporting
ERROR_MODEL // this error should always be last in this list, error code is passed as ERROR_MODEL+error_code
} eLoadState;
U32 mState;
std::string mFilename;
S32 mLod;
LLMatrix4 mTransform;
bool mFirstTransform;
LLVector3 mExtents[2];
bool mTrySLM;
bool mCacheOnlyHitIfRigged; // ignore cached SLM if it does not contain rig info (and we want rig info)
model_list mModelList;
scene mScene;
typedef std::queue<LLPointer<LLModel> > model_queue;
//queue of models that need a physics rep
model_queue mPhysicsQ;
//map of avatar joints as named in COLLADA assets to internal joint names
JointMap mJointMap;
JointTransformMap& mJointList;
JointNameSet& mJointsFromNode;
U32 mMaxJointsPerMesh;
LLModelLoader(
std::string filename,
S32 lod,
LLModelLoader::load_callback_t load_cb,
LLModelLoader::joint_lookup_func_t joint_lookup_func,
LLModelLoader::texture_load_func_t texture_load_func,
LLModelLoader::state_callback_t state_cb,
void* opaque_userdata,
JointTransformMap& jointTransformMap,
JointNameSet& jointsFromNodes,
JointMap& legalJointNamesMap,
U32 maxJointsPerMesh);
virtual ~LLModelLoader();
virtual void setNoNormalize() { mNoNormalize = true; }
virtual void setNoOptimize() { mNoOptimize = true; }
virtual void run();
static bool getSLMFilename(const std::string& model_filename, std::string& slm_filename);
// Will try SLM or derived class OpenFile as appropriate
//
virtual bool doLoadModel();
// Derived classes need to provide their parsing of files here
//
virtual bool OpenFile(const std::string& filename) = 0;
bool loadFromSLM(const std::string& filename);
void loadModelCallback();
void loadTextures() ; // called in the main thread.
void setLoadState(U32 state);
void stretch_extents(const LLModel* model, const LLMatrix4& mat);
S32 mNumOfFetchingTextures ; // updated in the main thread
bool areTexturesReady() { return !mNumOfFetchingTextures; } // called in the main thread.
bool verifyCount( int expected, int result );
//Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps)
void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset );
//Determines if a rig is a legacy from the joint list
U32 determineRigLegacyFlags( const std::vector<std::string> &jointListFromAsset );
//Determines if a rig is suitable for upload
bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset );
const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; }
void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; }
const bool isLegacyRigValid(void) const { return mLegacyRigFlags == 0; }
U32 getLegacyRigFlags() const { return mLegacyRigFlags; }
void setLegacyRigFlags( U32 rigFlags ) { mLegacyRigFlags = rigFlags; }
//-----------------------------------------------------------------------------
// isNodeAJoint()
//-----------------------------------------------------------------------------
bool isNodeAJoint(const char* name)
{
return name != NULL && mJointMap.find(name) != mJointMap.end();
}
const LLSD logOut() const { return mWarningsArray; }
void clearLog() { mWarningsArray.clear(); }
protected:
LLModelLoader::load_callback_t mLoadCallback;
LLModelLoader::joint_lookup_func_t mJointLookupFunc;
LLModelLoader::texture_load_func_t mTextureLoadFunc;
LLModelLoader::state_callback_t mStateCallback;
void* mOpaqueData;
bool mRigValidJointUpload;
U32 mLegacyRigFlags;
bool mNoNormalize;
bool mNoOptimize;
JointTransformMap mJointTransformMap;
LLSD mWarningsArray; // preview floater will pull logs from here
static std::list<LLModelLoader*> sActiveLoaderList;
static bool isAlive(LLModelLoader* loader);
};
#endif // LL_LLMODELLOADER_H