Skip to content

Commit bfb6c52

Browse files
committed
more correct face-count encoding/decoding (#1901)
1 parent 00d1fe2 commit bfb6c52

1 file changed

Lines changed: 10 additions & 68 deletions

File tree

indra/llprimitive/llprimitive.cpp

Lines changed: 10 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,47 +1138,6 @@ namespace
11381138
return (S32)(cur_ptr - start_loc);
11391139
}
11401140

1141-
/// Packs the default value of a 1-byte TextureEntry field in a way that allows
1142-
/// the receiving side to unambiguously determine the "number of faces" for the
1143-
/// TextureEntry.
1144-
///
1145-
/// @param cur_ptr Destination buffer for packed data.
1146-
/// @param data_ptr Source array of field values.
1147-
/// @param last_face_index Index of the last face.
1148-
/// @param type Informs htolememcpy() how to copy bytes to wire format.
1149-
/// @return Number of bytes written to the buffer.
1150-
S32 pack_TE_facecount(U8 *cur_ptr, U8 *data_ptr, U8 last_face_index, EMsgVariableType type)
1151-
{
1152-
// BUG: There can be a discrepancy in last_face_index as known to client and server
1153-
// (for mesh objects).
1154-
//
1155-
// WORKAROUND: We can inform the other side of our notion of last_face_index by
1156-
// re-packing the TE value of the last_face_index as an exception to the default.
1157-
// This is effectively a no-op since the value at last_face_index is, by protocol
1158-
// definition, the default (see implementation of the packing/unpacking algorithm
1159-
// in pack_TE_field() or unpack_TE_field() for details), however the receiving
1160-
// side will notice and interpret this as a declaration the number of faces.
1161-
1162-
U8 *start_loc = cur_ptr;
1163-
if (last_face_index > 0)
1164-
{
1165-
// The workaround need only be packed once for any particular update, so it is
1166-
// always done for a TE field whose data_size is 1 byte.
1167-
//
1168-
U8 data_size = 1;
1169-
1170-
// store a variable bitfield whose only bit corresponds to last_face_index
1171-
U64 bits = (U64)1 << last_face_index;
1172-
cur_ptr = pack_TE_variable_bitfield(cur_ptr, bits);
1173-
1174-
// pack the value
1175-
htolememcpy(cur_ptr, data_ptr + (last_face_index * data_size), type, data_size);
1176-
cur_ptr += data_size;
1177-
}
1178-
1179-
return (S32)(cur_ptr - start_loc);
1180-
}
1181-
11821141
/// Unpacks TextureEntry data encoded for wire transport.
11831142
///
11841143
/// @param dest Array where unpacked values will be stored.
@@ -1262,7 +1221,7 @@ namespace
12621221

12631222
// Store the value in the array at the flagged indices
12641223
U8 i = 0;
1265-
while (index_flags > 0)
1224+
while (index_flags > 0 && i < LLTEContents::MAX_TES)
12661225
{
12671226
if (index_flags & 0x01)
12681227
{
@@ -1272,10 +1231,14 @@ namespace
12721231
i++;
12731232
}
12741233

1275-
// update min_num_faces
1276-
if (i > min_num_faces)
1234+
// The packer thought there are at least i+1 faces since otherwise it wouldn't have packed
1235+
// any info past the "default value".
1236+
if (i >= min_num_faces)
12771237
{
1278-
min_num_faces = i;
1238+
// HACK: we track the max number of possible faces based on what was packed.
1239+
// We may decide to update our own notion of actual faces later if this is for
1240+
// a mesh object.
1241+
min_num_faces = i + 1;
12791242
}
12801243
}
12811244
return true;
@@ -1414,24 +1377,8 @@ S32 LLPrimitive::unpackTEMessageInternal(LLTEContents& tec)
14141377

14151378
// BUG: server and client may disagree as to the face_count on a mesh Primitive.
14161379
//
1417-
// HISTORY: In the beginning face_count of a Primitive was implicit according to
1418-
// its VolumeParams hence the face_count was not encoded in TE field data. Later
1419-
// "mesh" Primitives (aka "Scuplties") were added but had only one face. Then
1420-
// non-Sculpty mesh Primitives were added with variable face_count (up to 8) and
1421-
// multiple LOD, each with a potentially different face_count, and for several
1422-
// years the mesh asset upload pipeline suffered a bug where the server-side mesh
1423-
// asset would cache the face_count of lower-LOD collision shape rather than of
1424-
// the mesh at full glory. The result was: texture adjustments to unknown mesh
1425-
// faces would silently fail at the server. There was a similar client side-problem
1426-
// when mesh objects are loaded with low LOD shapes and server updates for missing
1427-
// faces are silently dropped.
1428-
//
1429-
// WORKAROUND: face_count as known to each side can be encoded in the TE field
1430-
// data without adjusting protocol using a trick (see pack_TE_facecount() for
1431-
// details).
1432-
//
1433-
// TLDR: This is where we adjust our notion of mesh face_count when it is smaller
1434-
// than that of the other side.
1380+
// WORKAROUND: when the server data suggests the mesh object has more faces than we know about
1381+
// we will accept the server's value.
14351382
if (mVolumep && mVolumep->getParams().isMeshSculpt())
14361383
{
14371384
U8 num_tes = getNumTEs();
@@ -1596,11 +1543,6 @@ U8* LLPrimitive::packTEMessageInternal(U8* cur_ptr) const
15961543
cur_ptr += pack_TE_field(cur_ptr, (U8 *)image_rot, 2 ,last_face_index, MVT_S16Array);
15971544
*cur_ptr++ = 0;
15981545
cur_ptr += pack_TE_field(cur_ptr, (U8 *)bump, 1 ,last_face_index, MVT_U8);
1599-
if (mVolumep && mVolumep->getParams().isMeshSculpt())
1600-
{
1601-
// workaround for historical num_faces discrepancy between client and server
1602-
cur_ptr += pack_TE_facecount(cur_ptr, (U8 *)bump, last_face_index, MVT_U8);
1603-
}
16041546
*cur_ptr++ = 0;
16051547
cur_ptr += pack_TE_field(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
16061548
*cur_ptr++ = 0;

0 commit comments

Comments
 (0)