PageRenderTime 62ms CodeModel.GetById 24ms app.highlight 33ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/newview/llfloatermodelpreview.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 475 lines | 322 code | 106 blank | 47 comment | 0 complexity | ea868eec476ed36b9627a80a0bfeaefe MD5 | raw file
  1/**
  2 * @file llfloatermodelpreview.h
  3 * @brief LLFloaterModelPreview class definition
  4 *
  5 * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#ifndef LL_LLFLOATERMODELPREVIEW_H
 28#define LL_LLFLOATERMODELPREVIEW_H
 29
 30#include "llfloaternamedesc.h"
 31
 32#include "lldynamictexture.h"
 33#include "llfloatermodelwizard.h"
 34#include "llquaternion.h"
 35#include "llmeshrepository.h"
 36#include "llmodel.h"
 37#include "llthread.h"
 38#include "llviewermenufile.h"
 39
 40class LLComboBox;
 41class LLJoint;
 42class LLViewerJointMesh;
 43class LLVOAvatar;
 44class LLTextBox;
 45class LLVertexBuffer;
 46class LLModelPreview;
 47class LLFloaterModelPreview;
 48class daeElement;
 49class domProfile_COMMON;
 50class domInstance_geometry;
 51class domNode;
 52class domTranslate;
 53class domController;
 54class LLMenuButton;
 55class LLToggleableMenu;
 56
 57typedef std::map<std::string, LLMatrix4> JointTransformMap;
 58typedef std::map<std::string, LLMatrix4>:: iterator JointTransformMapIt;
 59
 60const S32 NUM_LOD = 4;
 61
 62class LLModelLoader : public LLThread
 63{
 64public:
 65	typedef enum
 66	{
 67		STARTING = 0,
 68		READING_FILE,
 69		CREATING_FACES,
 70		GENERATING_VERTEX_BUFFERS,
 71		GENERATING_LOD,
 72		DONE,
 73		ERROR_PARSING, //basically loading failed
 74		ERROR_MATERIALS,
 75	} eLoadState;
 76
 77	U32 mState;
 78	std::string mFilename;
 79	S32 mLod;
 80	LLModelPreview* mPreview;
 81	LLMatrix4 mTransform;
 82	BOOL mFirstTransform;
 83	LLVector3 mExtents[2];
 84	bool mTrySLM;
 85	
 86	std::map<daeElement*, LLPointer<LLModel> > mModel;
 87	
 88	typedef std::vector<LLPointer<LLModel> > model_list;
 89	model_list mModelList;
 90
 91	typedef std::vector<LLModelInstance> model_instance_list;
 92	
 93	typedef std::map<LLMatrix4, model_instance_list > scene;
 94
 95	scene mScene;
 96
 97	typedef std::queue<LLPointer<LLModel> > model_queue;
 98
 99	//queue of models that need a physics rep
100	model_queue mPhysicsQ;
101
102	LLModelLoader( std::string filename, S32 lod, LLModelPreview* preview, JointTransformMap& jointMap, 
103				   std::deque<std::string>& jointsFromNodes );
104	~LLModelLoader() ;
105
106	virtual void run();
107	bool doLoadModel();
108	bool loadFromSLM(const std::string& filename);
109	void loadModelCallback();
110
111	void loadTextures() ; //called in the main thread.
112	void processElement(daeElement* element, bool& badElement);
113	std::map<std::string, LLImportMaterial> getMaterials(LLModel* model, domInstance_geometry* instance_geo);
114	LLImportMaterial profileToMaterial(domProfile_COMMON* material);
115	std::string getElementLabel(daeElement *element);
116	LLColor4 getDaeColor(daeElement* element);
117	
118	daeElement* getChildFromElement( daeElement* pElement, std::string const & name );
119	
120	bool isNodeAJoint( domNode* pNode );
121	void processJointNode( domNode* pNode, std::map<std::string,LLMatrix4>& jointTransforms );
122	void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform );
123	void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform );
124	void extractTranslationViaSID( daeElement* pElement, LLMatrix4& transform );
125
126	void setLoadState(U32 state);
127
128	void buildJointToNodeMappingFromScene( daeElement* pRoot );
129	void processJointToNodeMapping( domNode* pNode );
130	void processChildJoints( domNode* pParentNode );
131
132	//map of avatar joints as named in COLLADA assets to internal joint names
133	std::map<std::string, std::string> mJointMap;
134	JointTransformMap& mJointList;	
135	std::deque<std::string>& mJointsFromNode;
136
137	S32 mNumOfFetchingTextures ; //updated in the main thread
138	bool areTexturesReady() { return !mNumOfFetchingTextures; } //called in the main thread.
139
140private:
141	static std::list<LLModelLoader*> sActiveLoaderList;
142	static bool isAlive(LLModelLoader* loader) ;
143};
144
145class LLFloaterModelPreview : public LLFloaterModelUploadBase
146{
147public:
148	
149	class DecompRequest : public LLPhysicsDecomp::Request
150	{
151	public:
152		S32 mContinue;
153		LLPointer<LLModel> mModel;
154		
155		DecompRequest(const std::string& stage, LLModel* mdl);
156		virtual S32 statusCallback(const char* status, S32 p1, S32 p2);
157		virtual void completed();
158		
159	};
160	static LLFloaterModelPreview* sInstance;
161	
162	LLFloaterModelPreview(const LLSD& key);
163	virtual ~LLFloaterModelPreview();
164	
165	virtual BOOL postBuild();
166	
167	void initModelPreview();
168
169	BOOL handleMouseDown(S32 x, S32 y, MASK mask);
170	BOOL handleMouseUp(S32 x, S32 y, MASK mask);
171	BOOL handleHover(S32 x, S32 y, MASK mask);
172	BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); 
173	
174	/*virtual*/ void onOpen(const LLSD& key);
175
176	static void onMouseCaptureLostModelPreview(LLMouseHandler*);
177	static void setUploadAmount(S32 amount) { sUploadAmount = amount; }
178
179	void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost);
180	
181	void onBrowseLOD(S32 lod);
182	
183	static void onReset(void* data);
184
185	static void onUpload(void* data);
186	
187	void refresh();
188	
189	void			loadModel(S32 lod);
190	void 			loadModel(S32 lod, const std::string& file_name, bool force_disable_slm = false);
191	
192	void onViewOptionChecked(LLUICtrl* ctrl);
193	bool isViewOptionChecked(const LLSD& userdata);
194	bool isViewOptionEnabled(const LLSD& userdata);
195	void setViewOptionEnabled(const std::string& option, bool enabled);
196	void enableViewOption(const std::string& option);
197	void disableViewOption(const std::string& option);
198
199	// shows warning message if agent has no permissions to upload model
200	/*virtual*/ void onPermissionsReceived(const LLSD& result);
201
202	// called when error occurs during permissions request
203	/*virtual*/ void setPermissonsErrorStatus(U32 status, const std::string& reason);
204
205	/*virtual*/ void onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url);
206				void handleModelPhysicsFeeReceived();
207	/*virtual*/ void setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason);
208
209	/*virtual*/ void onModelUploadSuccess();
210
211	/*virtual*/ void onModelUploadFailure();
212
213protected:
214	friend class LLModelPreview;
215	friend class LLMeshFilePicker;
216	friend class LLPhysicsDecomp;
217	
218	static void		onImportScaleCommit(LLUICtrl*, void*);
219	static void		onPelvisOffsetCommit(LLUICtrl*, void*);
220	static void		onUploadJointsCommit(LLUICtrl*,void*);
221	static void		onUploadSkinCommit(LLUICtrl*,void*);
222
223	static void		onPreviewLODCommit(LLUICtrl*,void*);
224	
225	static void		onGenerateNormalsCommit(LLUICtrl*,void*);
226	
227	void toggleGenarateNormals();
228
229	static void		onAutoFillCommit(LLUICtrl*,void*);
230	
231	void onLODParamCommit(S32 lod, bool enforce_tri_limit);
232
233	static void		onExplodeCommit(LLUICtrl*, void*);
234	
235	static void onPhysicsParamCommit(LLUICtrl* ctrl, void* userdata);
236	static void onPhysicsStageExecute(LLUICtrl* ctrl, void* userdata);
237	static void onCancel(LLUICtrl* ctrl, void* userdata);
238	static void onPhysicsStageCancel(LLUICtrl* ctrl, void* userdata);
239	
240	static void onPhysicsBrowse(LLUICtrl* ctrl, void* userdata);
241	static void onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata);
242	static void onPhysicsOptimize(LLUICtrl* ctrl, void* userdata);
243	static void onPhysicsDecomposeBack(LLUICtrl* ctrl, void* userdata);
244	static void onPhysicsSimplifyBack(LLUICtrl* ctrl, void* userdata);
245		
246	void			draw();
247	
248	void initDecompControls();
249	
250	void setStatusMessage(const std::string& msg);
251
252	LLModelPreview*	mModelPreview;
253	
254	LLPhysicsDecomp::decomp_params mDecompParams;
255	
256	S32				mLastMouseX;
257	S32				mLastMouseY;
258	LLRect			mPreviewRect;
259	U32				mGLName;
260	static S32		sUploadAmount;
261	
262	std::set<LLPointer<DecompRequest> > mCurRequest;
263	std::string mStatusMessage;
264
265	//use "disabled" as false by default
266	std::map<std::string, bool> mViewOptionDisabled;
267	
268	//store which lod mode each LOD is using
269	// 0 - load from file
270	// 1 - auto generate
271	// 2 - use LoD above
272	S32 mLODMode[4];
273
274	LLMutex* mStatusLock;
275
276	LLSD mModelPhysicsFee;
277
278private:
279	void onClickCalculateBtn();
280	void toggleCalculateButton();
281
282	void onLoDSourceCommit(S32 lod);
283
284	// Toggles between "Calculate weights & fee" and "Upload" buttons.
285	void toggleCalculateButton(bool visible);
286
287	// resets display options of model preview to their defaults.
288	void resetDisplayOptions();
289
290	void createSmoothComboBox(LLComboBox* combo_box, float min, float max);
291
292	LLButton* mUploadBtn;
293	LLButton* mCalculateBtn;
294};
295
296class LLMeshFilePicker : public LLFilePickerThread
297{
298public:
299	LLMeshFilePicker(LLModelPreview* mp, S32 lod);
300	virtual void notify(const std::string& filename);
301
302private:
303	LLModelPreview* mMP;
304	S32 mLOD;
305};
306
307
308class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
309{	
310	typedef boost::signals2::signal<void (F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)> details_signal_t;
311	typedef boost::signals2::signal<void (void)> model_loaded_signal_t;
312	typedef boost::signals2::signal<void (bool)> model_updated_signal_t;
313
314public:
315	LLModelPreview(S32 width, S32 height, LLFloater* fmp);
316	virtual ~LLModelPreview();
317
318	void resetPreviewTarget();
319	void setPreviewTarget(F32 distance);
320	void setTexture(U32 name) { mTextureName = name; }
321
322	void setPhysicsFromLOD(S32 lod);
323	BOOL render();
324	void update();
325	void genBuffers(S32 lod, bool skinned);
326	void clearBuffers();
327	void refresh();
328	void rotate(F32 yaw_radians, F32 pitch_radians);
329	void zoom(F32 zoom_amt);
330	void pan(F32 right, F32 up);
331	virtual BOOL needsRender() { return mNeedsUpdate; }
332	void setPreviewLOD(S32 lod);
333	void clearModel(S32 lod);
334	void loadModel(std::string filename, S32 lod, bool force_disable_slm = false);
335	void loadModelCallback(S32 lod);
336	void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false);
337	void generateNormals();
338	U32 calcResourceCost();
339	void rebuildUploadData();
340	void saveUploadData(bool save_skinweights, bool save_joint_poisitions);
341	void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_poisitions);
342	void clearIncompatible(S32 lod);
343	void updateStatusMessages();
344	void updateLodControls(S32 lod);
345	void clearGLODGroup();
346	void onLODParamCommit(S32 lod, bool enforce_tri_limit);
347	void addEmptyFace( LLModel* pTarget );
348	
349	const bool getModelPivot( void ) const { return mHasPivot; }
350	void setHasPivot( bool val ) { mHasPivot = val; }
351	void setModelPivot( const LLVector3& pivot ) { mModelPivot = pivot; }
352
353	//Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps)
354	void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset );
355	void critiqueJointToNodeMappingFromScene( void  );
356	//Is a rig valid so that it can be used as a criteria for allowing for uploading of joint positions
357	//Accessors for joint position upload friendly rigs
358	const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; }
359	void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; }
360	bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset );
361	//Determines if a rig is a legacy from the joint list
362	bool isRigLegacy( const std::vector<std::string> &jointListFromAsset );	
363	//Accessors for the legacy rigs
364	const bool isLegacyRigValid( void ) const { return mLegacyRigValid; }
365	void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; }	
366	//Verify that a controller matches vertex counts
367	bool verifyController( domController* pController );
368
369	static void	textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
370	
371	boost::signals2::connection setDetailsCallback( const details_signal_t::slot_type& cb ){  return mDetailsSignal.connect(cb);  }
372	boost::signals2::connection setModelLoadedCallback( const model_loaded_signal_t::slot_type& cb ){  return mModelLoadedSignal.connect(cb);  }
373	boost::signals2::connection setModelUpdatedCallback( const model_updated_signal_t::slot_type& cb ){  return mModelUpdatedSignal.connect(cb);  }
374	
375	void setLoadState( U32 state ) { mLoadState = state; }
376	U32 getLoadState() { return mLoadState; }
377	void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; }
378	const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; }
379	
380	LLVector3 getTranslationForJointOffset( std::string joint );
381
382private:
383	//Utility function for controller vertex compare
384	bool verifyCount( int expected, int result );
385	//Creates the dummy avatar for the preview window
386	void		createPreviewAvatar( void );
387	//Accessor for the dummy avatar
388	LLVOAvatar* getPreviewAvatar( void ) { return mPreviewAvatar; }
389
390 protected:
391	friend class LLModelLoader;
392	friend class LLFloaterModelPreview;
393	friend class LLFloaterModelWizard;
394	friend class LLFloaterModelPreview::DecompRequest;
395	friend class LLFloaterModelWizard::DecompRequest;
396	friend class LLPhysicsDecomp;
397
398	LLFloater*  mFMP;
399
400	BOOL        mNeedsUpdate;
401	bool		mDirty;
402	bool		mGenLOD;
403	U32         mTextureName;
404	F32			mCameraDistance;
405	F32			mCameraYaw;
406	F32			mCameraPitch;
407	F32			mCameraZoom;
408	LLVector3	mCameraOffset;
409	LLVector3	mPreviewTarget;
410	LLVector3	mPreviewScale;
411	S32			mPreviewLOD;
412	U32			mResourceCost;
413	std::string mLODFile[LLModel::NUM_LODS];
414	bool		mLoading;
415	U32			mLoadState;
416	bool		mResetJoints;
417	bool		mRigParityWithScene;
418	
419	std::map<std::string, bool> mViewOption;
420
421	//GLOD object parameters (must rebuild object if these change)
422	bool mLODFrozen;
423	F32 mBuildShareTolerance;
424	U32 mBuildQueueMode;
425	U32 mBuildOperator;
426	U32 mBuildBorderMode;
427	U32 mRequestedLoDMode[LLModel::NUM_LODS];
428	S32 mRequestedTriangleCount[LLModel::NUM_LODS];
429	F32 mRequestedErrorThreshold[LLModel::NUM_LODS];
430	U32 mRequestedBuildOperator[LLModel::NUM_LODS];
431	U32 mRequestedQueueMode[LLModel::NUM_LODS];
432	U32 mRequestedBorderMode[LLModel::NUM_LODS];
433	F32 mRequestedShareTolerance[LLModel::NUM_LODS];
434	F32 mRequestedCreaseAngle[LLModel::NUM_LODS];
435
436	LLModelLoader* mModelLoader;
437
438	LLModelLoader::scene mScene[LLModel::NUM_LODS];
439	LLModelLoader::scene mBaseScene;
440
441	LLModelLoader::model_list mModel[LLModel::NUM_LODS];
442	LLModelLoader::model_list mBaseModel;
443
444	U32 mGroup;
445	std::map<LLPointer<LLModel>, U32> mObject;
446	U32 mMaxTriangleLimit;
447	
448	LLMeshUploadThread::instance_list mUploadData;
449	std::set<LLViewerFetchedTexture* > mTextureSet;
450
451	//map of vertex buffers to models (one vertex buffer in vector per face in model
452	std::map<LLModel*, std::vector<LLPointer<LLVertexBuffer> > > mVertexBuffer[LLModel::NUM_LODS+1];
453
454	details_signal_t mDetailsSignal;
455	model_loaded_signal_t mModelLoadedSignal;
456	model_updated_signal_t mModelUpdatedSignal;
457	
458	LLVector3	mModelPivot;
459	bool		mHasPivot;
460	
461	float		mPelvisZOffset;
462	
463	bool		mRigValidJointUpload;
464	bool		mLegacyRigValid;
465
466	bool		mLastJointUpdate;
467
468	std::deque<std::string> mMasterJointList;
469	std::deque<std::string> mMasterLegacyJointList;
470	std::deque<std::string> mJointsFromNode;
471	JointTransformMap		mJointTransformMap;
472	LLPointer<LLVOAvatar>	mPreviewAvatar;
473};
474
475#endif  // LL_LLFLOATERMODELPREVIEW_H