From 7691780825940364e3faa7a682490f51491d44dc Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Thu, 25 May 2017 11:11:02 +0100
Subject: [PATCH] SL-694 - Added extra param field for flags related to
 extended mesh functionality. Currently this is just one bit to flag an object
 as able to animate

---
 indra/llprimitive/llprimitive.cpp             | 65 +++++++++++++++++++
 indra/llprimitive/llprimitive.h               | 22 +++++++
 indra/newview/llpanelvolume.cpp               | 37 ++++++++++-
 indra/newview/llpanelvolume.h                 |  1 +
 indra/newview/llviewerobject.cpp              |  5 ++
 indra/newview/llvovolume.cpp                  | 53 +++++++++++++++
 indra/newview/llvovolume.h                    |  7 ++
 .../skins/default/xui/en/floater_tools.xml    | 18 +++--
 8 files changed, 203 insertions(+), 5 deletions(-)

diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index bfa65666b5e..54b87fec783 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -1599,6 +1599,8 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size)
 		return (size == 17);
 	case PARAMS_LIGHT_IMAGE:
 		return (size == 28);
+    case PARAMS_EXTENDED_MESH:
+        return (size == 4);
 	}
 	
 	return FALSE;
@@ -2026,3 +2028,66 @@ bool LLLightImageParams::fromLLSD(LLSD& sd)
 	
 	return false;
 }
+
+//============================================================================
+
+LLExtendedMeshParams::LLExtendedMeshParams()
+{
+	mFlags = 0;
+}
+
+BOOL LLExtendedMeshParams::pack(LLDataPacker &dp) const
+{
+	dp.packU32(mFlags, "flags");
+
+	return TRUE;
+}
+
+BOOL LLExtendedMeshParams::unpack(LLDataPacker &dp)
+{
+	dp.unpackU32(mFlags, "flags");
+	
+	return TRUE;
+}
+
+bool LLExtendedMeshParams::operator==(const LLNetworkData& data) const
+{
+	if (data.mType != PARAMS_EXTENDED_MESH)
+	{
+		return false;
+	}
+	
+	const LLExtendedMeshParams *param = (const LLExtendedMeshParams*)&data;
+	if ( (param->mFlags != mFlags) )
+	{
+		return false;
+	}
+
+	return true;
+}
+
+void LLExtendedMeshParams::copy(const LLNetworkData& data)
+{
+	const LLExtendedMeshParams *param = (LLExtendedMeshParams*)&data;
+	mFlags = param->mFlags;
+}
+
+LLSD LLExtendedMeshParams::asLLSD() const
+{
+	LLSD sd;
+	
+	sd["flags"] = LLSD::Integer(mFlags);
+		
+	return sd;
+}
+
+bool LLExtendedMeshParams::fromLLSD(LLSD& sd)
+{
+	if (sd.has("flags"))
+	{
+		setFlags( sd["flags"].asInteger());
+		return true;
+	} 
+	
+	return false;
+}
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 19d9d528175..9216c042296 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -106,6 +106,7 @@ class LLNetworkData
 		PARAMS_LIGHT_IMAGE = 0x40,
 		PARAMS_RESERVED = 0x50, // Used on server-side
 		PARAMS_MESH     = 0x60,
+        PARAMS_EXTENDED_MESH = 0x70,
 	};
 	
 public:
@@ -288,6 +289,27 @@ class LLLightImageParams : public LLNetworkData
 	
 };
 
+class LLExtendedMeshParams : public LLNetworkData
+{
+protected:
+	U32 mFlags;
+	
+public:
+	static const U32 ANIMATED_MESH_ENABLED_FLAG = 0x1 << 0;
+
+	LLExtendedMeshParams();
+	/*virtual*/ BOOL pack(LLDataPacker &dp) const;
+	/*virtual*/ BOOL unpack(LLDataPacker &dp);
+	/*virtual*/ bool operator==(const LLNetworkData& data) const;
+	/*virtual*/ void copy(const LLNetworkData& data);
+	LLSD asLLSD() const;
+	operator LLSD() const { return asLLSD(); }
+	bool fromLLSD(LLSD& sd);
+
+	void setFlags(const U32& flags) { mFlags = flags; }
+    U32 getFlags() const { return mFlags; }
+	
+};
 
 // This code is not naming-standards compliant. Leaving it like this for
 // now to make the connection to code in
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index c9f8683e0e7..423d0a8d882 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -86,6 +86,7 @@ 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<LLUICtrl>("FlexNumSections")->setValidateBeforeCommit(precommitValidate);
@@ -347,7 +348,16 @@ void LLPanelVolume::getState( )
 		getChildView("Light Focus")->setEnabled(false);
 		getChildView("Light Ambiance")->setEnabled(false);
 	}
-	
+
+    // Animated Mesh
+	BOOL is_animated_mesh = volobjp && volobjp->getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG;
+	getChild<LLUICtrl>("Animated Mesh Checkbox Ctrl")->setValue(is_animated_mesh);
+    // AXON FIXME CHECK FOR SKIN INFO ALSO
+    // WHAT ABOUT isPermanentEnforced?
+    // What about linksets with some skinned objects?
+    BOOL can_be_animated_mesh = volobjp && volobjp->canBeAnimatedMesh() && editable;
+    getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(can_be_animated_mesh);
+
 	// Flexible properties
 	BOOL is_flexible = volobjp && volobjp->isFlexible();
 	getChild<LLUICtrl>("Flexible1D Checkbox Ctrl")->setValue(is_flexible);
