Fix many issues with selection misapplication and rendering not matching applied materials

master
Graham Madarasz 2013-05-11 19:58:56 -07:00
parent a099815774
commit f356d7eb9f
14 changed files with 343 additions and 265 deletions

View File

@ -374,6 +374,24 @@ S32 LLPrimitive::setTEGlow(const U8 index, const F32 glow)
return mTextureList.setGlow(index, glow);
}
void LLPrimitive::setAllTESelected(bool sel)
{
for (int i = 0, cnt = getNumTEs(); i < cnt; i++)
{
setTESelected(i, sel);
}
}
void LLPrimitive::setTESelected(const U8 te, bool sel)
{
LLTextureEntry* tep = getTE(te);
if ( (tep) && (tep->setSelected(sel)) && (!sel) && (tep->hasPendingMaterialUpdate()) )
{
LLMaterialID material_id = tep->getMaterialID();
setTEMaterialID(te, material_id);
}
}
LLPCode LLPrimitive::legacyToPCode(const U8 legacy)
{
// TODO: Should this default to something valid?

View File

@ -361,6 +361,7 @@ public:
LLTextureEntry* getTE(const U8 te_num) const;
virtual void setNumTEs(const U8 num_tes);
virtual void setAllTESelected(bool sel);
virtual void setAllTETextures(const LLUUID &tex_id);
virtual void setTE(const U8 index, const LLTextureEntry& te);
virtual S32 setTEColor(const U8 te, const LLColor4 &color);
@ -386,6 +387,7 @@ public:
virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);
virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed
virtual void setTESelected(const U8 te, bool sel);
void copyTEs(const LLPrimitive *primitive);
S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const;

View File

@ -67,12 +67,16 @@ LLTextureEntry::LLTextureEntry()
LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)
: mMediaEntry(NULL)
, mSelected(false)
, mMaterialUpdatePending(false)
{
init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
}
LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
: mMediaEntry(NULL)
, mSelected(false)
, mMaterialUpdatePending(false)
{
mID = rhs.mID;
mScaleS = rhs.mScaleS;
@ -536,23 +540,20 @@ S32 LLTextureEntry::setMaterialID(const LLMaterialID& pMaterialID)
if (mMaterialID != pMaterialID)
{
mMaterialID = pMaterialID;
if (mMaterialID.isNull())
{
setMaterialParams(NULL);
}
return TEM_CHANGE_TEXTURE;
}
return TEM_CHANGE_NONE;
if (mMaterialID.isNull())
{
setMaterialParams(NULL);
}
return TEM_CHANGE_TEXTURE;
}
S32 LLTextureEntry::setMaterialParams(const LLMaterialPtr pMaterialParams)
{
if (mMaterial != pMaterialParams)
{
mMaterial = pMaterialParams;
return TEM_CHANGE_TEXTURE;
}
return TEM_CHANGE_NONE;
mMaterial = pMaterialParams;
return TEM_CHANGE_TEXTURE;
}
void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry)

View File

@ -100,6 +100,10 @@ public:
void init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 offset_s, F32 offset_t, F32 rotation, U8 bump);
bool hasPendingMaterialUpdate() const { return mMaterialUpdatePending; }
bool isSelected() const { return mSelected; }
bool setSelected(bool sel) { bool prev_sel = mSelected; mSelected = sel; return prev_sel; }
// These return a TEM_ flag from above to indicate if something changed.
S32 setID (const LLUUID &tex_id);
S32 setColor(const LLColor4 &color);
@ -194,11 +198,13 @@ public:
static const char* TEXTURE_MEDIA_DATA_KEY;
protected:
bool mSelected;
LLUUID mID; // Texture GUID
LLColor4 mColor;
U8 mBump; // Bump map, shiny, and fullbright
U8 mMediaFlags; // replace with web page, movie, etc.
F32 mGlow;
bool mMaterialUpdatePending;
LLMaterialID mMaterialID;
LLMaterialPtr mMaterial;

View File

