diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llprimitive/llprimitive.cpp | 219 |
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 |
1138 | BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const | 1335 | BOOL 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() ); |