# Polyhedron attributes

Attribute operations

The following is the complete list of legal values for the attribute opcodes. The format of the data depends on the opcode.

0x00 | OPT_TERMINATE
0X01 | OPT_ALL_NORMALS_COMPRESSED
0x02 | OPT_NORMALS_COMPRESSED
0x03 | OPT_ALL_PARAMETERS_COMPRESSED
0x04 | OPT_PARAMETERS_COMPRESSED
0x05 | OPT_ALL_VFCOLORS
0x06 | OPT_VERTEX_FCOLORS
0x07 | OPT_ALL_VECOLORS
0x08 | OPT_VERTEX_ECOLORS
0x09 | OPT_ALL_VMCOLORS
0x0A | OPT_VERTEX_FINDICES
0x0B | OPT_ALL_VFINDICES
0x0C | OPT_VERTEX_FINDICES
0x0D | OPT_ALL_VEINDICES
0x0E | OPT_VERTEX_EINDICES
0x0F | OPT_ALL_VMINDICES
0x10 | OPT_VERTEX_MINDICES
0x11 | OPT_ALL_NORMALS
0x12 | OPT_NORMALS
0x13 | OPT_ALL_NORMALS_POLAR
0x14 | OPT_NORMALS_POLAR
0x15 | OPT_ALL_VMVISIBILITIES
0x16 | OPT_VERTEX_MARKER_VISIBILITIES
0x17 | OPT_ALL_VMSYMBOLS
0x18 | OPT_VERTEX_MARKER_SYMBOLS
0x19 | OPT_ALL_VMSIZES
0x1A | OPT_VERTEX_MARKER_SIZES
0x1B | OPT_ALL_PARAMETERS
0x1C | OPT_PARAMETERS
| break in sequence
0x21 | OPT_ALL_FACE_COLORS
0x22 | OPT_FACE_COLORS
0x23 | OPT_ALL_FACE_INDICES
0x24 | OPT_FACE_INDICES
0x25 | OPT_ALL_FACE_NORMALS
0x26 | OPT_FACE_NORMALS
0x27 | OPT_ALL_FACE_VISIBILITIES
0x28 | OPT_FACE_VISIBILITIES
0x29 | OPT_ALL_FACE_PATTERNS
0x2A | OPT_FACE_PATTERNS
| break in sequence
0x33 | OPT_FACE_REGIONS
| break in sequence
0x47 | OPT_ALL_EDGE_COLORS
0x48 | OPT_EDGE_COLORS
0x49 | OPT_ALL_EDGE_INDICES
0x4A | OPT_EDGE_INDICES
0x4B | OPT_ALL_EDGE_NORMALS_POLAR
0x4C | OPT_EDGE_NORMALS_POLAR
0x4D | OPT_ALL_EDGE_VISIBILITIES
0x4E | OPT_EDGE_VISIBILITIES
0x4F | OPT_ALL_EDGE_PATTERNS
0x50 | OPT_EDGE_PATTERNS
0x51 | OPT_ALL_EDGE_WEIGHTS
0x52 | OPT_EDGE_WEIGHTS
| break in sequence
0x63 | OPT_POLYHEDRON_ATTRIBUTES

TKE_Shell and TKE_Mesh (a.k.a. polyhedra) suboptions and TKE_PolyCylinder flags have a bit to indicate the presence of “optionals” (a.k.a. attributes) on the faces, vertices, or edges.

If that bit is set, There will be a list of one or more attribute operations followed by an `OPT_TERMINATE`. Thus, the structure of this list is similar to a list of primitives in a segment, except that the opcodes and formats are specific to attributes.

The meaning of most of the attribute should be apparent from the name of the opcode. “Normals” are vertex normals. “Parameters” are texture coordinates bound to vertices. “Indices” are values for looking up into a previously defined color look-up table. Vertex colors and indices can affect marker, face or edge appearance, as specified with “vm”, “ve”, or “vf”. <p>

