From 51ca84afdfc8a4c3c884b5ab9bd4dffe662087a6 Mon Sep 17 00:00:00 2001
From: UbitUmarov
Date: Wed, 19 Sep 2012 00:29:16 +0100
Subject:  coment out mesh model upload code to add textures and individual
 meshs  assets to inventory, since it may actually be a bad ideia since good 
 model textures are deply related to it and there is no current use for 
 independent mesh assets. Added the option to have a reduced free for textures
 (2.5 C$ as is, total textures cost rounded to nearest int) compensating for
 the fact that they can't be used outside the model or its parts.

---
 .../Linden/Caps/BunchOfCaps/BunchOfCaps.cs         | 380 +++++++++++----------
 .../Linden/Caps/BunchOfCaps/MeshCost.cs            |  79 +++--
 2 files changed, 255 insertions(+), 204 deletions(-)

diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index cb6f7a1..073f175 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -116,8 +116,8 @@ namespace OpenSim.Region.ClientStack.Linden
         private bool m_dumpAssetsToFile = false;
         private string m_regionName;
         private int m_levelUpload = 0;
-        private bool m_addNewTextures = false;
-        private bool m_addNewMeshes = false;
+//        private bool m_addNewTextures = false;
+//        private bool m_addNewMeshes = false;
 
         public BunchOfCaps(Scene scene, Caps caps)
         {
@@ -608,172 +608,181 @@ namespace OpenSim.Region.ClientStack.Linden
             }
             else if (inventoryType == "object")
             {
-                inType = (sbyte)InventoryType.Object;
-                assType = (sbyte)AssetType.Object;
-
-                List<Vector3> positions = new List<Vector3>();
-                List<Quaternion> rotations = new List<Quaternion>();
-                OSDMap request = (OSDMap)OSDParser.DeserializeLLSDXml(data);
-                OSDArray instance_list = (OSDArray)request["instance_list"];
-                OSDArray mesh_list = (OSDArray)request["mesh_list"];
-                OSDArray texture_list = (OSDArray)request["texture_list"];
-                SceneObjectGroup grp = null;
-
-                // create and store texture assets
-                List<UUID> textures = new List<UUID>();
-                for (int i = 0; i < texture_list.Count; i++)
+                if (assetType == "mesh") // this code for now is for mesh models uploads only
                 {
-                    AssetBase textureAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Texture, "");
-                    textureAsset.Data = texture_list[i].AsBinary();
-                    m_assetService.Store(textureAsset);
-                    textures.Add(textureAsset.FullID);
-
-                    // save it to inventory
-                    if (m_addNewTextures && AddNewInventoryItem != null)
+                    inType = (sbyte)InventoryType.Object;
+                    assType = (sbyte)AssetType.Object;
+
+                    List<Vector3> positions = new List<Vector3>();
+                    List<Quaternion> rotations = new List<Quaternion>();
+                    OSDMap request = (OSDMap)OSDParser.DeserializeLLSDXml(data);
+                    OSDArray instance_list = (OSDArray)request["instance_list"];
+                    OSDArray mesh_list = (OSDArray)request["mesh_list"];
+                    OSDArray texture_list = (OSDArray)request["texture_list"];
+                    SceneObjectGroup grp = null;
+
+                    // create and store texture assets
+                    List<UUID> textures = new List<UUID>();
+                    for (int i = 0; i < texture_list.Count; i++)
                     {
-                        string name = assetName;
-                        if (name.Length > 25)
-                            name = name.Substring(0, 24);
-                        name += "_Texture#" + i.ToString();
-                        InventoryItemBase texitem = new InventoryItemBase();
-                        texitem.Owner = m_HostCapsObj.AgentID;
-                        texitem.CreatorId = m_HostCapsObj.AgentID.ToString();
-                        texitem.CreatorData = String.Empty;
-                        texitem.ID = UUID.Random();
-                        texitem.AssetID = textureAsset.FullID;
-                        texitem.Description = "mesh model texture";
-                        texitem.Name = name;
-                        texitem.AssetType = (int)AssetType.Texture;
-                        texitem.InvType = (int)InventoryType.Texture;
-                        texitem.Folder = UUID.Zero; // send to default
-
-                        // If we set PermissionMask.All then when we rez the item the next permissions will replace the current
-                        // (owner) permissions.  This becomes a problem if next permissions are changed.
-                        texitem.CurrentPermissions
-                            = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
-
-                        texitem.BasePermissions = (uint)PermissionMask.All;
-                        texitem.EveryOnePermissions = 0;
-                        texitem.NextPermissions = (uint)PermissionMask.All;
-                        texitem.CreationDate = Util.UnixTimeSinceEpoch();
-
-                        AddNewInventoryItem(m_HostCapsObj.AgentID, texitem, 0);
-                        texitem = null;
+                        AssetBase textureAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Texture, "");
+                        textureAsset.Data = texture_list[i].AsBinary();
+                        m_assetService.Store(textureAsset);
+                        textures.Add(textureAsset.FullID);
+                        /*
+                          don't do this
+                          replace it by optionaly making model textures cost less than if individually uploaded
+                          since they can't be used for other purpuses
+ 
+                                            // save it to inventory
+                                            if (m_addNewTextures && AddNewInventoryItem != null)
+                                            {
+                                                string name = assetName;
+                                                if (name.Length > 25)
+                                                    name = name.Substring(0, 24);
+                                                name += "_Texture#" + i.ToString();
+                                                InventoryItemBase texitem = new InventoryItemBase();
+                                                texitem.Owner = m_HostCapsObj.AgentID;
+                                                texitem.CreatorId = m_HostCapsObj.AgentID.ToString();
+                                                texitem.CreatorData = String.Empty;
+                                                texitem.ID = UUID.Random();
+                                                texitem.AssetID = textureAsset.FullID;
+                                                texitem.Description = "mesh model texture";
+                                                texitem.Name = name;
+                                                texitem.AssetType = (int)AssetType.Texture;
+                                                texitem.InvType = (int)InventoryType.Texture;
+                                                texitem.Folder = UUID.Zero; // send to default
+
+                                                // If we set PermissionMask.All then when we rez the item the next permissions will replace the current
+                                                // (owner) permissions.  This becomes a problem if next permissions are changed.
+                                                texitem.CurrentPermissions
+                                                    = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
+
+                                                texitem.BasePermissions = (uint)PermissionMask.All;
+                                                texitem.EveryOnePermissions = 0;
+                                                texitem.NextPermissions = (uint)PermissionMask.All;
+                                                texitem.CreationDate = Util.UnixTimeSinceEpoch();
+
+                                                AddNewInventoryItem(m_HostCapsObj.AgentID, texitem, 0);
+                                                texitem = null;
+                                            }
+                        */
+                        textureAsset = null;
                     }
 
