public static Envelope ReadEnvelope(ChunkReader reader) { var env = new Envelope(); // allocate the Envelope structure env.Index = reader.ReadVariableLengthIndex(); // index EnvelopeKey lastKey = null; while (reader.BytesLeft > 0) { // process subchunks as they're encountered var id = reader.ReadID<EnvelopeType>(); var sz = reader.ReadUInt16(); sz += (ushort)(sz & 1); using (var subChunkReader = reader.GetSubChunk(sz)) { switch (id) { case EnvelopeType.ID_TYPE: { env.Type = subChunkReader.ReadUInt16(); break; } case EnvelopeType.ID_NAME: { env.Name = subChunkReader.ReadString(); break; } case EnvelopeType.ID_PRE: { env.PreBehavior = (EvalType)subChunkReader.ReadUInt16(); break; } case EnvelopeType.ID_POST: { env.PostBehavior = (EvalType)subChunkReader.ReadUInt16(); break; } case EnvelopeType.ID_KEY: { lastKey = new EnvelopeKey( subChunkReader.ReadSingle(), // time subChunkReader.ReadSingle() // value ); env.Keys.Add(lastKey); //TODO: not sort all the time env.Keys.Sort((Comparison<EnvelopeKey>)delegate(EnvelopeKey k1, EnvelopeKey k2) { return k1.Time > k2.Time ? 1 : k1.Time < k2.Time ? -1 : 0; }); break; } case EnvelopeType.ID_SPAN: { if (lastKey == null) // We should've encountered an ID_KEY before an ID_SPAN throw new Exception("Key not defined"); //TODO: make proper exception class lastKey.Shape = subChunkReader.ReadID<KeyShape>(); switch (lastKey.Shape) { case KeyShape.ID_TCB: { lastKey.Tension = subChunkReader.ReadSingle(); lastKey.Continuity = subChunkReader.ReadSingle(); lastKey.Bias = subChunkReader.ReadSingle(); break; } case KeyShape.ID_BEZI: case KeyShape.ID_HERM: case KeyShape.ID_BEZ2: { Array.Clear(lastKey.param, 0, lastKey.param.Length); int i = 0; while (i < 4 && subChunkReader.BytesLeft > 0) { lastKey.param[i] = subChunkReader.ReadSingle(); i++; } break; } case KeyShape.ID_LINE: break; default: Console.WriteLine("Unknown envelope span shape type " + reader.GetIDString((uint)lastKey.Shape)); break; } break; } case EnvelopeType.ID_CHAN: { var plug = new LightwavePlugin(); plug.name = subChunkReader.ReadString(); plug.flags = subChunkReader.ReadUInt16(); plug.data = subChunkReader.ReadBytes((uint)reader.BytesLeft); env.ChannelFilters.Add(plug); break; } default: Console.WriteLine("Unknown envelope type " + reader.GetIDString((uint)id)); break; } } } return env; }
static void ReadPolygonTags(ChunkReader reader, List<Polygon> polygons, uint polygon_offset, uint tag_offset) { var type = reader.ReadID<PolygonTags>(); if (type != PolygonTags.ID_SURF && type != PolygonTags.ID_PART && type != PolygonTags.ID_SMGP) { if (type != PolygonTags.ID_COLR && // 'Sketch Color Name'? type != PolygonTags.ID_LXGN) // unknown Console.WriteLine("Unknown polygon tag type " + reader.GetIDString((uint)type)); return; } while (reader.BytesLeft > 0) { var polygonIndex = (int)(reader.ReadVariableLengthIndex() + polygon_offset); var tagIndex = (int)(reader.ReadVariableLengthIndex() + tag_offset); switch (type) { case PolygonTags.ID_SURF: polygons[polygonIndex].surf_index = (uint)tagIndex; break; case PolygonTags.ID_PART: polygons[polygonIndex].part_index = (uint)tagIndex; break; case PolygonTags.ID_SMGP: polygons[polygonIndex].SmoothingGroup = (int)tagIndex; break; default: Console.WriteLine("Unknown polygon tag type " + reader.GetIDString((uint)type)); break; } } }
public static VertexMap ReadVertexMap(ChunkReader reader, bool perpoly) { var type = reader.ReadID<VertexMapType>(); var dimensions = reader.ReadUInt16(); var name = reader.ReadString(); var vertex_map = new VertexMap(type, name, perpoly); var vertex_indices = new List<uint>(); var polygon_indices = new List<uint>(); var values = new List<float[]>(); // fill in the vertex-map values while (reader.BytesLeft > 0) { vertex_indices.Add(reader.ReadVariableLengthIndex()); if (perpoly) polygon_indices.Add(reader.ReadVariableLengthIndex()); var pointValues = new float[dimensions]; for (var j = 0; j < dimensions; j++) pointValues[j] = reader.ReadSingle(); values.Add(pointValues); } vertex_map.Values = values.ToArray(); vertex_map.vertex_index = vertex_indices.ToArray(); if (perpoly) vertex_map.polygon_index = polygon_indices.ToArray(); return vertex_map; }
static IEnumerable<Polygon> ReadPolygons(ChunkReader reader, uint vertex_offset) { var type = reader.ReadID<PolygonType>(); // fill in the new polygons while (reader.BytesLeft > 0) { var vertex_count = reader.ReadUInt16(); var flags = vertex_count & 0xFC00; vertex_count &= 0x03FF; var newPolygon = new Polygon(type, flags); for (var j = 0; j < vertex_count; j++) newPolygon.Vertices.Add( new PolygonVertex(reader.ReadVariableLengthIndex() + vertex_offset) ); yield return newPolygon; } }