** Operations to define values everywhere

byte operation, byte compression_scheme, byte bits_per_sample, array of compressed floats data

Values specified with uncompressed floats |
OPT_ALL_NORMALS | float[3]
OPT_ALL_VMARKER_SIZES | float
OPT_ALL_PARAMETERS | float[** variable **]
OPT_ALL_EDGE_WEIGHTS | float

byte operation, [byte parameter width], array of floats data note that the “parameter width” field, (which indicates the number of values on each vertex) is only used by ``OPT_ALL_PARAMETERS``

Values specified with bytes |
OPT_ALL_VMSYMBOLS | char
OPT_ALL_VMVISIBILITIES | char
OPT_ALL_FACE_VISIBILITIES | char
OPT_ALL_EDGE_VISIBILITIES | char
OPT_ALL_FACE_PATTERNS | char
OPT_ALL_EDGE_PATTERNS | char

byte operation, byte compression_scheme, array of bytes data

Operations to define a subset of values

Values specified with compressed floats |
OPT_NORMALS_COMPRESSED | float[3]
OPT_VERTEX_FCOLORS | float[3]
OPT_VERTEX_ECOLORS | float[3]
OPT_VERTEX_MCOLORS | float[3]
OPT_VERTEX_FINDICES | float
OPT_VERTEX_EINDICES | float
OPT_VERTEX_MINDICES | float
OPT_PARAMETERS_COMPRESSED | float[ variable ]
OPT_NORMALS_POLAR | float[2]
OPT_FACE_NORMALS_POLAR | float[2]
OPT_EDGE_NORMALS_POLAR | float[2]
OPT_FACE_COLORS | float[3]
OPT_FACE_INDICES | float
OPT_EDGE_COLORS | float[3]
OPT_EDGE_INDICES | float

