diff options
| -rw-r--r-- | indra/newview/llexperiencelog.cpp | 31 | ||||
| -rw-r--r-- | indra/newview/llexperiencelog.h | 5 | ||||
| -rwxr-xr-x | indra/newview/llfloatermodelpreview.cpp | 149 | ||||
| -rwxr-xr-x | indra/newview/llfloatermodelpreview.h | 2 | ||||
| -rw-r--r-- | indra/newview/llpanelexperiencelog.cpp | 17 | ||||
| -rw-r--r-- | indra/newview/llsnapshotlivepreview.cpp | 5 | ||||
| -rwxr-xr-x | indra/newview/lltooldraganddrop.cpp | 19 | ||||
| -rwxr-xr-x | indra/newview/llviewerobject.cpp | 16 | ||||
| -rwxr-xr-x | indra/newview/llviewerobject.h | 5 | 
9 files changed, 212 insertions, 37 deletions
diff --git a/indra/newview/llexperiencelog.cpp b/indra/newview/llexperiencelog.cpp index ec6134a4b3..ee5d561927 100644 --- a/indra/newview/llexperiencelog.cpp +++ b/indra/newview/llexperiencelog.cpp @@ -112,6 +112,7 @@ void LLExperienceLog::handleExperienceMessage(LLSD& message)  	}  	message["Time"] = time_of_day;  	mEvents[day].append(message); +	mEventsToSave[day].append(message);  	mSignals(message);  } @@ -180,9 +181,8 @@ void LLExperienceLog::notify( LLSD& message )  void LLExperienceLog::saveEvents()  { -	eraseExpired();  	std::string filename = getFilename(); -	LLSD settings = LLSD::emptyMap().with("Events", mEvents); +	LLSD settings = LLSD::emptyMap().with("Events", mEventsToSave);  	settings["MaxDays"] = (int)mMaxDays;  	settings["Notify"] = mNotifyNewEvent; @@ -217,9 +217,8 @@ void LLExperienceLog::loadEvents()  	if(mMaxDays > 0 && settings.has("Events"))  	{  		mEvents = settings["Events"]; +		mEventsToSave = mEvents;  	} - -	eraseExpired();  }  LLExperienceLog::~LLExperienceLog() @@ -235,6 +234,26 @@ void LLExperienceLog::eraseExpired()  	}  } +bool LLExperienceLog::isNotExpired(std::string& date) +{ +	LLDate event_date; +	S32 month, day, year; +	S32 matched = sscanf(date.c_str(), "%d-%d-%d", &year, &month, &day); +	if (matched != 3) return false; +	event_date.fromYMDHMS(year, month, day); +	const U32 seconds_in_day = 24 * 60 * 60; +	S32 curr_year = 0, curr_month = 0, curr_day = 0; + + +	LLDate curr_date = LLDate::now(); +	curr_date.split(&curr_year, &curr_month, &curr_day); +	curr_date.fromYMDHMS(curr_year, curr_month, curr_day); // Set hour, min, and sec to 0 + +	LLDate boundary_date =  LLDate(curr_date.secondsSinceEpoch() - seconds_in_day*getMaxDays()); +	return event_date >= boundary_date; + +} +  const LLSD& LLExperienceLog::getEvents() const  {  	return mEvents; @@ -248,10 +267,6 @@ void LLExperienceLog::clear()  void LLExperienceLog::setMaxDays( U32 val )  {  	mMaxDays = val; -	if(mMaxDays > 0) -	{ -		eraseExpired(); -	}  }  LLExperienceLog::callback_connection_t LLExperienceLog::addUpdateSignal( const callback_slot_t& cb ) diff --git a/indra/newview/llexperiencelog.h b/indra/newview/llexperiencelog.h index 1e473e27d5..ac227db336 100644 --- a/indra/newview/llexperiencelog.h +++ b/indra/newview/llexperiencelog.h @@ -59,6 +59,8 @@ public:  	static void notify(LLSD& message);  	static std::string getFilename();  	static std::string getPermissionString(const LLSD& message, const std::string& base); +	void setEventsToSave(LLSD new_events){mEventsToSave = new_events; } +	bool isNotExpired(std::string& date);  protected:  	LLExperienceLog();  	void handleExperienceMessage(LLSD& message); @@ -68,7 +70,10 @@ protected:  	void saveEvents();  	void eraseExpired(); + +  	LLSD mEvents; +	LLSD mEventsToSave;  	callback_signal_t mSignals;  	callback_connection_t mNotifyConnection;  	U32 mMaxDays; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 20760001fd..fea4e57d13 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -751,6 +751,8 @@ void LLFloaterModelPreview::onExplodeCommit(LLUICtrl* ctrl, void* userdata)  void LLFloaterModelPreview::onAutoFillCommit(LLUICtrl* ctrl, void* userdata)  {  	LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata; +	if (fp->mModelPreview->mHasBrokenModel) +		return;  	fp->mModelPreview->genLODs();  } @@ -1635,6 +1637,10 @@ bool LLModelLoader::doLoadModel()  				mModelList.push_back(model);  				mModel[mesh] = model;  			} +			else +			{ +				mPreview->mHasBrokenModel = true; +			}  		}  	} @@ -2289,6 +2295,12 @@ void LLModelLoader::loadModelCallback()  		return ;  	} +	//generate BBox here if non-valide model in scene was detected +	if (mPreview->mHasBrokenModel) +	{ +		mPreview->genModelBBox(); +	} +  	//cleanup model loader  	if (mPreview)  	{ @@ -3133,6 +3145,7 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)  , mResetJoints( false )  , mRigParityWithScene( false )  , mLastJointUpdate( false ) +, mHasBrokenModel( false )  {  	mNeedsUpdate = TRUE;  	mCameraDistance = 0.f; @@ -4295,6 +4308,114 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim  	 }*/  } +void LLModelPreview::genModelBBox() +{ +	LLVector3 min, max; +	min = this->mModelLoader->mExtents[0]; +	max = this->mModelLoader->mExtents[1]; + +	std::vector<LLVector3> v_list; +	v_list.resize(4); +	std::map<U8, std::vector<LLVector3> > face_list; + +	// Face 0 +	v_list[0] = LLVector3(min.mV[VX], max.mV[VY], max.mV[VZ]); +	v_list[1] = LLVector3(min.mV[VX], min.mV[VY], max.mV[VZ]); +	v_list[2] = LLVector3(max.mV[VX], min.mV[VY], max.mV[VZ]); +	v_list[3] = LLVector3(max.mV[VX], max.mV[VY], max.mV[VZ]); +	face_list.insert(std::pair<U8, std::vector<LLVector3> >(0, v_list)); + +	// Face 1 +	v_list[0] = LLVector3(max.mV[VX], min.mV[VY], max.mV[VZ]); +	v_list[1] = LLVector3(max.mV[VX], min.mV[VY], min.mV[VZ]); +	v_list[2] = LLVector3(max.mV[VX], max.mV[VY], min.mV[VZ]); +	v_list[3] = LLVector3(max.mV[VX], max.mV[VY], max.mV[VZ]); +	face_list.insert(std::pair<U8, std::vector<LLVector3> >(1, v_list)); + +	// Face 2 +	v_list[0] = LLVector3(min.mV[VX], max.mV[VY], min.mV[VZ]); +	v_list[1] = LLVector3(min.mV[VX], max.mV[VY], max.mV[VZ]); +	v_list[2] = LLVector3(max.mV[VX], max.mV[VY], max.mV[VZ]); +	v_list[3] = LLVector3(max.mV[VX], max.mV[VY], min.mV[VZ]); +	face_list.insert(std::pair<U8, std::vector<LLVector3> >(2, v_list)); + +	// Face 3 +	v_list[0] = LLVector3(min.mV[VX], max.mV[VY], max.mV[VZ]); +	v_list[1] = LLVector3(min.mV[VX], max.mV[VY], min.mV[VZ]); +	v_list[2] = LLVector3(min.mV[VX], min.mV[VY], min.mV[VZ]); +	v_list[3] = LLVector3(min.mV[VX], min.mV[VY], max.mV[VZ]); +	face_list.insert(std::pair<U8, std::vector<LLVector3> >(3, v_list)); + +	// Face 4 +	v_list[0] = LLVector3(min.mV[VX], min.mV[VY], max.mV[VZ]); +	v_list[1] = LLVector3(min.mV[VX], min.mV[VY], min.mV[VZ]); +	v_list[2] = LLVector3(max.mV[VX], min.mV[VY], min.mV[VZ]); +	v_list[3] = LLVector3(max.mV[VX], min.mV[VY], max.mV[VZ]); +	face_list.insert(std::pair<U8, std::vector<LLVector3> >(4, v_list)); + +	// Face 5 +	v_list[0] = LLVector3(min.mV[VX], min.mV[VY], min.mV[VZ]); +	v_list[1] = LLVector3(min.mV[VX], max.mV[VY], min.mV[VZ]); +	v_list[2] = LLVector3(max.mV[VX], max.mV[VY], min.mV[VZ]); +	v_list[3] = LLVector3(max.mV[VX], min.mV[VY], min.mV[VZ]); +	face_list.insert(std::pair<U8, std::vector<LLVector3> >(5, v_list)); + +	U16 Idx[] = { 0, 1, 2, 3, 0, 2, }; + +	U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; +	LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(type_mask, 0); +	buff->allocateBuffer(4, 6, true); + +	LLStrider<LLVector3> pos; +	LLStrider<U16> idx; +	LLStrider<LLVector3> norm; +	LLStrider<LLVector2> tc; + +	buff->getVertexStrider(pos); +	buff->getIndexStrider(idx); + +	buff->getNormalStrider(norm); +	buff->getTexCoord0Strider(tc); + +	for (U32 i = 0; i < 6; ++i) +	{ +		idx[i] = Idx[i]; +	} + +	LLVolumeParams volume_params; +	volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); +	LLModel* mdl = new LLModel(volume_params, 0.f); +	mdl->mLabel = "BBOX"; + +	mdl->setNumVolumeFaces(6); +	for (U8 i = 0; i < 6; ++i) +	{ +		for (U8 j = 0; j < 4; ++j) +		{ +			pos[j] = face_list[i][j]; +		} + +		mdl->setVolumeFaceData(i, pos, norm, tc, idx, buff->getNumVerts(), buff->getNumIndices()); +	} + +	if (validate_model(mdl)) +	{ +		LLMatrix4 mat; +		std::map<std::string, LLImportMaterial> materials; +		std::vector<LLModelInstance> instance_list; +		instance_list.push_back(LLModelInstance(mdl, mdl->mLabel, mat, materials)); + +		for (S32 i = LLModel::LOD_HIGH - 1; i >= 0; i--) +		{ +			mModel[i].clear(); +			mModel[i].push_back(mdl); + +			mScene[i].clear(); +			mScene[i].insert(std::pair<LLMatrix4, std::vector<LLModelInstance> >(mat, instance_list)); +		} +	} +} +  void LLModelPreview::updateStatusMessages()  {  	assert_main_thread(); @@ -4961,12 +5082,14 @@ void LLModelPreview::update()  	if (mGenLOD)  	{ -		mGenLOD = false; -		genLODs(); -		refresh(); -		updateStatusMessages(); +		if (!this->mHasBrokenModel) +		{ +			mGenLOD = false; +			genLODs(); +			refresh(); +			updateStatusMessages(); +		}		  	} -  }  //-----------------------------------------------------------------------------  // getTranslationForJointOffset() @@ -5292,7 +5415,11 @@ BOOL LLModelPreview::render()  				}  				gGL.pushMatrix(); -				LLMatrix4 mat = instance.mTransform; +				LLMatrix4 mat; +				if (model->getName() != "BBOX") +				{ +					mat = instance.mTransform; +				}  				gGL.multMatrix((GLfloat*) mat.mMatrix); @@ -5825,6 +5952,16 @@ void LLModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)  {  	if (!mLODFrozen)  	{ +		S32 lod_mode = 0; +		LLCtrlSelectionInterface* iface = this->mFMP->childGetSelectionInterface("lod_mode_" + lod_name[lod]); +		if (iface) +		{ +			lod_mode = iface->getFirstSelectedIndex(); +		} + +		if (lod_mode == 0 && this->mHasBrokenModel) +			return; +  		genLODs(lod, 3, enforce_tri_limit);  		refresh();  	} diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 618748bd4e..813e49305b 100755 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -342,6 +342,7 @@ public:  	void loadModel(std::string filename, S32 lod, bool force_disable_slm = false);  	void loadModelCallback(S32 lod);  	void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false); +	void genModelBBox(); // Generate just a model BBox if we can't generate proper LOD  	void generateNormals();  	void restoreNormals();  	U32 calcResourceCost(); @@ -422,6 +423,7 @@ private:  	U32			mLoadState;  	bool		mResetJoints;  	bool		mRigParityWithScene; +	bool		mHasBrokenModel;  	std::map<std::string, bool> mViewOption; diff --git a/indra/newview/llpanelexperiencelog.cpp b/indra/newview/llpanelexperiencelog.cpp index df03ef7526..30576a8d67 100644 --- a/indra/newview/llpanelexperiencelog.cpp +++ b/indra/newview/llpanelexperiencelog.cpp @@ -54,7 +54,6 @@ LLPanelExperienceLog::LLPanelExperienceLog(  )  	buildFromFile("panel_experience_log.xml");  } -  BOOL LLPanelExperienceLog::postBuild( void )  {  	LLExperienceLog* log = LLExperienceLog::getInstance(); @@ -112,7 +111,7 @@ void LLPanelExperienceLog::refresh()  	int itemsToSkip = mPageSize*mCurrentPage;  	int items = 0;  	bool moreItems = false; -	 +	LLSD events_to_save = events;  	if (!events.emptyMap())  	{  		LLSD::map_const_iterator day = events.endMap(); @@ -120,6 +119,13 @@ void LLPanelExperienceLog::refresh()  		{  			--day;  			const LLSD& dayArray = day->second; + +			std::string date = day->first; +			if(!LLExperienceLog::instance().isNotExpired(date)) +			{ +				events_to_save.erase(day->first); +				continue; +			}  			int size = dayArray.size();  			if(itemsToSkip > size)  			{ @@ -164,6 +170,7 @@ void LLPanelExperienceLog::refresh()  			}  		} while (day != events.beginMap());  	} +	LLExperienceLog::getInstance()->setEventsToSave(events_to_save);  	if(waiting)  	{  		mEventList->deleteAllItems(); @@ -237,12 +244,8 @@ void LLPanelExperienceLog::notifyChanged()  void LLPanelExperienceLog::logSizeChanged()  {  	int value = (int)(getChild<LLSpinCtrl>("logsizespinner")->get()); -	bool dirty = value > 0 && value < LLExperienceLog::instance().getMaxDays();  	LLExperienceLog::instance().setMaxDays(value); -	if(dirty) -	{ -		refresh(); -	} +	refresh();  }  void LLPanelExperienceLog::onSelectionChanged() diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index 6af9d61a54..8561a89ae5 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -463,7 +463,10 @@ void LLSnapshotLivePreview::reshape(S32 width, S32 height, BOOL called_from_pare  	if (old_rect.getWidth() != width || old_rect.getHeight() != height)  	{  		LL_DEBUGS() << "window reshaped, updating thumbnail" << LL_ENDL; -		updateSnapshot(TRUE); +		if (mViewContainer && mViewContainer->isInVisibleChain()) +		{ +			updateSnapshot(TRUE); +		}  	}  } diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 5c9aedcf8f..ff71028a9b 100755 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1013,13 +1013,10 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,  	// causing a dirty inventory) and we can do an update, stall the user  	// while fetching the inventory.  	// -	// Note: fetch only if inventory is both dirty and not present since previously checked faces -	// could have requested new fetch for same item (removed inventory and marked as dirty=false). -	// Objects without listeners (dirty==true and inventory!=NULL. In this specific case - before -	// first fetch) shouldn't be updated either since we won't receive any changes. -	if (hit_obj->isInventoryDirty() && hit_obj->getInventoryRoot() == NULL) +	// Fetch if inventory is dirty and listener is present (otherwise we will not receive update) +	if (hit_obj->isInventoryDirty() && hit_obj->hasInventoryListeners())  	{ -		hit_obj->fetchInventoryFromServer(); +		hit_obj->requestInventory();  		LLSD args;  		args["ERROR_MESSAGE"] = "Unable to add texture.\nPlease wait a few seconds and try again.";  		LLNotificationsUtil::add("ErrorMessage", args); @@ -1099,10 +1096,12 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,  		{  			hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);  		} -		// Force the object to update its refetch its inventory so it has this texture. -		hit_obj->fetchInventoryFromServer(); - 		// TODO: Check to see if adding the item was successful; if not, then -		// we should return false here. +		// Force the object to update and refetch its inventory so it has this texture. +		hit_obj->dirtyInventory(); +		hit_obj->requestInventory(); +		// TODO: Check to see if adding the item was successful; if not, then +		// we should return false here. This will requre a separate listener +		// since without listener, we have no way to receive update  	}  	return TRUE;  } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 05d116704e..c4d3829ee9 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -2840,6 +2840,11 @@ void LLViewerObject::clearInventoryListeners()  	mInventoryCallbacks.clear();  } +bool LLViewerObject::hasInventoryListeners() +{ +	return !mInventoryCallbacks.empty(); +} +  void LLViewerObject::requestInventory()  {  	if(mInventoryDirty && mInventory && !mInventoryCallbacks.empty()) @@ -2847,15 +2852,20 @@ void LLViewerObject::requestInventory()  		mInventory->clear(); // will deref and delete entries  		delete mInventory;  		mInventory = NULL; -		mInventoryDirty = FALSE; //since we are going to request it now  	} +  	if(mInventory)  	{ +		// inventory is either up to date or doesn't has a listener +		// if it is dirty, leave it this way in case we gain a listener  		doInventoryCallback();  	} -	// throw away duplicate requests  	else  	{ +		// since we are going to request it now +		mInventoryDirty = FALSE; + +		// Note: throws away duplicate requests  		fetchInventoryFromServer();  	}  } @@ -2865,8 +2875,6 @@ void LLViewerObject::fetchInventoryFromServer()  	if (!mInventoryPending)  	{  		delete mInventory; -		mInventory = NULL; -		mInventoryDirty = FALSE;  		LLMessageSystem* msg = gMessageSystem;  		msg->newMessageFast(_PREHASH_RequestTaskInventory);  		msg->nextBlockFast(_PREHASH_AgentData); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index db2749f413..65d6f8225f 100755 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -436,8 +436,8 @@ public:  	void removeInventoryListener(LLVOInventoryListener* listener);  	BOOL isInventoryPending() { return mInventoryPending; }  	void clearInventoryListeners(); +	bool hasInventoryListeners();  	void requestInventory(); -	void fetchInventoryFromServer();  	static void processTaskInv(LLMessageSystem* msg, void** user_data);  	void removeInventory(const LLUUID& item_id); @@ -593,6 +593,9 @@ private:  	static void initObjectDataMap(); +	// forms task inventory request if none are pending +	void fetchInventoryFromServer(); +  public:  	//  	// Viewer-side only types - use the LL_PCODE_APP mask.  | 
