From 51ca84afdfc8a4c3c884b5ab9bd4dffe662087a6 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 19 Sep 2012 00:29:16 +0100 Subject: [PATCH] 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 | 374 +++++++++--------- .../Linden/Caps/BunchOfCaps/MeshCost.cs | 73 +++- 2 files changed, 249 insertions(+), 198 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index cb6f7a13d6..073f175600 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 positions = new List(); - List rotations = new List(); - 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 textures = new List(); - 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); + inType = (sbyte)InventoryType.Object; + assType = (sbyte)AssetType.Object; - // save it to inventory - if (m_addNewTextures && AddNewInventoryItem != null) + List positions = new List(); + List rotations = new List(); + 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 textures = new List(); + 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 + 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); + // 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(); + 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; + AddNewInventoryItem(m_HostCapsObj.AgentID, texitem, 0); + texitem = null; + } + */ + textureAsset = null; } - textureAsset = null; - - } - - // create and store meshs assets - List meshAssets = new List(); - 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 meshAssets = new List(); + 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 + AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Mesh, ""); + meshAsset.Data = mesh_list[i].AsBinary(); + m_assetService.Store(meshAsset); + meshAssets.Add(meshAsset.FullID); - // 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); + /* 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 - meshitem.BasePermissions = (uint)PermissionMask.All; - meshitem.EveryOnePermissions = 0; - meshitem.NextPermissions = (uint)PermissionMask.All; - meshitem.CreationDate = Util.UnixTimeSinceEpoch(); + // 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); - AddNewInventoryItem(m_HostCapsObj.AgentID, meshitem, 0); - meshitem = null; + 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(); - - Primitive.TextureEntry textureEntry - = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE); - - 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++) + // build prims from instances + for (int i = 0; i < instance_list.Count; i++) { - 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(); + PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); - 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(); + Primitive.TextureEntry textureEntry + = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE); - if(imagerot != 0) - f.Rotation = imagerot; + OSDMap inner_instance_list = (OSDMap)instance_list[i]; - if(offsets != 0) - f.OffsetU = offsets; + 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(); - if (offsett != 0) - f.OffsetV = offsett; + 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 (scales != 0) - f.RepeatU = scales; + if (imagerot != 0) + f.Rotation = imagerot; - if (scalet != 0) - f.RepeatV = scalet; + if (offsets != 0) + f.OffsetU = offsets; - if (textures.Count > textureNum) - f.TextureID = textures[textureNum]; - else - f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE; + if (offsett != 0) + f.OffsetV = offsett; - textureEntry.FaceTextures[face] = f; - } + if (scales != 0) + f.RepeatU = scales; - pbs.TextureEntry = textureEntry.GetBytes(); + if (scalet != 0) + f.RepeatV = scalet; - 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) - } + if (textures.Count > textureNum) + f.TextureID = textures[textureNum]; + else + f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE; - Vector3 position = inner_instance_list["position"].AsVector3(); - Vector3 scale = inner_instance_list["scale"].AsVector3(); - Quaternion rotation = inner_instance_list["rotation"].AsQuaternion(); + textureEntry.FaceTextures[face] = f; + } + + 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) + } + + 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++; + + 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)); } - // 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++) + else // not a mesh model { - Vector3 offset = positions[i] - rootPos; - grp.Parts[i].OffsetPosition = offset; + m_log.ErrorFormat("[CAPS Asset Upload] got unsuported assetType for object upload"); + return; } - - 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)); } AssetBase asset; diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs index ba73a25f70..5096a916bd 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 + // upload fee tunning paramenters + // fees are normalized to 1.0 + // this parameters scale them to basic cost ( so 1.0 translates to 10 ) - const float primCreationCost = 0.01f; // 256 prims cost extra 2.56 + 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 - // weigthed size to money convertion - const float bytecost = 1e-4f; + // 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; - // for mesh upload fees based on compressed data sizes - // not using streaming physics and server costs as SL apparently does ?? - + // 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 < ModelMinCost) - meshsfee = ModelMinCost; + if (meshsfee < ModelMinCostFactor) + meshsfee = ModelMinCostFactor; + + // 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;