aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorUbitUmarov2012-09-19 00:29:16 +0100
committerUbitUmarov2012-09-19 00:29:16 +0100
commit51ca84afdfc8a4c3c884b5ab9bd4dffe662087a6 (patch)
tree3a92b74ad5e5af31b85c8ebd5ed98c2020bbb102 /OpenSim/Region
parentAdd booleans to control whether we actually crete inventory items (diff)
downloadopensim-SC-51ca84afdfc8a4c3c884b5ab9bd4dffe662087a6.zip
opensim-SC-51ca84afdfc8a4c3c884b5ab9bd4dffe662087a6.tar.gz
opensim-SC-51ca84afdfc8a4c3c884b5ab9bd4dffe662087a6.tar.bz2
opensim-SC-51ca84afdfc8a4c3c884b5ab9bd4dffe662087a6.tar.xz
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.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs380
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs79
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
116 private bool m_dumpAssetsToFile = false; 116 private bool m_dumpAssetsToFile = false;
117 private string m_regionName; 117 private string m_regionName;
118 private int m_levelUpload = 0; 118 private int m_levelUpload = 0;
119 private bool m_addNewTextures = false; 119// private bool m_addNewTextures = false;
120 private bool m_addNewMeshes = false; 120// private bool m_addNewMeshes = false;
121 121
122 public BunchOfCaps(Scene scene, Caps caps) 122 public BunchOfCaps(Scene scene, Caps caps)
123 { 123 {
@@ -608,172 +608,181 @@ namespace OpenSim.Region.ClientStack.Linden
608 } 608 }
609 else if (inventoryType == "object") 609 else if (inventoryType == "object")
610 { 610 {
611 inType = (sbyte)InventoryType.Object; 611 if (assetType == "mesh") // this code for now is for mesh models uploads only
612 assType = (sbyte)AssetType.Object;
613
614 List<Vector3> positions = new List<Vector3>();
615 List<Quaternion> rotations = new List<Quaternion>();
616 OSDMap request = (OSDMap)OSDParser.DeserializeLLSDXml(data);
617 OSDArray instance_list = (OSDArray)request["instance_list"];
618 OSDArray mesh_list = (OSDArray)request["mesh_list"];
619 OSDArray texture_list = (OSDArray)request["texture_list"];
620 SceneObjectGroup grp = null;
621
622 // create and store texture assets
623 List<UUID> textures = new List<UUID>();
624 for (int i = 0; i < texture_list.Count; i++)
625 { 612 {
626 AssetBase textureAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Texture, ""); 613 inType = (sbyte)InventoryType.Object;
627 textureAsset.Data = texture_list[i].AsBinary(); 614 assType = (sbyte)AssetType.Object;
628 m_assetService.Store(textureAsset); 615
629 textures.Add(textureAsset.FullID); 616 List<Vector3> positions = new List<Vector3>();
630 617 List<Quaternion> rotations = new List<Quaternion>();
631 // save it to inventory 618 OSDMap request = (OSDMap)OSDParser.DeserializeLLSDXml(data);
632 if (m_addNewTextures && AddNewInventoryItem != null) 619 OSDArray instance_list = (OSDArray)request["instance_list"];
620 OSDArray mesh_list = (OSDArray)request["mesh_list"];
621 OSDArray texture_list = (OSDArray)request["texture_list"];
622 SceneObjectGroup grp = null;
623
624 // create and store texture assets
625 List<UUID> textures = new List<UUID>();
626 for (int i = 0; i < texture_list.Count; i++)
633 { 627 {
634 string name = assetName; 628 AssetBase textureAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Texture, "");
635 if (name.Length > 25) 629 textureAsset.Data = texture_list[i].AsBinary();
636 name = name.Substring(0, 24); 630 m_assetService.Store(textureAsset);
637 name += "_Texture#" + i.ToString(); 631 textures.Add(textureAsset.FullID);
638 InventoryItemBase texitem = new InventoryItemBase(); 632 /*
639 texitem.Owner = m_HostCapsObj.AgentID; 633 don't do this
640 texitem.CreatorId = m_HostCapsObj.AgentID.ToString(); 634 replace it by optionaly making model textures cost less than if individually uploaded
641 texitem.CreatorData = String.Empty; 635 since they can't be used for other purpuses
642 texitem.ID = UUID.Random(); 636
643 texitem.AssetID = textureAsset.FullID; 637 // save it to inventory
644 texitem.Description = "mesh model texture"; 638 if (m_addNewTextures && AddNewInventoryItem != null)
645 texitem.Name = name; 639 {
646 texitem.AssetType = (int)AssetType.Texture; 640 string name = assetName;
647 texitem.InvType = (int)InventoryType.Texture; 641 if (name.Length > 25)
648 texitem.Folder = UUID.Zero; // send to default 642 name = name.Substring(0, 24);
649 643 name += "_Texture#" + i.ToString();
650 // If we set PermissionMask.All then when we rez the item the next permissions will replace the current 644 InventoryItemBase texitem = new InventoryItemBase();
651 // (owner) permissions. This becomes a problem if next permissions are changed. 645 texitem.Owner = m_HostCapsObj.AgentID;
652 texitem.CurrentPermissions 646 texitem.CreatorId = m_HostCapsObj.AgentID.ToString();
653 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer); 647 texitem.CreatorData = String.Empty;
654 648 texitem.ID = UUID.Random();
655 texitem.BasePermissions = (uint)PermissionMask.All; 649 texitem.AssetID = textureAsset.FullID;
656 texitem.EveryOnePermissions = 0; 650 texitem.Description = "mesh model texture";
657 texitem.NextPermissions = (uint)PermissionMask.All; 651 texitem.Name = name;
658 texitem.CreationDate = Util.UnixTimeSinceEpoch(); 652 texitem.AssetType = (int)AssetType.Texture;
659 653 texitem.InvType = (int)InventoryType.Texture;
660 AddNewInventoryItem(m_HostCapsObj.AgentID, texitem, 0); 654 texitem.Folder = UUID.Zero; // send to default
661 texitem = null; 655
656 // If we set PermissionMask.All then when we rez the item the next permissions will replace the current
657 // (owner) permissions. This becomes a problem if next permissions are changed.
658 texitem.CurrentPermissions
659 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
660
661 texitem.BasePermissions = (uint)PermissionMask.All;
662 texitem.EveryOnePermissions = 0;
663 texitem.NextPermissions = (uint)PermissionMask.All;
664 texitem.CreationDate = Util.UnixTimeSinceEpoch();
665
666 AddNewInventoryItem(m_HostCapsObj.AgentID, texitem, 0);
667 texitem = null;
668 }
669 */
670 textureAsset = null;
662 } 671 }
663 672
664 textureAsset = null; 673 // create and store meshs assets
665 674 List<UUID> meshAssets = new List<UUID>();
666 } 675 for (int i = 0; i < mesh_list.Count; i++)
667
668 // create and store meshs assets
669 List<UUID> meshAssets = new List<UUID>();
670 for (int i = 0; i < mesh_list.Count; i++)
671 {
672 AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Mesh, "");
673 meshAsset.Data = mesh_list[i].AsBinary();
674 m_assetService.Store(meshAsset);
675 meshAssets.Add(meshAsset.FullID);
676
677 // save it to inventory
678 if (m_addNewMeshes && AddNewInventoryItem != null)
679 { 676 {
680 string name = assetName; 677 AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Mesh, "");
681 if (name.Length > 25) 678 meshAsset.Data = mesh_list[i].AsBinary();
682 name = name.Substring(0, 24); 679 m_assetService.Store(meshAsset);
683 name += "_Mesh#" + i.ToString(); 680 meshAssets.Add(meshAsset.FullID);
684 InventoryItemBase meshitem = new InventoryItemBase(); 681
685 meshitem.Owner = m_HostCapsObj.AgentID; 682 /* this was a test, funny and showed viewers deal with mesh inventory itens
686 meshitem.CreatorId = m_HostCapsObj.AgentID.ToString(); 683 * nut also same reason as for textures
687 meshitem.CreatorData = String.Empty; 684 * let integrated in a model cost eventually less than hipotetical independent meshs assets
688 meshitem.ID = UUID.Random(); 685 * that will be in inventory
689 meshitem.AssetID = meshAsset.FullID; 686 // save it to inventory
690 meshitem.Description = "mesh "; 687 if (m_addNewMeshes && AddNewInventoryItem != null)
691 meshitem.Name = name; 688 {
692 meshitem.AssetType = (int)AssetType.Mesh; 689 string name = assetName;
693 meshitem.InvType = (int)InventoryType.Mesh; 690 if (name.Length > 25)
694 meshitem.Folder = UUID.Zero; // send to default 691 name = name.Substring(0, 24);
695 692 name += "_Mesh#" + i.ToString();
696 // If we set PermissionMask.All then when we rez the item the next permissions will replace the current 693 InventoryItemBase meshitem = new InventoryItemBase();
697 // (owner) permissions. This becomes a problem if next permissions are changed. 694 meshitem.Owner = m_HostCapsObj.AgentID;
698 meshitem.CurrentPermissions 695 meshitem.CreatorId = m_HostCapsObj.AgentID.ToString();
699 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer); 696 meshitem.CreatorData = String.Empty;
700 697 meshitem.ID = UUID.Random();
701 meshitem.BasePermissions = (uint)PermissionMask.All; 698 meshitem.AssetID = meshAsset.FullID;
702 meshitem.EveryOnePermissions = 0; 699 meshitem.Description = "mesh ";
703 meshitem.NextPermissions = (uint)PermissionMask.All; 700 meshitem.Name = name;
704 meshitem.CreationDate = Util.UnixTimeSinceEpoch(); 701 meshitem.AssetType = (int)AssetType.Mesh;
705 702 meshitem.InvType = (int)InventoryType.Mesh;
706 AddNewInventoryItem(m_HostCapsObj.AgentID, meshitem, 0); 703 meshitem.Folder = UUID.Zero; // send to default
707 meshitem = null; 704
705 // If we set PermissionMask.All then when we rez the item the next permissions will replace the current
706 // (owner) permissions. This becomes a problem if next permissions are changed.
707 meshitem.CurrentPermissions
708 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
709
710 meshitem.BasePermissions = (uint)PermissionMask.All;
711 meshitem.EveryOnePermissions = 0;
712 meshitem.NextPermissions = (uint)PermissionMask.All;
713 meshitem.CreationDate = Util.UnixTimeSinceEpoch();
714
715 AddNewInventoryItem(m_HostCapsObj.AgentID, meshitem, 0);
716 meshitem = null;
717 }
718 */
719 meshAsset = null;
708 } 720 }
709 721
710 meshAsset = null; 722 // build prims from instances
711 } 723 for (int i = 0; i < instance_list.Count; i++)
712 724 {
713 // build prims from instances 725 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
714 for (int i = 0; i < instance_list.Count; i++)
715 {
716 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
717 726
718 Primitive.TextureEntry textureEntry 727 Primitive.TextureEntry textureEntry
719 = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE); 728 = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE);
720 729
721 OSDMap inner_instance_list = (OSDMap)instance_list[i]; 730 OSDMap inner_instance_list = (OSDMap)instance_list[i];
722 731
723 OSDArray face_list = (OSDArray)inner_instance_list["face_list"]; 732 OSDArray face_list = (OSDArray)inner_instance_list["face_list"];
724 for (uint face = 0; face < face_list.Count; face++) 733 for (uint face = 0; face < face_list.Count; face++)
725 { 734 {
726 OSDMap faceMap = (OSDMap)face_list[(int)face]; 735 OSDMap faceMap = (OSDMap)face_list[(int)face];
727 Primitive.TextureEntryFace f = pbs.Textures.CreateFace(face); 736 Primitive.TextureEntryFace f = pbs.Textures.CreateFace(face);
728 if(faceMap.ContainsKey("fullbright")) 737 if (faceMap.ContainsKey("fullbright"))
729 f.Fullbright = faceMap["fullbright"].AsBoolean(); 738 f.Fullbright = faceMap["fullbright"].AsBoolean();
730 if (faceMap.ContainsKey ("diffuse_color")) 739 if (faceMap.ContainsKey("diffuse_color"))
731 f.RGBA = faceMap["diffuse_color"].AsColor4(); 740 f.RGBA = faceMap["diffuse_color"].AsColor4();
732 741
733 int textureNum = faceMap["image"].AsInteger(); 742 int textureNum = faceMap["image"].AsInteger();
734 float imagerot = faceMap["imagerot"].AsInteger(); 743 float imagerot = faceMap["imagerot"].AsInteger();
735 float offsets = (float)faceMap["offsets"].AsReal(); 744 float offsets = (float)faceMap["offsets"].AsReal();
736 float offsett = (float)faceMap["offsett"].AsReal(); 745 float offsett = (float)faceMap["offsett"].AsReal();
737 float scales = (float)faceMap["scales"].AsReal(); 746 float scales = (float)faceMap["scales"].AsReal();
738 float scalet = (float)faceMap["scalet"].AsReal(); 747 float scalet = (float)faceMap["scalet"].AsReal();
739 748
740 if(imagerot != 0) 749 if (imagerot != 0)
741 f.Rotation = imagerot; 750 f.Rotation = imagerot;
742 751
743 if(offsets != 0) 752 if (offsets != 0)
744 f.OffsetU = offsets; 753 f.OffsetU = offsets;
745 754
746 if (offsett != 0) 755 if (offsett != 0)
747 f.OffsetV = offsett; 756 f.OffsetV = offsett;
748 757
749 if (scales != 0) 758 if (scales != 0)
750 f.RepeatU = scales; 759 f.RepeatU = scales;
751 760
752 if (scalet != 0) 761 if (scalet != 0)
753 f.RepeatV = scalet; 762 f.RepeatV = scalet;
754 763
755 if (textures.Count > textureNum) 764 if (textures.Count > textureNum)
756 f.TextureID = textures[textureNum]; 765 f.TextureID = textures[textureNum];
757 else 766 else
758 f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE; 767 f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE;
759 768
760 textureEntry.FaceTextures[face] = f; 769 textureEntry.FaceTextures[face] = f;
761 } 770 }
762 771
763 pbs.TextureEntry = textureEntry.GetBytes(); 772 pbs.TextureEntry = textureEntry.GetBytes();
764 773
765 int meshindx = inner_instance_list["mesh"].AsInteger(); 774 int meshindx = inner_instance_list["mesh"].AsInteger();
766 if (meshAssets.Count > meshindx) 775 if (meshAssets.Count > meshindx)
767 { 776 {
768 pbs.SculptEntry = true; 777 pbs.SculptEntry = true;
769 pbs.SculptType = (byte)SculptType.Mesh; 778 pbs.SculptType = (byte)SculptType.Mesh;
770 pbs.SculptTexture = meshAssets[meshindx]; // actual asset UUID after meshs suport introduction 779 pbs.SculptTexture = meshAssets[meshindx]; // actual asset UUID after meshs suport introduction
771 // data will be requested from asset on rez (i hope) 780 // data will be requested from asset on rez (i hope)
772 } 781 }
773 782
774 Vector3 position = inner_instance_list["position"].AsVector3(); 783 Vector3 position = inner_instance_list["position"].AsVector3();
775 Vector3 scale = inner_instance_list["scale"].AsVector3(); 784 Vector3 scale = inner_instance_list["scale"].AsVector3();
776 Quaternion rotation = inner_instance_list["rotation"].AsQuaternion(); 785 Quaternion rotation = inner_instance_list["rotation"].AsQuaternion();
777 786
778// no longer used - begin ------------------------ 787// no longer used - begin ------------------------
779// int physicsShapeType = inner_instance_list["physics_shape_type"].AsInteger(); 788// int physicsShapeType = inner_instance_list["physics_shape_type"].AsInteger();
@@ -793,23 +802,23 @@ namespace OpenSim.Region.ClientStack.Linden
793// int owner_mask = permissions["owner_mask"].AsInteger(); 802// int owner_mask = permissions["owner_mask"].AsInteger();
794// no longer used - end ------------------------ 803// no longer used - end ------------------------
795 804
796 UUID owner_id = m_HostCapsObj.AgentID; 805 UUID owner_id = m_HostCapsObj.AgentID;
797 806
798 SceneObjectPart prim 807 SceneObjectPart prim
799 = new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero); 808 = new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero);
800 809
801 prim.Scale = scale; 810 prim.Scale = scale;
802 prim.OffsetPosition = position; 811 prim.OffsetPosition = position;
803 rotations.Add(rotation); 812 rotations.Add(rotation);
804 positions.Add(position); 813 positions.Add(position);
805 prim.UUID = UUID.Random(); 814 prim.UUID = UUID.Random();
806 prim.CreatorID = owner_id; 815 prim.CreatorID = owner_id;
807 prim.OwnerID = owner_id; 816 prim.OwnerID = owner_id;
808 prim.GroupID = UUID.Zero; 817 prim.GroupID = UUID.Zero;
809 prim.LastOwnerID = prim.OwnerID; 818 prim.LastOwnerID = prim.OwnerID;
810 prim.CreationDate = Util.UnixTimeSinceEpoch(); 819 prim.CreationDate = Util.UnixTimeSinceEpoch();
811 prim.Name = assetName; 820 prim.Name = assetName;
812 prim.Description = ""; 821 prim.Description = "";
813 822
814// prim.BaseMask = (uint)base_mask; 823// prim.BaseMask = (uint)base_mask;
815// prim.EveryoneMask = (uint)everyone_mask; 824// prim.EveryoneMask = (uint)everyone_mask;
@@ -817,32 +826,39 @@ namespace OpenSim.Region.ClientStack.Linden
817// prim.NextOwnerMask = (uint)next_owner_mask; 826// prim.NextOwnerMask = (uint)next_owner_mask;
818// prim.OwnerMask = (uint)owner_mask; 827// prim.OwnerMask = (uint)owner_mask;
819 828
820 if (grp == null) 829 if (grp == null)
821 grp = new SceneObjectGroup(prim); 830 grp = new SceneObjectGroup(prim);
822 else 831 else
823 grp.AddPart(prim); 832 grp.AddPart(prim);
824 } 833 }
825 834
826 // Fix first link number 835 // Fix first link number
827 if (grp.Parts.Length > 1) 836 if (grp.Parts.Length > 1)
828 grp.RootPart.LinkNum++; 837 grp.RootPart.LinkNum++;
829 838
830 Vector3 rootPos = positions[0]; 839 Vector3 rootPos = positions[0];
831 grp.AbsolutePosition = rootPos; 840 grp.AbsolutePosition = rootPos;
832 for (int i = 0; i < positions.Count; i++) 841 for (int i = 0; i < positions.Count; i++)
833 { 842 {
834 Vector3 offset = positions[i] - rootPos; 843 Vector3 offset = positions[i] - rootPos;
835 grp.Parts[i].OffsetPosition = offset; 844 grp.Parts[i].OffsetPosition = offset;
845 }
846
847 for (int i = 0; i < rotations.Count; i++)
848 {
849 if (i != 0)
850 grp.Parts[i].RotationOffset = rotations[i];
851 }
852
853 grp.UpdateGroupRotationR(rotations[0]);
854 data = ASCIIEncoding.ASCII.GetBytes(SceneObjectSerializer.ToOriginalXmlFormat(grp));
836 } 855 }
837 856
838 for (int i = 0; i < rotations.Count; i++) 857 else // not a mesh model
839 { 858 {
840 if (i != 0) 859 m_log.ErrorFormat("[CAPS Asset Upload] got unsuported assetType for object upload");
841 grp.Parts[i].RotationOffset = rotations[i]; 860 return;
842 } 861 }
843
844 grp.UpdateGroupRotationR(rotations[0]);
845 data = ASCIIEncoding.ASCII.GetBytes(SceneObjectSerializer.ToOriginalXmlFormat(grp));
846 } 862 }
847 863
848 AssetBase asset; 864 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
25{ 25{
26 public class ModelCost 26 public class ModelCost
27 { 27 {
28 float ModelMinCost = 5.0f; // try to favor small meshs versus sculpts 28 // upload fee tunning paramenters
29 29 // fees are normalized to 1.0
30 const float primCreationCost = 0.01f; // 256 prims cost extra 2.56 30 // this parameters scale them to basic cost ( so 1.0 translates to 10 )
31 31
32 // weigthed size to money convertion 32 public float ModelMeshCostFactor = 1.0f; // scale total cost relative to basic (excluding textures)
33 const float bytecost = 1e-4f; 33 public float ModelTextureCostFactor = 0.25f; //(2.5c$) scale textures fee to basic.
34 34 // promote integration in a model
35 // for mesh upload fees based on compressed data sizes 35 // since they will not show up in inventory
36 // not using streaming physics and server costs as SL apparently does ?? 36 public float ModelMinCostFactor = 0.5f; // minimum total model free excluding textures
37 37
38 // itens costs in normalized values
39 // ie will be multiplied by basicCost and factors above
40 const float primCreationCost = 0.002f; // extra cost for each prim creation overhead
41 // weigthed size to normalized cost
42 const float bytecost = 1e-5f;
43
44 // mesh upload fees based on compressed data sizes
45 // several data sections are counted more that once
46 // to promote user optimization
47 // following parameters control how many extra times they are added
48 // to global size.
49 // LOD meshs
38 const float medSizeWth = 1f; // 2x 50 const float medSizeWth = 1f; // 2x
39 const float lowSizeWth = 1.5f; // 2.5x 51 const float lowSizeWth = 1.5f; // 2.5x
40 const float lowestSizeWth = 2f; // 3x 52 const float lowestSizeWth = 2f; // 3x
41 // favor potencial optimized meshs versus automatic decomposition 53 // favor potencially physical optimized meshs versus automatic decomposition
42 const float physMeshSizeWth = 6f; // counts 7x 54 const float physMeshSizeWth = 6f; // counts 7x
43 const float physHullSizeWth = 8f; // counts 9x 55 const float physHullSizeWth = 8f; // counts 9x
44 56
45 // stream cost area factors 57 // stream cost area factors
58 // more or less like SL
46 const float highLodFactor = 17.36f; 59 const float highLodFactor = 17.36f;
47 const float midLodFactor = 277.78f; 60 const float midLodFactor = 277.78f;
48 const float lowLodFactor = 1111.11f; 61 const float lowLodFactor = 1111.11f;
49 62
63 // physics cost is below, identical to SL, assuming shape type convex
64 // server cost is below identical to SL assuming non scripted non physical object
65
66 // internal
50 const int bytesPerCoord = 6; // 3 coords, 2 bytes per each 67 const int bytesPerCoord = 6; // 3 coords, 2 bytes per each
51 68
69 // storage for a single mesh asset cost parameters
52 private class ameshCostParam 70 private class ameshCostParam
53 { 71 {
72 // LOD sizes for size dependent streaming cost
54 public int highLODSize; 73 public int highLODSize;
55 public int medLODSize; 74 public int medLODSize;
56 public int lowLODSize; 75 public int lowLODSize;
57 public int lowestLODSize; 76 public int lowestLODSize;
77 // normalized fee based on compressed data sizes
58 public float costFee; 78 public float costFee;
79 // physics cost
59 public float physicsCost; 80 public float physicsCost;
60 } 81 }
61 82
83 // calculates a mesh model costs
84 // returns false on error, with a reason on parameter error
85 // resources input LLSD request
86 // basicCost input region assets upload cost
87 // totalcost returns model total upload fee
88 // meshcostdata returns detailed costs for viewer
62 public bool MeshModelCost(LLSDAssetResource resources, int basicCost, out int totalcost, LLSDAssetUploadResponseData meshcostdata, out string error) 89 public bool MeshModelCost(LLSDAssetResource resources, int basicCost, out int totalcost, LLSDAssetUploadResponseData meshcostdata, out string error)
63 { 90 {
64 totalcost = 0; 91 totalcost = 0;
@@ -87,11 +114,12 @@ namespace OpenSim.Region.ClientStack.Linden
87 // textures cost 114 // textures cost
88 if (resources.texture_list != null && resources.texture_list.Array.Count > 0) 115 if (resources.texture_list != null && resources.texture_list.Array.Count > 0)
89 { 116 {
90 int textures_cost = resources.texture_list.Array.Count; 117 float textures_cost = (float)(resources.texture_list.Array.Count * basicCost);
91 textures_cost *= basicCost; 118 textures_cost *= ModelTextureCostFactor;
92 119
93 meshcostdata.upload_price_breakdown.texture = textures_cost; 120 itmp = (int)(textures_cost + 0.5f); // round
94 totalcost += textures_cost; 121 meshcostdata.upload_price_breakdown.texture = itmp;
122 totalcost += itmp;
95 } 123 }
96 124
97 // meshs assets cost 125 // meshs assets cost
@@ -176,12 +204,16 @@ namespace OpenSim.Region.ClientStack.Linden
176 if (meshcostdata.resource_cost < meshcostdata.simulation_cost) 204 if (meshcostdata.resource_cost < meshcostdata.simulation_cost)
177 meshcostdata.resource_cost = meshcostdata.simulation_cost; 205 meshcostdata.resource_cost = meshcostdata.simulation_cost;
178 206
207 // scale cost
208 // at this point a cost of 1.0 whould mean basic cost
209 meshsfee *= ModelMeshCostFactor;
210
211 if (meshsfee < ModelMinCostFactor)
212 meshsfee = ModelMinCostFactor;
179 213
180 if (meshsfee < ModelMinCost) 214 // actually scale it to basic cost
181 meshsfee = ModelMinCost; 215 meshsfee *= (float)basicCost;
182 216
183 // scale cost with basic cost changes relative to 10
184 meshsfee *= (float)basicCost / 10.0f;
185 meshsfee += 0.5f; // rounding 217 meshsfee += 0.5f; // rounding
186 218
187 totalcost += (int)meshsfee; 219 totalcost += (int)meshsfee;
@@ -192,6 +224,7 @@ namespace OpenSim.Region.ClientStack.Linden
192 return true; 224 return true;
193 } 225 }
194 226
227 // single mesh asset cost
195 private bool MeshCost(byte[] data, ameshCostParam cost, out string error) 228 private bool MeshCost(byte[] data, ameshCostParam cost, out string error)
196 { 229 {
197 cost.highLODSize = 0; 230 cost.highLODSize = 0;
@@ -377,6 +410,7 @@ namespace OpenSim.Region.ClientStack.Linden
377 return true; 410 return true;
378 } 411 }
379 412
413 // parses a LOD or physics mesh component
380 private bool submesh(byte[] data, int offset, int size, out int ntriangles) 414 private bool submesh(byte[] data, int offset, int size, out int ntriangles)
381 { 415 {
382 ntriangles = 0; 416 ntriangles = 0;
@@ -443,6 +477,7 @@ namespace OpenSim.Region.ClientStack.Linden
443 return true; 477 return true;
444 } 478 }
445 479
480 // parses convex hulls component
446 private bool hulls(byte[] data, int offset, int size, out int nvertices, out int nhulls) 481 private bool hulls(byte[] data, int offset, int size, out int nvertices, out int nhulls)
447 { 482 {
448 nvertices = 0; 483 nvertices = 0;
@@ -512,6 +547,7 @@ namespace OpenSim.Region.ClientStack.Linden
512 return true; 547 return true;
513 } 548 }
514 549
550 // returns streaming cost from on mesh LODs sizes in curCost and square of prim size length
515 private float streamingCost(ameshCostParam curCost, float sqdiam) 551 private float streamingCost(ameshCostParam curCost, float sqdiam)
516 { 552 {
517 // compute efective areas 553 // compute efective areas
@@ -571,7 +607,6 @@ namespace OpenSim.Region.ClientStack.Linden
571 h = 16; 607 h = 16;
572 608
573 // compute cost weighted by relative effective areas 609 // compute cost weighted by relative effective areas
574
575 float cost = (float)lst * mlst + (float)l * ml + (float)m * mm + (float)h * mh; 610 float cost = (float)lst * mlst + (float)l * ml + (float)m * mm + (float)h * mh;
576 cost /= ma; 611 cost /= ma;
577 612