byte operation, byte compression_scheme, byte bits_per_sample, int count, variable array ** indices (see <a href=”#notes”>notes</a>), **array of compressed floats data (see <a href=”#aocf”>below</a>)<P>

Values specified with uncompressed floats |
OPT_NORMALS | float[3]
OPT_PARAMETERS | float[ variable ]
OPT_VERTEX_MARKER_SIZES | float
OPT_EDGE_WEIGHTS | float

byte operation, [byte parameter width], int count, variable array ** indices (see <a href=”#notes”>notes</a>), **array of floats data

note that the “parameter width” field, (which indicates the number of values on each vertex) is only used by ``OPT_ALL_PARAMETERS``

Values specified with bytes |
OPT_VERTEX_MARKER_VISIBILITIES | char
OPT_FACE_VISIBILITIES | char
OPT_EDGE_VISIBILITIES | char
OPT_FACE_PATTERNS | char
OPT_EDGE_PATTERNS | char
OPT_VERTEX_MARKER_SYMBOLS | char

byte operation, byte compression_scheme, int count, variable array ** indices **array of bytes data

In the above format, “count” specifies the number of values that are defined. “Indices” and is an array of size-dependent values. They will be unsigned values that are 8-bit unsigned characters, 16-bit unsigned shorts, or 32-bit unsigned integers, rounded up from the number of bits required to store the point count (face count in the case of `OPT_FACE_COLORS` or `OPT_FACE_INDICES`). “Data” is an array of unsigned values packed bitwise with no padding betweenentries whatsoever.

With this format, some of the values may be left undefined. They take on default or inherited values from elsewhere in a manner specific to the application and/or graphics system.

Miscellaneous options

OPT_FACE_REGIONS | OPT_POLYHEDRON_ATTRIBUTES

All are variable format, described below.

## Notes

The entire list is terminated with an `OPT_TERMINATE` opcode

Array of compressed floats

Points, normals, colors, color indices and parameters (a.k.a. texture coordinates) are all fundamentally arrays of floating point values. Of those, all but points are given as part of the polyhedron optionals (“points” are defined as part of TKE_Shell and TKE_Mesh which have links to this section for the definition of an “array of compressed floats”). The following schemes are currently defined:

1 | CS_TRIVIAL
2 | CS_TRIVIAL_IMPLICIT (obsolete)
3 | CS_REPULSE

CS_TRIVIAL If the value to be encoded has a variable number of dimensions (e.g. vertex parameters, a.k.a. texture coordinates). Under the `CS_TRIVIAL` scheme, the array consists of a minimum for each dimension, followed by a maximum for each dimension. All are encoded as 32-bit floats. Next comes a packed array of raw data samples. The initial bounding volume is omitted when possible:

- Normal vectors use {-1,-1,-1,1,1,1}

- Colors (by value, but not by index) use {0,0,0,1,1,1}

- Vertices, when the TK_Global_Quantization write flag is set, inherit the top-level global bounding box.

The bounding cuboid is linearly divided into 2 bits_per_sample equally spaced buckets. The samples field is then a packed array of samples in the order xyzxyz…xyz. The array is padded with bits set to 0 to align it to the next character, but no padding whatsoever exists between individual samples. Legal values for bits_per_sample allow for anything in the range from 2 to 31. For colors and normals, there is only one bounding cuboid possible, and are omitted. Normals use. Colors use.

CS_TRIVIAL_IMPLICIT (obsolete) `CS_TRIVIAL_IMPLICIT` differs from `CS_TRIVIAL` only in that the bounding cuboid is inferred from the nature of the data it is encoding. `CS_TRIVIAL_IMPLICIT` can be used only for normals, colors, parameters and colors-by-index. Fornormals, the assumed bounding box is {-1,-1,-1,1,1,1}. For the colors, the assumption is {0,0,0,1,1,1}. This compression scheme was deprecated because of the observation that the difference between `CS_TRIVIAL` and `CS_TRIVIAL_IMPLICIT` could be inferred from context.

CS_REPULSE `CS_REPULSE` is defined only for bits_per_sample values of 8 and 10. A predefined set of unit vectors is hardcoded into both the reading and writing sides. The bit-packed array of samples is interpreted as indices into this array of hardcoded unit vectors. The last index in both the 8 and 10 bit versions is a reserved value that indicates that thenormal is not valid (left for the receiving end’s graphics system to compute). For the definition of the predefined unit vectors, see Repulse normal compression source data.

Face regions - array of compresed Ints

If face regions are defined, they are specified as one Int per face,which may then be compressed. The form of storage is defined by Byte compression_scheme which currently consists of two parts.

The upper part (compression_scheme & 0xF8) defines the storage size of all the following values:

0 | Int values are stored as Ints
8 | Int values are stored as Bytes
16 | Int values are stored as Words

The lower part (compression_scheme & 0x07) defines the form of compression applied to the array of values:

0 | No compression. One region value per face.
1 | Sequential, zero based. A count is given indicating the number of distinct regions, folowed by count values indicating the number of faces in each successive region.
2 | Sequential, non-zero based. A count is given indicating the number of distinct regions, folowed by the first region index, and then count values indicating the number of faces in each successive region.
3 | Grouped faces. A count is given indicating the number of groups specified, followed by count pairs of region/length values

For example, a cube defining regions for the faces as (0 0 0 0 1 1) could use scheme 1 to encode this as (2 4 2), another cube with regions (2 2 2 2 1 1) could use scheme 3 to produce (2 2 4 1 2).

Face region support was added in HSF format 7.05.

Polyhedron attributes

If polyhedron attributes are defined, they are attributes (such as color) which are set at the geometry level (as opposed to the segment level or the face/edge/vertex level). They are stored as one or more normal attributes followed by a `TKE_Termination` opcode (distinct from the `OPT_TERMINATE` which is required when all optional fields are done).

Polyhedron attribute support was added in HSF format 7.05.