diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 380 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/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 | |||
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 | ||