public void AddVertex(Vertex vertex) { foreach (Vertex v in VertexSet) { if (v.Equals(vertex)) { throw new ArgumentException("Vertices must have unique ids."); } } VertexSet.Add(vertex); }
public void AddEdge(Edge edge) { if (VertexSet.Contains(edge.StartVertex) && VertexSet.Contains(edge.EndVertex)) { EdgeSet.Add(edge); } else { throw new ArgumentException("Could not find one or both of the specified vertices in the edge set."); } }
/// <summary> /// Looks for a possibly adjusted vertex value in the current set. /// </summary> /// <param name="vertex">The original vertex value.</param> /// <returns>The possibly adjusted vertex value.</returns> public XYZ FindOrAdd(XYZ vertex) { XYZ adjustedVertex = null; if (!VertexSet.TryGetValue(vertex, out adjustedVertex)) { adjustedVertex = vertex; VertexSet.Add(adjustedVertex); } return(adjustedVertex); }
public override int Degree(TV vertex) { if (vertex == null) { throw new ArgumentNullException(); } if (!VertexSet.Contains(vertex)) { throw new ArgumentException(); } return(InDegree(vertex) + OutDegree(vertex)); }
public override bool AreAdjacent(TV v1, TV v2) { if (v1 == null || v2 == null) { throw new ArgumentNullException(); } if (!VertexSet.Contains(v1) || !VertexSet.Contains(v2)) { throw new ArgumentException(); } return(EdgeSet.Contains(new PairValue <TV>(v1, v2))); }
public void AddEdge(Vertex beginningVertex, Vertex endingVertex, Movement movement) { if (VertexSet.Contains(beginningVertex) && VertexSet.Contains(endingVertex)) { Edge edge = new Edge(beginningVertex, endingVertex, movement); EdgeSet.Add(edge); } else { throw new ArgumentException("Could not find one or both of the specified vertices in the edge set."); } }
public override KeyValuePair <T, K> GetVertexPair(T v1Key) { if (v1Key == null) { throw new ArgumentNullException(); } var vertex = VertexSet.FirstOrDefault(x => x.Key.Equals(v1Key)); if (!VertexSet.Contains(vertex)) { throw new ArgumentException(); } return(vertex); }
public override IEnumerable <T> AdjacentVertex(T vertex) { if (vertex == null) { throw new ArgumentNullException(); } if (!VertexSet.Contains(vertex)) { throw new ArgumentException(); } foreach (IPairValue <T> p in EdgeSet) { if (p.GetFirst().Equals(vertex)) { yield return(p.GetSecond()); } } }
public override bool AreAdjacent(T v1, T v2) { if (v1 is null) { throw new ArgumentNullException(nameof(v1)); } if (v2 is null) { throw new ArgumentNullException(nameof(v2)); } if (!VertexSet.Contains(v1) || !VertexSet.Contains(v2)) { throw new ArgumentException(); } return(EdgeSet.Contains(new PairValueI <T>(v1, v2))); }
public override bool AddEdge(TV v1, TV v2, TK weigth) { if (v1 == null || v2 == null || weigth == null) { throw new ArgumentNullException(); } if (!VertexSet.Contains(v1) || !VertexSet.Contains(v2)) { return(false); } IPairValue <TV> pair = new PairValue <TV>(v1, v2); if (EdgeSet.Contains(pair)) { return(false); } EdgeSet.Add(pair); Weigths[pair] = weigth; return(true); }
public override bool AddEdge(KeyValuePair <T, K> v1, KeyValuePair <T, K> v2, K weight) { if (v1.Key == null || v2.Key == null || weight == null) { throw new ArgumentNullException(); } if (!VertexSet.Contains(v1) || !VertexSet.Contains(v2)) { return(false); } IPairValue <T> pair = new PairValue <T>(v1.Key, v2.Key); if (EdgeSet.Contains(pair)) { return(false); } EdgeSet.Add(pair); Weights[pair] = weight; return(true); }
public override int InDegree(TV vertex) { if (vertex == null) { throw new ArgumentNullException(); } if (!VertexSet.Contains(vertex)) { throw new ArgumentException(); } int counter = 0; foreach (var pair in EdgeSet) { if (pair.GetSecond().Equals(vertex)) { counter++; } } return(counter); }
public override int Degree(T vertex) { if (vertex == null) { throw new ArgumentNullException(); } if (!VertexSet.Contains(vertex)) { throw new ArgumentException(); } int counter = 0; foreach (IPairValue <T> pair in EdgeSet) { if (pair.GetFirst().Equals(vertex)) { counter++; } } return(counter); }
public List <string> BFS(int s) { // Mark all the vertices as not // visited(By default set as false) bool[] visited = new bool[VertexSet.Count()]; for (int i = 0; i < VertexSet.Count() - 1; i++) { visited[i] = false; } // Create a queue for BFS List <int> queue = new List <int>(); List <string> rofl = new List <string>(); // Mark the current node as // visited and enqueue it visited[s] = true; queue.Add(s); while (queue.Any()) { s = queue.First(); rofl.Add(VertexSet[s].ToString()); queue.RemoveAt(queue.IndexOf(queue.First())); List <TV> list = AdjacentVertex(VertexSet[s]).ToList(); foreach (var val in list) { if (!visited[VertexSet.IndexOf(val)]) { visited[VertexSet.IndexOf(val)] = true; queue.Add(VertexSet.IndexOf(val)); } } } return(rofl); }
public override bool AddEdge(T v1, T v2, K weight) { if (v1 is null) { throw new ArgumentNullException(nameof(v1)); } if (v2 is null) { throw new ArgumentNullException(nameof(v2)); } if (weight is null) { throw new ArgumentNullException(nameof(weight)); } if (!VertexSet.Contains(v1) || !VertexSet.Contains(v2)) { return(false); } IPairValue <T> pair_1 = new PairValueI <T>(v1, v2); IPairValue <T> pair_2 = new PairValueI <T>(v2, v1); if (EdgeSet.Contains(pair_1) || EdgeSet.Contains(pair_2)) { return(false); } EdgeSet.Add(pair_1); EdgeSet.Add(pair_2); Weights[pair_1] = weight; Weights[pair_2] = weight; return(true); }
public void AddVertexSet(VertexSet vertexSet) { vertexDict[vertexSet.id] = vertexSet; }
public void ReadVertices( Dictionary<string, VertexSet> vertexSets, XmlNode node, ColladaMeshInfo meshInfo ) { string verticesId = string.Empty; if( node.Attributes[ "id" ] != null ) verticesId = node.Attributes[ "id" ].Value; else { DebugMessage( node ); // vertices inside of a controller don't have the id // Since I don't handle bone weights (the data in these), // just skip this for now. TODO: Fix return; } VertexSet vertexSet = new VertexSet(); vertexSet.id = verticesId; vertexSets[ vertexSet.id ] = vertexSet; foreach( XmlNode childNode in node.ChildNodes ) { switch( childNode.Name ) { case "input": { InputSourceCollection entry = ReadInput( childNode, meshInfo ); vertexSet.vertexEntries.Add( entry ); break; } default: DebugMessage( childNode ); break; } } }
private static void ParseBlock(Block block, ref MsTsShape shape, ref Vertex vertex, ref int[] intArray) { float x, y, z; Vector3 point; KujuTokenID currentToken = KujuTokenID.error; Block newBlock; uint flags; switch (block.Token) { case KujuTokenID.shape: newBlock = block.ReadSubBlock(KujuTokenID.shape_header); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.volumes); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.shader_names); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.texture_filter_names); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.points); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.uv_points); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.normals); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.sort_vectors); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.colours); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.matrices); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.images); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.textures); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.light_materials); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.light_model_cfgs); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.vtx_states); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.prim_states); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.lod_controls); ParseBlock(newBlock, ref shape); break; case KujuTokenID.shape_header: case KujuTokenID.volumes: case KujuTokenID.texture_filter_names: case KujuTokenID.sort_vectors: case KujuTokenID.colours: case KujuTokenID.light_materials: case KujuTokenID.light_model_cfgs: //Unsupported stuff, so just read to the end at the minute block.Skip((int)block.Length()); break; case KujuTokenID.vtx_state: flags = block.ReadUInt32(); int matrix1 = block.ReadInt32(); int lightMaterialIdx = block.ReadInt32(); int lightStateCfgIdx = block.ReadInt32(); uint lightFlags = block.ReadUInt32(); int matrix2 = -1; if ((block is BinaryBlock && block.Length() - block.Position() > 1) || (!(block is BinaryBlock) && block.Length() - block.Position() > 2)) { matrix2 = block.ReadInt32(); } VertexStates vs = new VertexStates(); vs.flags = flags; vs.hierarchyID = matrix1; vs.lightingMatrixID = lightMaterialIdx; vs.lightingConfigIdx = lightStateCfgIdx; vs.lightingFlags = lightFlags; vs.matrix2ID = matrix2; shape.vtx_states.Add(vs); break; case KujuTokenID.vtx_states: int vtxStateCount = block.ReadUInt16(); if (block is BinaryBlock) { block.ReadUInt16(); } while (vtxStateCount > 0) { newBlock = block.ReadSubBlock(KujuTokenID.vtx_state); ParseBlock(newBlock, ref shape); vtxStateCount--; } break; case KujuTokenID.prim_state: flags = block.ReadUInt32(); int shader = block.ReadInt32(); int[] texIdxs = {}; newBlock = block.ReadSubBlock(KujuTokenID.tex_idxs); ParseBlock(newBlock, ref shape, ref texIdxs); float zBias = block.ReadSingle(); int vertexStates = block.ReadInt32(); int alphaTestMode = block.ReadInt32(); int lightCfgIdx = block.ReadInt32(); int zBufferMode = block.ReadInt32(); PrimitiveState p = new PrimitiveState(); p.Name = block.Label; p.Flags = flags; p.Shader = shader; p.Textures = texIdxs; p.ZBias = zBias; p.vertexStates = vertexStates; p.alphaTestMode = alphaTestMode; p.lightCfgIdx = lightCfgIdx; p.zBufferMode = zBufferMode; shape.prim_states.Add(p); break; case KujuTokenID.tex_idxs: int texIdxCount = block.ReadUInt16(); if (block is BinaryBlock) { block.ReadUInt16(); } Array.Resize(ref intArray, texIdxCount); int idx = 0; while (texIdxCount > 0) { intArray[idx] = block.ReadUInt16(); idx++; texIdxCount--; } break; case KujuTokenID.prim_states: int primStateCount = block.ReadUInt16(); if (block is BinaryBlock) { block.ReadUInt16(); } while (primStateCount > 0) { newBlock = block.ReadSubBlock(KujuTokenID.prim_state); ParseBlock(newBlock, ref shape); primStateCount--; } break; case KujuTokenID.texture: int imageIDX = block.ReadInt32(); int filterMode = (int)block.ReadUInt32(); float mipmapLODBias = block.ReadSingle(); uint borderColor = 0xff000000U; if (block.Length() - block.Position() > 1) { borderColor = block.ReadUInt32(); } //Unpack border color float r, g, b, a; r = borderColor % 256; g = (borderColor / 256) % 256; b = (borderColor / 256 / 256) % 256; a = (borderColor / 256 / 256 / 256) % 256; Texture t = new Texture(); t.fileName = shape.images[imageIDX]; t.filterMode = filterMode; t.mipmapLODBias = (int)mipmapLODBias; t.borderColor = new Color32((byte)r, (byte)g, (byte)b, (byte)a); shape.textures.Add(t); break; case KujuTokenID.textures: int textureCount = block.ReadUInt16(); if (block is BinaryBlock) { block.ReadUInt16(); } while (textureCount > 0) { newBlock = block.ReadSubBlock(KujuTokenID.texture); ParseBlock(newBlock, ref shape); textureCount--; } break; case KujuTokenID.image: shape.images.Add(block.ReadString()); break; case KujuTokenID.images: int imageCount = block.ReadUInt16(); if (block is BinaryBlock) { block.ReadUInt16(); } while (imageCount > 0) { newBlock = block.ReadSubBlock(KujuTokenID.image); ParseBlock(newBlock, ref shape); imageCount--; } break; case KujuTokenID.cullable_prims: int numPrims = block.ReadInt32(); int numFlatSections = block.ReadInt32(); int numPrimIdxs = block.ReadInt32(); break; case KujuTokenID.geometry_info: int faceNormals = block.ReadInt32(); int txLightCommands = block.ReadInt32(); int nodeXTrilistIdxs = block.ReadInt32(); int trilistIdxs = block.ReadInt32(); int lineListIdxs = block.ReadInt32(); nodeXTrilistIdxs = block.ReadInt32(); //Duped, or is the first one actually something else? int trilists = block.ReadInt32(); int lineLists = block.ReadInt32(); int pointLists = block.ReadInt32(); int nodeXTrilists = block.ReadInt32(); newBlock = block.ReadSubBlock(KujuTokenID.geometry_nodes); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.geometry_node_map); ParseBlock(newBlock, ref shape); break; case KujuTokenID.geometry_node_map: int[] geometryNodes = new int[block.ReadInt32()]; for (int i = 0; i < geometryNodes.Length; i++) { geometryNodes[i] = block.ReadInt32(); } break; case KujuTokenID.geometry_node: int n_txLightCommands = block.ReadInt32(); int n_nodeXTxLightCmds = block.ReadInt32(); int n_trilists = block.ReadInt32(); int n_lineLists = block.ReadInt32(); int n_pointLists = block.ReadInt32(); newBlock = block.ReadSubBlock(KujuTokenID.cullable_prims); ParseBlock(newBlock, ref shape); break; case KujuTokenID.geometry_nodes: int geometryNodeCount = block.ReadUInt16(); if (block is BinaryBlock) { block.ReadUInt16(); } while (geometryNodeCount > 0) { newBlock = block.ReadSubBlock(KujuTokenID.geometry_node); ParseBlock(newBlock, ref shape); geometryNodeCount--; } break; case KujuTokenID.point: x = block.ReadSingle(); y = block.ReadSingle(); z = block.ReadSingle(); point = new Vector3(x, y, z); shape.points.Add(point); break; case KujuTokenID.vector: x = block.ReadSingle(); y = block.ReadSingle(); z = block.ReadSingle(); point = new Vector3(x, y, z); shape.normals.Add(point); break; case KujuTokenID.points: int pointCount = block.ReadUInt16(); if (block is BinaryBlock) { block.ReadUInt16(); } while (pointCount > 0) { newBlock = block.ReadSubBlock(KujuTokenID.point); ParseBlock(newBlock, ref shape); pointCount--; } break; case KujuTokenID.uv_point: x = block.ReadSingle(); y = block.ReadSingle(); var uv_point = new Vector2(x, y); shape.uv_points.Add(uv_point); break; case KujuTokenID.uv_points: int uvPointCount = block.ReadUInt16(); if (block is BinaryBlock) { block.ReadUInt16(); } while (uvPointCount > 0) { newBlock = block.ReadSubBlock(KujuTokenID.uv_point); ParseBlock(newBlock, ref shape); uvPointCount--; } break; case KujuTokenID.matrices: int matrixCount = block.ReadUInt16(); if (block is BinaryBlock) { block.ReadUInt16(); } while (matrixCount > 0) { newBlock = block.ReadSubBlock(KujuTokenID.matrix); ParseBlock(newBlock, ref shape); matrixCount--; } break; case KujuTokenID.matrix: Matrix currentMatrix = new Matrix(); currentMatrix.Name = block.Label; currentMatrix.A = new Vector3(block.ReadSingle(), block.ReadSingle(), block.ReadSingle()); currentMatrix.B = new Vector3(block.ReadSingle(), block.ReadSingle(), block.ReadSingle()); currentMatrix.C = new Vector3(block.ReadSingle(), block.ReadSingle(), block.ReadSingle()); currentMatrix.D = new Vector3(block.ReadSingle(), block.ReadSingle(), block.ReadSingle()); shape.matrices.Add(currentMatrix); break; case KujuTokenID.normals: int normalCount = block.ReadUInt16(); if (block is BinaryBlock) { block.ReadUInt16(); } while (normalCount > 0) { newBlock = block.ReadSubBlock(KujuTokenID.vector); ParseBlock(newBlock, ref shape); normalCount--; } break; case KujuTokenID.distance_levels_header: int DLevBias = block.ReadInt16(); break; case KujuTokenID.distance_levels: int distanceLevelCount = block.ReadInt16(); if (block is BinaryBlock) { block.ReadUInt16(); } while (distanceLevelCount > 0) { newBlock = block.ReadSubBlock(KujuTokenID.distance_level); ParseBlock(newBlock, ref shape); distanceLevelCount--; } break; case KujuTokenID.distance_level_header: newBlock = block.ReadSubBlock(KujuTokenID.dlevel_selection); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.hierarchy); ParseBlock(newBlock, ref shape); break; case KujuTokenID.distance_level: newBlock = block.ReadSubBlock(KujuTokenID.distance_level_header); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.sub_objects); ParseBlock(newBlock, ref shape); shape.LODs.Add(currentLOD); break; case KujuTokenID.dlevel_selection: currentLOD = new LOD(block.ReadSingle()); break; case KujuTokenID.hierarchy: currentLOD.hierarchy = new int[block.ReadInt32()]; for (int i = 0; i < currentLOD.hierarchy.Length; i++) { currentLOD.hierarchy[i] = block.ReadInt32(); } break; case KujuTokenID.lod_control: newBlock = block.ReadSubBlock(KujuTokenID.distance_levels_header); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.distance_levels); ParseBlock(newBlock, ref shape); break; case KujuTokenID.lod_controls: int lodCount = block.ReadInt16(); if (block is BinaryBlock) { block.ReadUInt16(); } while (lodCount > 0) { newBlock = block.ReadSubBlock(KujuTokenID.lod_control); ParseBlock(newBlock, ref shape); lodCount--; } break; case KujuTokenID.primitives: int capacity = block.ReadInt32(); //Count of the number of entries in the block, not the number of primitives while (capacity > 0) { newBlock = block.ReadSubBlock(new KujuTokenID[] { KujuTokenID.prim_state_idx, KujuTokenID.indexed_trilist }); switch (newBlock.Token) { case KujuTokenID.prim_state_idx: ParseBlock(newBlock, ref shape); string txF = null; try { txF = OpenBveApi.Path.CombineFile(currentFolder, shape.textures[shape.prim_states[shape.currentPrimitiveState].Textures[0]].fileName); if (!File.Exists(txF)) { Interface.AddMessage(MessageType.Warning, true, "Texture file " + shape.textures[shape.prim_states[shape.currentPrimitiveState].Textures[0]].fileName + " was not found."); txF = null; } } catch { Interface.AddMessage(MessageType.Warning, true, "Texture file path " + shape.textures[shape.prim_states[shape.currentPrimitiveState].Textures[0]].fileName + " was invalid."); } currentLOD.subObjects[currentLOD.subObjects.Count - 1].materials.Add(new Material(txF)); break; case KujuTokenID.indexed_trilist: ParseBlock(newBlock, ref shape); break; default: throw new Exception("Unexpected primitive type, got " + currentToken); } capacity--; } break; case KujuTokenID.prim_state_idx: shape.currentPrimitiveState = block.ReadInt32(); break; case KujuTokenID.indexed_trilist: newBlock = block.ReadSubBlock(KujuTokenID.vertex_idxs); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.normal_idxs); ParseBlock(newBlock, ref shape); break; case KujuTokenID.sub_object: newBlock = block.ReadSubBlock(KujuTokenID.sub_object_header); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.vertices); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.vertex_sets); ParseBlock(newBlock, ref shape); newBlock = block.ReadSubBlock(KujuTokenID.primitives); ParseBlock(newBlock, ref shape); break; case KujuTokenID.sub_objects: int subObjectCount = block.ReadInt16(); if (block is BinaryBlock) { block.ReadUInt16(); } while (subObjectCount > 0) { newBlock = block.ReadSubBlock(KujuTokenID.sub_object); ParseBlock(newBlock, ref shape); subObjectCount--; } break; case KujuTokenID.sub_object_header: currentLOD.subObjects.Add(new SubObject()); shape.totalObjects++; flags = block.ReadUInt32(); int sortVectorIdx = block.ReadInt32(); int volIdx = block.ReadInt32(); uint sourceVertexFormatFlags = block.ReadUInt32(); uint destinationVertexFormatFlags = block.ReadUInt32(); newBlock = block.ReadSubBlock(KujuTokenID.geometry_info); ParseBlock(newBlock, ref shape); /* * Optional stuff, need to check if we're running off the end of the stream before reading each block */ if (block.Length() - block.Position() > 1) { newBlock = block.ReadSubBlock(KujuTokenID.subobject_shaders); ParseBlock(newBlock, ref shape); } if (block.Length() - block.Position() > 1) { newBlock = block.ReadSubBlock(KujuTokenID.subobject_light_cfgs); ParseBlock(newBlock, ref shape); } if (block.Length() - block.Position() > 1) { int subObjectID = block.ReadInt32(); } break; case KujuTokenID.subobject_light_cfgs: int[] subobject_light_cfgs = new int[block.ReadInt32()]; for (int i = 0; i < subobject_light_cfgs.Length; i++) { subobject_light_cfgs[i] = block.ReadInt32(); } break; case KujuTokenID.subobject_shaders: int[] subobject_shaders = new int[block.ReadInt32()]; for (int i = 0; i < subobject_shaders.Length; i++) { subobject_shaders[i] = block.ReadInt32(); } break; case KujuTokenID.vertices: int vertexCount = block.ReadInt16(); if (block is BinaryBlock) { block.ReadUInt16(); } while (vertexCount > 0) { newBlock = block.ReadSubBlock(KujuTokenID.vertex); ParseBlock(newBlock, ref shape); vertexCount--; } break; case KujuTokenID.vertex: flags = block.ReadUInt32(); //Various control variables, not supported int myPoint = block.ReadInt32(); //Index to points array int myNormal = block.ReadInt32(); //Index to normals array Vertex v = new Vertex(shape.points[myPoint], shape.normals[myNormal]); uint Color1 = block.ReadUInt32(); uint Color2 = block.ReadUInt32(); newBlock = block.ReadSubBlock(KujuTokenID.vertex_uvs); ParseBlock(newBlock, ref shape, ref v); currentLOD.subObjects[currentLOD.subObjects.Count - 1].verticies.Add(v); break; case KujuTokenID.vertex_idxs: int remainingVertex = block.ReadInt32() / 3; while (remainingVertex > 0) { int v1 = block.ReadInt32(); int v2 = block.ReadInt32(); int v3 = block.ReadInt32(); currentLOD.subObjects[currentLOD.subObjects.Count - 1].faces.Add(new Face(new int[] { v1, v2, v3 }, currentLOD.subObjects[currentLOD.subObjects.Count - 1].materials.Count - 1)); remainingVertex--; } break; case KujuTokenID.vertex_set: int vertexStateIndex = block.ReadInt32(); //Index to the vtx_states member int hierarchy = shape.vtx_states[vertexStateIndex].hierarchyID; //Now pull the hierachy ID out int setStartVertexIndex = block.ReadInt32(); //First vertex int setVertexCount = block.ReadInt32(); //Total number of vert VertexSet vts = new VertexSet(); vts.hierarchyIndex = hierarchy; vts.startVertex = setStartVertexIndex; vts.numVerticies = setVertexCount; currentLOD.subObjects[currentLOD.subObjects.Count - 1].vertexSets.Add(vts); break; case KujuTokenID.vertex_sets: int vertexSetCount = block.ReadInt16(); if (block is BinaryBlock) { block.ReadUInt16(); } while (vertexSetCount > 0) { newBlock = block.ReadSubBlock(KujuTokenID.vertex_set); ParseBlock(newBlock, ref shape); vertexSetCount--; } //We now need to transform our verticies currentLOD.subObjects[currentLOD.subObjects.Count - 1].TransformVerticies(shape.matrices); break; case KujuTokenID.vertex_uvs: int[] vertex_uvs = new int[block.ReadInt32()]; for (int i = 0; i < vertex_uvs.Length; i++) { vertex_uvs[i] = block.ReadInt32(); } //Looks as if vertex_uvs should always be of length 1, thus: vertex.TextureCoordinates = shape.uv_points[vertex_uvs[0]]; break; } }