@@ -899,6 +909,31 @@ void LLPanelVolume::onCommitFlexible( LLUICtrl* ctrl, void* userdata )
 	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<LLUICtrl>("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);
+    }
+}
+
 void LLPanelVolume::onCommitIsFlexible(LLUICtrl *, void*)
 {
 	if (mObject->flagObjectPermanent())
diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h
index deb6b6f2a6c..d85df69b19a 100644
--- a/indra/newview/llpanelvolume.h
+++ b/indra/newview/llpanelvolume.h
@@ -63,6 +63,7 @@ class LLPanelVolume : public LLPanel
 	static void 	onCommitLight(			LLUICtrl* ctrl, void* userdata);
 	void 			onCommitIsFlexible(		LLUICtrl* ctrl, void* userdata);
 	static void 	onCommitFlexible(		LLUICtrl* ctrl, void* userdata);
+    void            onCommitAnimatedMeshCheckbox(LLUICtrl* ctrl, void* userdata);
 	static void     onCommitPhysicsParam(       LLUICtrl* ctrl, void* userdata);
 	static void 	onCommitMaterial(		LLUICtrl* ctrl, void* userdata);
 
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 1d6daed9cc0..030c0ca9f6d 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -5458,6 +5458,11 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para
 		  new_block = new LLLightImageParams();
 		  break;
 	  }
+      case LLNetworkData::PARAMS_EXTENDED_MESH:
+      {
+		  new_block = new LLExtendedMeshParams();
+		  break;
+      }
 	  default:
 	  {
 		  LL_INFOS() << "Unknown param type." << LL_ENDL;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 90ba814a157..ed0205704f0 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -3269,6 +3269,59 @@ BOOL LLVOVolume::setIsFlexible(BOOL is_flexible)
 	return res;
 }
 
+//----------------------------------------------------------------------------
+// AXON - methods related to extended mesh flags
+
+U32 LLVOVolume::getExtendedMeshFlags() const
+{
+	const LLExtendedMeshParams *param_block = 
+        (const LLExtendedMeshParams *)getParameterEntry(LLNetworkData::PARAMS_EXTENDED_MESH);
+	if (param_block)
+	{
+		return param_block->getFlags();
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+void LLVOVolume::setExtendedMeshFlags(U32 flags)
+{
+    U32 curr_flags = getExtendedMeshFlags();
+    if (curr_flags != flags)
+    {
+        bool in_use = (flags != 0);
+        setParameterEntryInUse(LLNetworkData::PARAMS_EXTENDED_MESH, in_use, true);
+        LLExtendedMeshParams *param_block = 
+            (LLExtendedMeshParams *)getParameterEntry(LLNetworkData::PARAMS_EXTENDED_MESH);
+        if (param_block)
+        {
+            param_block->setFlags(flags);
+        }
+        parameterChanged(LLNetworkData::PARAMS_EXTENDED_MESH, true);
+    }
+}
+
+bool LLVOVolume::canBeAnimatedMesh() const
+{
+    if (!isMesh())
+    {
+        return false;
+    }
+	const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(getVolume()->getParams().getSculptID(), this);
+    if (!skin)
+    {
+        return false;
+    }
+    return true;
+}
+
+bool LLVOVolume::isAnimatedMesh() const
+{
+    return canBeAnimatedMesh() && (getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG);
+}
+
 //----------------------------------------------------------------------------
 
 void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point)
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index a3319083200..5918166aff4 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -261,10 +261,17 @@ class LLVOVolume : public LLViewerObject
 	virtual BOOL isMesh() const;
 	virtual BOOL hasLightTexture() const;
 
+    
 	BOOL isVolumeGlobal() const;
 	BOOL canBeFlexible() const;
 	BOOL setIsFlexible(BOOL is_flexible);
 
+    // Extended Mesh Properties
+    U32 getExtendedMeshFlags() const;
+    void setExtendedMeshFlags(U32 flags);
+    bool canBeAnimatedMesh() const;
+    bool isAnimatedMesh() const;
+
     // Functions that deal with media, or media navigation
     
     // Update this object's media data with the given media data array
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index ed3cc268516..63e2ed4bb94 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -2,7 +2,7 @@
 <floater
  positioning="cascading"
  legacy_header_height="18"
- height="590"
+ height="600"
  layout="topleft"
  bg_opaque_image="Window_NoTitle_Foreground"
  bg_alpha_image="Window_NoTitle_Background"
@@ -2131,7 +2131,7 @@ even though the user gets a free copy.
         <panel
          border="false"
          follows="all"
-         height="367"
+         height="387"
          label="Features"
          layout="topleft"
          left_delta="0"
@@ -2169,13 +2169,23 @@ even though the user gets a free copy.
                 Edit object features:
             </text>
             <check_box
-             height="19"
+             height="15"
+             label="Animated Mesh"
+             layout="topleft"
+             left="10"
+             name="Animated Mesh Checkbox Ctrl"
+             tool_tip="Allows rigged mesh objects to be animated independently"
+             top_pad="10"
+             width="121" />
+            <check_box
+             height="10"
              label="Flexible Path"
+             follows="left|top"
              layout="topleft"
              left="10"
              name="Flexible1D Checkbox Ctrl"
              tool_tip="Allows object to flex about the Z axis (Client-side only)"
-             top_pad="20"
+             top_pad="15"
              width="121" />
             <spinner
              follows="left|top"
-- 
GitLab