diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index ddb69c4a8e..3789ee94ad 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -489,6 +489,7 @@ namespace OpenSim.Region.ClientStack.Linden cost = (uint)baseCost; } + // check funds if (mm != null) { if (!mm.UploadCovered(client.AgentId, (int)cost)) @@ -565,26 +566,41 @@ namespace OpenSim.Region.ClientStack.Linden sbyte assType = 0; sbyte inType = 0; + IClientAPI client = null; + + IMoneyModule mm = m_Scene.RequestModuleInterface(); + if (mm != null) + { + // make sure client still has enougth credit + if (!mm.UploadCovered(m_HostCapsObj.AgentID, (int)cost)) + { + m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client); + if (client != null) + client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); + return; + } + } + if (inventoryType == "sound") { - inType = 1; - assType = 1; + inType = (sbyte)InventoryType.Sound; + assType = (sbyte)AssetType.Sound; } else if (inventoryType == "animation") { - inType = 19; - assType = 20; + inType = (sbyte)InventoryType.Animation; + assType = (sbyte)AssetType.Animation; } else if (inventoryType == "wearable") { - inType = 18; + inType = (sbyte)InventoryType.Wearable; switch (assetType) { case "bodypart": - assType = 13; + assType = (sbyte)AssetType.Bodypart; break; case "clothing": - assType = 5; + assType = (sbyte)AssetType.Clothing; break; } } @@ -601,6 +617,7 @@ namespace OpenSim.Region.ClientStack.Linden 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++) { @@ -608,14 +625,97 @@ namespace OpenSim.Region.ClientStack.Linden textureAsset.Data = texture_list[i].AsBinary(); m_assetService.Store(textureAsset); textures.Add(textureAsset.FullID); + + // save it to inventory + if (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; + } + // 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 (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; + } + + // 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"]; @@ -660,14 +760,14 @@ namespace OpenSim.Region.ClientStack.Linden pbs.TextureEntry = textureEntry.GetBytes(); - AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Mesh, ""); - meshAsset.Data = mesh_list[i].AsBinary(); - m_assetService.Store(meshAsset); - - pbs.SculptEntry = true; - pbs.SculptTexture = meshAsset.FullID; - pbs.SculptType = (byte)SculptType.Mesh; - pbs.SculptData = meshAsset.Data; + 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(); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs index 622a2d91c9..ba73a25f70 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs @@ -42,7 +42,7 @@ namespace OpenSim.Region.ClientStack.Linden const float physMeshSizeWth = 6f; // counts 7x const float physHullSizeWth = 8f; // counts 9x - // stream cost size factors + // stream cost area factors const float highLodFactor = 17.36f; const float midLodFactor = 277.78f; const float lowLodFactor = 1111.11f; @@ -94,13 +94,12 @@ namespace OpenSim.Region.ClientStack.Linden totalcost += textures_cost; } - float meshsfee = 0; - // meshs assets cost - + float meshsfee = 0; int numberMeshs = 0; + bool haveMeshs = false; List meshsCosts = new List(); - // a model could have no mesh actually + if (resources.mesh_list != null && resources.mesh_list.Array.Count > 0) { numberMeshs = resources.mesh_list.Array.Count; @@ -117,6 +116,7 @@ namespace OpenSim.Region.ClientStack.Linden meshsCosts.Add(curCost); meshsfee += curCost.costFee; } + haveMeshs = true; } // instances (prims) cost @@ -126,44 +126,43 @@ namespace OpenSim.Region.ClientStack.Linden { Hashtable inst = (Hashtable)resources.instance_list.Array[i]; - // streamming cost - // assume all instances have a mesh - // but in general they can have normal prims - // but for now that seems not suported - // when they do, we will need to inspect pbs information - // and have cost funtions for all prims types - // don't check for shape type none, since - // that could be used to upload meshs with low cost - // changing later inworld - - ArrayList ascale = (ArrayList)inst["scale"]; - Vector3 scale; - double tmp; - tmp = (double)ascale[0]; - scale.X = (float)tmp; - tmp = (double)ascale[1]; - scale.Y = (float)tmp; - tmp = (double)ascale[2]; - scale.Z = (float)tmp; - - float sqdiam = scale.LengthSquared(); - - mesh = (int)inst["mesh"]; - - if(mesh >= numberMeshs) + if (haveMeshs && inst.ContainsKey("mesh")) { - error = "Unable to upload mesh model. incoerent information."; - return false; + mesh = (int)inst["mesh"]; + + if (mesh >= numberMeshs) + { + error = "Unable to upload mesh model. incoerent information."; + return false; + } + + // streamming cost + ArrayList ascale = (ArrayList)inst["scale"]; + Vector3 scale; + double tmp; + tmp = (double)ascale[0]; + scale.X = (float)tmp; + tmp = (double)ascale[1]; + scale.Y = (float)tmp; + tmp = (double)ascale[2]; + scale.Z = (float)tmp; + + float sqdiam = scale.LengthSquared(); + + ameshCostParam curCost = meshsCosts[mesh]; + float mesh_streaming = streamingCost(curCost, sqdiam); + + meshcostdata.model_streaming_cost += mesh_streaming; + meshcostdata.physics_cost += curCost.physicsCost; + } + else // instance as no mesh ?? + { + // to do later if needed + meshcostdata.model_streaming_cost += 0.5f; + meshcostdata.physics_cost += 1.0f; } - ameshCostParam curCost = meshsCosts[mesh]; - float mesh_streaming = streamingCost(curCost, sqdiam); - - meshcostdata.model_streaming_cost += mesh_streaming; - - meshcostdata.physics_cost += curCost.physicsCost; - - // unscripted and static prim server cost + // assume unscripted and static prim server cost meshcostdata.simulation_cost += 0.5f; // charge for prims creation meshsfee += primCreationCost; @@ -174,6 +173,10 @@ namespace OpenSim.Region.ClientStack.Linden else meshcostdata.resource_cost = meshcostdata.physics_cost; + if (meshcostdata.resource_cost < meshcostdata.simulation_cost) + meshcostdata.resource_cost = meshcostdata.simulation_cost; + + if (meshsfee < ModelMinCost) meshsfee = ModelMinCost; diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index 5b125eac75..0ac56ec73f 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -149,13 +149,16 @@ namespace OpenSim.Region.ClientStack.Linden HasEvents = (x, y) => { return this.responses.ContainsKey(x); }; GetEvents = (x, y, s) => { - try + lock (responses) { - return this.responses[x]; - } - finally - { - responses.Remove(x); + try + { + return this.responses[x]; + } + finally + { + responses.Remove(x); + } } }; @@ -218,14 +221,14 @@ namespace OpenSim.Region.ClientStack.Linden response["content_type"] = "text/plain"; response["keepalive"] = false; response["reusecontext"] = false; - - responses[requestID] = response; + lock (responses) + responses[requestID] = response; return; } response = m_getTextureHandler.Handle(request); - - responses[requestID] = response; + lock (responses) + responses[requestID] = response; } }