@ -216,6 +216,51 @@ boost::signals2::connection LLMaterialMgr::get(const LLUUID& region_id, const LL
return connection;
}
boost::signals2::connection LLMaterialMgr::getTE(const LLUUID& region_id, const LLMaterialID& material_id, U32 te, LLMaterialMgr::get_callback_te_t::slot_type cb)
{
boost::signals2::connection connection;
material_map_t::const_iterator itMaterial = mMaterials.find(material_id);
if (itMaterial != mMaterials.end())
{
LL_DEBUGS("Materials") << "region " << region_id << " found materialid " << material_id << LL_ENDL;
get_callback_te_t signal;
signal.connect(cb);
signal(material_id, itMaterial->second, te);
connection = boost::signals2::connection();
}
else
{
if (!isGetPending(region_id, material_id))
{
get_queue_t::iterator itQueue = mGetQueue.find(region_id);
if (mGetQueue.end() == itQueue)
{
LL_DEBUGS("Materials") << "mGetQueue inserting region "<<region_id << LL_ENDL;
std::pair<get_queue_t::iterator, bool> ret = mGetQueue.insert(std::pair<LLUUID, material_queue_t>(region_id, material_queue_t()));
itQueue = ret.first;
}
LL_DEBUGS("Materials") << "adding material id " << material_id << LL_ENDL;
itQueue->second.insert(material_id);
markGetPending(region_id, material_id);
}
TEMaterialPair te_mat_pair;
te_mat_pair.te = te;
te_mat_pair.materialID = material_id;
get_callback_te_map_t::iterator itCallback = mGetTECallbacks.find(te_mat_pair);
if (itCallback == mGetTECallbacks.end())
{
std::pair<get_callback_te_map_t::iterator, bool> ret = mGetTECallbacks.insert(std::pair<TEMaterialPair, get_callback_te_t*>(te_mat_pair, new get_callback_te_t()));
itCallback = ret.first;
}
connection = itCallback->second->connect(cb);
}
return connection;
}
bool LLMaterialMgr::isGetAllPending(const LLUUID& region_id) const
{
getall_pending_map_t::const_iterator itPending = mGetAllPending.find(region_id);
@ -300,6 +345,22 @@ const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LL
mGetCallbacks.erase(itCallback);
}
TEMaterialPair te_mat_pair;
te_mat_pair.materialID = material_id;
U32 i = 0;
while (i < LLTEContents::MAX_TES)
{
te_mat_pair.te = i++;
get_callback_te_map_t::iterator itCallbackTE = mGetTECallbacks.find(te_mat_pair);
if (itCallbackTE != mGetTECallbacks.end())
{
(*itCallbackTE->second)(material_id, itMaterial->second, te_mat_pair.te);
delete itCallbackTE->second;
mGetTECallbacks.erase(itCallbackTE);
}
}
return itMaterial->second;
}

View File

@ -44,8 +44,12 @@ public:
typedef std::map<LLMaterialID, LLMaterialPtr> material_map_t;
typedef boost::signals2::signal<void (const LLMaterialID&, const LLMaterialPtr)> get_callback_t;
typedef boost::signals2::signal<void (const LLMaterialID&, const LLMaterialPtr, U32 te)> get_callback_te_t;
const LLMaterialPtr get(const LLUUID& region_id, const LLMaterialID& material_id);
boost::signals2::connection get(const LLUUID& region_id, const LLMaterialID& material_id, get_callback_t::slot_type cb);
boost::signals2::connection getTE(const LLUUID& region_id, const LLMaterialID& material_id, U32 te, get_callback_te_t::slot_type cb);
typedef boost::signals2::signal<void (const LLUUID&, const material_map_t&)> getall_callback_t;
void getAll(const LLUUID& region_id);
boost::signals2::connection getAll(const LLUUID& region_id, getall_callback_t::slot_type cb);
@ -78,6 +82,26 @@ protected:
typedef std::map<LLMaterialID, get_callback_t*> get_callback_map_t;
get_callback_map_t mGetCallbacks;
// struct for TE-specific material ID query
struct TEMaterialPair
{
U32 te;
LLMaterialID materialID;
};
// needed for std::map compliance only
//
friend inline bool operator<(
const struct LLMaterialMgr::TEMaterialPair& lhs,
const struct LLMaterialMgr::TEMaterialPair& rhs)
{
return (lhs.materialID < rhs.materialID) ? TRUE :
(lhs.te < rhs.te) ? TRUE : FALSE;
}
typedef std::map<TEMaterialPair, get_callback_te_t*> get_callback_te_map_t;
get_callback_te_map_t mGetTECallbacks;
typedef std::set<LLUUID> getall_queue_t;
getall_queue_t mGetAllQueue;
getall_queue_t mGetAllRequested;

View File