-                    textureAsset = null;
-                    
-                }
-
-                // create and store meshs assets
-                List<UUID> meshAssets = new List<UUID>();
-                for (int i = 0; i < mesh_list.Count; i++)
-                {
-                    AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Mesh, "");
-                    meshAsset.Data = mesh_list[i].AsBinary();
-                    m_assetService.Store(meshAsset);
-                    meshAssets.Add(meshAsset.FullID);
-
-                    // save it to inventory
-                    if (m_addNewMeshes && AddNewInventoryItem != null)
+                    // create and store meshs assets
+                    List<UUID> meshAssets = new List<UUID>();
+                    for (int i = 0; i < mesh_list.Count; i++)
                     {
-                        string name = assetName;
-                        if (name.Length > 25)
-                            name = name.Substring(0, 24);
-                        name += "_Mesh#" + i.ToString();
-                        InventoryItemBase meshitem = new InventoryItemBase();
-                        meshitem.Owner = m_HostCapsObj.AgentID;
-                        meshitem.CreatorId = m_HostCapsObj.AgentID.ToString();
-                        meshitem.CreatorData = String.Empty;
-                        meshitem.ID = UUID.Random();
-                        meshitem.AssetID = meshAsset.FullID;
-                        meshitem.Description = "mesh ";
-                        meshitem.Name = name;
-                        meshitem.AssetType = (int)AssetType.Mesh;
-                        meshitem.InvType = (int)InventoryType.Mesh;
-                        meshitem.Folder = UUID.Zero; // send to default
-
-                        // If we set PermissionMask.All then when we rez the item the next permissions will replace the current
-                        // (owner) permissions.  This becomes a problem if next permissions are changed.
-                        meshitem.CurrentPermissions
-                            = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
-
-                        meshitem.BasePermissions = (uint)PermissionMask.All;
-                        meshitem.EveryOnePermissions = 0;
-                        meshitem.NextPermissions = (uint)PermissionMask.All;
-                        meshitem.CreationDate = Util.UnixTimeSinceEpoch();
-
-                        AddNewInventoryItem(m_HostCapsObj.AgentID, meshitem, 0);
-                        meshitem = null;
+                        AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Mesh, "");
+                        meshAsset.Data = mesh_list[i].AsBinary();
+                        m_assetService.Store(meshAsset);
+                        meshAssets.Add(meshAsset.FullID);
+
+                        /* this was a test, funny and showed viewers deal with mesh inventory itens
+                         * nut also same reason as for textures
+                         * let integrated in a model cost eventually less than hipotetical independent meshs assets
+                         * that will be in inventory
+                                            // save it to inventory
+                                            if (m_addNewMeshes && AddNewInventoryItem != null)
+                                            {
+                                                string name = assetName;
+                                                if (name.Length > 25)
+                                                    name = name.Substring(0, 24);
+                                                name += "_Mesh#" + i.ToString();
+                                                InventoryItemBase meshitem = new InventoryItemBase();
+                                                meshitem.Owner = m_HostCapsObj.AgentID;
+                                                meshitem.CreatorId = m_HostCapsObj.AgentID.ToString();
+                                                meshitem.CreatorData = String.Empty;
+                                                meshitem.ID = UUID.Random();
+                                                meshitem.AssetID = meshAsset.FullID;
+                                                meshitem.Description = "mesh ";
+                                                meshitem.Name = name;
+                                                meshitem.AssetType = (int)AssetType.Mesh;
+                                                meshitem.InvType = (int)InventoryType.Mesh;
+                                                meshitem.Folder = UUID.Zero; // send to default
+
+                                                // If we set PermissionMask.All then when we rez the item the next permissions will replace the current
+                                                // (owner) permissions.  This becomes a problem if next permissions are changed.
+                                                meshitem.CurrentPermissions
+                                                    = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
+
+                                                meshitem.BasePermissions = (uint)PermissionMask.All;
+                                                meshitem.EveryOnePermissions = 0;
+                                                meshitem.NextPermissions = (uint)PermissionMask.All;
+                                                meshitem.CreationDate = Util.UnixTimeSinceEpoch();
+
+                                                AddNewInventoryItem(m_HostCapsObj.AgentID, meshitem, 0);
+                                                meshitem = null;
+                                            }
+                        */
+                        meshAsset = null;
                     }
 
