Merge branch 'ubitwork' of ssh://3dhosting.de/var/git/careminster into ubitwork

avinationmerge
ubit 2012-09-19 02:35:12 +02:00
commit 453c008998
2 changed files with 305 additions and 212 deletions

View File

@ -87,6 +87,7 @@ namespace OpenSim.Region.ClientStack.Linden
private Scene m_Scene; private Scene m_Scene;
private Caps m_HostCapsObj; private Caps m_HostCapsObj;
private ModelCost m_ModelCost;
private static readonly string m_requestPath = "0000/"; private static readonly string m_requestPath = "0000/";
// private static readonly string m_mapLayerPath = "0001/"; // private static readonly string m_mapLayerPath = "0001/";
@ -116,13 +117,22 @@ namespace OpenSim.Region.ClientStack.Linden
private bool m_dumpAssetsToFile = false; private bool m_dumpAssetsToFile = false;
private string m_regionName; private string m_regionName;
private int m_levelUpload = 0; private int m_levelUpload = 0;
private bool m_addNewTextures = false; // private bool m_addNewTextures = false;
private bool m_addNewMeshes = false; // private bool m_addNewMeshes = false;
public BunchOfCaps(Scene scene, Caps caps) public BunchOfCaps(Scene scene, Caps caps)
{ {
m_Scene = scene; m_Scene = scene;
m_HostCapsObj = caps; m_HostCapsObj = caps;
// create a model upload cost provider
m_ModelCost = new ModelCost();
// tell it about scene object limits
m_ModelCost.NonPhysicalPrimScaleMax = m_Scene.m_maxNonphys;
m_ModelCost.PhysicalPrimScaleMax = m_Scene.m_maxPhys;
// m_ModelCost.PrimScaleMin = ??
// m_ModelCost.ObjectLinkedPartsMax = ??
IConfigSource config = m_Scene.Config; IConfigSource config = m_Scene.Config;
if (config != null) if (config != null)
{ {
@ -193,7 +203,6 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
try try
{ {
// I don't think this one works...
m_HostCapsObj.RegisterHandler( m_HostCapsObj.RegisterHandler(
"NewFileAgentInventory", "NewFileAgentInventory",
new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>( new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>(
@ -472,9 +481,8 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
string error; string error;
int modelcost; int modelcost;
ModelCost mc = new ModelCost();
if (!mc.MeshModelCost(llsdRequest.asset_resources, baseCost, out modelcost, if (!m_ModelCost.MeshModelCost(llsdRequest.asset_resources, baseCost, out modelcost,
meshcostdata, out error)) meshcostdata, out error))
{ {
client.SendAgentAlertMessage(error, false); client.SendAgentAlertMessage(error, false);
@ -608,172 +616,181 @@ namespace OpenSim.Region.ClientStack.Linden
} }
else if (inventoryType == "object") else if (inventoryType == "object")
{ {
inType = (sbyte)InventoryType.Object; if (assetType == "mesh") // this code for now is for mesh models uploads only
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++)
{ {
AssetBase textureAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Texture, ""); inType = (sbyte)InventoryType.Object;
textureAsset.Data = texture_list[i].AsBinary(); assType = (sbyte)AssetType.Object;
m_assetService.Store(textureAsset);
textures.Add(textureAsset.FullID);
// save it to inventory List<Vector3> positions = new List<Vector3>();
if (m_addNewTextures && AddNewInventoryItem != null) 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; AssetBase textureAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Texture, "");
if (name.Length > 25) textureAsset.Data = texture_list[i].AsBinary();
name = name.Substring(0, 24); m_assetService.Store(textureAsset);
name += "_Texture#" + i.ToString(); textures.Add(textureAsset.FullID);
InventoryItemBase texitem = new InventoryItemBase(); /*
texitem.Owner = m_HostCapsObj.AgentID; don't do this
texitem.CreatorId = m_HostCapsObj.AgentID.ToString(); replace it by optionaly making model textures cost less than if individually uploaded
texitem.CreatorData = String.Empty; since they can't be used for other purpuses
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 // save it to inventory
// (owner) permissions. This becomes a problem if next permissions are changed. if (m_addNewTextures && AddNewInventoryItem != null)
texitem.CurrentPermissions {
= (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer); 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
texitem.BasePermissions = (uint)PermissionMask.All; // If we set PermissionMask.All then when we rez the item the next permissions will replace the current
texitem.EveryOnePermissions = 0; // (owner) permissions. This becomes a problem if next permissions are changed.
texitem.NextPermissions = (uint)PermissionMask.All; texitem.CurrentPermissions
texitem.CreationDate = Util.UnixTimeSinceEpoch(); = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
AddNewInventoryItem(m_HostCapsObj.AgentID, texitem, 0); texitem.BasePermissions = (uint)PermissionMask.All;
texitem = null; 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++)
// 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)
{ {
string name = assetName; AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Mesh, "");
if (name.Length > 25) meshAsset.Data = mesh_list[i].AsBinary();
name = name.Substring(0, 24); m_assetService.Store(meshAsset);
name += "_Mesh#" + i.ToString(); meshAssets.Add(meshAsset.FullID);
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 /* this was a test, funny and showed viewers deal with mesh inventory itens
// (owner) permissions. This becomes a problem if next permissions are changed. * nut also same reason as for textures
meshitem.CurrentPermissions * let integrated in a model cost eventually less than hipotetical independent meshs assets
= (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer); * 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; // If we set PermissionMask.All then when we rez the item the next permissions will replace the current
meshitem.EveryOnePermissions = 0; // (owner) permissions. This becomes a problem if next permissions are changed.
meshitem.NextPermissions = (uint)PermissionMask.All; meshitem.CurrentPermissions
meshitem.CreationDate = Util.UnixTimeSinceEpoch(); = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
AddNewInventoryItem(m_HostCapsObj.AgentID, meshitem, 0); meshitem.BasePermissions = (uint)PermissionMask.All;
meshitem = null; 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++)
// 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++)
{ {
OSDMap faceMap = (OSDMap)face_list[(int)face]; PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
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(); Primitive.TextureEntry textureEntry
float imagerot = faceMap["imagerot"].AsInteger(); = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE);
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) OSDMap inner_instance_list = (OSDMap)instance_list[i];
f.Rotation = imagerot;
if(offsets != 0) OSDArray face_list = (OSDArray)inner_instance_list["face_list"];
f.OffsetU = offsets; 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) int textureNum = faceMap["image"].AsInteger();
f.OffsetV = offsett; 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) if (imagerot != 0)
f.RepeatU = scales; f.Rotation = imagerot;
if (scalet != 0) if (offsets != 0)
f.RepeatV = scalet; f.OffsetU = offsets;
if (textures.Count > textureNum) if (offsett != 0)
f.TextureID = textures[textureNum]; f.OffsetV = offsett;
else
f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE;
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 (textures.Count > textureNum)
if (meshAssets.Count > meshindx) f.TextureID = textures[textureNum];
{ else
pbs.SculptEntry = true; f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE;
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(); textureEntry.FaceTextures[face] = f;
Vector3 scale = inner_instance_list["scale"].AsVector3(); }
Quaternion rotation = inner_instance_list["rotation"].AsQuaternion();
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 ------------------------ // no longer used - begin ------------------------
// int physicsShapeType = inner_instance_list["physics_shape_type"].AsInteger(); // int physicsShapeType = inner_instance_list["physics_shape_type"].AsInteger();
@ -793,23 +810,23 @@ namespace OpenSim.Region.ClientStack.Linden
// int owner_mask = permissions["owner_mask"].AsInteger(); // int owner_mask = permissions["owner_mask"].AsInteger();
// no longer used - end ------------------------ // no longer used - end ------------------------
UUID owner_id = m_HostCapsObj.AgentID; UUID owner_id = m_HostCapsObj.AgentID;
SceneObjectPart prim SceneObjectPart prim
= new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero); = new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero);
prim.Scale = scale; prim.Scale = scale;
prim.OffsetPosition = position; prim.OffsetPosition = position;
rotations.Add(rotation); rotations.Add(rotation);
positions.Add(position); positions.Add(position);
prim.UUID = UUID.Random(); prim.UUID = UUID.Random();
prim.CreatorID = owner_id; prim.CreatorID = owner_id;
prim.OwnerID = owner_id; prim.OwnerID = owner_id;
prim.GroupID = UUID.Zero; prim.GroupID = UUID.Zero;
prim.LastOwnerID = prim.OwnerID; prim.LastOwnerID = prim.OwnerID;
prim.CreationDate = Util.UnixTimeSinceEpoch(); prim.CreationDate = Util.UnixTimeSinceEpoch();
prim.Name = assetName; prim.Name = assetName;
prim.Description = ""; prim.Description = "";
// prim.BaseMask = (uint)base_mask; // prim.BaseMask = (uint)base_mask;
// prim.EveryoneMask = (uint)everyone_mask; // prim.EveryoneMask = (uint)everyone_mask;
@ -817,32 +834,39 @@ namespace OpenSim.Region.ClientStack.Linden
// prim.NextOwnerMask = (uint)next_owner_mask; // prim.NextOwnerMask = (uint)next_owner_mask;
// prim.OwnerMask = (uint)owner_mask; // prim.OwnerMask = (uint)owner_mask;
if (grp == null) if (grp == null)
grp = new SceneObjectGroup(prim); grp = new SceneObjectGroup(prim);
else else
grp.AddPart(prim); 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 else // not a mesh model
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; m_log.ErrorFormat("[CAPS Asset Upload] got unsuported assetType for object upload");
grp.Parts[i].OffsetPosition = offset; 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; AssetBase asset;

View File

@ -23,42 +23,81 @@ using OSDMap = OpenMetaverse.StructuredData.OSDMap;
namespace OpenSim.Region.ClientStack.Linden namespace OpenSim.Region.ClientStack.Linden
{ {
public struct ModelPrimLimits
{
}
public class ModelCost 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 // upload fee tunning paramenters
// fees are normalized to 1.0
// this parameters scale them to basic cost ( so 1.0 translates to 10 )
// weigthed size to money convertion public float ModelMeshCostFactor = 1.0f; // scale total cost relative to basic (excluding textures)
const float bytecost = 1e-4f; 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
// for mesh upload fees based on compressed data sizes // itens costs in normalized values
// not using streaming physics and server costs as SL apparently does ?? // 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 medSizeWth = 1f; // 2x
const float lowSizeWth = 1.5f; // 2.5x const float lowSizeWth = 1.5f; // 2.5x
const float lowestSizeWth = 2f; // 3x 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 physMeshSizeWth = 6f; // counts 7x
const float physHullSizeWth = 8f; // counts 9x const float physHullSizeWth = 8f; // counts 9x
// stream cost area factors // stream cost area factors
// more or less like SL
const float highLodFactor = 17.36f; const float highLodFactor = 17.36f;
const float midLodFactor = 277.78f; const float midLodFactor = 277.78f;
const float lowLodFactor = 1111.11f; 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 const int bytesPerCoord = 6; // 3 coords, 2 bytes per each
// control prims dimensions
public float PrimScaleMin = 0.01f;
public float NonPhysicalPrimScaleMax = 256f;
public float PhysicalPrimScaleMax = 10f;
public int ObjectLinkedPartsMax = 512;
// storage for a single mesh asset cost parameters
private class ameshCostParam private class ameshCostParam
{ {
// LOD sizes for size dependent streaming cost
public int highLODSize; public int highLODSize;
public int medLODSize; public int medLODSize;
public int lowLODSize; public int lowLODSize;
public int lowestLODSize; public int lowestLODSize;
// normalized fee based on compressed data sizes
public float costFee; public float costFee;
// physics cost
public float physicsCost; 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) public bool MeshModelCost(LLSDAssetResource resources, int basicCost, out int totalcost, LLSDAssetUploadResponseData meshcostdata, out string error)
{ {
totalcost = 0; totalcost = 0;
@ -72,6 +111,14 @@ namespace OpenSim.Region.ClientStack.Linden
return false; return false;
} }
int numberInstances = resources.instance_list.Array.Count;
if( numberInstances > ObjectLinkedPartsMax )
{
error = "upload failed: Model whould have two many linked prims";
return false;
}
meshcostdata.model_streaming_cost = 0.0; meshcostdata.model_streaming_cost = 0.0;
meshcostdata.simulation_cost = 0.0; meshcostdata.simulation_cost = 0.0;
meshcostdata.physics_cost = 0.0; meshcostdata.physics_cost = 0.0;
@ -87,11 +134,12 @@ namespace OpenSim.Region.ClientStack.Linden
// textures cost // textures cost
if (resources.texture_list != null && resources.texture_list.Array.Count > 0) if (resources.texture_list != null && resources.texture_list.Array.Count > 0)
{ {
int textures_cost = resources.texture_list.Array.Count; float textures_cost = (float)(resources.texture_list.Array.Count * basicCost);
textures_cost *= basicCost; textures_cost *= ModelTextureCostFactor;
meshcostdata.upload_price_breakdown.texture = textures_cost; itmp = (int)(textures_cost + 0.5f); // round
totalcost += textures_cost; meshcostdata.upload_price_breakdown.texture = itmp;
totalcost += itmp;
} }
// meshs assets cost // meshs assets cost
@ -120,12 +168,35 @@ namespace OpenSim.Region.ClientStack.Linden
} }
// instances (prims) cost // instances (prims) cost
int numberInstances = resources.instance_list.Array.Count;
int mesh; int mesh;
for (int i = 0; i < numberInstances; i++) for (int i = 0; i < numberInstances; i++)
{ {
Hashtable inst = (Hashtable)resources.instance_list.Array[i]; Hashtable inst = (Hashtable)resources.instance_list.Array[i];
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;
if (scale.X < PrimScaleMin || scale.Y < PrimScaleMin || scale.Z < PrimScaleMin)
{
error = " upload fail: Model contains parts with a dimension lower than 0.01. Please adjust scaling";
return false;
}
if (scale.X > NonPhysicalPrimScaleMax || scale.Y > NonPhysicalPrimScaleMax || scale.Z > NonPhysicalPrimScaleMax)
{
error = "upload fail: Model contains parts larger than maximum allowed. Please adjust scaling";
return false;
}
if (haveMeshs && inst.ContainsKey("mesh")) if (haveMeshs && inst.ContainsKey("mesh"))
{ {
mesh = (int)inst["mesh"]; mesh = (int)inst["mesh"];
@ -137,15 +208,6 @@ namespace OpenSim.Region.ClientStack.Linden
} }
// streamming cost // 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(); float sqdiam = scale.LengthSquared();
@ -176,12 +238,16 @@ namespace OpenSim.Region.ClientStack.Linden
if (meshcostdata.resource_cost < meshcostdata.simulation_cost) if (meshcostdata.resource_cost < meshcostdata.simulation_cost)
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) if (meshsfee < ModelMinCostFactor)
meshsfee = ModelMinCost; 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 meshsfee += 0.5f; // rounding
totalcost += (int)meshsfee; totalcost += (int)meshsfee;
@ -192,6 +258,7 @@ namespace OpenSim.Region.ClientStack.Linden
return true; return true;
} }
// single mesh asset cost
private bool MeshCost(byte[] data, ameshCostParam cost, out string error) private bool MeshCost(byte[] data, ameshCostParam cost, out string error)
{ {
cost.highLODSize = 0; cost.highLODSize = 0;
@ -377,6 +444,7 @@ namespace OpenSim.Region.ClientStack.Linden
return true; return true;
} }
// parses a LOD or physics mesh component
private bool submesh(byte[] data, int offset, int size, out int ntriangles) private bool submesh(byte[] data, int offset, int size, out int ntriangles)
{ {
ntriangles = 0; ntriangles = 0;
@ -443,6 +511,7 @@ namespace OpenSim.Region.ClientStack.Linden
return true; return true;
} }
// parses convex hulls component
private bool hulls(byte[] data, int offset, int size, out int nvertices, out int nhulls) private bool hulls(byte[] data, int offset, int size, out int nvertices, out int nhulls)
{ {
nvertices = 0; nvertices = 0;
@ -512,6 +581,7 @@ namespace OpenSim.Region.ClientStack.Linden
return true; 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) private float streamingCost(ameshCostParam curCost, float sqdiam)
{ {
// compute efective areas // compute efective areas
@ -571,7 +641,6 @@ namespace OpenSim.Region.ClientStack.Linden
h = 16; h = 16;
// compute cost weighted by relative effective areas // compute cost weighted by relative effective areas
float cost = (float)lst * mlst + (float)l * ml + (float)m * mm + (float)h * mh; float cost = (float)lst * mlst + (float)l * ml + (float)m * mm + (float)h * mh;
cost /= ma; cost /= ma;