/** * @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 "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 "llmenubutton.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 "lltrans.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 "llnotificationsutil.h" #include "lldrawpool.h" #include "lluictrlfactory.h" // For mesh physics #include "llagent.h" #include "llviewercontrol.h" #include "llmeshrepository.h" #include "llvoavatarself.h" #include const F32 DEFAULT_GRAVITY_MULTIPLIER = 1.f; const F32 DEFAULT_DENSITY = 1000.f; // "Features" Tab BOOL LLPanelVolume::postBuild() { // Flexible Objects Parameters { childSetCommitCallback("Animated Mesh Checkbox Ctrl", boost::bind(&LLPanelVolume::onCommitAnimatedMeshCheckbox, this, _1, _2), NULL); childSetCommitCallback("Flexible1D Checkbox Ctrl", boost::bind(&LLPanelVolume::onCommitIsFlexible, this, _1, _2), NULL); 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); } // PHYSICS Parameters { // PhysicsShapeType combobox mComboPhysicsShapeType = getChild("Physics Shape Type Combo Ctrl"); mComboPhysicsShapeType->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsShapeType, this, _1, mComboPhysicsShapeType)); // PhysicsGravity mSpinPhysicsGravity = getChild("Physics Gravity"); mSpinPhysicsGravity->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsGravity, this, _1, mSpinPhysicsGravity)); // PhysicsFriction mSpinPhysicsFriction = getChild("Physics Friction"); mSpinPhysicsFriction->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsFriction, this, _1, mSpinPhysicsFriction)); // PhysicsDensity mSpinPhysicsDensity = getChild("Physics Density"); mSpinPhysicsDensity->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsDensity, this, _1, mSpinPhysicsDensity)); // PhysicsRestitution mSpinPhysicsRestitution = getChild("Physics Restitution"); mSpinPhysicsRestitution->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsRestitution, this, _1, mSpinPhysicsRestitution)); } mMenuClipboardFeatures = getChild("clipboard_features_params_btn"); mMenuClipboardLight = getChild("clipboard_light_params_btn"); std::map material_name_map; material_name_map["Stone"]= LLTrans::getString("Stone"); material_name_map["Metal"]= LLTrans::getString("Metal"); material_name_map["Glass"]= LLTrans::getString("Glass"); material_name_map["Wood"]= LLTrans::getString("Wood"); material_name_map["Flesh"]= LLTrans::getString("Flesh"); material_name_map["Plastic"]= LLTrans::getString("Plastic"); material_name_map["Rubber"]= LLTrans::getString("Rubber"); material_name_map["Light"]= LLTrans::getString("Light"); LLMaterialTable::basic.initTableTransNames(material_name_map); // material type popup mComboMaterial = getChild("material"); childSetCommitCallback("material",onCommitMaterial,this); mComboMaterial->removeall(); for (LLMaterialTable::info_list_t::iterator iter = LLMaterialTable::basic.mMaterialInfoList.begin(); iter != LLMaterialTable::basic.mMaterialInfoList.end(); ++iter) { LLMaterialInfo* minfop = *iter; if (minfop->mMCode != LL_MCODE_LIGHT) { mComboMaterial->add(minfop->mName); } } mComboMaterialItemCount = mComboMaterial->getItemCount(); // Start with everyone disabled clearCtrls(); return TRUE; } LLPanelVolume::LLPanelVolume() : LLPanel(), mComboMaterialItemCount(0) { setMouseOpaque(FALSE); mCommitCallbackRegistrar.add("PanelVolume.menuDoToSelected", boost::bind(&LLPanelVolume::menuDoToSelected, this, _2)); mEnableCallbackRegistrar.add("PanelVolume.menuEnable", boost::bind(&LLPanelVolume::menuEnableItem, this, _2)); } 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; } LLVOVolume *root_volobjp = NULL; if (root_objectp && (root_objectp->getPCode() == LL_PCODE_VOLUME)) { root_volobjp = (LLVOVolume *)root_objectp; } if( !objectp ) { //forfeit focus if (gFocusMgr.childHasKeyboardFocus(this)) { gFocusMgr.setKeyboardFocus(NULL); } // Disable all text input fields clearCtrls(); return; } LLUUID owner_id; std::string owner_name; LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name); // BUG? Check for all objects being editable? BOOL editable = root_objectp->permModify() && !root_objectp->isPermanentEnforced(); BOOL single_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ) && LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1; BOOL single_root_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ) && LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 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) { //mLabelColor ->setEnabled( TRUE ); LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); if(LightColorSwatch) { LightColorSwatch->setEnabled( TRUE ); LightColorSwatch->setValid( TRUE ); LightColorSwatch->set(volobjp->getLightSRGBBaseColor()); } 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->getLightSRGBBaseColor(); } else { getChild("Light Intensity", true)->clear(); getChild("Light Radius", true)->clear(); getChild("Light Falloff", true)->clear(); 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); } // Animated Mesh BOOL is_animated_mesh = single_root_volume && root_volobjp && root_volobjp->isAnimatedObject(); getChild("Animated Mesh Checkbox Ctrl")->setValue(is_animated_mesh); BOOL enabled_animated_object_box = FALSE; if (root_volobjp && root_volobjp == volobjp) { enabled_animated_object_box = single_root_volume && root_volobjp && root_volobjp->canBeAnimatedObject() && editable; #if 0 if (!enabled_animated_object_box) { LL_INFOS() << "not enabled: srv " << single_root_volume << " root_volobjp " << (bool) root_volobjp << LL_ENDL; if (root_volobjp) { LL_INFOS() << " cba " << root_volobjp->canBeAnimatedObject() << " editable " << editable << " permModify() " << root_volobjp->permModify() << " ispermenf " << root_volobjp->isPermanentEnforced() << LL_ENDL; } } #endif if (enabled_animated_object_box && !is_animated_mesh && root_volobjp->isAttachment() && !gAgentAvatarp->canAttachMoreAnimatedObjects()) { // Turning this attachment animated would cause us to exceed the limit. enabled_animated_object_box = false; } } getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(enabled_animated_object_box); //refresh any bakes if (root_volobjp) { root_volobjp->refreshBakeTexture(); LLViewerObject::const_child_list_t& child_list = root_volobjp->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); iter != child_list.end(); ++iter) { LLViewerObject* objectp = *iter; if (objectp) { objectp->refreshBakeTexture(); } } if (gAgentAvatarp) { gAgentAvatarp->updateMeshVisibility(); } } // 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 && !volobjp->isMesh() && !objectp->isPermanentEnforced()); } 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); } // Material properties // Update material part // slightly inefficient - materials are unique per object, not per TE U8 material_code = 0; struct f : public LLSelectedTEGetFunctor { U8 get(LLViewerObject* object, S32 te) { return object->getMaterial(); } } func; bool material_same = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_code ); std::string LEGACY_FULLBRIGHT_DESC = LLTrans::getString("Fullbright"); if (editable && single_volume && material_same) { mComboMaterial->setEnabled( TRUE ); if (material_code == LL_MCODE_LIGHT) { if (mComboMaterial->getItemCount() == mComboMaterialItemCount) { mComboMaterial->add(LEGACY_FULLBRIGHT_DESC); } mComboMaterial->setSimple(LEGACY_FULLBRIGHT_DESC); } else { if (mComboMaterial->getItemCount() != mComboMaterialItemCount) { mComboMaterial->remove(LEGACY_FULLBRIGHT_DESC); } mComboMaterial->setSimple(std::string(LLMaterialTable::basic.getName(material_code))); } } else { mComboMaterial->setEnabled( FALSE ); } // Physics properties mSpinPhysicsGravity->set(objectp->getPhysicsGravity()); mSpinPhysicsGravity->setEnabled(editable); mSpinPhysicsFriction->set(objectp->getPhysicsFriction()); mSpinPhysicsFriction->setEnabled(editable); mSpinPhysicsDensity->set(objectp->getPhysicsDensity()); mSpinPhysicsDensity->setEnabled(editable); mSpinPhysicsRestitution->set(objectp->getPhysicsRestitution()); mSpinPhysicsRestitution->setEnabled(editable); // update the physics shape combo to include allowed physics shapes mComboPhysicsShapeType->removeall(); mComboPhysicsShapeType->add(getString("None"), LLSD(1)); BOOL isMesh = FALSE; LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT); if (sculpt_params) { U8 sculpt_type = sculpt_params->getSculptType(); U8 sculpt_stitching = sculpt_type & LL_SCULPT_TYPE_MASK; isMesh = (sculpt_stitching == LL_SCULPT_TYPE_MESH); } if(isMesh && objectp) { const LLVolumeParams &volume_params = objectp->getVolume()->getParams(); LLUUID mesh_id = volume_params.getSculptID(); if(gMeshRepo.hasPhysicsShape(mesh_id)) { // if a mesh contains an uploaded or decomposed physics mesh, // allow 'Prim' mComboPhysicsShapeType->add(getString("Prim"), LLSD(0)); } } else { // simple prims always allow physics shape prim mComboPhysicsShapeType->add(getString("Prim"), LLSD(0)); } mComboPhysicsShapeType->add(getString("Convex Hull"), LLSD(2)); mComboPhysicsShapeType->setValue(LLSD(objectp->getPhysicsShapeType())); mComboPhysicsShapeType->setEnabled(editable && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced())); mObject = objectp; mRootObject = root_objectp; mMenuClipboardFeatures->setEnabled(editable && single_volume && volobjp); // Note: physics doesn't need to be limited by single volume mMenuClipboardLight->setEnabled(editable && single_volume && volobjp); } // 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()->getShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 0 ? TRUE : FALSE; getChildView("Light FOV")->setVisible( visible); getChildView("Light Focus")->setVisible( visible); getChildView("Light Ambiance")->setVisible( visible); getChildView("light texture control")->setVisible( visible); bool enable_mesh = false; LLSD sim_features; LLViewerRegion *region = gAgent.getRegion(); if(region) { LLSD sim_features; region->getSimulatorFeatures(sim_features); enable_mesh = sim_features.has("PhysicsShapeTypes"); } getChildView("label physicsshapetype")->setVisible(enable_mesh); getChildView("Physics Shape Type Combo Ctrl")->setVisible(enable_mesh); getChildView("Physics Gravity")->setVisible(enable_mesh); getChildView("Physics Friction")->setVisible(enable_mesh); getChildView("Physics Density")->setVisible(enable_mesh); getChildView("Physics Restitution")->setVisible(enable_mesh); /* TODO: add/remove individual physics shape types as per the PhysicsShapeTypes simulator features */ } 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);; 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("Animated Mesh Checkbox Ctrl")->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); mSpinPhysicsGravity->setEnabled(FALSE); mSpinPhysicsFriction->setEnabled(FALSE); mSpinPhysicsDensity->setEnabled(FALSE); mSpinPhysicsRestitution->setEnabled(FALSE); mComboMaterial->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); LL_INFOS() << "update light sent" << LL_ENDL; } 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()); } LL_INFOS() << "update flexible sent" << LL_ENDL; } void LLPanelVolume::sendPhysicsShapeType(LLUICtrl* ctrl, void* userdata) { U8 type = ctrl->getValue().asInteger(); LLSelectMgr::getInstance()->selectionSetPhysicsType(type); refreshCost(); } void LLPanelVolume::sendPhysicsGravity(LLUICtrl* ctrl, void* userdata) { F32 val = ctrl->getValue().asReal(); LLSelectMgr::getInstance()->selectionSetGravity(val); } void LLPanelVolume::sendPhysicsFriction(LLUICtrl* ctrl, void* userdata) { F32 val = ctrl->getValue().asReal(); LLSelectMgr::getInstance()->selectionSetFriction(val); } void LLPanelVolume::sendPhysicsRestitution(LLUICtrl* ctrl, void* userdata) { F32 val = ctrl->getValue().asReal(); LLSelectMgr::getInstance()->selectionSetRestitution(val); } void LLPanelVolume::sendPhysicsDensity(LLUICtrl* ctrl, void* userdata) { F32 val = ctrl->getValue().asReal(); LLSelectMgr::getInstance()->selectionSetDensity(val); } void LLPanelVolume::refreshCost() { LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); if (obj) { obj->getObjectCost(); } } 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"); LLVOVolume *volobjp = (LLVOVolume *) mObject.get(); if (volobjp && LightTextureCtrl) { // Cancel the light texture as requested // NORSPEC-292 // // Texture picker triggers cancel both in case of actual cancel and in case of // selection of "None" texture. LLUUID tex_id = LightTextureCtrl->getImageAssetID(); bool is_spotlight = volobjp->isLightSpotlight(); volobjp->setLightTextureID(tex_id); //updates spotlight if (!is_spotlight && tex_id.notNull()) { LLVector3 spot_params = volobjp->getSpotLightParams(); getChild("Light FOV")->setValue(spot_params.mV[0]); getChild("Light Focus")->setValue(spot_params.mV[1]); getChild("Light Ambiance")->setValue(spot_params.mV[2]); } } } 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->setLightSRGBColor(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); } } void LLPanelVolume::onCopyFeatures() { LLViewerObject* objectp = mObject; if (!objectp) { return; } LLSD clipboard; LLVOVolume *volobjp = NULL; if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) { volobjp = (LLVOVolume *)objectp; } // Flexi Prim if (volobjp && volobjp->isFlexible()) { LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); if (attributes) { clipboard["flex"]["lod"] = attributes->getSimulateLOD(); clipboard["flex"]["gav"] = attributes->getGravity(); clipboard["flex"]["ten"] = attributes->getTension(); clipboard["flex"]["fri"] = attributes->getAirFriction(); clipboard["flex"]["sen"] = attributes->getWindSensitivity(); LLVector3 force = attributes->getUserForce(); clipboard["flex"]["forx"] = force.mV[0]; clipboard["flex"]["fory"] = force.mV[1]; clipboard["flex"]["forz"] = force.mV[2]; } } // Physics { clipboard["physics"]["shape"] = objectp->getPhysicsShapeType(); clipboard["physics"]["gravity"] = objectp->getPhysicsGravity(); clipboard["physics"]["friction"] = objectp->getPhysicsFriction(); clipboard["physics"]["density"] = objectp->getPhysicsDensity(); clipboard["physics"]["restitution"] = objectp->getPhysicsRestitution(); U8 material_code = 0; struct f : public LLSelectedTEGetFunctor { U8 get(LLViewerObject* object, S32 te) { return object->getMaterial(); } } func; bool material_same = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, material_code); // This should always be true since material should be per object. if (material_same) { clipboard["physics"]["material"] = material_code; } } mClipboardParams["features"] = clipboard; } void LLPanelVolume::onPasteFeatures() { LLViewerObject* objectp = mObject; if (!objectp && mClipboardParams.has("features")) { return; } LLSD &clipboard = mClipboardParams["features"]; LLVOVolume *volobjp = NULL; if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) { volobjp = (LLVOVolume *)objectp; } // Physics bool is_root = objectp->isRoot(); // Not sure if phantom should go under physics, but doesn't fit elsewhere BOOL is_phantom = clipboard["is_phantom"].asBoolean() && is_root; LLSelectMgr::getInstance()->selectionUpdatePhantom(is_phantom); BOOL is_physical = clipboard["is_physical"].asBoolean() && is_root; LLSelectMgr::getInstance()->selectionUpdatePhysics(is_physical); if (clipboard.has("physics")) { objectp->setPhysicsShapeType((U8)clipboard["physics"]["shape"].asInteger()); U8 cur_material = objectp->getMaterial(); U8 material = (U8)clipboard["physics"]["material"].asInteger() | (cur_material & ~LL_MCODE_MASK); objectp->setMaterial(material); objectp->sendMaterialUpdate(); objectp->setPhysicsGravity(clipboard["physics"]["gravity"].asReal()); objectp->setPhysicsFriction(clipboard["physics"]["friction"].asReal()); objectp->setPhysicsDensity(clipboard["physics"]["density"].asReal()); objectp->setPhysicsRestitution(clipboard["physics"]["restitution"].asReal()); objectp->updateFlags(TRUE); } // Flexible bool is_flexible = clipboard.has("flex"); if (is_flexible && volobjp->canBeFlexible()) { LLVOVolume *volobjp = (LLVOVolume *)objectp; BOOL update_shape = FALSE; // do before setParameterEntry or it will think that it is already flexi update_shape = volobjp->setIsFlexible(is_flexible); if (objectp->getClickAction() == CLICK_ACTION_SIT) { objectp->setClickAction(CLICK_ACTION_NONE); } LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); if (attributes) { LLFlexibleObjectData new_attributes; new_attributes = *attributes; new_attributes.setSimulateLOD(clipboard["flex"]["lod"].asInteger()); new_attributes.setGravity(clipboard["flex"]["gav"].asReal()); new_attributes.setTension(clipboard["flex"]["ten"].asReal()); new_attributes.setAirFriction(clipboard["flex"]["fri"].asReal()); new_attributes.setWindSensitivity(clipboard["flex"]["sen"].asReal()); F32 fx = (F32)clipboard["flex"]["forx"].asReal(); F32 fy = (F32)clipboard["flex"]["fory"].asReal(); F32 fz = (F32)clipboard["flex"]["forz"].asReal(); LLVector3 force(fx, fy, fz); new_attributes.setUserForce(force); objectp->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE, new_attributes, true); } if (update_shape) { mObject->sendShapeUpdate(); LLSelectMgr::getInstance()->selectionUpdatePhantom(volobjp->flagPhantom()); } } else { LLVOVolume *volobjp = (LLVOVolume *)objectp; if (volobjp->setIsFlexible(false)) { mObject->sendShapeUpdate(); LLSelectMgr::getInstance()->selectionUpdatePhantom(volobjp->flagPhantom()); } } } void LLPanelVolume::onCopyLight() { LLViewerObject* objectp = mObject; if (!objectp) { return; } LLSD clipboard; LLVOVolume *volobjp = NULL; if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) { volobjp = (LLVOVolume *)objectp; } // Light Source if (volobjp && volobjp->getIsLight()) { clipboard["light"]["intensity"] = volobjp->getLightIntensity(); clipboard["light"]["radius"] = volobjp->getLightRadius(); clipboard["light"]["falloff"] = volobjp->getLightFalloff(); LLColor3 color = volobjp->getLightSRGBColor(); clipboard["light"]["r"] = color.mV[0]; clipboard["light"]["g"] = color.mV[1]; clipboard["light"]["b"] = color.mV[2]; // Spotlight if (volobjp->isLightSpotlight()) { LLUUID id = volobjp->getLightTextureID(); if (id.notNull() && get_can_copy_texture(id)) { clipboard["spot"]["id"] = id; LLVector3 spot_params = volobjp->getSpotLightParams(); clipboard["spot"]["fov"] = spot_params.mV[0]; clipboard["spot"]["focus"] = spot_params.mV[1]; clipboard["spot"]["ambiance"] = spot_params.mV[2]; } } } mClipboardParams["light"] = clipboard; } void LLPanelVolume::onPasteLight() { LLViewerObject* objectp = mObject; if (!objectp && mClipboardParams.has("light")) { return; } LLSD &clipboard = mClipboardParams["light"]; LLVOVolume *volobjp = NULL; if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) { volobjp = (LLVOVolume *)objectp; } // Light Source if (volobjp) { if (clipboard.has("light")) { volobjp->setIsLight(TRUE); volobjp->setLightIntensity((F32)clipboard["light"]["intensity"].asReal()); volobjp->setLightRadius((F32)clipboard["light"]["radius"].asReal()); volobjp->setLightFalloff((F32)clipboard["light"]["falloff"].asReal()); F32 r = (F32)clipboard["light"]["r"].asReal(); F32 g = (F32)clipboard["light"]["g"].asReal(); F32 b = (F32)clipboard["light"]["b"].asReal(); volobjp->setLightSRGBColor(LLColor3(r, g, b)); } else { volobjp->setIsLight(FALSE); } if (clipboard.has("spot")) { volobjp->setLightTextureID(clipboard["spot"]["id"].asUUID()); LLVector3 spot_params; spot_params.mV[0] = (F32)clipboard["spot"]["fov"].asReal(); spot_params.mV[1] = (F32)clipboard["spot"]["focus"].asReal(); spot_params.mV[2] = (F32)clipboard["spot"]["ambiance"].asReal(); volobjp->setSpotLightParams(spot_params); } } } void LLPanelVolume::menuDoToSelected(const LLSD& userdata) { std::string command = userdata.asString(); // paste if (command == "features_paste") { onPasteFeatures(); } else if (command == "light_paste") { onPasteLight(); } // copy else if (command == "features_copy") { onCopyFeatures(); } else if (command == "light_copy") { onCopyLight(); } } bool LLPanelVolume::menuEnableItem(const LLSD& userdata) { std::string command = userdata.asString(); // paste options if (command == "features_paste") { return mClipboardParams.has("features"); } else if (command == "light_paste") { return mClipboardParams.has("light"); } return false; } // static void LLPanelVolume::onCommitMaterial( LLUICtrl* ctrl, void* userdata ) { LLPanelVolume* self = (LLPanelVolume*)userdata; LLComboBox* box = (LLComboBox*) ctrl; if (box) { // apply the currently selected material to the object const std::string& material_name = box->getSimple(); std::string LEGACY_FULLBRIGHT_DESC = LLTrans::getString("Fullbright"); if (material_name != LEGACY_FULLBRIGHT_DESC) { U8 material_code = LLMaterialTable::basic.getMCode(material_name); if (self) { LLViewerObject* objectp = self->mObject; if (objectp) { objectp->setPhysicsGravity(DEFAULT_GRAVITY_MULTIPLIER); objectp->setPhysicsFriction(LLMaterialTable::basic.getFriction(material_code)); //currently density is always set to 1000 serverside regardless of chosen material, //actual material density should be used here, if this behavior change objectp->setPhysicsDensity(DEFAULT_DENSITY); objectp->setPhysicsRestitution(LLMaterialTable::basic.getRestitution(material_code)); } } LLSelectMgr::getInstance()->selectionSetMaterial(material_code); } } } // 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->setLightSRGBColor(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, this time volobjp won't change params on its own. if (volobjp->getLightTextureID() != id) { volobjp->setLightTextureID(id); } 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(); } void LLPanelVolume::onCommitAnimatedMeshCheckbox(LLUICtrl *, void*) { LLViewerObject* objectp = mObject; if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) { return; } LLVOVolume *volobjp = (LLVOVolume *)objectp; BOOL animated_mesh = getChild("Animated Mesh Checkbox Ctrl")->getValue(); U32 flags = volobjp->getExtendedMeshFlags(); U32 new_flags = flags; if (animated_mesh) { new_flags |= LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG; } else { new_flags &= ~LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG; } if (new_flags != flags) { volobjp->setExtendedMeshFlags(new_flags); } //refresh any bakes if (volobjp) { volobjp->refreshBakeTexture(); LLViewerObject::const_child_list_t& child_list = volobjp->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); iter != child_list.end(); ++iter) { LLViewerObject* objectp = *iter; if (objectp) { objectp->refreshBakeTexture(); } } if (gAgentAvatarp) { gAgentAvatarp->updateMeshVisibility(); } } } void LLPanelVolume::onCommitIsFlexible(LLUICtrl *, void*) { if (mObject->flagObjectPermanent()) { LLNotificationsUtil::add("PathfindingLinksets_ChangeToFlexiblePath", LLSD(), LLSD(), boost::bind(&LLPanelVolume::handleResponseChangeToFlexible, this, _1, _2)); } else { sendIsFlexible(); } } void LLPanelVolume::handleResponseChangeToFlexible(const LLSD &pNotification, const LLSD &pResponse) { if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0) { sendIsFlexible(); } else { getChild("Flexible1D Checkbox Ctrl")->setValue(FALSE); } }