-                    meshAsset = null;
-                }
-
-                // build prims from instances
-                for (int i = 0; i < instance_list.Count; i++)
-                {
-                    PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
+                    // build prims from instances
+                    for (int i = 0; i < instance_list.Count; i++)
+                    {
+                        PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
 
-                    Primitive.TextureEntry textureEntry
-                        = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE);
+                        Primitive.TextureEntry textureEntry
+                            = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE);
 
-                    OSDMap inner_instance_list = (OSDMap)instance_list[i];
+                        OSDMap inner_instance_list = (OSDMap)instance_list[i];
 
-                    OSDArray face_list = (OSDArray)inner_instance_list["face_list"];
-                    for (uint face = 0; face < face_list.Count; face++)
-                    {
-                        OSDMap faceMap = (OSDMap)face_list[(int)face];
-                        Primitive.TextureEntryFace f = pbs.Textures.CreateFace(face);
-                        if(faceMap.ContainsKey("fullbright"))
-                            f.Fullbright = faceMap["fullbright"].AsBoolean();
-                        if (faceMap.ContainsKey ("diffuse_color"))
-                            f.RGBA = faceMap["diffuse_color"].AsColor4();
+                        OSDArray face_list = (OSDArray)inner_instance_list["face_list"];
+                        for (uint face = 0; face < face_list.Count; face++)
+                        {
+                            OSDMap faceMap = (OSDMap)face_list[(int)face];
+                            Primitive.TextureEntryFace f = pbs.Textures.CreateFace(face);
+                            if (faceMap.ContainsKey("fullbright"))
+                                f.Fullbright = faceMap["fullbright"].AsBoolean();
+                            if (faceMap.ContainsKey("diffuse_color"))
+                                f.RGBA = faceMap["diffuse_color"].AsColor4();
 
-                        int textureNum = faceMap["image"].AsInteger();
-                        float imagerot = faceMap["imagerot"].AsInteger();
-                        float offsets = (float)faceMap["offsets"].AsReal();
-                        float offsett = (float)faceMap["offsett"].AsReal();
-                        float scales = (float)faceMap["scales"].AsReal();
-                        float scalet = (float)faceMap["scalet"].AsReal();
+                            int textureNum = faceMap["image"].AsInteger();
+                            float imagerot = faceMap["imagerot"].AsInteger();
+                            float offsets = (float)faceMap["offsets"].AsReal();
+                            float offsett = (float)faceMap["offsett"].AsReal();
+                            float scales = (float)faceMap["scales"].AsReal();
+                            float scalet = (float)faceMap["scalet"].AsReal();
 
-                        if(imagerot != 0)
-                            f.Rotation = imagerot;
+                            if (imagerot != 0)
+                                f.Rotation = imagerot;
 
-                        if(offsets != 0)
-                            f.OffsetU = offsets;
+                            if (offsets != 0)
+                                f.OffsetU = offsets;
 
-                        if (offsett != 0)
-                            f.OffsetV = offsett;
+                            if (offsett != 0)
+                                f.OffsetV = offsett;
 
-                        if (scales != 0)
-                            f.RepeatU = scales;
+                            if (scales != 0)
+                                f.RepeatU = scales;
 
-                        if (scalet != 0)
-                            f.RepeatV = scalet;
+                            if (scalet != 0)
+                                f.RepeatV = scalet;
 
-                        if (textures.Count > textureNum)
-                            f.TextureID = textures[textureNum];
-                        else
-                            f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE;
+                            if (textures.Count > textureNum)
+                                f.TextureID = textures[textureNum];
+                            else
+                                f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE;
 
-                        textureEntry.FaceTextures[face] = f;
-                    }
+                            textureEntry.FaceTextures[face] = f;
+                        }
 
