aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llprimitive/llprimitive.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llprimitive/llprimitive.cpp219
1 files changed, 213 insertions, 6 deletions
diff --git a/linden/indra/llprimitive/llprimitive.cpp b/linden/indra/llprimitive/llprimitive.cpp
index 6fc0a55..c2d1d1e 100644
--- a/linden/indra/llprimitive/llprimitive.cpp
+++ b/linden/indra/llprimitive/llprimitive.cpp
@@ -958,16 +958,213 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai
958 958
959 U32 old_face_mask = mVolumep->mFaceMask; 959 U32 old_face_mask = mVolumep->mFaceMask;
960 960
961 S32 face_bit = 0;
962 S32 cur_mask = 0;
963
964 // grab copies of the old faces so we can determine the TE mappings...
965 std::vector<LLProfile::Face> old_faces; // list of old faces for remapping texture entries
966 LLTextureEntry old_tes[9];
967
968 for (S32 face = 0; face < mVolumep->getNumFaces(); face++)
969 {
970 old_faces.push_back(mVolumep->getProfile().mFaces[face]);
971 }
972
973 for (face_bit = 0; face_bit < 9; face_bit++)
974 {
975 cur_mask = 0x1 << face_bit;
976 if (old_face_mask & cur_mask)
977 {
978 S32 te_index = face_index_from_id(cur_mask, old_faces);
979 old_tes[face_bit] = *getTE(te_index);
980 //llinfos << face_bit << ":" << te_index << ":" << old_tes[face_bit].getID() << llendl;
981 }
982 }
983
984
961 // build the new object 985 // build the new object
962 sVolumeManager->unrefVolume(mVolumep); 986 sVolumeManager->unrefVolume(mVolumep);
963 mVolumep = volumep; 987 mVolumep = volumep;
964 988
965 U32 new_face_mask = mVolumep->mFaceMask; 989 U32 new_face_mask = mVolumep->mFaceMask;
966 if (old_face_mask != new_face_mask) 990 S32 i;
991
992 /*
993 std::string old_mask_string;
994 for (i = 0; i < 9; i++)
995 {
996 if (old_face_mask & (1 << i))
997 {
998 old_mask_string.append("1");
999 }
1000 else
1001 {
1002 old_mask_string.append("0");
1003 }
1004 }
1005 std::string new_mask_string;
1006 for (i = 0; i < 9; i++)
1007 {
1008 if (new_face_mask & (1 << i))
1009 {
1010 new_mask_string.append("1");
1011 }
1012 else
1013 {
1014 new_mask_string.append("0");
1015 }
1016 }
1017
1018 llinfos << "old mask: " << old_mask_string << llendl;
1019 llinfos << "new mask: " << new_mask_string << llendl;
1020 */
1021
1022
1023 if (old_face_mask == new_face_mask)
967 { 1024 {
1025 // nothing to do
1026 return TRUE;
1027 }
1028
1029 if (mVolumep->getNumFaces() == 0 && new_face_mask != 0)
1030 {
1031 llwarns << "Object with 0 faces found...INCORRECT!" << llendl;
968 setNumTEs(mVolumep->getNumFaces()); 1032 setNumTEs(mVolumep->getNumFaces());
969 } 1033 return TRUE;
970 1034 }
1035
1036
1037 S32 face_mapping[9];
1038 for (face_bit = 0; face_bit < 9; face_bit++)
1039 {
1040 face_mapping[face_bit] = face_bit;
1041 }
1042
1043 // Generate the face-type mappings
1044 for (face_bit = 0; face_bit < 9; face_bit++)
1045 {
1046 cur_mask = 0x1 << face_bit;
1047 if (!(new_face_mask & cur_mask))
1048 {
1049 // Face doesn't exist in new map.
1050 face_mapping[face_bit] = -1;
1051 continue;
1052 }
1053 else if (old_face_mask & cur_mask)
1054 {
1055 // Face exists in new and old map.
1056 face_mapping[face_bit] = face_bit;
1057 continue;
1058 }
1059
1060 // OK, how we've got a mismatch, where we have to fill a new face with one from
1061 // the old face.
1062 if (cur_mask & (LL_FACE_PATH_BEGIN | LL_FACE_PATH_END | LL_FACE_INNER_SIDE))
1063 {
1064 // It's a top/bottom/hollow interior face.
1065 if (old_face_mask & LL_FACE_PATH_END)
1066 {
1067 face_mapping[face_bit] = 1;
1068 continue;
1069 }
1070 else
1071 {
1072 S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0;
1073 for (i = 0; i < 4; i++)
1074 {
1075 if (old_face_mask & cur_outer_mask)
1076 {
1077 face_mapping[face_bit] = 5 + i;
1078 break;
1079 }
1080 cur_outer_mask <<= 1;
1081 }
1082 if (i == 4)
1083 {
1084 llwarns << "No path end or outer face in volume!" << llendl;
1085 }
1086 continue;
1087 }
1088 }
1089
1090 if (cur_mask & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END))
1091 {
1092 // A cut slice. Use the hollow interior if we have it.
1093 if (old_face_mask & LL_FACE_INNER_SIDE)
1094 {
1095 face_mapping[face_bit] = 2;
1096 continue;
1097 }
1098
1099 // No interior, use the bottom face.
1100 // Could figure out which of the outer faces was nearest, but that would be harder.
1101 if (old_face_mask & LL_FACE_PATH_END)
1102 {
1103 face_mapping[face_bit] = 1;
1104 continue;
1105 }
1106 else
1107 {
1108 S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0;
1109 for (i = 0; i < 4; i++)
1110 {
1111 if (old_face_mask & cur_outer_mask)
1112 {
1113 face_mapping[face_bit] = 5 + i;
1114 break;
1115 }
1116 cur_outer_mask <<= 1;
1117 }
1118 if (i == 4)
1119 {
1120 llwarns << "No path end or outer face in volume!" << llendl;
1121 }
1122 continue;
1123 }
1124 }
1125
1126 // OK, the face that's missing is an outer face...
1127 // Pull from the nearest adjacent outer face (there's always guaranteed to be one...
1128 S32 cur_outer = face_bit - 5;
1129 S32 min_dist = 5;
1130 S32 min_outer_bit = -1;
1131 S32 i;
1132 for (i = 0; i < 4; i++)
1133 {
1134 if (old_face_mask & (LL_FACE_OUTER_SIDE_0 << i))
1135 {
1136 S32 dist = abs(i - cur_outer);
1137 if (dist < min_dist)
1138 {
1139 min_dist = dist;
1140 min_outer_bit = i + 5;
1141 }
1142 }
1143 }
1144 if (-1 == min_outer_bit)
1145 {
1146 llinfos << (LLVolume *)mVolumep << llendl;
1147 llwarns << "Bad! No outer faces, impossible!" << llendl;
1148 }
1149 face_mapping[face_bit] = min_outer_bit;
1150 }
1151
1152
1153 setNumTEs(mVolumep->getNumFaces());
1154 for (face_bit = 0; face_bit < 9; face_bit++)
1155 {
1156 cur_mask = 0x1 << face_bit;
1157 if (new_face_mask & cur_mask)
1158 {
1159 if (-1 == face_mapping[face_bit])
1160 {
1161 llwarns << "No mapping from old face to new face!" << llendl;
1162 }
1163
1164 S32 te_num = face_index_from_id(cur_mask, mVolumep->getProfile().mFaces);
1165 setTE(te_num, old_tes[face_mapping[face_bit]]);
1166 }
1167 }
971 return TRUE; 1168 return TRUE;
972} 1169}
973 1170
@@ -1135,7 +1332,7 @@ S32 LLPrimitive::unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 dat
1135// Pack information about all texture entries into container: 1332// Pack information about all texture entries into container:
1136// { TextureEntry Variable 2 } 1333// { TextureEntry Variable 2 }
1137// Includes information about image ID, color, scale S,T, offset S,T and rotation 1334// Includes information about image ID, color, scale S,T, offset S,T and rotation
1138BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const 1335BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys, bool shield) const
1139{ 1336{
1140 const U32 MAX_TES = 32; 1337 const U32 MAX_TES = 32;
1141 1338
@@ -1164,7 +1361,17 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
1164 for (face_index = 0; face_index <= last_face_index; face_index++) 1361 for (face_index = 0; face_index <= last_face_index; face_index++)
1165 { 1362 {
1166 // Directly sending image_ids is not safe! 1363 // Directly sending image_ids is not safe!
1167 memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16); /* Flawfinder: ignore */ 1364 if(shield && !(face_index == 4 || face_index == 8 || face_index == 9 || face_index == 10 || face_index == 11 || face_index == 18 || face_index == 19))
1365 {
1366 S8 f_f_i = face_index;
1367 if(face_index == 0)f_f_i = 64;
1368 if(face_index == 5)f_f_i = 9;
1369 if(face_index == 6)f_f_i = 10;
1370 if(face_index == 3)f_f_i = 11;
1371 if(f_f_i == face_index)memcpy(&image_ids[face_index*16],LLUUID("c228d1cf-4b5d-4ba8-84f4-899a0796aa97").mData,16);
1372 else if(f_f_i == 64)memcpy(&image_ids[face_index*16],LLUUID("2a9a406c-f448-68f2-4e38-878f8c46c190").mData,16);//Imprudence FIXME: example
1373 else memcpy(&image_ids[face_index*16],LLUUID("4934f1bf-3b1f-cf4f-dbdf-a72550d05bc6").mData,16);//grey block
1374 }else memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16); /* Flawfinder: ignore */
1168 1375
1169 // Cast LLColor4 to LLColor4U 1376 // Cast LLColor4 to LLColor4U
1170 coloru.setVec( getTE(face_index)->getColor() ); 1377 coloru.setVec( getTE(face_index)->getColor() );