/** * @file llpanelvolume.cpp * @brief Object editing (position, scale, etc.) in the tools floater * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ #include "llviewerprecompiledheaders.h" // file include #include "llpanelvolume.h" // linden library includes #include "llclickaction.h" #include "lleconomy.h" #include "llerror.h" #include "llfontgl.h" #include "llflexibleobject.h" #include "llmaterialtable.h" #include "llpermissionsflags.h" #include "llstring.h" #include "llvolume.h" #include "m3math.h" #include "material_codes.h" // project includes #include "llbutton.h" #include "llcheckboxctrl.h" #include "llcolorswatch.h" #include "lltexturectrl.h" #include "llcombobox.h" //#include "llfirstuse.h" #include "llfocusmgr.h" #include "llmanipscale.h" #include "llpreviewscript.h" #include "llresmgr.h" #include "llselectmgr.h" #include "llspinctrl.h" #include "lltextbox.h" #include "lltool.h" #include "lltoolcomp.h" #include "lltoolmgr.h" #include "llui.h" #include "llviewerobject.h" #include "llviewerregion.h" #include "llviewerwindow.h" #include "llvovolume.h" #include "llworld.h" #include "pipeline.h" #include "llviewershadermgr.h" #include "lldrawpool.h" #include "lluictrlfactory.h" // "Features" Tab BOOL LLPanelVolume::postBuild() { // Flexible Objects Parameters { childSetCommitCallback("Flexible1D Checkbox Ctrl",onCommitIsFlexible,this); childSetCommitCallback("FlexNumSections",onCommitFlexible,this); getChild("FlexNumSections")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("FlexGravity",onCommitFlexible,this); getChild("FlexGravity")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("FlexFriction",onCommitFlexible,this); getChild("FlexFriction")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("FlexWind",onCommitFlexible,this); getChild("FlexWind")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("FlexTension",onCommitFlexible,this); getChild("FlexTension")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("FlexForceX",onCommitFlexible,this); getChild("FlexForceX")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("FlexForceY",onCommitFlexible,this); getChild("FlexForceY")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("FlexForceZ",onCommitFlexible,this); getChild("FlexForceZ")->setValidateBeforeCommit(precommitValidate); } // LIGHT Parameters { childSetCommitCallback("Light Checkbox Ctrl",onCommitIsLight,this); LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); if(LightColorSwatch){ LightColorSwatch->setOnCancelCallback(boost::bind(&LLPanelVolume::onLightCancelColor, this, _2)); LightColorSwatch->setOnSelectCallback(boost::bind(&LLPanelVolume::onLightSelectColor, this, _2)); childSetCommitCallback("colorswatch",onCommitLight,this); } LLTextureCtrl* LightTexPicker = getChild("light texture control"); if (LightTexPicker) { LightTexPicker->setOnCancelCallback(boost::bind(&LLPanelVolume::onLightCancelTexture, this, _2)); LightTexPicker->setOnSelectCallback(boost::bind(&LLPanelVolume::onLightSelectTexture, this, _2)); childSetCommitCallback("light texture control", onCommitLight, this); } childSetCommitCallback("Light Intensity",onCommitLight,this); getChild("Light Intensity")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("Light Radius",onCommitLight,this); getChild("Light Radius")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("Light Falloff",onCommitLight,this); getChild("Light Falloff")->setValidateBeforeCommit(precommitValidate); childSetCommitCallback("Light FOV", onCommitLight, this); getChild("Light FOV")->setValidateBeforeCommit( precommitValidate); childSetCommitCallback("Light Focus", onCommitLight, this); getChild("Light Focus")->setValidateBeforeCommit( precommitValidate); childSetCommitCallback("Light Ambiance", onCommitLight, this); getChild("Light Ambiance")->setValidateBeforeCommit( precommitValidate); } // Start with everyone disabled clearCtrls(); return TRUE; } LLPanelVolume::LLPanelVolume() : LLPanel() { setMouseOpaque(FALSE); } LLPanelVolume::~LLPanelVolume() { // Children all cleaned up by default view destructor. } void LLPanelVolume::getState( ) { LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(); LLViewerObject* root_objectp = objectp; if(!objectp) { objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); // *FIX: shouldn't we just keep the child? if (objectp) { LLViewerObject* parentp = objectp->getRootEdit(); if (parentp) { root_objectp = parentp; } else { root_objectp = objectp; } } } LLVOVolume *volobjp = NULL; if ( objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) { volobjp = (LLVOVolume *)objectp; } if( !objectp ) { //forfeit focus if (gFocusMgr.childHasKeyboardFocus(this)) { gFocusMgr.setKeyboardFocus(NULL); } // Disable all text input fields clearCtrls(); return; } BOOL owners_identical; LLUUID owner_id; std::string owner_name; owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name); // BUG? Check for all objects being editable? BOOL editable = root_objectp->permModify(); BOOL single_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ) && LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1; // Select Single Message if (single_volume) { getChildView("edit_object")->setVisible(true); getChildView("edit_object")->setEnabled(true); getChildView("select_single")->setVisible(false); } else { getChildView("edit_object")->setVisible(false); getChildView("select_single")->setVisible(true); getChildView("select_single")->setEnabled(true); } // Light properties BOOL is_light = volobjp && volobjp->getIsLight(); getChild("Light Checkbox Ctrl")->setValue(is_light); getChildView("Light Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp); if (is_light && editable && single_volume) { getChildView("label color")->setEnabled(true); //mLabelColor ->setEnabled( TRUE ); LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); if(LightColorSwatch) { LightColorSwatch->setEnabled( TRUE ); LightColorSwatch->setValid( TRUE ); LightColorSwatch->set(volobjp->getLightBaseColor()); } LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); if (LightTextureCtrl) { LightTextureCtrl->setEnabled(TRUE); LightTextureCtrl->setValid(TRUE); LightTextureCtrl->setImageAssetID(volobjp->getLightTextureID()); } getChildView("Light Intensity")->setEnabled(true); getChildView("Light Radius")->setEnabled(true); getChildView("Light Falloff")->setEnabled(true); getChildView("Light FOV")->setEnabled(true); getChildView("Light Focus")->setEnabled(true); getChildView("Light Ambiance")->setEnabled(true); getChild("Light Intensity")->setValue(volobjp->getLightIntensity()); getChild("Light Radius")->setValue(volobjp->getLightRadius()); getChild("Light Falloff")->setValue(volobjp->getLightFalloff()); LLVector3 params = volobjp->getSpotLightParams(); getChild("Light FOV")->setValue(params.mV[0]); getChild("Light Focus")->setValue(params.mV[1]); getChild("Light Ambiance")->setValue(params.mV[2]); mLightSavedColor = volobjp->getLightColor(); } else { getChild("Light Intensity", true)->clear(); getChild("Light Radius", true)->clear(); getChild("Light Falloff", true)->clear(); getChildView("label color")->setEnabled(false); LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); if(LightColorSwatch) { LightColorSwatch->setEnabled( FALSE ); LightColorSwatch->setValid( FALSE ); } LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); if (LightTextureCtrl) { LightTextureCtrl->setEnabled(FALSE); LightTextureCtrl->setValid(FALSE); } getChildView("Light Intensity")->setEnabled(false); getChildView("Light Radius")->setEnabled(false); getChildView("Light Falloff")->setEnabled(false); getChildView("Light FOV")->setEnabled(false); getChildView("Light Focus")->setEnabled(false); getChildView("Light Ambiance")->setEnabled(false); } // Flexible properties BOOL is_flexible = volobjp && volobjp->isFlexible(); getChild("Flexible1D Checkbox Ctrl")->setValue(is_flexible); if (is_flexible || (volobjp && volobjp->canBeFlexible())) { getChildView("Flexible1D Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp); } else { getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false); } if (is_flexible && editable && single_volume) { getChildView("FlexNumSections")->setVisible(true); getChildView("FlexGravity")->setVisible(true); getChildView("FlexTension")->setVisible(true); getChildView("FlexFriction")->setVisible(true); getChildView("FlexWind")->setVisible(true); getChildView("FlexForceX")->setVisible(true); getChildView("FlexForceY")->setVisible(true); getChildView("FlexForceZ")->setVisible(true); getChildView("FlexNumSections")->setEnabled(true); getChildView("FlexGravity")->setEnabled(true); getChildView("FlexTension")->setEnabled(true); getChildView("FlexFriction")->setEnabled(true); getChildView("FlexWind")->setEnabled(true); getChildView("FlexForceX")->setEnabled(true); getChildView("FlexForceY")->setEnabled(true); getChildView("FlexForceZ")->setEnabled(true); LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); getChild("FlexNumSections")->setValue((F32)attributes->getSimulateLOD()); getChild("FlexGravity")->setValue(attributes->getGravity()); getChild("FlexTension")->setValue(attributes->getTension()); getChild("FlexFriction")->setValue(attributes->getAirFriction()); getChild("FlexWind")->setValue(attributes->getWindSensitivity()); getChild("FlexForceX")->setValue(attributes->getUserForce().mV[VX]); getChild("FlexForceY")->setValue(attributes->getUserForce().mV[VY]); getChild("FlexForceZ")->setValue(attributes->getUserForce().mV[VZ]); } else { getChild("FlexNumSections", true)->clear(); getChild("FlexGravity", true)->clear(); getChild("FlexTension", true)->clear(); getChild("FlexFriction", true)->clear(); getChild("FlexWind", true)->clear(); getChild("FlexForceX", true)->clear(); getChild("FlexForceY", true)->clear(); getChild("FlexForceZ", true)->clear(); getChildView("FlexNumSections")->setEnabled(false); getChildView("FlexGravity")->setEnabled(false); getChildView("FlexTension")->setEnabled(false); getChildView("FlexFriction")->setEnabled(false); getChildView("FlexWind")->setEnabled(false); getChildView("FlexForceX")->setEnabled(false); getChildView("FlexForceY")->setEnabled(false); getChildView("FlexForceZ")->setEnabled(false); } mObject = objectp; mRootObject = root_objectp; } // static bool LLPanelVolume::precommitValidate( const LLSD& data ) { // TODO: Richard will fill this in later. return TRUE; // FALSE means that validation failed and new value should not be commited. } void LLPanelVolume::refresh() { getState(); if (mObject.notNull() && mObject->isDead()) { mObject = NULL; } if (mRootObject.notNull() && mRootObject->isDead()) { mRootObject = NULL; } BOOL visible = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 0 ? TRUE : FALSE; getChildView("label texture")->setVisible( visible); getChildView("Light FOV")->setVisible( visible); getChildView("Light Focus")->setVisible( visible); getChildView("Light Ambiance")->setVisible( visible); getChildView("light texture control")->setVisible( visible); } void LLPanelVolume::draw() { LLPanel::draw(); } // virtual void LLPanelVolume::clearCtrls() { LLPanel::clearCtrls(); getChildView("select_single")->setEnabled(false); getChildView("select_single")->setVisible(true); getChildView("edit_object")->setEnabled(false); getChildView("edit_object")->setVisible(false); getChildView("Light Checkbox Ctrl")->setEnabled(false); getChildView("label color")->setEnabled(false); getChildView("label color")->setEnabled(false); LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); if(LightColorSwatch) { LightColorSwatch->setEnabled( FALSE ); LightColorSwatch->setValid( FALSE ); } LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); if(LightTextureCtrl) { LightTextureCtrl->setEnabled( FALSE ); LightTextureCtrl->setValid( FALSE ); } getChildView("Light Intensity")->setEnabled(false); getChildView("Light Radius")->setEnabled(false); getChildView("Light Falloff")->setEnabled(false); getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false); getChildView("FlexNumSections")->setEnabled(false); getChildView("FlexGravity")->setEnabled(false); getChildView("FlexTension")->setEnabled(false); getChildView("FlexFriction")->setEnabled(false); getChildView("FlexWind")->setEnabled(false); getChildView("FlexForceX")->setEnabled(false); getChildView("FlexForceY")->setEnabled(false); getChildView("FlexForceZ")->setEnabled(false); } // // Static functions // void LLPanelVolume::sendIsLight() { LLViewerObject* objectp = mObject; if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) { return; } LLVOVolume *volobjp = (LLVOVolume *)objectp; BOOL value = getChild("Light Checkbox Ctrl")->getValue(); volobjp->setIsLight(value); llinfos << "update light sent" << llendl; } void LLPanelVolume::sendIsFlexible() { LLViewerObject* objectp = mObject; if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) { return; } LLVOVolume *volobjp = (LLVOVolume *)objectp; BOOL is_flexible = getChild("Flexible1D Checkbox Ctrl")->getValue(); //BOOL is_flexible = mCheckFlexible1D->get(); if (is_flexible) { //LLFirstUse::useFlexible(); if (objectp->getClickAction() == CLICK_ACTION_SIT) { LLSelectMgr::getInstance()->selectionSetClickAction(CLICK_ACTION_NONE); } } if (volobjp->setIsFlexible(is_flexible)) { mObject->sendShapeUpdate(); LLSelectMgr::getInstance()->selectionUpdatePhantom(volobjp->flagPhantom()); } llinfos << "update flexible sent" << llendl; } void LLPanelVolume::onLightCancelColor(const LLSD& data) { LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); if(LightColorSwatch) { LightColorSwatch->setColor(mLightSavedColor); } onLightSelectColor(data); } void LLPanelVolume::onLightCancelTexture(const LLSD& data) { LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); if (LightTextureCtrl) { LightTextureCtrl->setImageAssetID(mLightSavedTexture); } } void LLPanelVolume::onLightSelectColor(const LLSD& data) { LLViewerObject* objectp = mObject; if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) { return; } LLVOVolume *volobjp = (LLVOVolume *)objectp; LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); if(LightColorSwatch) { LLColor4 clr = LightColorSwatch->get(); LLColor3 clr3( clr ); volobjp->setLightColor(clr3); mLightSavedColor = clr; } } void LLPanelVolume::onLightSelectTexture(const LLSD& data) { if (mObject.isNull() || (mObject->getPCode() != LL_PCODE_VOLUME)) { return; } LLVOVolume *volobjp = (LLVOVolume *) mObject.get(); LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); if(LightTextureCtrl) { LLUUID id = LightTextureCtrl->getImageAssetID(); volobjp->setLightTextureID(id); mLightSavedTexture = id; } } // static void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata ) { LLPanelVolume* self = (LLPanelVolume*) userdata; LLViewerObject* objectp = self->mObject; if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) { return; } LLVOVolume *volobjp = (LLVOVolume *)objectp; volobjp->setLightIntensity((F32)self->getChild("Light Intensity")->getValue().asReal()); volobjp->setLightRadius((F32)self->getChild("Light Radius")->getValue().asReal()); volobjp->setLightFalloff((F32)self->getChild("Light Falloff")->getValue().asReal()); LLColorSwatchCtrl* LightColorSwatch = self->getChild("colorswatch"); if(LightColorSwatch) { LLColor4 clr = LightColorSwatch->get(); volobjp->setLightColor(LLColor3(clr)); } LLTextureCtrl* LightTextureCtrl = self->getChild("light texture control"); if(LightTextureCtrl) { LLUUID id = LightTextureCtrl->getImageAssetID(); if (id.notNull()) { if (!volobjp->isLightSpotlight()) { //this commit is making this a spot light, set UI to default params volobjp->setLightTextureID(id); LLVector3 spot_params = volobjp->getSpotLightParams(); self->getChild("Light FOV")->setValue(spot_params.mV[0]); self->getChild("Light Focus")->setValue(spot_params.mV[1]); self->getChild("Light Ambiance")->setValue(spot_params.mV[2]); } else { //modifying existing params LLVector3 spot_params; spot_params.mV[0] = (F32) self->getChild("Light FOV")->getValue().asReal(); spot_params.mV[1] = (F32) self->getChild("Light Focus")->getValue().asReal(); spot_params.mV[2] = (F32) self->getChild("Light Ambiance")->getValue().asReal(); volobjp->setSpotLightParams(spot_params); } } else if (volobjp->isLightSpotlight()) { //no longer a spot light volobjp->setLightTextureID(id); //self->getChildView("Light FOV")->setEnabled(FALSE); //self->getChildView("Light Focus")->setEnabled(FALSE); //self->getChildView("Light Ambiance")->setEnabled(FALSE); } } } // static void LLPanelVolume::onCommitIsLight( LLUICtrl* ctrl, void* userdata ) { LLPanelVolume* self = (LLPanelVolume*) userdata; self->sendIsLight(); } //---------------------------------------------------------------------------- // static void LLPanelVolume::onCommitFlexible( LLUICtrl* ctrl, void* userdata ) { LLPanelVolume* self = (LLPanelVolume*) userdata; LLViewerObject* objectp = self->mObject; if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) { return; } LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); if (attributes) { LLFlexibleObjectData new_attributes; new_attributes = *attributes; new_attributes.setSimulateLOD(self->getChild("FlexNumSections")->getValue().asInteger());//(S32)self->mSpinSections->get()); new_attributes.setGravity((F32)self->getChild("FlexGravity")->getValue().asReal()); new_attributes.setTension((F32)self->getChild("FlexTension")->getValue().asReal()); new_attributes.setAirFriction((F32)self->getChild("FlexFriction")->getValue().asReal()); new_attributes.setWindSensitivity((F32)self->getChild("FlexWind")->getValue().asReal()); F32 fx = (F32)self->getChild("FlexForceX")->getValue().asReal(); F32 fy = (F32)self->getChild("FlexForceY")->getValue().asReal(); F32 fz = (F32)self->getChild("FlexForceZ")->getValue().asReal(); LLVector3 force(fx,fy,fz); new_attributes.setUserForce(force); objectp->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE, new_attributes, true); } // Values may fail validation self->refresh(); } // static void LLPanelVolume::onCommitIsFlexible( LLUICtrl* ctrl, void* userdata ) { LLPanelVolume* self = (LLPanelVolume*) userdata; self->sendIsFlexible(); }