-                    pbs.TextureEntry = textureEntry.GetBytes();
+                        pbs.TextureEntry = textureEntry.GetBytes();
 
-                    int meshindx = inner_instance_list["mesh"].AsInteger();
-                    if (meshAssets.Count > meshindx)
-                    {
-                        pbs.SculptEntry = true;
-                        pbs.SculptType = (byte)SculptType.Mesh;
-                        pbs.SculptTexture = meshAssets[meshindx]; // actual asset UUID after meshs suport introduction
-                        // data will be requested from asset on rez (i hope)
-                    }
+                        int meshindx = inner_instance_list["mesh"].AsInteger();
+                        if (meshAssets.Count > meshindx)
+                        {
+                            pbs.SculptEntry = true;
+                            pbs.SculptType = (byte)SculptType.Mesh;
+                            pbs.SculptTexture = meshAssets[meshindx]; // actual asset UUID after meshs suport introduction
+                            // data will be requested from asset on rez (i hope)
+                        }
 
-                    Vector3 position = inner_instance_list["position"].AsVector3();
-                    Vector3 scale = inner_instance_list["scale"].AsVector3();
-                    Quaternion rotation = inner_instance_list["rotation"].AsQuaternion();
+                        Vector3 position = inner_instance_list["position"].AsVector3();
+                        Vector3 scale = inner_instance_list["scale"].AsVector3();
+                        Quaternion rotation = inner_instance_list["rotation"].AsQuaternion();
 
 // no longer used - begin ------------------------
 //                    int physicsShapeType = inner_instance_list["physics_shape_type"].AsInteger();
@@ -793,23 +802,23 @@ namespace OpenSim.Region.ClientStack.Linden
 //                    int owner_mask = permissions["owner_mask"].AsInteger();
 // no longer used - end ------------------------
 
-		      UUID owner_id = m_HostCapsObj.AgentID;
+                        UUID owner_id = m_HostCapsObj.AgentID;
 
-                    SceneObjectPart prim
-                        = new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero);
+                        SceneObjectPart prim
+                            = new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero);
 
-                    prim.Scale = scale;
-                    prim.OffsetPosition = position;
-                    rotations.Add(rotation);
-                    positions.Add(position);
-                    prim.UUID = UUID.Random();
-                    prim.CreatorID = owner_id;
-                    prim.OwnerID = owner_id;
-                    prim.GroupID = UUID.Zero;
-                    prim.LastOwnerID = prim.OwnerID;
-                    prim.CreationDate = Util.UnixTimeSinceEpoch();
-                    prim.Name = assetName;
-                    prim.Description = "";
+                        prim.Scale = scale;
+                        prim.OffsetPosition = position;
+                        rotations.Add(rotation);
+                        positions.Add(position);
+                        prim.UUID = UUID.Random();
+                        prim.CreatorID = owner_id;
+                        prim.OwnerID = owner_id;
+                        prim.GroupID = UUID.Zero;
+                        prim.LastOwnerID = prim.OwnerID;
+                        prim.CreationDate = Util.UnixTimeSinceEpoch();
+                        prim.Name = assetName;
+                        prim.Description = "";
 
 //                    prim.BaseMask = (uint)base_mask;
 //                    prim.EveryoneMask = (uint)everyone_mask;