@ -1562,36 +1562,108 @@ void LLPanelFace::getState()
// Materials
{
mMaterialID = LLMaterialID::null;
mMaterial = NULL;
struct f1 : public LLSelectedTEGetFunctor<LLMaterialID>
struct f1 : public LLSelectedTEGetFunctor<LLMaterialPtr>
{
LLMaterialID get(LLViewerObject* object, S32 te_index)
LLMaterialPtr get(LLViewerObject* object, S32 te_index)
{
LLMaterialID material_id;
return object->getTE(te_index)->getMaterialID();
return object->getTE(te_index)->getMaterialParams();
}
} func;
LLObjectSelectionHandle sel = LLSelectMgr::getInstance()->getSelection();
LLSelectNode* node = sel->getFirstNode();
if (node)
{
int selected_te = node->getLastSelectedTE();
if (selected_te >= 0)
{
mMaterialID = node->getObject()->getTE(selected_te)->getMaterialID();
}
}
LLMaterialPtr material;
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, mMaterial );
llinfos << "Material ID returned: '" << mMaterialID.asString() << "', isNull? " << (mMaterialID.isNull()?"TRUE":"FALSE") << llendl;
if (!mMaterialID.isNull() && editable)
if (mMaterial && editable)
{
llinfos << "Requesting material ID " << mMaterialID.asString() << llendl;
LLMaterialMgr::getInstance()->get(objectp->getRegion()->getRegionID(),mMaterialID,boost::bind(&LLPanelFace::onMaterialLoaded, this, _1, _2));
LL_DEBUGS("Materials: OnMatererialsLoaded:") << material->asLLSD() << LL_ENDL;
// Alpha
LLCtrlSelectionInterface* combobox_alphamode =
childGetSelectionInterface("combobox alphamode");
if (combobox_alphamode)
{
combobox_alphamode->selectNthItem(mMaterial->getDiffuseAlphaMode());
}
else
{
llwarns << "failed childGetSelectionInterface for 'combobox alphamode'" << llendl;
}
getChild<LLUICtrl>("maskcutoff")->setValue(mMaterial->getAlphaMaskCutoff());
updateAlphaControls(getChild<LLComboBox>("combobox alphamode"),this);
LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT;
bool identical_texgen = true;
bool identical_planar_texgen = false;
struct f44 : public LLSelectedTEGetFunctor<LLTextureEntry::e_texgen>
{
LLTextureEntry::e_texgen get(LLViewerObject* object, S32 face)
{
return (LLTextureEntry::e_texgen)(object->getTE(face)->getTexGen());
}
} func;
identical_texgen = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, selected_texgen );
identical_planar_texgen = (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR));
// Shiny (specular)
F32 offset_x, offset_y, repeat_x, repeat_y, rot;
LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
texture_ctrl->setImageAssetID(material->getSpecularID());
LLComboBox* combobox_shininess = getChild<LLComboBox>("combobox shininess");
if (!material->getSpecularID().isNull())
{
mMaterial->getSpecularOffset(offset_x,offset_y);
mMaterial->getSpecularRepeat(repeat_x,repeat_y);
if (identical_planar_texgen)
{
repeat_x *= 2.0f;
repeat_y *= 2.0f;
}
rot = mMaterial->getSpecularRotation();
getChild<LLUICtrl>("shinyScaleU")->setValue(repeat_x);
getChild<LLUICtrl>("shinyScaleV")->setValue(repeat_y);
getChild<LLUICtrl>("shinyRot")->setValue(rot*RAD_TO_DEG);
getChild<LLUICtrl>("shinyOffsetU")->setValue(offset_x);
getChild<LLUICtrl>("shinyOffsetV")->setValue(offset_y);
getChild<LLUICtrl>("glossiness")->setValue(mMaterial->getSpecularLightExponent());
getChild<LLUICtrl>("environment")->setValue(mMaterial->getEnvironmentIntensity());
}
updateShinyControls(combobox_shininess,this, !mMaterial->getSpecularID().isNull(), true);
// Assert desired colorswatch color to match material AFTER updateShinyControls
// to avoid getting overwritten with the default on some UI state changes.
//
if (!material->getSpecularID().isNull())
{
getChild<LLColorSwatchCtrl>("shinycolorswatch")->setOriginal(mMaterial->getSpecularLightColor());
getChild<LLColorSwatchCtrl>("shinycolorswatch")->set(mMaterial->getSpecularLightColor(),TRUE);
}
// Bumpy (normal)
texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
texture_ctrl->setImageAssetID(mMaterial->getNormalID());
LLComboBox* combobox_bumpiness = getChild<LLComboBox>("combobox bumpiness");
if (!mMaterial->getNormalID().isNull())
{
mMaterial->getNormalOffset(offset_x,offset_y);
mMaterial->getNormalRepeat(repeat_x,repeat_y);
if (identical_planar_texgen)
{
repeat_x *= 2.0f;
repeat_y *= 2.0f;
}
rot = material->getNormalRotation();
getChild<LLUICtrl>("bumpyScaleU")->setValue(repeat_x);
getChild<LLUICtrl>("bumpyScaleV")->setValue(repeat_y);
getChild<LLUICtrl>("bumpyRot")->setValue(rot*RAD_TO_DEG);
getChild<LLUICtrl>("bumpyOffsetU")->setValue(offset_x);
getChild<LLUICtrl>("bumpyOffsetV")->setValue(offset_y);
}
updateBumpyControls(combobox_bumpiness,this, !mMaterial->getNormalID().isNull(), true);
}
}
@ -1658,104 +1730,6 @@ void LLPanelFace::refresh()
getState();
}
void LLPanelFace::onMaterialLoaded(const LLMaterialID& material_id, const LLMaterialPtr material)
{ //laying out UI based on material parameters (calls setVisible on various components)
LL_DEBUGS("Materials") << "material id " << material_id.asString() << " data " << material->asLLSD() << LL_ENDL;
//make a local copy of the material for editing
// (prevents local edits from overwriting client state on shared materials)
mMaterial = new LLMaterial(*material);
mMaterialID = material_id;
// Alpha
LLCtrlSelectionInterface* combobox_alphamode =
childGetSelectionInterface("combobox alphamode");
if (combobox_alphamode)
{
combobox_alphamode->selectNthItem(material->getDiffuseAlphaMode());
}
else
{
llwarns << "failed childGetSelectionInterface for 'combobox alphamode'" << llendl;
}
getChild<LLUICtrl>("maskcutoff")->setValue(material->getAlphaMaskCutoff());
updateAlphaControls(getChild<LLComboBox>("combobox alphamode"),this);
LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT;
bool identical_texgen = true;
bool identical_planar_texgen = false;
struct f44 : public LLSelectedTEGetFunctor<LLTextureEntry::e_texgen>
{
LLTextureEntry::e_texgen get(LLViewerObject* object, S32 face)
{
return (LLTextureEntry::e_texgen)(object->getTE(face)->getTexGen());
}
} func;
identical_texgen = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, selected_texgen );
identical_planar_texgen = (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR));
// Shiny (specular)
F32 offset_x, offset_y, repeat_x, repeat_y, rot;
LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
texture_ctrl->setImageAssetID(material->getSpecularID());
LLComboBox* combobox_shininess = getChild<LLComboBox>("combobox shininess");
if (!material->getSpecularID().isNull())
{
material->getSpecularOffset(offset_x,offset_y);
material->getSpecularRepeat(repeat_x,repeat_y);
if (identical_planar_texgen)
{
repeat_x *= 2.0f;
repeat_y *= 2.0f;
}
rot = material->getSpecularRotation();
getChild<LLUICtrl>("shinyScaleU")->setValue(repeat_x);
getChild<LLUICtrl>("shinyScaleV")->setValue(repeat_y);
getChild<LLUICtrl>("shinyRot")->setValue(rot*RAD_TO_DEG);
getChild<LLUICtrl>("shinyOffsetU")->setValue(offset_x);
getChild<LLUICtrl>("shinyOffsetV")->setValue(offset_y);
getChild<LLUICtrl>("glossiness")->setValue(material->getSpecularLightExponent());
getChild<LLUICtrl>("environment")->setValue(material->getEnvironmentIntensity());
}
updateShinyControls(combobox_shininess,this, !material->getSpecularID().isNull(), true);
// Assert desired colorswatch color to match material AFTER updateShinyControls
// to avoid getting overwritten with the default on some UI state changes.
//
if (!material->getSpecularID().isNull())
{
getChild<LLColorSwatchCtrl>("shinycolorswatch")->setOriginal(material->getSpecularLightColor());
getChild<LLColorSwatchCtrl>("shinycolorswatch")->set(material->getSpecularLightColor(),TRUE);
}
// Bumpy (normal)
texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
texture_ctrl->setImageAssetID(material->getNormalID());
LLComboBox* combobox_bumpiness = getChild<LLComboBox>("combobox bumpiness");
if (!material->getNormalID().isNull())
{
material->getNormalOffset(offset_x,offset_y);
material->getNormalRepeat(repeat_x,repeat_y);
if (identical_planar_texgen)
{
repeat_x *= 2.0f;
repeat_y *= 2.0f;
}
rot = material->getNormalRotation();
getChild<LLUICtrl>("bumpyScaleU")->setValue(repeat_x);
getChild<LLUICtrl>("bumpyScaleV")->setValue(repeat_y);
getChild<LLUICtrl>("bumpyRot")->setValue(rot*RAD_TO_DEG);
getChild<LLUICtrl>("bumpyOffsetU")->setValue(offset_x);
getChild<LLUICtrl>("bumpyOffsetV")->setValue(offset_y);
}
updateBumpyControls(combobox_bumpiness,this, !material->getNormalID().isNull(), true);
}
void LLPanelFace::updateMaterial()
{ // assign current state of UI to material definition for submit to sim
LL_DEBUGS("Materials") << "Entered." << LL_ENDL;
@ -1781,53 +1755,38 @@ void LLPanelFace::updateMaterial()
bool identical_texgen = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, selected_texgen );
bool identical_planar_texgen = (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR));
if ((mIsAlpha && (alpha_mode != LLMaterial::DIFFUSE_ALPHA_MODE_BLEND))
bool is_default_blend_mode = mIsAlpha ? (alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
: (alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
if ( !is_default_blend_mode
|| (bumpiness == BUMPY_TEXTURE)
|| (shininess == SHINY_TEXTURE))
{
// The user's specified something that needs a material.
bool new_material = false;
if (!mMaterial)
{
new_material = true;
mMaterial = LLMaterialPtr(new LLMaterial());
}
LLMaterialPtr material_to_set = mMaterial;
bool subselection = false;
// If we're editing a single face and not the entire material for an object,
// we need to clone the material so that our changes to the material's settings
// don't automatically propagate to the non-selected faces
// NORSPEC-92
// Create new or clone material
//
LLObjectSelectionHandle sel = LLSelectMgr::getInstance()->getSelection();
LLSelectNode* node = sel->getFirstNode();
if (node)
if (mMaterial.isNull())
{
if (node->getTESelectMask() != TE_SELECT_MASK_ALL)
{
llinfos << "Cloning material to apply to subselection." << llendl;
material_to_set = new LLMaterial(mMaterial->asLLSD());
subselection = true;
}
else
{
llinfos << "Apply material change to whole selection." << llendl;
}
mMaterial = LLMaterialPtr(new LLMaterial());
new_material = true;
}
else
{
mMaterial = LLMaterialPtr(new LLMaterial(mMaterial->asLLSD()));
}
llassert(!material_to_set.isNull());
llassert_always(mMaterial);
material_to_set->setDiffuseAlphaMode(getChild<LLComboBox>("combobox alphamode")->getCurrentIndex());
material_to_set->setAlphaMaskCutoff((U8)(getChild<LLUICtrl>("maskcutoff")->getValue().asInteger()));
mMaterial->setDiffuseAlphaMode(getChild<LLComboBox>("combobox alphamode")->getCurrentIndex());
mMaterial->setAlphaMaskCutoff((U8)(getChild<LLUICtrl>("maskcutoff")->getValue().asInteger()));
LLUUID norm_map_id = getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID();
if (!norm_map_id.isNull() && (bumpiness == BUMPY_TEXTURE))
{
LL_DEBUGS("Materials") << "Setting bumpy texture, bumpiness = " << bumpiness << LL_ENDL;
material_to_set->setNormalID(norm_map_id);
mMaterial->setNormalID(norm_map_id);
F32 bumpy_scale_u = getChild<LLUICtrl>("bumpyScaleU")->getValue().asReal();
F32 bumpy_scale_v = getChild<LLUICtrl>("bumpyScaleV")->getValue().asReal();
@ -1838,18 +1797,18 @@ void LLPanelFace::updateMaterial()
bumpy_scale_v *= 0.5f;
}
material_to_set->setNormalOffset(getChild<LLUICtrl>("bumpyOffsetU")->getValue().asReal(),
mMaterial->setNormalOffset(getChild<LLUICtrl>("bumpyOffsetU")->getValue().asReal(),
getChild<LLUICtrl>("bumpyOffsetV")->getValue().asReal());
material_to_set->setNormalRepeat(bumpy_scale_u, bumpy_scale_v);
material_to_set->setNormalRotation(getChild<LLUICtrl>("bumpyRot")->getValue().asReal()*DEG_TO_RAD);
mMaterial->setNormalRepeat(bumpy_scale_u, bumpy_scale_v);
mMaterial->setNormalRotation(getChild<LLUICtrl>("bumpyRot")->getValue().asReal()*DEG_TO_RAD);
}
else
{
LL_DEBUGS("Materials") << "Removing bumpy texture, bumpiness = " << bumpiness << LL_ENDL;
material_to_set->setNormalID(LLUUID());
material_to_set->setNormalOffset(0.0f,0.0f);
material_to_set->setNormalRepeat(1.0f,1.0f);
material_to_set->setNormalRotation(0.0f);
mMaterial->setNormalID(LLUUID());
mMaterial->setNormalOffset(0.0f,0.0f);
mMaterial->setNormalRepeat(1.0f,1.0f);
mMaterial->setNormalRotation(0.0f);
}
LLUUID spec_map_id = getChild<LLTextureCtrl>("shinytexture control")->getImageAssetID();
@ -1857,8 +1816,8 @@ void LLPanelFace::updateMaterial()
if (!spec_map_id.isNull() && (shininess == SHINY_TEXTURE))
{
LL_DEBUGS("Materials") << "Setting shiny texture, shininess = " << shininess << LL_ENDL;
material_to_set->setSpecularID(spec_map_id);
material_to_set->setSpecularOffset(getChild<LLUICtrl>("shinyOffsetU")->getValue().asReal(),
mMaterial->setSpecularID(spec_map_id);
mMaterial->setSpecularOffset(getChild<LLUICtrl>("shinyOffsetU")->getValue().asReal(),
getChild<LLUICtrl>("shinyOffsetV")->getValue().asReal());
F32 shiny_scale_u = getChild<LLUICtrl>("shinyScaleU")->getValue().asReal();
@ -1870,55 +1829,42 @@ void LLPanelFace::updateMaterial()
shiny_scale_v *= 0.5f;
}
material_to_set->setSpecularRepeat(shiny_scale_u, shiny_scale_v);
material_to_set->setSpecularRotation(getChild<LLUICtrl>("shinyRot")->getValue().asReal()*DEG_TO_RAD);
mMaterial->setSpecularRepeat(shiny_scale_u, shiny_scale_v);
mMaterial->setSpecularRotation(getChild<LLUICtrl>("shinyRot")->getValue().asReal()*DEG_TO_RAD);
//override shininess to 0.2f if this is a new material
if (!new_material)
{
material_to_set->setSpecularLightColor(getChild<LLColorSwatchCtrl>("shinycolorswatch")->get());
material_to_set->setSpecularLightExponent(getChild<LLUICtrl>("glossiness")->getValue().asInteger());
material_to_set->setEnvironmentIntensity(getChild<LLUICtrl>("environment")->getValue().asInteger());
mMaterial->setSpecularLightColor(getChild<LLColorSwatchCtrl>("shinycolorswatch")->get());
mMaterial->setSpecularLightExponent(getChild<LLUICtrl>("glossiness")->getValue().asInteger());
mMaterial->setEnvironmentIntensity(getChild<LLUICtrl>("environment")->getValue().asInteger());
}
}
else
{
LL_DEBUGS("Materials") << "Removing shiny texture, shininess = " << shininess << LL_ENDL;
material_to_set->setSpecularID(LLUUID());
material_to_set->setSpecularOffset(0.0f,0.0f);
material_to_set->setSpecularRepeat(1.0f,1.0f);
material_to_set->setSpecularRotation(0.0f);
material_to_set->setSpecularLightColor(LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR);
material_to_set->setSpecularLightExponent(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT);
material_to_set->setEnvironmentIntensity(0);
mMaterial->setSpecularID(LLUUID());
mMaterial->setSpecularOffset(0.0f,0.0f);
mMaterial->setSpecularRepeat(1.0f,1.0f);
mMaterial->setSpecularRotation(0.0f);
mMaterial->setSpecularLightColor(LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR);
mMaterial->setSpecularLightExponent(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT);
mMaterial->setEnvironmentIntensity(0);
}
LL_DEBUGS("Materials") << "Updating material: " << material_to_set->asLLSD() << LL_ENDL;
LL_DEBUGS("Materials") << "Updating material: " << mMaterial->asLLSD() << LL_ENDL;
if (node && node->getObject() && node->getObject()->permModify() && subselection)
{
int selected_te = node->getLastSelectedTE();
if (selected_te >= 0)
{
LLMaterialMgr::getInstance()->put(node->getObject()->getID(),selected_te,*material_to_set);
node->getObject()->getTE(selected_te)->setMaterialParams(material_to_set);
node->getObject()->sendTEUpdate();
}
}
else
{
LLSelectMgr::getInstance()->selectionSetMaterial( material_to_set );
}
LLSelectMgr::getInstance()->selectionSetMaterial( mMaterial );
}
else
{
// The user has specified settings that don't need a material.
if (mMaterial || !mMaterialID.isNull())
//if (mMaterial || !mMaterialID.isNull())
{
LL_DEBUGS("Materials") << "Resetting material entry" << LL_ENDL;
mMaterial = NULL;
mMaterialID = LLMaterialID::null;
// Delete existing material entry...
LLSelectMgr::getInstance()->selectionRemoveMaterial();
}

View File

@ -87,7 +87,7 @@ protected:
void onCommitAlpha(const LLSD& data);
void onCancelColor(const LLSD& data);
void onSelectColor(const LLSD& data);
void onMaterialLoaded(const LLMaterialID& material_id, const LLMaterialPtr material);
void updateMaterial();
static void onCommitTextureInfo( LLUICtrl* ctrl, void* userdata);

View File

@ -815,6 +815,7 @@ void LLSelectMgr::addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to
if (objectp->getNumTEs() > 0)
{
nodep->selectAllTEs(TRUE);
objectp->setAllTESelected(true);
}
else
{
@ -872,10 +873,12 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab
else if (face == SELECT_ALL_TES)
{
nodep->selectAllTEs(TRUE);
objectp->setAllTESelected(true);
}
else if (0 <= face && face < SELECT_MAX_TES)
{
nodep->selectTE(face, TRUE);
objectp->setTESelected(face, true);
}
else
{
@ -1095,6 +1098,7 @@ LLObjectSelectionHandle LLSelectMgr::selectHighlightedObjects()
// flag this object as selected
objectp->setSelected(TRUE);
objectp->setAllTESelected(true);
mSelectedObjects->mSelectType = getSelectTypeForObject(objectp);
@ -1318,6 +1322,7 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable)
if (nodep->isTESelected(te))
{
nodep->selectTE(te, FALSE);
objectp->setTESelected(te, false);
}
else
{

View File

@ -530,6 +530,17 @@ void LLViewerObject::setNameValueList(const std::string& name_value_list)
}
}
void LLViewerObject::setSelected(BOOL sel)
{
mUserSelected = sel;
resetRot();
if (!sel)
{
setAllTESelected(false);
}
}
// This method returns true if the object is over land owned by the
// agent.
bool LLViewerObject::isReturnable()
@ -4116,14 +4127,8 @@ S32 LLViewerObject::setTENormalMapCore(const U8 te, LLViewerTexture *image)
{
mat->setNormalID(uuid);
}
setChanged(TEXTURE);
if (mDrawable.notNull())
{
gPipeline.markTextured(mDrawable);
}
}
mTENormalMaps[te] = image;
changeTENormalMap(te,image);
return retval;
}
@ -4144,14 +4149,9 @@ S32 LLViewerObject::setTESpecularMapCore(const U8 te, LLViewerTexture *image)
if (mat)
{
mat->setSpecularID(uuid);
}
setChanged(TEXTURE);
if (mDrawable.notNull())
{
gPipeline.markTextured(mDrawable);
}
}
mTESpecularMaps[te] = image;
changeTESpecularMap(te, image);
return retval;
}
@ -4171,6 +4171,11 @@ void LLViewerObject::changeTENormalMap(S32 index, LLViewerTexture* new_image)
{
return ;
}
setChanged(TEXTURE);
if (mDrawable.notNull())
{
gPipeline.markTextured(mDrawable);
}
mTENormalMaps[index] = new_image ;
}
@ -4180,6 +4185,11 @@ void LLViewerObject::changeTESpecularMap(S32 index, LLViewerTexture* new_image)
{
return ;
}
setChanged(TEXTURE);
if (mDrawable.notNull())
{
gPipeline.markTextured(mDrawable);
}
mTESpecularMaps[index] = new_image ;
}
@ -4375,18 +4385,21 @@ S32 LLViewerObject::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID
<< ", material " << pMaterialID
<< LL_ENDL;
}
else if (pMaterialID != tep->getMaterialID())
//else if (pMaterialID != tep->getMaterialID())
{
LL_DEBUGS("Material") << "Changing texture entry for te " << (S32)te
<< ", object " << mID
<< ", material " << pMaterialID
<< LL_ENDL;
retval = LLPrimitive::setTEMaterialID(te, pMaterialID);
setChanged(TEXTURE);
if (mDrawable.notNull() && retval)
{
gPipeline.markTextured(mDrawable);
}
}
// Kitty would like to know if this is necessary?
// Since we should get a setTEMaterialParams that does it anyway?
//
setChanged(TEXTURE);
if (mDrawable.notNull())
{
gPipeline.markTextured(mDrawable);
}
return retval;
}
@ -4398,22 +4411,23 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri
if (!tep)
{
llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
return 0;
}
else if (pMaterialParams != tep->getMaterialParams())
retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams);
LL_DEBUGS("Material") << "Changing material params for te " << (S32)te
<< ", object " << mID
<< " (" << retval << ")"
<< LL_ENDL;
setTENormalMap(te, tep->getMaterialParams()->getNormalID());
setTESpecularMap(te, tep->getMaterialParams()->getSpecularID());
setChanged(TEXTURE);
if (mDrawable.notNull())
{
retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams);
LL_DEBUGS("Material") << "Changing material params for te " << (S32)te
<< ", object " << mID
<< " (" << retval << ")"
<< LL_ENDL;
setTENormalMap(te, tep->getMaterialParams()->getNormalID());
setTESpecularMap(te, tep->getMaterialParams()->getSpecularID());
setChanged(TEXTURE);
if (mDrawable.notNull() && retval)
{
gPipeline.markTextured(mDrawable);
}
gPipeline.markTextured(mDrawable);
}
return retval;
}

