/// <summary> /// Processes all ways from the PrimitiveGroup and adds them to the output queue. /// </summary> /// <param name="block">The PrimitiveBlock that contains specified PrimitiveGroup.</param> /// <param name="group">The PrimitiveGroup with nodes to process.</param> private void ProcessWays(PrimitiveBlock block, PrimitiveGroup group) { if (group.Ways == null) { return; } foreach (var way in group.Ways) { long refStore = 0; List <long> refs = new List <long>(way.Refs.Count); for (int i = 0; i < way.Refs.Count; i++) { refStore += (long)way.Refs[i]; refs.Add(refStore); } List <Tag> tags = new List <Tag>(); if (way.Keys != null) { for (int i = 0; i < way.Keys.Count; i++) { tags.Add(new Tag(block.StringTable[way.Keys[i]], block.StringTable[way.Values[i]])); } } EntityMetadata metadata = this.ProcessMetadata(way.Metadata, block); WayInfo parsed = new WayInfo((long)way.ID, new TagsCollection(tags), refs, metadata); _cache.Enqueue(parsed); } }
/// <summary> /// Processes all nodes in non-dense format from the PrimitiveGroup and adds them to the output queue. /// </summary> /// <param name="block">The PrimitiveBlock that contains specified PrimitiveGroup.</param> /// <param name="group">The PrimitiveGroup with nodes to process.</param> private void ProcessNodes(PrimitiveBlock block, PrimitiveGroup group) { if (group.Nodes == null) { return; } foreach (PbfNode node in group.Nodes) { double lat = 1E-09 * (block.LatOffset + (block.Granularity * node.Latitude)); double lon = 1E-09 * (block.LonOffset + (block.Granularity * node.Longitude)); List <Tag> tags = new List <Tag>(); if (node.Keys != null) { for (int i = 0; i < node.Keys.Count; i++) { tags.Add(new Tag(block.StringTable[node.Keys[i]], block.StringTable[node.Values[i]])); } } EntityMetadata metadata = this.ProcessMetadata(node.Metadata, block); NodeInfo parsed = new NodeInfo((long)node.ID, lat, lon, new TagsCollection(tags), metadata); _cache.Enqueue(parsed); } }
/// <summary> /// Processes OSM entities in Primitive group. /// </summary> /// <param name="block">The PrimitiveBlock that contains specified PrimitiveGroup.</param> /// <param name="group">The PrimitiveGroup to process.</param> private void ProcessPrimitiveGroup(PrimitiveBlock block, PrimitiveGroup group) { this.ProcessNodes(block, group); this.ProcessDenseNodes(block, group); this.ProcessWays(block, group); this.ProcessRelations(block, group); }
private IEnumerable <Node> ProcessNodes(PrimitiveBlock block, PrimitiveGroup group, AttributeRegistry attributeRegistry) { if (group.Nodes == null) { yield break; } foreach (PbfNode node in group.Nodes) { double lat = 1E-09 * (block.LatOffset + (block.Granularity * node.Latitude)); double lon = 1E-09 * (block.LonOffset + (block.Granularity * node.Longitude)); List <Tag> tags = null; if (node.Keys != null) { tags = node.Keys.Select((t, i) => new Tag() { Typ = attributeRegistry.GetAttributeValueId(OsmAttribute.TagType, block.StringTable[t]), Value = block.StringTable[node.Values[i]] }).ToList(); } yield return(new Node(node.ID, lat, lon, tags ?? new List <Tag>())); } }
/// <summary> /// Creates a PrimitiveGroup with serialized relations objects from relation tokens. /// </summary> /// <param name="timestampGranularity">Timestamp granularity defined in PrimitiveBlock.</param> /// <returns>PrimitiveGroup with relations from tokens or null if tokens is empty.</returns> private PrimitiveGroup BuildRelationsPrimitiveGroup(int timestampGranularity) { PrimitiveGroup result = null; if (_relationBuffer.Count > 0) { result = new PrimitiveGroup(); result.Relations = this.BuildRelations(timestampGranularity); } return(result); }
/// <summary> /// Creates a PrimitiveGroup with serialized ways from tokens. /// </summary> /// <param name="timestampGranularity">Timestamp granularity defined in PrimitiveBlock.</param> /// <returns>PrimitiveGroup with ways from tokens or null if tokens is empty.</returns> private PrimitiveGroup BuildWaysPrimitiveGroup(int timestampGranularity) { PrimitiveGroup result = null; if (_wayBuffer.Count > 0) { result = new PrimitiveGroup(); result.Ways = this.BuildWays(timestampGranularity); } return(result); }
private IEnumerable <Node> ProcessDenseNodes(PrimitiveBlock block, PrimitiveGroup group, AttributeRegistry attributeRegistry) { if (group.DenseNodes == null) { yield break; } long idStore = 0; long latStore = 0; long lonStore = 0; int keyValueIndex = 0; for (int i = 0; i < group.DenseNodes.Id.Count; i++) { idStore += group.DenseNodes.Id[i]; lonStore += group.DenseNodes.Longitude[i]; latStore += group.DenseNodes.Latitude[i]; double lat = 1E-09 * (block.LatOffset + (block.Granularity * latStore)); double lon = 1E-09 * (block.LonOffset + (block.Granularity * lonStore)); var tags = new List <Tag>(); if (group.DenseNodes.KeysVals.Count > 0) { while (group.DenseNodes.KeysVals[keyValueIndex] != 0) { string key = block.StringTable[group.DenseNodes.KeysVals[keyValueIndex++]]; string value = block.StringTable[group.DenseNodes.KeysVals[keyValueIndex++]]; var tagType = attributeRegistry.GetAttributeValueId(OsmAttribute.TagType, key); var tag = new Tag() { Typ = tagType, Value = value }; tags.Add(tag); } keyValueIndex++; } var node = new Node() { NodeId = idStore, Latitude = lat, Longitude = lon, Tags = tags }; yield return(node); } }
public void TestDecodeBlockWithRelation() { var block = new PrimitiveBlock(); block.date_granularity = 1000; block.granularity = 100; block.lat_offset = 0; block.lon_offset = 0; block.stringtable = new StringTable(); block.stringtable.s.Add(System.Text.Encoding.UTF8.GetBytes("highway")); block.stringtable.s.Add(System.Text.Encoding.UTF8.GetBytes("residential")); block.stringtable.s.Add(System.Text.Encoding.UTF8.GetBytes("Ben")); var pbfRelation = new OsmSharp.IO.PBF.Relation() { id = 1, info = new Info() { changeset = 10, timestamp = 10, uid = 100, user_sid = 2, version = 2 } }; pbfRelation.keys.Add(0); pbfRelation.vals.Add(1); pbfRelation.memids.Add(10); pbfRelation.memids.Add(1); // delta-encoding. pbfRelation.roles_sid.Add(3); pbfRelation.roles_sid.Add(3); pbfRelation.types.Add(OsmSharp.IO.PBF.Relation.MemberType.NODE); pbfRelation.types.Add(OsmSharp.IO.PBF.Relation.MemberType.WAY); var primitiveGroup = new PrimitiveGroup(); primitiveGroup.relations.Add(pbfRelation); block.primitivegroup.Add(primitiveGroup); var primitivesConsumer = new PrimitivesConsumerMock(); block.Decode(primitivesConsumer, false, false, false); Assert.AreEqual(0, primitivesConsumer.Nodes.Count); Assert.AreEqual(0, primitivesConsumer.Ways.Count); Assert.AreEqual(1, primitivesConsumer.Relations.Count); }
/// <summary> /// Processes all relations from the PrimitiveGroup and adds them to the output queue. /// </summary> /// <param name="block">The PrimitiveBlock that contains specified PrimitiveGroup.</param> /// <param name="group">The PrimitiveGroup with nodes to process.</param> private void ProcessRelations(PrimitiveBlock block, PrimitiveGroup group) { if (group.Relations == null) { return; } foreach (var relation in group.Relations) { long memberRefStore = 0; List <RelationMemberInfo> members = new List <RelationMemberInfo>(); for (int i = 0; i < relation.MemberIds.Count; i++) { memberRefStore += (long)relation.MemberIds[i]; string role = block.StringTable[relation.RolesIndexes[i]]; EntityType memberType = 0; switch (relation.Types[i]) { case PbfRelationMemberType.Node: memberType = EntityType.Node; break; case PbfRelationMemberType.Way: memberType = EntityType.Way; break; case PbfRelationMemberType.Relation: memberType = EntityType.Relation; break; } members.Add(new RelationMemberInfo() { MemberType = memberType, Reference = memberRefStore, Role = role }); } List <Tag> tags = new List <Tag>(); if (relation.Keys != null) { for (int i = 0; i < relation.Keys.Count; i++) { tags.Add(new Tag(block.StringTable[relation.Keys[i]], block.StringTable[relation.Values[i]])); } } EntityMetadata metadata = this.ProcessMetadata(relation.Metadata, block); RelationInfo parsed = new RelationInfo((long)relation.ID, new TagsCollection(tags), members, metadata); _cache.Enqueue(parsed); } }
public void TestDecodeBlockWithWay() { var block = new PrimitiveBlock(); block.date_granularity = 1000; block.granularity = 100; block.lat_offset = 0; block.lon_offset = 0; block.stringtable = new StringTable(); block.stringtable.s.Add(System.Text.Encoding.UTF8.GetBytes("highway")); block.stringtable.s.Add(System.Text.Encoding.UTF8.GetBytes("residential")); block.stringtable.s.Add(System.Text.Encoding.UTF8.GetBytes("Ben")); var pbfWay = new OsmSharp.IO.PBF.Way() { id = 1, info = new Info() { changeset = 10, timestamp = 10, uid = 100, user_sid = 2, version = 2 } }; pbfWay.keys.Add(0); pbfWay.vals.Add(1); pbfWay.refs.Add(0); pbfWay.refs.Add(1); var primitiveGroup = new PrimitiveGroup(); primitiveGroup.ways.Add(pbfWay); block.primitivegroup.Add(primitiveGroup); var primitivesConsumer = new PrimitivesConsumerMock(); block.Decode(primitivesConsumer, false, false, false); Assert.AreEqual(0, primitivesConsumer.Nodes.Count); Assert.AreEqual(1, primitivesConsumer.Ways.Count); Assert.AreEqual(0, primitivesConsumer.Relations.Count); }
public void TestDecodeBlockWithNode() { var block = new PrimitiveBlock(); block.date_granularity = 1000; block.granularity = 100; block.lat_offset = 0; block.lon_offset = 0; block.stringtable = new StringTable(); block.stringtable.s.Add(System.Text.Encoding.UTF8.GetBytes("highway")); block.stringtable.s.Add(System.Text.Encoding.UTF8.GetBytes("residential")); block.stringtable.s.Add(System.Text.Encoding.UTF8.GetBytes("Ben")); var node = new Node() { id = 1, info = new Info() { changeset = 10, timestamp = 10, uid = 100, user_sid = 2, version = 2 }, lat = Encoder.EncodeLatLon(10.9, block.lat_offset, block.granularity), lon = Encoder.EncodeLatLon(11.0, block.lat_offset, block.granularity) }; node.keys.Add(0); node.vals.Add(1); var primitiveGroup = new PrimitiveGroup(); primitiveGroup.nodes.Add(node); block.primitivegroup.Add(primitiveGroup); var primitivesConsumer = new PrimitivesConsumerMock(); block.Decode(primitivesConsumer, false, false, false); Assert.AreEqual(1, primitivesConsumer.Nodes.Count); Assert.AreEqual(0, primitivesConsumer.Ways.Count); Assert.AreEqual(0, primitivesConsumer.Relations.Count); }
/// <summary> /// Creates a PrimitiveGroup with serialized nodes from tokens. /// </summary> /// <param name="timestampGranularity">Timestamp granularity defined in PrimitiveBlock.</param> /// <param name="positionGranularity">Granularity defined in PrimitiveBlock.</param> /// <param name="latOffset">Latitude offset defined in PrimitiveBlock.</param> /// <param name="lonOffset">Longitude offset defined in PrimitiveBlock.</param> /// <returns>PrimitiveGroup with nodes from tokens or null if tokens is empty.</returns> private PrimitiveGroup BuildNodesPrimitiveGroup(int timestampGranularity, int positionGranularity, long latOffset, long lonOffset) { PrimitiveGroup result = null; if (_nodesBuffer.Count > 0) { result = new PrimitiveGroup(); if (this.Settings.UseDenseFormat) { result.DenseNodes = this.BuildDenseNodes(timestampGranularity, positionGranularity, latOffset, lonOffset); } else { result.Nodes = this.BuildNodes(timestampGranularity, positionGranularity, latOffset, lonOffset); } } return(result); }
/// <summary> /// Creates a PrimitiveBlock with entities of specified type from data in tokens. /// </summary> /// <param name="entityType">The type of entity to include in PrimitiveBlock.</param> /// <returns>PrimitiveBlock with entities of specified type or null if tokens doesn't contain any entities of specified type.</returns> private PrimitiveBlock BuildPrimitiveBlock(EntityType entityType) { PrimitiveBlock result = new PrimitiveBlock(); result.PrimitiveGroup = new List <PrimitiveGroup>(); PrimitiveGroup entityGroup = null; switch (entityType) { case EntityType.Node: entityGroup = this.BuildNodesPrimitiveGroup(result.DateGranularity, result.Granularity, result.LatOffset, result.LonOffset); result.StringTable = _nodesBuffer.BuildStringTable(); _nodesBuffer.Clear(); break; case EntityType.Way: entityGroup = this.BuildWaysPrimitiveGroup(result.DateGranularity); result.StringTable = _wayBuffer.BuildStringTable(); _wayBuffer.Clear(); break; case EntityType.Relation: entityGroup = this.BuildRelationsPrimitiveGroup(result.DateGranularity); result.StringTable = _relationBuffer.BuildStringTable(); _relationBuffer.Clear(); break; } if (entityGroup == null) { return(null); } result.PrimitiveGroup.Add(entityGroup); return(result); }
private void PrimGroupChange(object sender, EventArgs e) { Button btn = (Button)sender; foreach (var cbtn in ButtonGroups) { var col = ButtonColors[cbtn.Value]; if (cbtn.Key == btn) { cbtn.Key.BackColor = Color.FromArgb((col.R * 128) / 255 + 127, (col.G * 128) / 255 + 127, (col.B * 128) / 255 + 127); } else { cbtn.Key.BackColor = col; } } SelectedGroup = ButtonGroups[btn]; //set primitive list to reflect the group CurrentFullList = new List <InstructionIDNamePair>(); if (SelectedGroup == PrimitiveGroup.Control || SelectedGroup == PrimitiveGroup.All) { CurrentFullList.Add(new InstructionIDNamePair("Return True", 254)); CurrentFullList.Add(new InstructionIDNamePair("Return False", 255)); } if (SelectedGroup == PrimitiveGroup.All) { for (ushort id = 0; id < 68; id++) { var primName = EditorScope.Behaviour.Get <STR>(139).GetString(id); CurrentFullList.Add(new InstructionIDNamePair((primName == null) ? "Primitive #" + id : primName, id)); } } if (SelectedGroup == PrimitiveGroup.Subroutine || SelectedGroup == PrimitiveGroup.All) { if (bhav.ChunkID > 4095) { if (bhav.ChunkID < 8192) { CurrentFullList.AddRange(Scope.GetAllSubroutines(ScopeSource.Private)); } CurrentFullList.AddRange(Scope.GetAllSubroutines(ScopeSource.SemiGlobal)); } CurrentFullList.AddRange(Scope.GetAllSubroutines(ScopeSource.Global)); } else { var prims = PrimitiveRegistry.PrimitiveGroups[SelectedGroup]; foreach (var id in prims) { var primName = EditorScope.Behaviour.Get <STR>(139).GetString(id); CurrentFullList.Add(new InstructionIDNamePair((primName == null) ? "Primitive #" + id : primName, id)); } } SearchBox.Text = ""; UpdatePrimitiveList(); }
public List <PrimitiveGroup> GroupPrimitives(Facepoint[] points, out int pointCount, out int faceCount) { pointCount = 0; faceCount = 0; List <PrimitiveClass> fpPrimitives = new List <PrimitiveClass>(); if (_useStrips) { //Remap points so there is only one id per individual point Remapper remapData = new Remapper(); remapData.Remap <Facepoint>(points, null); //Set up tristripper with remapped point ids TriStripper stripper = new TriStripper( remapData._remapTable.Select(x => (uint)x).ToArray(), points.Select(x => x.NodeID).ToArray(), remapData._impTable); stripper.SetCacheSize(_cacheSize); stripper.SetMinStripSize(_minStripLen); stripper.SetPushCacheHits(_pushCacheHits); //Backward search doesn't work, //but generally won't improve the optimization with the cache on anyway //stripper.SetBackwardSearch(_backwardSearch); //Create strips using ids List <Primitive> primArray = stripper.Strip(); //Recollect facepoints with new indices and get point/face count for (int i = 0; i < primArray.Count; i++) { Primitive p = primArray[i]; if (p.Type == PrimType.TriangleList) { int count = p.Indices.Count / 3; faceCount += count; for (int r = 0; r < count; r++) { fpPrimitives.Add(new PointTriangle( points[remapData._impTable[p.Indices[r * 3 + 0]]], points[remapData._impTable[p.Indices[r * 3 + 1]]], points[remapData._impTable[p.Indices[r * 3 + 2]]])); } } else { faceCount += p.Indices.Count - 2; fpPrimitives.Add(new PointTriangleStrip() { _points = p.Indices.Select(x => points[remapData._impTable[x]]).ToList() }); } pointCount += p.Indices.Count; } } else { faceCount = (pointCount = points.Length) / 3; for (int r = 0; r < faceCount; r++) { fpPrimitives.Add(new PointTriangle( points[r * 3 + 0], points[r * 3 + 1], points[r * 3 + 2])); } } //Group primitives by each point's influence id fpPrimitives.Sort(PrimitiveClass.Compare); List <PrimitiveGroup> groups = new List <PrimitiveGroup>(); foreach (PrimitiveClass p in fpPrimitives) { bool added = false; foreach (PrimitiveGroup g in groups) { if (added = g.TryAdd(p)) { break; } } if (!added) { PrimitiveGroup g = new PrimitiveGroup(); g.TryAdd(p); groups.Add(g); } } return(groups); }
//Decode a single primitive using command list public void Run( ref byte *pIn, byte **pAssets, byte **pOut, int count, PrimitiveGroup group, ref ushort *indices, IMatrixNode[] nodeTable, bool[] textureMatrixIdentity) { //pIn is the address in the primitives //pOut is address of the face data buffers //pAssets is the address of the raw asset buffers int weight = 0; int index = 0, outSize; DecodeOp o; ElementDef *pDef; byte * p; byte[] pTexMtx = new byte[8]; byte *tIn, tOut; group._facePoints.Add(new List <Facepoint>()); //Iterate commands in list fixed(ushort *pNode = Nodes) { fixed(int *pDefData = Defs) { fixed(byte *pCmd = Commands) { for (int i = 0; i < count; i++) { pDef = (ElementDef *)pDefData; p = pCmd; Facepoint f = new Facepoint(); Continue: o = (DecodeOp)(*p++); switch (o) { //Process weight using cache case DecodeOp.PosWeight: weight = pNode[*pIn++ / 3]; goto Continue; case DecodeOp.TexMtx0: case DecodeOp.TexMtx1: case DecodeOp.TexMtx2: case DecodeOp.TexMtx3: case DecodeOp.TexMtx4: case DecodeOp.TexMtx5: case DecodeOp.TexMtx6: case DecodeOp.TexMtx7: index = (int)o - (int)DecodeOp.TexMtx0; byte value = *pIn++; if (value % 3 != 0) { Console.WriteLine("Raw texture matrix value is 0x{0}", value.ToString()); } else { value /= 3; if (value < 10) { textureMatrixIdentity[index] = true; //Console.WriteLine("Texture matrix value is {0}", value.ToString()); } else if (value >= 20) { Console.WriteLine("Texture matrix value is {0}", value.ToString()); } else { pTexMtx[index] = (byte)(value - 10); textureMatrixIdentity[index] = false; } } goto Continue; case DecodeOp.ElementDirect: ElementCodec.Decoders[pDef->Output](ref pIn, ref pOut[pDef->Type], VQuant.DeQuantTable[pDef->Scale]); goto Continue; case DecodeOp.ElementIndexed: //Get asset index if (pDef->Format == 2) { index = *(bushort *)pIn; pIn += 2; } else { index = *pIn++; } switch (pDef->Type) { case 0: f._vertexIndex = index; break; case 1: f._normalIndex = index; break; case 2: case 3: f._colorIndices[pDef->Type - 2] = index; break; default: f._UVIndices[pDef->Type - 4] = index; break; } if (pDef->Type == 0) //Special processing for vertices { //Match weight and index with remap table int mapEntry = (weight << 16) | index; //Find matching index, starting at end of list //Lower index until a match is found at that index or index is less than 0 index = RemapTable.Count; while (--index >= 0 && RemapTable[index] != mapEntry) { ; } //No match, create new entry //Will be processed into vertices at the end! if (index < 0) { index = RemapTable.Count; RemapTable.Add(mapEntry); _points.Add(new List <Facepoint>()); } //Write index *indices++ = (ushort)index; _points[index].Add(f); } else { //Copy data from buffer outSize = pDef->Output; //Input data from asset cache tIn = pAssets[pDef->Type] + index * outSize; tOut = pOut[pDef->Type]; if (tIn != null && tOut != null) { //Copy data to output while (outSize-- > 0) { *tOut++ = *tIn++; } //Increment element output pointer pOut[pDef->Type] = tOut; } } pDef++; goto Continue; default: break; //End } @group._facePoints[@group._facePoints.Count - 1].Add(f); } } } } }
/// <summary> /// Processes all nodes in dense format from the PrimitiveGroup and adds them to the output queue. /// </summary> /// <param name="block">The PrimitiveBlock that contains specified PrimitiveGroup.</param> /// <param name="group">The PrimitiveGroup with nodes to process.</param> private void ProcessDenseNodes(PrimitiveBlock block, PrimitiveGroup group) { if (group.DenseNodes == null) { return; } long idStore = 0; long latStore = 0; long lonStore = 0; int keyValueIndex = 0; long timestampStore = 0; long changesetStore = 0; int userIdStore = 0; int usernameIdStore = 0; for (int i = 0; i < group.DenseNodes.Id.Count; i++) { idStore += group.DenseNodes.Id[i]; lonStore += group.DenseNodes.Longitude[i]; latStore += group.DenseNodes.Latitude[i]; double lat = 1E-09 * (block.LatOffset + (block.Granularity * latStore)); double lon = 1E-09 * (block.LonOffset + (block.Granularity * lonStore)); List <Tag> tags = new List <Tag>(); if (group.DenseNodes.KeysVals.Count > 0) { while (group.DenseNodes.KeysVals[keyValueIndex] != 0) { string key = block.StringTable[group.DenseNodes.KeysVals[keyValueIndex++]]; string value = block.StringTable[group.DenseNodes.KeysVals[keyValueIndex++]]; tags.Add(new Tag(key, value)); } //Skip '0' used as delimiter keyValueIndex++; } EntityMetadata metadata = null; if (this.Settings.ReadMetadata && group.DenseNodes.DenseInfo != null) { timestampStore += group.DenseNodes.DenseInfo.Timestamp[i]; changesetStore += group.DenseNodes.DenseInfo.Changeset[i]; userIdStore += group.DenseNodes.DenseInfo.UserId[i]; usernameIdStore += group.DenseNodes.DenseInfo.UserNameIndex[i]; metadata = new EntityMetadata() { Changeset = (int)changesetStore, Timestamp = _unixEpoch.AddMilliseconds(timestampStore * block.DateGranularity), Uid = userIdStore, User = block.StringTable[usernameIdStore], Version = group.DenseNodes.DenseInfo.Version[i], Visible = true }; if (group.DenseNodes.DenseInfo.Visible.Count > 0) { metadata.Visible = group.DenseNodes.DenseInfo.Visible[i]; } } NodeInfo parsed = new NodeInfo((long)idStore, lat, lon, new TagsCollection(tags), metadata); _cache.Enqueue(parsed); } }
public void TestDecodeBlockWithDenseNodes() { var block = new PrimitiveBlock(); block.date_granularity = 1000; block.granularity = 100; block.lat_offset = 0; block.lon_offset = 0; block.stringtable = new StringTable(); block.stringtable.s.Add(System.Text.Encoding.UTF8.GetBytes(string.Empty)); // always encode empty string as '0'. block.stringtable.s.Add(System.Text.Encoding.UTF8.GetBytes("highway")); // 1 block.stringtable.s.Add(System.Text.Encoding.UTF8.GetBytes("residential")); // 2 block.stringtable.s.Add(System.Text.Encoding.UTF8.GetBytes("Ben")); // 3 block.stringtable.s.Add(System.Text.Encoding.UTF8.GetBytes("track")); // 4 block.stringtable.s.Add(System.Text.Encoding.UTF8.GetBytes("trunk")); // 5 var primitiveGroup = new PrimitiveGroup(); primitiveGroup.dense = new DenseNodes(); primitiveGroup.dense.denseinfo = new DenseInfo(); primitiveGroup.dense.denseinfo.changeset.Add(10); primitiveGroup.dense.denseinfo.changeset.Add(1); primitiveGroup.dense.denseinfo.changeset.Add(1); primitiveGroup.dense.denseinfo.timestamp.Add(10); primitiveGroup.dense.denseinfo.timestamp.Add(1); primitiveGroup.dense.denseinfo.timestamp.Add(1); primitiveGroup.dense.denseinfo.uid.Add(1); primitiveGroup.dense.denseinfo.uid.Add(0); primitiveGroup.dense.denseinfo.uid.Add(0); primitiveGroup.dense.denseinfo.user_sid.Add(3); primitiveGroup.dense.denseinfo.user_sid.Add(0); primitiveGroup.dense.denseinfo.user_sid.Add(0); primitiveGroup.dense.denseinfo.version.Add(1); primitiveGroup.dense.denseinfo.version.Add(1); primitiveGroup.dense.denseinfo.version.Add(1); primitiveGroup.dense.id.Add(1); primitiveGroup.dense.id.Add(1); primitiveGroup.dense.id.Add(1); primitiveGroup.dense.keys_vals.Add(1); primitiveGroup.dense.keys_vals.Add(2); primitiveGroup.dense.keys_vals.Add(0); // highway=residential. primitiveGroup.dense.keys_vals.Add(1); primitiveGroup.dense.keys_vals.Add(4); primitiveGroup.dense.keys_vals.Add(0); // highway=track. primitiveGroup.dense.keys_vals.Add(0); // empty. primitiveGroup.dense.lat.Add(Encoder.EncodeLatLon(10.0f, block.lat_offset, block.granularity)); primitiveGroup.dense.lat.Add(Encoder.EncodeLatLon(11.0f, block.lat_offset, block.granularity) - primitiveGroup.dense.lat[primitiveGroup.dense.lat.Count - 1]); primitiveGroup.dense.lat.Add(Encoder.EncodeLatLon(12.0f, block.lat_offset, block.granularity) - primitiveGroup.dense.lat[primitiveGroup.dense.lat.Count - 1]); primitiveGroup.dense.lon.Add(Encoder.EncodeLatLon(100.0f, block.lon_offset, block.granularity)); primitiveGroup.dense.lon.Add(Encoder.EncodeLatLon(110.0f, block.lon_offset, block.granularity) - primitiveGroup.dense.lon[primitiveGroup.dense.lon.Count - 1]); primitiveGroup.dense.lon.Add(Encoder.EncodeLatLon(120.0f, block.lon_offset, block.granularity) - primitiveGroup.dense.lon[primitiveGroup.dense.lon.Count - 1]); block.primitivegroup.Add(primitiveGroup); var primitivesConsumer = new PrimitivesConsumerMock(); block.Decode(primitivesConsumer, false, false, false); Assert.AreEqual(3, primitivesConsumer.Nodes.Count); Assert.AreEqual(0, primitivesConsumer.Ways.Count); Assert.AreEqual(0, primitivesConsumer.Relations.Count); var node = primitivesConsumer.Nodes[0]; Assert.IsNotNull(node); Assert.AreEqual(1, node.id); Assert.AreEqual(10, node.info.changeset); Assert.AreEqual(10, node.info.timestamp); Assert.AreEqual(1, node.info.uid); Assert.AreEqual(3, node.info.user_sid); Assert.AreEqual(1, node.info.version); Assert.AreEqual(1, node.keys.Count); Assert.AreEqual(1, node.keys[0]); Assert.AreEqual(1, node.vals.Count); Assert.AreEqual(2, node.vals[0]); node = primitivesConsumer.Nodes[1]; Assert.IsNotNull(node); Assert.AreEqual(2, node.id); Assert.AreEqual(11, node.info.changeset); Assert.AreEqual(11, node.info.timestamp); Assert.AreEqual(1, node.info.uid); Assert.AreEqual(3, node.info.user_sid); Assert.AreEqual(2, node.info.version); Assert.AreEqual(1, node.keys.Count); Assert.AreEqual(1, node.keys[0]); Assert.AreEqual(1, node.vals.Count); Assert.AreEqual(4, node.vals[0]); node = primitivesConsumer.Nodes[2]; Assert.IsNotNull(node); Assert.AreEqual(3, node.id); Assert.AreEqual(12, node.info.changeset); Assert.AreEqual(12, node.info.timestamp); Assert.AreEqual(1, node.info.uid); Assert.AreEqual(3, node.info.user_sid); Assert.AreEqual(3, node.info.version); Assert.AreEqual(0, node.keys.Count); Assert.AreEqual(0, node.vals.Count); }
private void PrimGroupChange(object sender, EventArgs e) { Button btn = (Button)sender; foreach (var cbtn in ButtonGroups) { var col = ButtonColors[cbtn.Value]; if (cbtn.Key == btn) cbtn.Key.BackColor = Color.FromArgb((col.R * 128) / 255 + 127, (col.G * 128) / 255 + 127, (col.B * 128) / 255 + 127); else cbtn.Key.BackColor = col; } SelectedGroup = ButtonGroups[btn]; //set primitive list to reflect the group CurrentFullList = new List<InstructionIDNamePair>(); if (SelectedGroup == PrimitiveGroup.All) { for (ushort id = 0; id < 68; id++) { var primName = EditorScope.Behaviour.Get<STR>(139).GetString(id); CurrentFullList.Add(new InstructionIDNamePair((primName == null) ? "Primitive #" + id : primName, id)); } } if (SelectedGroup == PrimitiveGroup.Subroutine || SelectedGroup == PrimitiveGroup.All) { if (bhav.ChunkID > 4095) { if (bhav.ChunkID < 8192) CurrentFullList.AddRange(Scope.GetAllSubroutines(ScopeSource.Private)); CurrentFullList.AddRange(Scope.GetAllSubroutines(ScopeSource.SemiGlobal)); } CurrentFullList.AddRange(Scope.GetAllSubroutines(ScopeSource.Global)); } else { var prims = PrimitiveRegistry.PrimitiveGroups[SelectedGroup]; foreach (var id in prims) { var primName = EditorScope.Behaviour.Get<STR>(139).GetString(id); CurrentFullList.Add(new InstructionIDNamePair((primName == null) ? "Primitive #" + id : primName, id)); } } SearchBox.Text = ""; UpdatePrimitiveList(); }
//Decode a single primitive using command list public void Run(ref byte *pIn, byte **pAssets, byte **pOut, int count, PrimitiveGroup group, ref ushort *indices, IMatrixNode[] nodeTable) { int weight = 0; //Vector3 Position = new Vector3(); //Vector3 Normal = new Vector3(); //Vector2[] UV = new Vector2[8]; //RGBAPixel[] Color = new RGBAPixel[2]; int index = 0, outSize; DecodeOp o; ElementDef *pDef; byte * p; //byte[] pTexMtx = new byte[8]; byte *tIn, tOut; group._points.Add(new List <Facepoint>()); //Iterate commands in list fixed(ushort *pNode = Nodes) fixed(int *pDefData = Defs) fixed(byte *pCmd = Commands) { for (int i = 0; i < count; i++) { pDef = (ElementDef *)pDefData; p = pCmd; Facepoint f = new Facepoint(); Top: o = (DecodeOp)(*p++); switch (o) { //Process weight using cache case DecodeOp.PosWeight: weight = pNode[*pIn++ / 3]; if (weight < nodeTable.Length) { f.Node = nodeTable[weight]; } goto Top; case DecodeOp.TexMtx0: case DecodeOp.TexMtx1: case DecodeOp.TexMtx2: case DecodeOp.TexMtx3: case DecodeOp.TexMtx4: case DecodeOp.TexMtx5: case DecodeOp.TexMtx6: case DecodeOp.TexMtx7: //index = (int)o - (int)DecodeOp.TexMtx0; if (*pIn++ == 0x60) //Identity matrix... { Console.WriteLine("wtf"); } //pTexMtx[index] = (byte)(*pIn++ / 3); goto Top; case DecodeOp.ElementDirect: ElementCodec.Decoders[pDef->Output] (ref pIn, ref pOut[pDef->Type], VQuant.DeQuantTable[pDef->Scale]); goto Top; case DecodeOp.ElementIndexed: //Get asset index if (pDef->Format == 2) { index = *(bushort *)pIn; pIn += 2; } else { index = *pIn++; } switch (pDef->Type) { case 0: f.VertexIndex = index; break; case 1: f.NormalIndex = index; break; case 2: case 3: f.ColorIndex[pDef->Type - 2] = index; break; default: f.UVIndex[pDef->Type - 4] = index; break; } if (pDef->Type == 0) //Special processing for vertices { //Match weight and index with remap table int mapEntry = (weight << 16) | index; int *pTmp = (int *)RemapTable.Address; //Find matching index, starting at end of list //Do nothing while the index lowers index = RemapSize; while ((--index >= 0) && (pTmp[index] != mapEntry)) { ; } //No match, create new entry //Will be processed into vertices at the end! if (index < 0) { pTmp[index = RemapSize++] = mapEntry; } //Write index //*(ushort*)pOut[pDef->Type] = (ushort)index; //pOut[pDef->Type] += 2; *indices++ = (ushort)index; } else { //Copy data from buffer outSize = pDef->Output; //Input data from asset cache tIn = pAssets[pDef->Type] + (index * outSize); tOut = pOut[pDef->Type]; //Copy data to output while (outSize-- > 0) { *tOut++ = *tIn++; } //Increment element output pointer pOut[pDef->Type] = tOut; } pDef++; goto Top; //Can't use this until it works faster. Merges all data into vertices. // if (pDef->Type == 0) // { // tOut = (byte*)&Position; // goto Apply; // } // else if (pDef->Type == 1) // { // tOut = (byte*)&Normal; // goto Apply; // } // else if (pDef->Type < 4) // { // fixed (RGBAPixel* color = &Color[pDef->Type - 2]) // tOut = (byte*)color; // goto Apply; // } // else // { // fixed (Vector2* uv = &UV[pDef->Type - 4]) // tOut = (byte*)uv; // goto Apply; // } //Apply: // //Copy data from buffer // outSize = pDef->Output; // //Input data from asset cache // tIn = pAssets[pDef->Type] + (index * outSize); // //Copy data to output // while (outSize-- > 0) // *tOut++ = *tIn++; // pDef++; // goto Top; default: break; //End } ////Remap as whole vertex ////Match vertex with remap table //VertData mapEntry = new VertData(Position, weight, Normal, Color, UV); //VertData* pTmp = (VertData*)RemapTable.Address; ////Find matching index, starting at end of list //index = RemapSize; //while ((--index >= 0) && (pTmp[index] != mapEntry)); ////No match, create new entry //if (index < 0) // pTmp[index = RemapSize++] = mapEntry; ////Write index //*pOut++ = (ushort)index; group._points[group._points.Count - 1].Add(f); } } }