Modify importer to (optionally) improve debug output, perform name-based LOD association, and handle models with many materials.

master
Graham Linden 2014-04-22 08:58:38 -07:00
parent c71e459bed
commit ae035a0d66
20 changed files with 1280 additions and 3618 deletions

View File

@ -36,6 +36,7 @@ set(llcommon_SOURCE_FILES
llavatarname.cpp
llbase32.cpp
llbase64.cpp
llcallbacklist.cpp
llcommon.cpp
llcommonutils.cpp
llcoros.cpp
@ -139,6 +140,7 @@ set(llcommon_HEADER_FILES
llboost.h
llchat.h
llclickaction.h
llcallbacklist.h
llcommon.h
llcommonutils.h
llcoros.h

View File

@ -24,16 +24,10 @@
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llcallbacklist.h"
#include "lleventtimer.h"
#include "llerrorlegacy.h"
// Library includes
#include "llerror.h"
//
// Globals
//
LLCallbackList gIdleCallbacks;
@ -56,24 +50,24 @@ void LLCallbackList::addFunction( callback_t func, void *data)
{
if (!func)
{
llerrs << "LLCallbackList::addFunction - function is NULL" << llendl;
return;
}
// only add one callback per func/data pair
callback_pair_t t(func, data);
callback_list_t::iterator iter = std::find(mCallbackList.begin(), mCallbackList.end(), t);
if (iter == mCallbackList.end())
//
if (containsFunction(func))
{
mCallbackList.push_back(t);
return;
}
callback_pair_t t(func, data);
mCallbackList.push_back(t);
}
BOOL LLCallbackList::containsFunction( callback_t func, void *data)
bool LLCallbackList::containsFunction( callback_t func, void *data)
{
callback_pair_t t(func, data);
callback_list_t::iterator iter = std::find(mCallbackList.begin(), mCallbackList.end(), t);
callback_list_t::iterator iter = find(func,data);
if (iter != mCallbackList.end())
{
return TRUE;
@ -85,10 +79,9 @@ BOOL LLCallbackList::containsFunction( callback_t func, void *data)
}
BOOL LLCallbackList::deleteFunction( callback_t func, void *data)
bool LLCallbackList::deleteFunction( callback_t func, void *data)
{
callback_pair_t t(func, data);
callback_list_t::iterator iter = std::find(mCallbackList.begin(), mCallbackList.end(), t);
callback_list_t::iterator iter = find(func,data);
if (iter != mCallbackList.end())
{
mCallbackList.erase(iter);
@ -100,6 +93,13 @@ BOOL LLCallbackList::deleteFunction( callback_t func, void *data)
}
}
inline
LLCallbackList::callback_list_t::iterator
LLCallbackList::find(callback_t func, void *data)
{
callback_pair_t t(func, data);
return std::find(mCallbackList.begin(), mCallbackList.end(), t);
}
void LLCallbackList::deleteAllFunctions()
{
@ -228,78 +228,3 @@ void doPeriodically(bool_func_t callable, F32 seconds)
{
new BoolFuncEventTimer(callable, seconds);
}
#ifdef _DEBUG
void test1(void *data)
{
S32 *s32_data = (S32 *)data;
llinfos << "testfunc1 " << *s32_data << llendl;
}
void test2(void *data)
{
S32 *s32_data = (S32 *)data;
llinfos << "testfunc2 " << *s32_data << llendl;
}
void
LLCallbackList::test()
{
S32 a = 1;
S32 b = 2;
LLCallbackList *list = new LLCallbackList;
llinfos << "Testing LLCallbackList" << llendl;
if (!list->deleteFunction(NULL))
{
llinfos << "passed 1" << llendl;
}
else
{
llinfos << "error, removed function from empty list" << llendl;
}
// llinfos << "This should crash" << llendl;
// list->addFunction(NULL);
list->addFunction(&test1, &a);
list->addFunction(&test1, &a);
llinfos << "Expect: test1 1, test1 1" << llendl;
list->callFunctions();
list->addFunction(&test1, &b);
list->addFunction(&test2, &b);
llinfos << "Expect: test1 1, test1 1, test1 2, test2 2" << llendl;
list->callFunctions();
if (list->deleteFunction(&test1, &b))
{
llinfos << "passed 3" << llendl;
}
else
{
llinfos << "error removing function" << llendl;
}
llinfos << "Expect: test1 1, test1 1, test2 2" << llendl;
list->callFunctions();
list->deleteAllFunctions();
llinfos << "Expect nothing" << llendl;
list->callFunctions();
llinfos << "nothing :-)" << llendl;
delete list;
llinfos << "test complete" << llendl;
}
#endif // _DEBUG

View File

@ -28,27 +28,34 @@
#define LL_LLCALLBACKLIST_H
#include "llstl.h"
#include <boost/function.hpp>
#include <list>
class LLCallbackList
{
public:
typedef void (*callback_t)(void*);
typedef std::pair< callback_t,void* > callback_pair_t;
// NOTE: It is confirmed that we DEPEND on the order provided by using a list :(
//
typedef std::list< callback_pair_t > callback_list_t;
LLCallbackList();
~LLCallbackList();
void addFunction( callback_t func, void *data = NULL ); // register a callback, which will be called as func(data)
BOOL containsFunction( callback_t func, void *data = NULL ); // true if list already contains the function/data pair
BOOL deleteFunction( callback_t func, void *data = NULL ); // removes the first instance of this function/data pair from the list, false if not found
void callFunctions(); // calls all functions
void addFunction( callback_t func, void *data = NULL ); // register a callback, which will be called as func(data)
bool containsFunction( callback_t func, void *data = NULL ); // true if list already contains the function/data pair
bool deleteFunction( callback_t func, void *data = NULL ); // removes the first instance of this function/data pair from the list, false if not found
void callFunctions(); // calls all functions
void deleteAllFunctions();
static void test();
protected:
// Use a list so that the callbacks are ordered in case that matters
typedef std::pair<callback_t,void*> callback_pair_t;
typedef std::list<callback_pair_t > callback_list_t;
inline callback_list_t::iterator find(callback_t func, void *data);
callback_list_t mCallbackList;
};

View File

@ -33,6 +33,7 @@
#include <string>
#include "stdtypes.h"
#include "llpreprocessor.h"
/**
* @class LLDate

View File

@ -305,7 +305,6 @@ protected:
virtual ~LLInstanceTracker()
{
// it's unsafe to delete instances of this type while all instances are being iterated over.
llassert_always(getStatic().sIterationNestDepth == 0);
getSet_().erase(static_cast<T*>(this));
}

View File

@ -27,6 +27,8 @@
#ifndef LL_LLSTL_H
#define LL_LLSTL_H
#include "stdtypes.h"
#include <functional>
#include <algorithm>
#include <map>
@ -489,7 +491,7 @@ bool before(const std::type_info* lhs, const std::type_info* rhs)
return strcmp(lhs->name(), rhs->name()) < 0;
#else // not Linux, or gcc 4.4+
// Just use before(), as we normally would
return lhs->before(*rhs);
return lhs->before(*rhs) ? true : false;
#endif
}

View File

@ -969,6 +969,7 @@ protected:
~LLVolume(); // use unref
public:
typedef std::vector<LLVolumeFace> face_list_t;
struct FaceParams
{
@ -1041,6 +1042,10 @@ public:
// conversion if *(LLVolume*) to LLVolume&
const LLVolumeFace &getVolumeFace(const S32 f) const {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE
LLVolumeFace &getVolumeFace(const S32 f) {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE
face_list_t& getVolumeFaces() { return mVolumeFaces; }
U32 mFaceMask; // bit array of which faces exist in this volume
LLVector3 mLODScaleBias; // vector for biasing LOD based on scale

View File

@ -274,6 +274,19 @@ const LLMatrix4& LLMatrix4::invert(void)
return *this;
}
// Convenience func for simplifying comparison-heavy code by
// intentionally stomping values in [-FLT_EPS,FLT_EPS] to 0.0f
//
void LLMatrix4::condition(void)
{
U32 i;
U32 j;
for (i = 0; i < 3;i++)
for (j = 0; j < 3;j++)
mMatrix[i][j] = ((mMatrix[i][j] > -FLT_EPSILON)
&& (mMatrix[i][j] < FLT_EPSILON)) ? 0.0f : mMatrix[i][j];
}
LLVector4 LLMatrix4::getFwdRow4() const
{
return LLVector4(mMatrix[VX][VX], mMatrix[VX][VY], mMatrix[VX][VZ], mMatrix[VX][VW]);

View File

@ -180,6 +180,11 @@ public:
const LLMatrix4& setTranslation(const LLVector4 &translation);
const LLMatrix4& setTranslation(const LLVector3 &translation);
// Convenience func for simplifying comparison-heavy code by
// intentionally stomping values [-FLT_EPS,FLT_EPS] to 0.0
//
void condition(void);
///////////////////////////
//
// Get properties of a matrix

View File

@ -8,6 +8,7 @@ include(LLMath)
include(LLMessage)
include(LLXML)
include(LLPhysicsExtensions)
include(LLCharacter)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
@ -16,6 +17,7 @@ include_directories(
${LLXML_INCLUDE_DIRS}
${LIBS_PREBUILT_DIR}/include/collada
${LIBS_PREBUILT_DIR}/include/collada/1.4
${LLCHARACTER_INCLUDE_DIRS}
)
include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
@ -24,11 +26,13 @@ include_directories(SYSTEM
)
set(llprimitive_SOURCE_FILES
lldaeloader.cpp
llmaterialid.cpp
llmaterial.cpp
llmaterialtable.cpp
llmediaentry.cpp
llmodel.cpp
llmodelloader.cpp
llprimitive.cpp
llprimtexturelist.cpp
lltextureanim.cpp
@ -41,13 +45,14 @@ set(llprimitive_SOURCE_FILES
set(llprimitive_HEADER_FILES
CMakeLists.txt
lldaeloader.h
legacy_object_types.h
llmaterial.h
llmaterialid.h
llmaterialtable.h
llmediaentry.h
llmodel.h
llmodelloader.h
llprimitive.h
llprimtexturelist.h
lltextureanim.h
@ -73,6 +78,7 @@ target_link_libraries(llprimitive
${LLMESSAGE_LIBRARIES}
${LLXML_LIBRARIES}
${LLPHYSICSEXTENSIONS_LIBRARIES}
${LLCHARACTER_LIBRARIES}
)

File diff suppressed because it is too large Load Diff

View File

@ -138,15 +138,16 @@ public:
BOOL upload_skin,
BOOL upload_joints,
BOOL nowrite = FALSE,
BOOL as_slm = FALSE);
BOOL as_slm = FALSE,
int submodel_id = 0);
static LLSD writeModelToStream(
std::ostream& ostr,
LLSD& mdl,
BOOL nowrite = FALSE, BOOL as_slm = FALSE);
void ClearFacesAndMaterials() { mVolumeFaces.clear(); mMaterialList.clear(); }
static LLModel* loadModelFromDomMesh(domMesh* mesh);
static std::string getElementLabel(daeElement* element);
std::string getName() const;
std::string getMetric() const {return mMetric;}
EModelStatus getStatus() const {return mStatus;}
@ -169,20 +170,25 @@ public:
void addFace(const LLVolumeFace& face);
void sortVolumeFacesByMaterialName();
void normalizeVolumeFaces();
void trimVolumeFacesToSize(U32 new_count = LL_SCULPT_MESH_MAX_FACES, LLVolume::face_list_t* remainder = NULL);
void optimizeVolumeFaces();
void offsetMesh( const LLVector3& pivotPoint );
void getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out);
LLVector3 getTransformedCenter(const LLMatrix4& mat);
//reorder face list based on mMaterialList in this and reference so
//order matches that of reference (material ordering touchup)
bool matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
bool isMaterialListSubset( LLModel* ref );
bool needToAddFaces( LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
std::vector<std::string> mMaterialList;
typedef std::vector<std::string> material_list;
material_list mMaterialList;
material_list& getMaterialList() { return mMaterialList; }
//data used for skin weights
class JointWeight
@ -275,9 +281,115 @@ public:
Decomposition mPhysics;
EModelStatus mStatus ;
protected:
void addVolumeFacesFromDomMesh(domMesh* mesh);
virtual BOOL createVolumeFacesFromDomMesh(domMesh *mesh);
int mSubmodelID;
};
typedef std::vector<LLPointer<LLModel> > model_list;
typedef std::queue<LLPointer<LLModel> > model_queue;
class LLModelMaterialBase
{
public:
std::string mDiffuseMapFilename;
std::string mDiffuseMapLabel;
std::string mBinding;
LLColor4 mDiffuseColor;
bool mFullbright;
LLModelMaterialBase()
: mFullbright(false)
{
mDiffuseColor.set(1,1,1,1);
}
};
class LLImportMaterial : public LLModelMaterialBase
{
public:
friend class LLMeshUploadThread;
friend class LLModelPreview;
bool operator<(const LLImportMaterial &params) const;
LLImportMaterial() : LLModelMaterialBase()
{
mDiffuseColor.set(1,1,1,1);
}
LLImportMaterial(LLSD& data);
virtual ~LLImportMaterial();
LLSD asLLSD();
const LLUUID& getDiffuseMap() const { return mDiffuseMapID; }
void setDiffuseMap(const LLUUID& texId) { mDiffuseMapID = texId; }
protected:
LLUUID mDiffuseMapID;
void* mOpaqueData; // allow refs to viewer/platform-specific structs for each material
// currently only stores an LLPointer< LLViewerFetchedTexture > > to
// maintain refs to textures associated with each material for free
// ref counting.
};
typedef std::map<std::string, LLImportMaterial> material_map;
class LLModelInstanceBase
{
public:
LLPointer<LLModel> mModel;
LLPointer<LLModel> mLOD[5];
LLUUID mMeshID;
LLMatrix4 mTransform;
material_map mMaterial;
LLModelInstanceBase(LLModel* model, LLMatrix4& transform, material_map& materials)
: mModel(model), mTransform(transform), mMaterial(materials)
{
}
LLModelInstanceBase()
: mModel(NULL)
{
}
};
typedef std::vector<LLModelInstanceBase> model_instance_list;
class LLModelInstance : public LLModelInstanceBase
{
public:
std::string mLabel;
LLUUID mMeshID;
S32 mLocalMeshID;
LLModelInstance(LLModel* model, const std::string& label, LLMatrix4& transform, material_map& materials)
: LLModelInstanceBase(model, transform, materials), mLabel(label)
{
mLocalMeshID = -1;
}
LLModelInstance(LLSD& data);
LLSD asLLSD();
};
#define LL_DEGENERACY_TOLERANCE 1e-7f
inline F32 dot3fpu(const LLVector4a& a, const LLVector4a& b)
{
volatile F32 p0 = a[0] * b[0];
volatile F32 p1 = a[1] * b[1];
volatile F32 p2 = a[2] * b[2];
return p0 + p1 + p2;
}
bool ll_is_degenerate(const LLVector4a& a, const LLVector4a& b, const LLVector4a& c, F32 tolerance = LL_DEGENERACY_TOLERANCE);
bool validate_face(const LLVolumeFace& face);
bool validate_model(const LLModel* mdl);
#endif //LL_LLMODEL_H

View File

@ -191,6 +191,13 @@ bool LLTextureEntry::operator==(const LLTextureEntry &rhs) const
return(true);
}
bool LLTextureEntry::operator <(const LLTextureEntry &rhs) const
{
if (mID < rhs.mID) return(true);
if (mMaterialID < rhs.mMaterialID) return (true);
return(false);
}
LLSD LLTextureEntry::asLLSD() const
{
LLSD sd;
@ -545,7 +552,7 @@ S32 LLTextureEntry::setMaterialID(const LLMaterialID& pMaterialID)
{
mMaterialUpdatePending = true;
mMaterialID = pMaterialID;
return TEM_CHANGE_TEXTURE;
return TEM_CHANGE_NONE;
}
mMaterialUpdatePending = false;

View File

@ -89,6 +89,10 @@ public:
bool operator==(const LLTextureEntry &rhs) const;
bool operator!=(const LLTextureEntry &rhs) const;
// Added to allow use with std::map
//
bool operator <(const LLTextureEntry &rhs) const;
LLSD asLLSD() const;
void asLLSD(LLSD& sd) const;

View File

@ -132,7 +132,6 @@ set(viewer_SOURCE_FILES
llbreadcrumbview.cpp
llbrowsernotification.cpp
llbuycurrencyhtml.cpp
llcallbacklist.cpp
llcallingcard.cpp
llcapabilitylistener.cpp
llcaphttpsender.cpp
@ -720,7 +719,6 @@ set(viewer_HEADER_FILES
llbox.h
llbreadcrumbview.h
llbuycurrencyhtml.h
llcallbacklist.h
llcallingcard.h
llcapabilitylistener.h
llcapabilityprovider.h

View File

@ -2,6 +2,28 @@
<llsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="llsd.xsd">
<map>
<key>ImporterDebug</key>
<map>
<key>Comment</key>
<string>Enable debug output to more precisely identify sources of import errors. Warning: the output can slow down import on many machines.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Integer</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>IMShowTime</key>
<map>
<key>Comment</key>
<string>Enable(disable) timestamp showing in the chat.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>IMShowTime</key>
<map>
<key>Comment</key>

File diff suppressed because it is too large Load Diff

View File

@ -37,6 +37,8 @@
#include "llviewermenufile.h"
#include "llfloatermodeluploadbase.h"
#include "lldaeloader.h"
class LLComboBox;
class LLJoint;
class LLViewerJointMesh;
@ -45,103 +47,18 @@ class LLTextBox;
class LLVertexBuffer;
class LLModelPreview;
class LLFloaterModelPreview;
class DAE;
class daeElement;
class domProfile_COMMON;
class domInstance_geometry;
class domNode;
class domTranslate;
class domController;
class domSkin;
class domMesh;
class LLMenuButton;
class LLToggleableMenu;
typedef std::map<std::string, LLMatrix4> JointTransformMap;
typedef std::map<std::string, LLMatrix4>:: iterator JointTransformMapIt;
const S32 NUM_LOD = 4;
class LLModelLoader : public LLThread
{
public:
typedef enum
{
STARTING = 0,
READING_FILE,
CREATING_FACES,
GENERATING_VERTEX_BUFFERS,
GENERATING_LOD,
DONE,
ERROR_PARSING, //basically loading failed
ERROR_MATERIALS,
} eLoadState;
U32 mState;
std::string mFilename;
S32 mLod;
LLModelPreview* mPreview;
LLMatrix4 mTransform;
BOOL mFirstTransform;
LLVector3 mExtents[2];
bool mTrySLM;
std::map<daeElement*, LLPointer<LLModel> > mModel;
typedef std::vector<LLPointer<LLModel> > model_list;
model_list mModelList;
typedef std::vector<LLModelInstance> model_instance_list;
typedef std::map<LLMatrix4, model_instance_list > scene;
scene mScene;
typedef std::queue<LLPointer<LLModel> > model_queue;
//queue of models that need a physics rep
model_queue mPhysicsQ;
LLModelLoader( std::string filename, S32 lod, LLModelPreview* preview, JointTransformMap& jointMap,
std::deque<std::string>& jointsFromNodes );
~LLModelLoader() ;
virtual void run();
bool doLoadModel();
bool loadFromSLM(const std::string& filename);
void loadModelCallback();
void loadTextures() ; //called in the main thread.
void processElement(daeElement* element, bool& badElement);
std::map<std::string, LLImportMaterial> getMaterials(LLModel* model, domInstance_geometry* instance_geo);
LLImportMaterial profileToMaterial(domProfile_COMMON* material);
std::string getElementLabel(daeElement *element);
LLColor4 getDaeColor(daeElement* element);
daeElement* getChildFromElement( daeElement* pElement, std::string const & name );
bool isNodeAJoint( domNode* pNode );
void processJointNode( domNode* pNode, std::map<std::string,LLMatrix4>& jointTransforms );
void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform );
void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform );
void extractTranslationViaSID( daeElement* pElement, LLMatrix4& transform );
void setLoadState(U32 state);
void buildJointToNodeMappingFromScene( daeElement* pRoot );
void processJointToNodeMapping( domNode* pNode );
void processChildJoints( domNode* pParentNode );
//map of avatar joints as named in COLLADA assets to internal joint names
std::map<std::string, std::string> mJointMap;
JointTransformMap& mJointList;
std::deque<std::string>& mJointsFromNode;
S32 mNumOfFetchingTextures ; //updated in the main thread
bool areTexturesReady() { return !mNumOfFetchingTextures; } //called in the main thread.
private:
static std::list<LLModelLoader*> sActiveLoaderList;
static bool isAlive(LLModelLoader* loader) ;
};
class LLFloaterModelPreview : public LLFloaterModelUploadBase
{
public:
@ -358,21 +275,14 @@ public:
void setHasPivot( bool val ) { mHasPivot = val; }
void setModelPivot( const LLVector3& pivot ) { mModelPivot = pivot; }
//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 );
void critiqueJointToNodeMappingFromScene( void );
//Is a rig valid so that it can be used as a criteria for allowing for uploading of joint positions
//Accessors for joint position upload friendly rigs
const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; }
void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; }
bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset );
//Determines if a rig is a legacy from the joint list
bool isRigLegacy( const std::vector<std::string> &jointListFromAsset );
//Accessors for the legacy rigs
const bool isLegacyRigValid( void ) const { return mLegacyRigValid; }
void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; }
//Verify that a controller matches vertex counts
bool verifyController( domController* pController );
void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; }
static void textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
@ -387,6 +297,14 @@ public:
LLVector3 getTranslationForJointOffset( std::string joint );
protected:
static void loadedCallback(LLModelLoader::scene& scene,LLModelLoader::model_list& model_list, S32 lod, void* opaque);
static void stateChangedCallback(U32 state, void* opaque);
static LLJoint* lookupJointByName(const std::string&, void* opaque);
static U32 loadTextures(LLImportMaterial& material, void* opaque);
private:
//Utility function for controller vertex compare
bool verifyCount( int expected, int result );
@ -452,7 +370,7 @@ private:
U32 mMaxTriangleLimit;
LLMeshUploadThread::instance_list mUploadData;
std::set<LLViewerFetchedTexture* > mTextureSet;
std::set<LLViewerFetchedTexture * > mTextureSet;
//map of vertex buffers to models (one vertex buffer in vector per face in model
std::map<LLModel*, std::vector<LLPointer<LLVertexBuffer> > > mVertexBuffer[LLModel::NUM_LODS+1];
@ -470,11 +388,10 @@ private:
bool mLegacyRigValid;
bool mLastJointUpdate;
JointSet mJointsFromNode;
JointTransformMap mJointTransformMap;
std::deque<std::string> mMasterJointList;
std::deque<std::string> mMasterLegacyJointList;
std::deque<std::string> mJointsFromNode;
JointTransformMap mJointTransformMap;
LLPointer<LLVOAvatar> mPreviewAvatar;
};

View File

@ -498,6 +498,12 @@ void get_vertex_buffer_from_mesh(LLCDMeshData& mesh, LLModel::PhysicsMesh& res,
}
}
LLViewerFetchedTexture* LLMeshUploadThread::FindViewerTexture(const LLImportMaterial& material)
{
LLPointer< LLViewerFetchedTexture > * ppTex = static_cast< LLPointer< LLViewerFetchedTexture > * >(material.mOpaqueData);
return ppTex ? (*ppTex).get() : NULL;
}
volatile S32 LLMeshRepoThread::sActiveHeaderRequests = 0;
volatile S32 LLMeshRepoThread::sActiveLODRequests = 0;
U32 LLMeshRepoThread::sMaxConcurrentRequests = 1;
@ -2027,6 +2033,14 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
{
LLMeshUploadData data;
data.mBaseModel = iter->first;
if (data.mBaseModel->mSubmodelID)
{
// These are handled below to insure correct parenting order on creation
// due to map walking being based on model address (aka random)
continue;
}
LLModelInstance& first_instance = *(iter->second.begin());
for (S32 i = 0; i < 5; i++)
{
@ -2064,7 +2078,10 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
data.mModel[LLModel::LOD_IMPOSTOR],
decomp,
mUploadSkin,
mUploadJoints);
mUploadJoints,
FALSE,
FALSE,
data.mBaseModel->mSubmodelID);
data.mAssetData = ostr.str();
std::string str = ostr.str();
@ -2098,17 +2115,26 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
instance_entry["scale"] = ll_sd_from_vector3(scale);
instance_entry["material"] = LL_MCODE_WOOD;
instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);
instance_entry["physics_shape_type"] = data.mModel[LLModel::LOD_PHYSICS].notNull() ? (U8)(LLViewerObject::PHYSICS_SHAPE_PRIM) : (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);
instance_entry["mesh"] = mesh_index[data.mBaseModel];
instance_entry["face_list"] = LLSD::emptyArray();
S32 end = llmin((S32)data.mBaseModel->mMaterialList.size(), data.mBaseModel->getNumVolumeFaces()) ;
// We want to be able to allow more than 8 materials...
//
S32 end = llmin((S32)instance.mMaterial.size(), instance.mModel->getNumVolumeFaces()) ;
for (S32 face_num = 0; face_num < end; face_num++)
{
LLImportMaterial& material = instance.mMaterial[data.mBaseModel->mMaterialList[face_num]];
LLSD face_entry = LLSD::emptyMap();
LLViewerFetchedTexture *texture = material.mDiffuseMap.get();
LLViewerFetchedTexture *texture = NULL;
if (material.mDiffuseMapFilename.size())
{
texture = FindViewerTexture(material);
}
if ((texture != NULL) &&
(textures.find(texture) == textures.end()))
@ -2123,9 +2149,171 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
{
LLPointer<LLImageJ2C> upload_file =
LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage());
if (!upload_file.isNull() && upload_file->getDataSize())
{
texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());
}
}
}
if (texture != NULL &&
mUploadTextures &&
texture_index.find(texture) == texture_index.end())
{
texture_index[texture] = texture_num;
std::string str = texture_str.str();
res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end());
texture_num++;
}
// Subset of TextureEntry fields.
if (texture != NULL && mUploadTextures)
{
face_entry["image"] = texture_index[texture];
face_entry["scales"] = 1.0;
face_entry["scalet"] = 1.0;
face_entry["offsets"] = 0.0;
face_entry["offsett"] = 0.0;
face_entry["imagerot"] = 0.0;
}
face_entry["diffuse_color"] = ll_sd_from_color4(material.mDiffuseColor);
face_entry["fullbright"] = material.mFullbright;
instance_entry["face_list"][face_num] = face_entry;
}
res["instance_list"][instance_num] = instance_entry;
instance_num++;
}
}
for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter)
{
LLMeshUploadData data;
data.mBaseModel = iter->first;
if (!data.mBaseModel->mSubmodelID)
{
// These were handled above already...
//
continue;
}
LLModelInstance& first_instance = *(iter->second.begin());
for (S32 i = 0; i < 5; i++)
{
data.mModel[i] = first_instance.mLOD[i];
}
if (mesh_index.find(data.mBaseModel) == mesh_index.end())
{
// Have not seen this model before - create a new mesh_list entry for it.
if (model_name.empty())
{
model_name = data.mBaseModel->getName();
}
if (model_metric.empty())
{
model_metric = data.mBaseModel->getMetric();
}
std::stringstream ostr;
LLModel::Decomposition& decomp =
data.mModel[LLModel::LOD_PHYSICS].notNull() ?
data.mModel[LLModel::LOD_PHYSICS]->mPhysics :
data.mBaseModel->mPhysics;
decomp.mBaseHull = mHullMap[data.mBaseModel];
LLSD mesh_header = LLModel::writeModel(
ostr,
data.mModel[LLModel::LOD_PHYSICS],
data.mModel[LLModel::LOD_HIGH],
data.mModel[LLModel::LOD_MEDIUM],
data.mModel[LLModel::LOD_LOW],
data.mModel[LLModel::LOD_IMPOSTOR],
decomp,
mUploadSkin,
mUploadJoints,
FALSE,
FALSE,
data.mBaseModel->mSubmodelID);
data.mAssetData = ostr.str();
std::string str = ostr.str();
res["mesh_list"][mesh_num] = LLSD::Binary(str.begin(),str.end());
mesh_index[data.mBaseModel] = mesh_num;
mesh_num++;
}
// For all instances that use this model
for (instance_list::iterator instance_iter = iter->second.begin();
instance_iter != iter->second.end();
++instance_iter)
{
LLModelInstance& instance = *instance_iter;
LLSD instance_entry;
for (S32 i = 0; i < 5; i++)
{
data.mModel[i] = instance.mLOD[i];
}
LLVector3 pos, scale;
LLQuaternion rot;
LLMatrix4 transformation = instance.mTransform;
decomposeMeshMatrix(transformation,pos,rot,scale);
instance_entry["position"] = ll_sd_from_vector3(pos);
instance_entry["rotation"] = ll_sd_from_quaternion(rot);
instance_entry["scale"] = ll_sd_from_vector3(scale);
instance_entry["material"] = LL_MCODE_WOOD;
instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_NONE);
instance_entry["mesh"] = mesh_index[data.mBaseModel];
instance_entry["face_list"] = LLSD::emptyArray();
// We want to be able to allow more than 8 materials...
//
S32 end = llmin((S32)instance.mMaterial.size(), instance.mModel->getNumVolumeFaces()) ;
for (S32 face_num = 0; face_num < end; face_num++)
{
LLImportMaterial& material = instance.mMaterial[data.mBaseModel->mMaterialList[face_num]];
LLSD face_entry = LLSD::emptyMap();
LLViewerFetchedTexture *texture = NULL;
if (material.mDiffuseMapFilename.size())
{
texture = FindViewerTexture(material);
}
if ((texture != NULL) &&
(textures.find(texture) == textures.end()))
{
textures.insert(texture);
}
std::stringstream texture_str;
if (texture != NULL && include_textures && mUploadTextures)
{
if(texture->hasSavedRawImage())
{
LLPointer<LLImageJ2C> upload_file =
LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage());
if (!upload_file.isNull() && upload_file->getDataSize())
{
texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());
}
}
}
if (texture != NULL &&
mUploadTextures &&
@ -3756,37 +3944,6 @@ void LLMeshUploadThread::decomposeMeshMatrix(LLMatrix4& transformation,
result_rot = quat_rotation;
}
bool LLImportMaterial::operator<(const LLImportMaterial &rhs) const
{
if (mDiffuseMap != rhs.mDiffuseMap)
{
return mDiffuseMap < rhs.mDiffuseMap;
}
if (mDiffuseMapFilename != rhs.mDiffuseMapFilename)
{
return mDiffuseMapFilename < rhs.mDiffuseMapFilename;
}
if (mDiffuseMapLabel != rhs.mDiffuseMapLabel)
{
return mDiffuseMapLabel < rhs.mDiffuseMapLabel;
}
if (mDiffuseColor != rhs.mDiffuseColor)
{
return mDiffuseColor < rhs.mDiffuseColor;
}
if (mBinding != rhs.mBinding)
{
return mBinding < rhs.mBinding;
}
return mFullbright < rhs.mFullbright;
}
void LLMeshRepository::updateInventory(inventory_data data)
{
LLMutexLock lock(mMeshMutex);
@ -4372,60 +4529,6 @@ void LLPhysicsDecomp::Request::setStatusMessage(const std::string& msg)
mStatusMessage = msg;
}
LLModelInstance::LLModelInstance(LLSD& data)
{
mLocalMeshID = data["mesh_id"].asInteger();
mLabel = data["label"].asString();
mTransform.setValue(data["transform"]);
for (U32 i = 0; i < data["material"].size(); ++i)
{
LLImportMaterial mat(data["material"][i]);
mMaterial[mat.mBinding] = mat;
}
}
LLSD LLModelInstance::asLLSD()
{
LLSD ret;
ret["mesh_id"] = mModel->mLocalID;
ret["label"] = mLabel;
ret["transform"] = mTransform.getValue();
U32 i = 0;
for (std::map<std::string, LLImportMaterial>::iterator iter = mMaterial.begin(); iter != mMaterial.end(); ++iter)
{
ret["material"][i++] = iter->second.asLLSD();
}
return ret;
}
LLImportMaterial::LLImportMaterial(LLSD& data)
{
mDiffuseMapFilename = data["diffuse"]["filename"].asString();
mDiffuseMapLabel = data["diffuse"]["label"].asString();
mDiffuseColor.setValue(data["diffuse"]["color"]);
mFullbright = data["fullbright"].asBoolean();
mBinding = data["binding"].asString();
}
LLSD LLImportMaterial::asLLSD()
{
LLSD ret;
ret["diffuse"]["filename"] = mDiffuseMapFilename;
ret["diffuse"]["label"] = mDiffuseMapLabel;
ret["diffuse"]["color"] = mDiffuseColor.getValue();
ret["fullbright"] = mFullbright;
ret["binding"] = mBinding;
return ret;
}
void LLMeshRepository::buildPhysicsMesh(LLModel::Decomposition& decomp)
{
decomp.mMesh.resize(decomp.mHull.size());

View File

@ -90,54 +90,6 @@ public:
}
};
class LLImportMaterial
{
public:
LLPointer<LLViewerFetchedTexture> mDiffuseMap;
std::string mDiffuseMapFilename;
std::string mDiffuseMapLabel;
std::string mBinding;
LLColor4 mDiffuseColor;
bool mFullbright;
bool operator<(const LLImportMaterial &params) const;
LLImportMaterial()
: mFullbright(false)
{
mDiffuseColor.set(1,1,1,1);
}
LLImportMaterial(LLSD& data);
LLSD asLLSD();
};
class LLModelInstance
{
public:
LLPointer<LLModel> mModel;
LLPointer<LLModel> mLOD[5];
std::string mLabel;
LLUUID mMeshID;
S32 mLocalMeshID;
LLMatrix4 mTransform;
std::map<std::string, LLImportMaterial> mMaterial;
LLModelInstance(LLModel* model, const std::string& label, LLMatrix4& transform, std::map<std::string, LLImportMaterial>& materials)
: mModel(model), mLabel(label), mTransform(transform), mMaterial(materials)
{
mLocalMeshID = -1;
}
LLModelInstance(LLSD& data);
LLSD asLLSD();
};
class LLPhysicsDecomp : public LLThread
{
public:
@ -483,6 +435,8 @@ public:
// Inherited from LLCore::HttpHandler
virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
LLViewerFetchedTexture* FindViewerTexture(const LLImportMaterial& material);
private:
LLHandle<LLWholeModelFeeObserver> mFeeObserverHandle;
LLHandle<LLWholeModelUploadObserver> mUploadObserverHandle;