@@ -817,32 +826,39 @@ namespace OpenSim.Region.ClientStack.Linden
 //                    prim.NextOwnerMask = (uint)next_owner_mask;
 //                    prim.OwnerMask = (uint)owner_mask;
 
-                    if (grp == null)
-                        grp = new SceneObjectGroup(prim);
-                    else
-                        grp.AddPart(prim);
-                }
+                        if (grp == null)
+                            grp = new SceneObjectGroup(prim);
+                        else
+                            grp.AddPart(prim);
+                    }
 
-                // Fix first link number
-                if (grp.Parts.Length > 1)
-                    grp.RootPart.LinkNum++;
+                    // Fix first link number
+                    if (grp.Parts.Length > 1)
+                        grp.RootPart.LinkNum++;
 
-                Vector3 rootPos = positions[0];
-                grp.AbsolutePosition = rootPos;
-                for (int i = 0; i < positions.Count; i++)
-                {
-                    Vector3 offset = positions[i] - rootPos;
-                    grp.Parts[i].OffsetPosition = offset;
+                    Vector3 rootPos = positions[0];
+                    grp.AbsolutePosition = rootPos;
+                    for (int i = 0; i < positions.Count; i++)
+                    {
+                        Vector3 offset = positions[i] - rootPos;
+                        grp.Parts[i].OffsetPosition = offset;
+                    }
+
+                    for (int i = 0; i < rotations.Count; i++)
+                    {
+                        if (i != 0)
+                            grp.Parts[i].RotationOffset = rotations[i];
+                    }
+
+                    grp.UpdateGroupRotationR(rotations[0]);
+                    data = ASCIIEncoding.ASCII.GetBytes(SceneObjectSerializer.ToOriginalXmlFormat(grp));
                 }
 
-                for (int i = 0; i < rotations.Count; i++)
+                else // not a mesh model
                 {
-                    if (i != 0)
-                        grp.Parts[i].RotationOffset = rotations[i];
+                    m_log.ErrorFormat("[CAPS Asset Upload] got unsuported assetType for object upload");
+                    return;
                 }