View File

@ -211,7 +211,7 @@ public:
LLViewerRegion* getRegion() const { return mRegionp; }
BOOL isSelected() const { return mUserSelected; }
virtual void setSelected(BOOL sel) { mUserSelected = sel; resetRot();}
virtual void setSelected(BOOL sel);
const LLUUID &getID() const { return mID; }
U32 getLocalID() const { return mLocalID; }

View File

@ -1973,33 +1973,34 @@ S32 LLVOVolume::setTEGlow(const U8 te, const F32 glow)
return res;
}
void LLVOVolume::setTEMaterialParamsCallback(const LLMaterialID &pMaterialID, const LLMaterialPtr pMaterialParams)
void LLVOVolume::setTEMaterialParamsCallback(const LLMaterialID &pMaterialID, const LLMaterialPtr pMaterialParams, U32 te)
{
LL_DEBUGS("MaterialTEs") << "materialid " << pMaterialID.asString() << LL_ENDL;
for (U8 i = 0; i < getNumTEs(); i++)
LL_DEBUGS("MaterialTEs") << "materialid " << pMaterialID.asString() << " to TE " << te << LL_ENDL;
LLTextureEntry* texture_entry = getTE(te);
if (texture_entry && (texture_entry->getMaterialID().isNull() || (texture_entry->getMaterialID() == pMaterialID)))
{
if (getTE(i) && (getTE(i)->getMaterialID().isNull() || (getTE(i)->getMaterialID() == pMaterialID)))
{
setTEMaterialParams(i, pMaterialParams);
}
setTEMaterialParams(te, pMaterialParams);
}
}
S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
{
S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID);
LL_DEBUGS("MaterialTEs") << "te "<< (S32)te << " materialid " << pMaterialID.asString() << " res " << res
<< ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
<< LL_ENDL;
if (res)
{
LL_DEBUGS("MaterialTEs") << " " << pMaterialID.asString() << LL_ENDL;
LLMaterialMgr::instance().get(getRegion()->getRegionID(), pMaterialID, boost::bind(&LLVOVolume::setTEMaterialParamsCallback, this, _1, _2));
gPipeline.markTextured(mDrawable);
mFaceMappingChanged = TRUE;
}
return res;
S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID);
LL_DEBUGS("MaterialTEs") << "te "<< (S32)te << " materialid " << pMaterialID.asString() << " res " << res
<< ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
<< LL_ENDL;
LL_DEBUGS("MaterialTEs") << " " << pMaterialID.asString() << LL_ENDL;
// Use TE-specific version of boost CB hook-up to avoid cross-contaminatin'
LLMaterialMgr::instance().getTE(getRegion()->getRegionID(), pMaterialID, te, boost::bind(&LLVOVolume::setTEMaterialParamsCallback, this, _1, _2, _3));
setChanged(TEXTURE);
if (!mDrawable.isNull())
{
gPipeline.markTextured(mDrawable);
}
mFaceMappingChanged = TRUE;
return TEM_CHANGE_TEXTURE;
}
S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
{
@ -2007,13 +2008,13 @@ S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialPa
LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << pMaterialParams->asLLSD() << " res " << res
<< ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
<< LL_ENDL;
if (res)
setChanged(TEXTURE);
if (!mDrawable.isNull())
{
gPipeline.markTextured(mDrawable);
mFaceMappingChanged = TRUE;
}
return res;
mFaceMappingChanged = TRUE;
return TEM_CHANGE_TEXTURE;
}
S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t)

View File

@ -187,7 +187,7 @@ public:
/*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags);
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
/*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
void setTEMaterialParamsCallback(const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams);
void setTEMaterialParamsCallback(const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams, U32 te);
/*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
/*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t);
/*virtual*/ S32 setTEScaleS(const U8 te, const F32 s);

View File

@ -644,8 +644,8 @@
layout="topleft"
label_width="205"
left="10"
max_val="9999"
min_val="-9999"
max_val="180"
min_val="-180"
name="bumpyRot"
width="265" />
@ -707,8 +707,8 @@
layout="topleft"
label_width="205"
left="10"
max_val="9999"
min_val="-9999"
max_val="180"
min_val="-180"
name="shinyRot"
width="265" />