summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/llface.cpp45
-rw-r--r--indra/newview/llface.h2
-rw-r--r--indra/newview/llpanelface.cpp155
-rw-r--r--indra/newview/llpanelface.h2
-rw-r--r--indra/newview/skins/default/xui/en/panel_tools_texture.xml11
5 files changed, 193 insertions, 22 deletions
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index b2da5bb9f8..473e55ce82 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -1106,7 +1106,7 @@ void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_po
// Returns the necessary texture transform to align this face's TE to align_to's TE
bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offset,
- LLVector2* res_st_scale, F32* res_st_rot) const
+ LLVector2* res_st_scale, F32* res_st_rot, LLRender::eTexIndex map) const
{
if (!align_to)
{
@@ -1119,6 +1119,43 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs
return false;
}
+ F32 map_rot = 0.f, map_scaleS = 0.f, map_scaleT = 0.f, map_offsS = 0.f, map_offsT = 0.f;
+
+ switch (map)
+ {
+ case LLRender::DIFFUSE_MAP:
+ map_rot = orig_tep->getRotation();
+ map_scaleS = orig_tep->mScaleS;
+ map_scaleT = orig_tep->mScaleT;
+ map_offsS = orig_tep->mOffsetS;
+ map_offsT = orig_tep->mOffsetT;
+ break;
+ case LLRender::NORMAL_MAP:
+ if (orig_tep->getMaterialParams()->getNormalID().isNull())
+ {
+ return false;
+ }
+ map_rot = orig_tep->getMaterialParams()->getNormalRotation();
+ map_scaleS = orig_tep->getMaterialParams()->getNormalRepeatX();
+ map_scaleT = orig_tep->getMaterialParams()->getNormalRepeatY();
+ map_offsS = orig_tep->getMaterialParams()->getNormalOffsetX();
+ map_offsT = orig_tep->getMaterialParams()->getNormalOffsetY();
+ break;
+ case LLRender::SPECULAR_MAP:
+ if (orig_tep->getMaterialParams()->getSpecularID().isNull())
+ {
+ return false;
+ }
+ map_rot = orig_tep->getMaterialParams()->getSpecularRotation();
+ map_scaleS = orig_tep->getMaterialParams()->getSpecularRepeatX();
+ map_scaleT = orig_tep->getMaterialParams()->getSpecularRepeatY();
+ map_offsS = orig_tep->getMaterialParams()->getSpecularOffsetX();
+ map_offsT = orig_tep->getMaterialParams()->getSpecularOffsetY();
+ break;
+ default: /*make compiler happy*/
+ break;
+ }
+
LLVector3 orig_pos, this_pos;
LLQuaternion orig_face_rot, this_face_rot;
F32 orig_proj_scale, this_proj_scale;
@@ -1126,7 +1163,7 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs
getPlanarProjectedParams(&this_face_rot, &this_pos, &this_proj_scale);
// The rotation of "this face's" texture:
- LLQuaternion orig_st_rot = LLQuaternion(orig_tep->getRotation(), LLVector3::z_axis) * orig_face_rot;
+ LLQuaternion orig_st_rot = LLQuaternion(map_rot, LLVector3::z_axis) * orig_face_rot;
LLQuaternion this_st_rot = orig_st_rot * ~this_face_rot;
F32 x_ang, y_ang, z_ang;
this_st_rot.getEulerAngles(&x_ang, &y_ang, &z_ang);
@@ -1134,10 +1171,10 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs
// Offset and scale of "this face's" texture:
LLVector3 centers_dist = (this_pos - orig_pos) * ~orig_st_rot;
- LLVector3 st_scale(orig_tep->mScaleS, orig_tep->mScaleT, 1.f);
+ LLVector3 st_scale(map_scaleS, map_scaleT, 1.f);
st_scale *= orig_proj_scale;
centers_dist.scaleVec(st_scale);
- LLVector2 orig_st_offset(orig_tep->mOffsetS, orig_tep->mOffsetT);
+ LLVector2 orig_st_offset(map_offsS, map_offsT);
*res_st_offset = orig_st_offset + (LLVector2)centers_dist;
res_st_offset->mV[VX] -= (S32)res_st_offset->mV[VX];
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 736d45b7ad..10c2b31b6f 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -114,7 +114,7 @@ public:
LLVector2 surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal);
void getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const;
bool calcAlignedPlanarTE(const LLFace* align_to, LLVector2* st_offset,
- LLVector2* st_scale, F32* st_rot) const;
+ LLVector2* st_scale, F32* st_rot, LLRender::eTexIndex map = LLRender::DIFFUSE_MAP) const;
U32 getState() const { return mState; }
void setState(U32 state) { mState |= state; }
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 5e6a44c09d..5cbd1e2f99 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -82,6 +82,8 @@ const S32 ALPHAMODE_MASK = 2; // Alpha masking mode
const S32 BUMPY_TEXTURE = 18; // use supplied normal map
const S32 SHINY_TEXTURE = 4; // use supplied specular map
+BOOST_STATIC_ASSERT(MATTYPE_DIFFUSE == LLRender::DIFFUSE_MAP && MATTYPE_NORMAL == LLRender::NORMAL_MAP && MATTYPE_SPECULAR == LLRender::SPECULAR_MAP);
+
//
// "Use texture" label for normal/specular type comboboxes
// Filled in at initialization from translated strings
@@ -154,6 +156,7 @@ BOOL LLPanelFace::postBuild()
childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this);
childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
+ childSetAction("button align textures", &LLPanelFace::onAlignTexture, this);
LLTextureCtrl* mTextureCtrl;
LLTextureCtrl* mShinyTextureCtrl;
@@ -439,11 +442,28 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
{
BOOL valid;
F32 value;
- LLSpinCtrl* ctrlTexScaleS = mPanel->getChild<LLSpinCtrl>("TexScaleU");
- LLSpinCtrl* ctrlTexScaleT = mPanel->getChild<LLSpinCtrl>("TexScaleV");
- LLSpinCtrl* ctrlTexOffsetS = mPanel->getChild<LLSpinCtrl>("TexOffsetU");
- LLSpinCtrl* ctrlTexOffsetT = mPanel->getChild<LLSpinCtrl>("TexOffsetV");
- LLSpinCtrl* ctrlTexRotation = mPanel->getChild<LLSpinCtrl>("TexRot");
+
+ LLRadioGroup * radio_mat_type = mPanel->getChild<LLRadioGroup>("radio_material_type");
+ std::string prefix;
+ switch (radio_mat_type->getSelectedIndex())
+ {
+ case MATTYPE_DIFFUSE:
+ prefix = "Tex";
+ break;
+ case MATTYPE_NORMAL:
+ prefix = "bumpy";
+ break;
+ case MATTYPE_SPECULAR:
+ prefix = "shiny";
+ break;
+ }
+
+ LLSpinCtrl * ctrlTexScaleS = mPanel->getChild<LLSpinCtrl>(prefix + "ScaleU");
+ LLSpinCtrl * ctrlTexScaleT = mPanel->getChild<LLSpinCtrl>(prefix + "ScaleV");
+ LLSpinCtrl * ctrlTexOffsetS = mPanel->getChild<LLSpinCtrl>(prefix + "OffsetU");
+ LLSpinCtrl * ctrlTexOffsetT = mPanel->getChild<LLSpinCtrl>(prefix + "OffsetV");
+ LLSpinCtrl * ctrlTexRotation = mPanel->getChild<LLSpinCtrl>(prefix + "Rot");
+
LLComboBox* comboTexGen = mPanel->getChild<LLComboBox>("combobox texgen");
LLCheckBoxCtrl* cb_planar_align = mPanel->getChild<LLCheckBoxCtrl>("checkbox planar align");
bool align_planar = (cb_planar_align && cb_planar_align->get());
@@ -466,8 +486,8 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
if (align_planar)
{
- LLPanelFace::LLSelectedTEMaterial::setNormalRepeatX(mPanel, value, te);
- LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatX(mPanel, value, te);
+ LLPanelFace::LLSelectedTEMaterial::setNormalRepeatX(mPanel, value, te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatX(mPanel, value, te, object->getID());
}
}
}
@@ -491,8 +511,8 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
if (align_planar)
{
- LLPanelFace::LLSelectedTEMaterial::setNormalRepeatY(mPanel, value, te);
- LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatY(mPanel, value, te);
+ LLPanelFace::LLSelectedTEMaterial::setNormalRepeatY(mPanel, value, te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatY(mPanel, value, te, object->getID());
}
}
}
@@ -507,8 +527,8 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
if (align_planar)
{
- LLPanelFace::LLSelectedTEMaterial::setNormalOffsetX(mPanel, value, te);
- LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetX(mPanel, value, te);
+ LLPanelFace::LLSelectedTEMaterial::setNormalOffsetX(mPanel, value, te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetX(mPanel, value, te, object->getID());
}
}
}
@@ -523,8 +543,8 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
if (align_planar)
{
- LLPanelFace::LLSelectedTEMaterial::setNormalOffsetY(mPanel, value, te);
- LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetY(mPanel, value, te);
+ LLPanelFace::LLSelectedTEMaterial::setNormalOffsetY(mPanel, value, te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetY(mPanel, value, te, object->getID());
}
}
}
@@ -539,8 +559,8 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
if (align_planar)
{
- LLPanelFace::LLSelectedTEMaterial::setNormalRotation(mPanel, value, te);
- LLPanelFace::LLSelectedTEMaterial::setSpecularRotation(mPanel, value, te);
+ LLPanelFace::LLSelectedTEMaterial::setNormalRotation(mPanel, value, te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setSpecularRotation(mPanel, value, te, object->getID());
}
}
}
@@ -612,6 +632,68 @@ private:
LLFace* mCenterFace;
};
+struct LLPanelFaceSetAlignedConcreteTEFunctor : public LLSelectedTEFunctor
+{
+ LLPanelFaceSetAlignedConcreteTEFunctor(LLPanelFace* panel, LLFace* center_face, LLRender::eTexIndex map) :
+ mPanel(panel),
+ mChefFace(center_face),
+ mMap(map)
+ {}
+
+ virtual bool apply(LLViewerObject* object, S32 te)
+ {
+ LLFace* facep = object->mDrawable->getFace(te);
+ if (!facep)
+ {
+ return true;
+ }
+
+ if (facep->getViewerObject()->getVolume()->getNumVolumeFaces() <= te)
+ {
+ return true;
+ }
+
+ if (mChefFace != facep)
+ {
+ LLVector2 uv_offset, uv_scale;
+ F32 uv_rot;
+ if (facep->calcAlignedPlanarTE(mChefFace, &uv_offset, &uv_scale, &uv_rot, mMap))
+ {
+ switch (mMap)
+ {
+ case LLRender::DIFFUSE_MAP:
+ object->setTEOffset(te, uv_offset.mV[VX], uv_offset.mV[VY]);
+ object->setTEScale(te, uv_scale.mV[VX], uv_scale.mV[VY]);
+ object->setTERotation(te, uv_rot);
+ break;
+ case LLRender::NORMAL_MAP:
+ LLPanelFace::LLSelectedTEMaterial::setNormalRotation(mPanel, uv_rot, te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setNormalOffsetX(mPanel, uv_offset.mV[VX], te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setNormalOffsetY(mPanel, uv_offset.mV[VY], te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setNormalRepeatX(mPanel, uv_scale.mV[VX], te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setNormalRepeatY(mPanel, uv_scale.mV[VY], te, object->getID());
+ break;
+ case LLRender::SPECULAR_MAP:
+ LLPanelFace::LLSelectedTEMaterial::setSpecularRotation(mPanel, uv_rot, te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetX(mPanel, uv_offset.mV[VX], te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetY(mPanel, uv_offset.mV[VY], te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatX(mPanel, uv_scale.mV[VX], te, object->getID());
+ LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatY(mPanel, uv_scale.mV[VY], te, object->getID());
+ break;
+ default: /*make compiler happy*/
+ break;
+ }
+ }
+ }
+
+ return true;
+ }
+private:
+ LLPanelFace* mPanel;
+ LLFace* mChefFace;
+ LLRender::eTexIndex mMap;
+};
+
// Functor that tests if a face is aligned to mCenterFace
struct LLPanelFaceGetIsAlignedTEFunctor : public LLSelectedTEFunctor
{
@@ -697,6 +779,17 @@ void LLPanelFace::sendTextureInfo()
LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc);
}
+void LLPanelFace::alignTestureLayer()
+{
+ LLFace* last_face = NULL;
+ bool identical_face = false;
+ LLSelectedTE::getFace(last_face, identical_face);
+
+ LLRadioGroup * radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
+ LLPanelFaceSetAlignedConcreteTEFunctor setfunc(this, last_face, static_cast<LLRender::eTexIndex>(radio_mat_type->getSelectedIndex()));
+ LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);
+}
+
void LLPanelFace::getState()
{
updateUI();
@@ -983,6 +1076,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
bool enabled = (editable && isIdenticalPlanarTexgen());
childSetValue("checkbox planar align", align_planar && enabled);
childSetEnabled("checkbox planar align", enabled);
+ childSetEnabled("button align textures", enabled && LLSelectMgr::getInstance()->getSelection()->getObjectCount() > 1);
if (align_planar && enabled)
{
@@ -2129,7 +2223,18 @@ void LLPanelFace::onCommitMaterialBumpyRot(LLUICtrl* ctrl, void* userdata)
}
else
{
- LLSelectedTEMaterial::setNormalRotation(self,self->getCurrentBumpyRot() * DEG_TO_RAD);
+ if ((bool)self->childGetValue("checkbox planar align").asBoolean())
+ {
+ LLFace* last_face = NULL;
+ bool identical_face = false;
+ LLSelectedTE::getFace(last_face, identical_face);
+ LLPanelFaceSetAlignedTEFunctor setfunc(self, last_face);
+ LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);
+ }
+ else
+ {
+ LLSelectedTEMaterial::setNormalRotation(self, self->getCurrentBumpyRot() * DEG_TO_RAD);
+ }
}
}
@@ -2146,7 +2251,18 @@ void LLPanelFace::onCommitMaterialShinyRot(LLUICtrl* ctrl, void* userdata)
}
else
{
- LLSelectedTEMaterial::setSpecularRotation(self,self->getCurrentShinyRot() * DEG_TO_RAD);
+ if ((bool)self->childGetValue("checkbox planar align").asBoolean())
+ {
+ LLFace* last_face = NULL;
+ bool identical_face = false;
+ LLSelectedTE::getFace(last_face, identical_face);
+ LLPanelFaceSetAlignedTEFunctor setfunc(self, last_face);
+ LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);
+ }
+ else
+ {
+ LLSelectedTEMaterial::setSpecularRotation(self, self->getCurrentShinyRot() * DEG_TO_RAD);
+ }
}
}
@@ -2403,6 +2519,11 @@ void LLPanelFace::onClickAutoFix(void* userdata)
LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc);
}
+void LLPanelFace::onAlignTexture(void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*)userdata;
+ self->alignTestureLayer();
+}
// TODO: I don't know who put these in or what these are for???
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 0b40d7d41a..2d57d89a44 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -126,6 +126,7 @@ protected:
void sendFullbright(); // applies and sends full bright
void sendGlow();
void sendMedia();
+ void alignTestureLayer();
// this function is to return TRUE if the drag should succeed.
static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item);
@@ -202,6 +203,7 @@ protected:
static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata);
static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo);
static void onClickAutoFix(void*);
+ static void onAlignTexture(void*);
static F32 valueGlow(LLViewerObject* object, S32 face);
diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
index 67b99ca588..90f32ae452 100644
--- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
@@ -770,6 +770,17 @@
tool_tip="Align textures on all selected faces with the last selected face. Requires Planar texture mapping."
top_delta="16"
width="260" />
+ <button
+ left="10"
+ top="222"
+ height="20"
+ label="Align"
+ label_selected="Align current texture layers"
+ layout="topleft"
+ name="button align textures"
+ top_delta="0"
+ tool_tip="Align current texture layers"
+ width="66" />
<web_browser
visible="false"
enabled="false"