-
-                grp.UpdateGroupRotationR(rotations[0]);
-                data = ASCIIEncoding.ASCII.GetBytes(SceneObjectSerializer.ToOriginalXmlFormat(grp));
             }
 
             AssetBase asset;
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs
index ba73a25..5096a91 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs
@@ -25,40 +25,67 @@ namespace OpenSim.Region.ClientStack.Linden
 {
     public class ModelCost
     {
-        float ModelMinCost = 5.0f; // try to favor small meshs versus sculpts
-
-        const float primCreationCost = 0.01f;  // 256 prims cost extra 2.56
-
-        // weigthed size to money convertion
-        const float bytecost = 1e-4f;
-
-        // for mesh upload fees based on compressed data sizes
-        // not using streaming physics and server costs as SL apparently does ??
-        
+        // upload fee tunning paramenters
+        // fees are normalized to 1.0
+        // this parameters scale them to basic cost ( so 1.0 translates to 10 )
+
+        public float ModelMeshCostFactor = 1.0f; // scale total cost relative to basic (excluding textures)
+        public float ModelTextureCostFactor = 0.25f; //(2.5c$) scale textures fee to basic.
+                                                     //   promote integration in a model
+                                                     // since they will not show up in inventory                                                                                                       
+        public float ModelMinCostFactor = 0.5f; // minimum total model free excluding textures
+
+        // itens costs in normalized values
+        // ie will be multiplied by basicCost and factors above
+        const float primCreationCost = 0.002f;  // extra cost for each prim creation overhead
+        // weigthed size to normalized cost
+        const float bytecost = 1e-5f;
+
+        // mesh upload fees based on compressed data sizes
+        // several data sections are counted more that once
+        // to promote user optimization
+        // following parameters control how many extra times they are added
+        // to global size.
+        // LOD meshs
         const float medSizeWth = 1f; // 2x
         const float lowSizeWth = 1.5f; // 2.5x
         const float lowestSizeWth = 2f; // 3x
-        // favor potencial optimized meshs versus automatic decomposition
+        // favor potencially physical optimized meshs versus automatic decomposition
         const float physMeshSizeWth = 6f; // counts  7x
-        const float physHullSizeWth = 8f; // counts  9x
-        
+        const float physHullSizeWth = 8f; // counts  9x      
+
         // stream cost area factors 
+        // more or less like SL
         const float highLodFactor = 17.36f;
         const float midLodFactor = 277.78f;
         const float lowLodFactor = 1111.11f;
 
+        // physics cost is below, identical to SL, assuming shape type convex
+        // server cost is below identical to SL assuming non scripted non physical object
+
+        // internal
         const int bytesPerCoord = 6; // 3 coords, 2 bytes per each
 
+        // storage for a single mesh asset cost parameters       
         private class ameshCostParam
         {
+            // LOD sizes for size dependent streaming cost
             public int highLODSize;
             public int medLODSize;
             public int lowLODSize;
             public int lowestLODSize;
+            // normalized fee based on compressed data sizes
             public float costFee;
+            // physics cost
             public float physicsCost;
         }
 
+        // calculates a mesh model costs
+        // returns false on error, with a reason on parameter error
+        // resources input LLSD request
+        // basicCost input region assets upload cost
+        // totalcost returns model total upload fee
+        // meshcostdata returns detailed costs for viewer 
         public bool MeshModelCost(LLSDAssetResource resources, int basicCost, out int totalcost, LLSDAssetUploadResponseData meshcostdata, out string error)
         {
             totalcost = 0;
@@ -87,11 +114,12 @@ namespace OpenSim.Region.ClientStack.Linden
             // textures cost
             if (resources.texture_list != null && resources.texture_list.Array.Count > 0)
             {
-                int textures_cost = resources.texture_list.Array.Count;
-                textures_cost *= basicCost;
+                float textures_cost = (float)(resources.texture_list.Array.Count * basicCost);
+                textures_cost *= ModelTextureCostFactor;
 
-                meshcostdata.upload_price_breakdown.texture = textures_cost;
-                totalcost += textures_cost;
+                itmp = (int)(textures_cost + 0.5f); // round
+                meshcostdata.upload_price_breakdown.texture = itmp;
+                totalcost += itmp;
             }
 
             // meshs assets cost
@@ -176,12 +204,16 @@ namespace OpenSim.Region.ClientStack.Linden
             if (meshcostdata.resource_cost < meshcostdata.simulation_cost)
                 meshcostdata.resource_cost = meshcostdata.simulation_cost;
 
+            // scale cost
+            // at this point a cost of 1.0 whould mean basic cost
+            meshsfee *= ModelMeshCostFactor;
+
+            if (meshsfee < ModelMinCostFactor)
+                meshsfee = ModelMinCostFactor;
 
-            if (meshsfee < ModelMinCost)
-                meshsfee = ModelMinCost;
+            // actually scale it to basic cost
+            meshsfee *= (float)basicCost;
 
-            // scale cost with basic cost changes relative to 10
-            meshsfee *= (float)basicCost / 10.0f;
             meshsfee += 0.5f; // rounding
 
             totalcost += (int)meshsfee;
@@ -192,6 +224,7 @@ namespace OpenSim.Region.ClientStack.Linden
             return true;
         }
 
+        // single mesh asset cost
         private bool MeshCost(byte[] data, ameshCostParam cost, out string error)
         {
             cost.highLODSize = 0;
@@ -377,6 +410,7 @@ namespace OpenSim.Region.ClientStack.Linden
             return true;
         }
 
+        // parses a LOD or physics mesh component
         private bool submesh(byte[] data, int offset, int size, out int ntriangles)
         {
             ntriangles = 0;
@@ -443,6 +477,7 @@ namespace OpenSim.Region.ClientStack.Linden
             return true;
         }
 
+        // parses convex hulls component
         private bool hulls(byte[] data, int offset, int size, out int nvertices, out int nhulls)
         {
             nvertices = 0;
@@ -512,6 +547,7 @@ namespace OpenSim.Region.ClientStack.Linden
             return true;
         }
 
+        // returns streaming cost from on mesh LODs sizes in curCost and square of prim size length 
         private float streamingCost(ameshCostParam curCost, float sqdiam)
         {
             // compute efective areas
@@ -571,7 +607,6 @@ namespace OpenSim.Region.ClientStack.Linden
                 h = 16;
 
             // compute cost weighted by relative effective areas
-
             float cost = (float)lst * mlst + (float)l * ml + (float)m * mm + (float)h * mh;
             cost /= ma;
 
-- 
cgit v1.1