TKE_Shell
Opcode
ASCII | S |
Hexadecimal | 0x53 |
Decimal | 83 |
Operands
Operands depend on suboptions. Operands enclosed in brackets (‘<STRONG>[]</STRONG>’) will not be present in all situations. See the description of the specific operands for the rules that dictate whether or not they appear.
Format 1: (standard)
Format 2: (edgebreaker)
Format 3: (bounding only)
Format 4: (collection)
Format 5: (null shell)
suboptions | a bit field with information about the formatting. See below for more details |
suboptions2 | more formatting information. Present if and only if suboptions contains the TKSH_EXPANDED bit, otherwise implicitly assumed to be zero |
index | indicates the tagged opcode in the hsf file of which this shell is given as a refinement. Present if and only if suboptions does not contain the TKSH_FIRSTPASS bit |
level_of_detail | the level of detail into which this shell is meant to be inserted. The full-resolution version is level 0. Coarser versions have higher LOD numbers. HSF files may have up to 256 distinct levels, though HOOPS-based applications are limited to 8 levels as of this writing |
points | compressed or uncompressed vertex location data. See below for more details |
faces | face data. See below for more details |
edgebreaker_data | highly compressed data for points and faces combined. See edgebreaker.html |
bounding | an axis-aligned bounding cuboid in the order Xmin, Ymin, Zmin, Xmax, Ymax, Zmax. Present if and only if suboptions contains the TKSH_BOUNDING_ONLY bit |
collection | a set of Opcodes to be interpreted as the Level of Detail for a shell (e.g. a polyline and two markers in place of a cylinder-shaped shell at LOD 2). All subsequent opcodes will be interpreted as part of the collection until a TKE_Termination opcode is encountered. More details below. |
attributes | optional attributes to be bound to vertices, edges and/or faces. See attributes.html |
Suboptions and Suboptions2
As mentioned above, the formatting depends on the values of “suboptions” and “suboptions2”. The following two tables define the bits of those two flags, as well as the rules that use the values of those bits to determine by which format the shell is to be interpreted. Bits that dictate a particular format are all mutually exclusive.
Suboptions
0x01 | TKSH_COMPRESSED_POINTS -- Points are compressed |
0x02 | RESERVED -- unused |
0x04 | TKSH_TRISTRIPS -- Information on how to interpret the face list |
0x08 | TKSH_HAS_OPTIONALS -- Vertices, edges and/or faces have attributes. See attributes.html |
0x10 | TKSH_FIRSTPASS -- A new shell, not a refinement. "Index" does not exist |
0x20 | TKSH_BOUNDING_ONLY -- Shell is format 3. This bit takes precedence over TKSH_CONNECTIVITY_COMPRESSION and TKSH2_COLLECTION |
0x40 | TKSH_CONNECTIVITY_COMPRESSION -- Shell is format 2 |
0x80 | TKSH_EXPANDED -- Suboptions2 is present |
Suboptions2
0x0001 |
TKSH2_COLLECTION -- Shell is format 4 |
0x0002 |
TKSH2_NULL -- Shell is format 5. This bit takes precedence over TKSH2_COLLECTION, TKSH_CONNECTIVITY_COMPRESSION and/or TKSH_BOUNDING_ONLY |
0x0004 |
TKSH2_HAS_NEGATIVE_FACES -- Face list contains signed, not unsigned, values |
0x0004 |
TKSH2_GLOBAL_QUANTIZATION -- Compressed vertices inherit global bounding box instead of specifying their own. |
Notes
Shell is inserted into the currently opened segment.
Points (uncompressed)
int
pointcount, float array
uncompressed triplets of point data, in order xyzxyz…
Points (compressed)
byte
compression scheme, int
pointcount, byte
bits_per_sample, variable
array of compressed floats (see attributes.html)
Points are either compressed or uncompressed vertex data. Compression status is dictated by the TKSH_COMPRESSED_POINTS
bit in the shell suboptions. If uncompressed, it will consist of triples of 32-bit floating point coordinates in the order xyzxyz… If compressed, it will consist of a compression scheme identifier, followed by data that is specific to that compression scheme. The specifics of the compressed format are described in attributes.html in the “array of compressed floats” section. bits_per_sample
may have any value from 2 to 31.
Interpretation of the face (a.k.a polygon or facet) data in faces
will depend on whether the TKSH_TRISTRIPS
bit is set in suboptions. In any case, however, it will specify which vertices should be connected to form faces.
Faces (compressed)
byte
compression scheme, int
face list length, <strong>byte</strong> bits per value, variable
face list data (see below).
If the TKSH_TRISTRIPS
bit is set in suboptions, the face list is interpreted exactly as per the HOOPS function, Insert_Shell
. Here is the relevant excerpt from the HOOPS Reference Manual:
The
face_list
is an array of integers. The first integer is the number of vertices that should be connected to form the first face. For example, “3” for a triangle. The next three integers (in this example) are the offsets into the points array at which the three x-y-z’s can be found. The first point in the points array is considered to be at offset zero, so “0, 1, 2” in the face_list array would form the triangle from the first three entries in points.Continuing with the example, a second triangle might be specified as “3, 0, 1, 3”, meaning “form a face using three vertices. The vertices are at offsets zero, one, and three in the points array”. So this second face happens to share an edge - the (0, 1) edge - with the first face. A third face might be “4, 1, 2, 11, 12”, forming a quadrilateral. Faces continue being formed until an flist_length number of integers in face_list have been processed.
One special case: if a vertex count in the list is negative, that means “continue with the previous face and subtract a polygon formed from the following vertices”. This allows you to build faces with true holes in them. Multiple holes get an “even-odd” rule applied. A region is part of the face if there are an odd number of edges between it and infinity in the plane of the face. Otherwise a region is considered exterior and is not drawn. The edges of the hole receive the usual edge attributes. For face-numbering purposes (for example, Edit_Shell_Faces) the hole is not counted separately - it’s a part of the face it’s in.
If the TKSH_TRISTRIPS
bit is set in suboptions, the shell is assumed to contain triangles only and may not contain holes, and the “faces” are actually the way that vertices are connected into triangle strips. The first 3 vertices form a triangle, and every additional vertex is combined with the two previous ones to define one additional triangle. Exactly as with OpenGL’s GL_TRIANGLE_STRIP
primitive, the orientation of every even triangle is reversed, beginning with the second.
There is still special meaning attached to a negative count in the TKSH_TRISTRIPS
case. A negative count indicates the beginning of a triangle fan. As with triangle strips, every vertex i after the second (for i < 2) defines a new triangle. Triangle strips connect i to vertices i-2 and i-1. Triangle fans connect i to vertices 0 and i-1.
The values will of a type appropriate to the maximum vertex index (as opposed to always 32-bit integers). For shells that have less than 256 vertices, the values will be 8-bit characters. Otherwise they will be 16-bit shorts for shells with less than 65536 and 32-bit integers for shells with more.
If suboptions2 contains the TKSH_HAS_NEGATIVE_FACES
bit, vertex indices will use 16-bit shorts if the maximum index is greater than or equal to 128, and 32-bit integers if the maximum is greater than or equal to 327678.
As of this writing, CS_TRIVIAL is the only supported value for compression scheme for faces. Future revisions may introduce new methods, however.
If suboptions2 contains TKSH2_COLLECTION
, a shell is interpreted according to format 4. This is a set of opcodes, possibly including primitives other than shells, that are to be inserted into the Level of Detail for a shell (e.g. a polyline and two markers in place of a cylinder-shaped shell at LOD 2). All subsequent opcodes will be interpreted as part of the collection until a TKE_Termination
opcode is encountered. Legal opcodes as part of a collection are the following:
In other words, a collection allows for any geometry with the exception of lights and cutting planes (TKE_Area_Light, TKE_Distant_Light, :doc:TKE_Local_Light </general/hsf/opcodes/TKE_Local_Light>`, TKE_Spot_Light and TKE_Cutting_Plane). There are no limits placed on the number of opcodes that may be in a collection prior to the TKE_Termination. This situation is an exception to the rule that there should be only one TKE_Termination opcode in the file.
Shells that are included as part of a collection may not themselves contain collections (i.e. they may not be format 4). Additionally, their level_of_detail
member will be present but ignored.