lmstearn Posted May 16, 2014 Share Posted May 16, 2014 It is caused by floating point rounding and the fact that those fields are stored as scaled integers inside plugin. Besides 0.01 doesn't make difference anywhere. How does the scalar 9.680000 round up to 9.690000? Only if its 9.685000-9.689999. If it's only 2 significant digits then 9.680000 would round up to 9.700000- but then why not just display 9.68 or 9.69 for three significant digits? Link to comment Share on other sites More sharing options...
Arthmoor Posted May 16, 2014 Share Posted May 16, 2014 Because floating point storage and representation does not obey your desire for logical outcomes? Link to comment Share on other sites More sharing options...
zilav Posted May 16, 2014 Author Share Posted May 16, 2014 Hi I am seeing some severe slowdowns with r1573 when copying records. For example "Copy as new record into..." Static from skyrim.esm into a new mod. r1573 needs 10 minutes [00:13] [stuff.esp] Adding master "Skyrim.esm" [10:33] Copying done. 3.0.31 needs seconds [00:15] [stuf1.esp] Adding master "Skyrim.esm" [00:18] Copying done. Thanks for all Yep we know, being investigated. Though this is the reason why 3.0.32 is not released yet and killed kittens There is also a minor visual glitch (missing lod geometry when up close) with lodgen that needs to be fixed. Dragonblood 1 Link to comment Share on other sites More sharing options...
Arthmoor Posted May 16, 2014 Share Posted May 16, 2014 Is this slow copy thing with a specific record or type of record? I just did several randomly picked Static entries and each one says it took about 6 seconds to finish. Link to comment Share on other sites More sharing options...
Sheson Posted May 16, 2014 Share Posted May 16, 2014 Is this slow copy thing with a specific record or type of record? I just did several randomly picked Static entries and each one says it took about 6 seconds to finish. The timing example of 10 minutes was copying the entire tree - all statics. Seemed a good test case Link to comment Share on other sites More sharing options...
hlp Posted May 17, 2014 Share Posted May 17, 2014 Nope, seems a global change. I'll try pinpointing it over the weekend, but I was too tired last night. Link to comment Share on other sites More sharing options...
DayDreamer Posted May 18, 2014 Share Posted May 18, 2014 This is a not working script, I tried to create it from your description, but nothing were matching up when running on vanilla skyrim navmeshes. That's why I asked for more information.OK, I've figured it out. Each Triangle has 3 Edges, which you've numbered Triangle #0, Triangle #1, Triangle #2. But you numbered the unknown Flags as 1, 2, 3 -- they should probably be 0 relative. And I got confused by the position around the edge where the flag appears. That's just happenstance, although the CK does exhibit some consistency in assigning edges. Actually, it's quite simple: Flag 1 (now External1) should be Edge0External, Flag 2 (now External2Mid) should be Edge1External, Flag 3 (now External3End) should be Edge2External. If Flag 1 Edge0External is set, then Edges\Triangle#0 doesn't have a triangle number in it. Instead, it has an External Connection number. Then, the External Connections\Connection # has the external mesh and the triangle in that external mesh. Right now, the Edges labels are confusing. OK for the common case, but wrong for the externals. Could we have Edges\Edge, just like Vertices\Vertex? How hard would it be to change the orthography for external connection numbers? Perhaps "{ nn }"? UPDATE: Maybe anywhere a triangle is referenced, Triangle #nn, and for external External #nn? (Triangle and External having the same number of letters.) Triangle #613 |- Edges | |- Edge #0 (0<->1) Triangle #614 | |- Edge #1 (1<->2) -1 | |- Edge #2 (2<->0) External #23 |- Flags | |- Edge2External External Connections External #23 |- Unknown |- Mesh [...] |- Triangle Triangle #166 Link to comment Share on other sites More sharing options...
DayDreamer Posted May 18, 2014 Share Posted May 18, 2014 In the External Connections table, the Mesh can be the same as the current mesh. That is, this isn't necessarily "external" -- or symmetric. This is how they do jumps down from ledges for NPCs; one-way links through this table. It may have something to do with Cover Edges values, too. Link to comment Share on other sites More sharing options...
DayDreamer Posted May 18, 2014 Share Posted May 18, 2014 How do I access Edges? flags := GetElementNativeValues(tri, 'Flags'); // triangle has external connections? if flags and 1 > 0 then begin edges = ElementByPath(tri, 'Edges'); ExtNumber := GetElementNativeValues(edges, 'Triangle #0 (0 <-> 1)'); Or can that be an array? An array would be more convenient! ExtNumber := ElementByIndex(edges, 0); Link to comment Share on other sites More sharing options...
hlp Posted May 18, 2014 Share Posted May 18, 2014 You need to access the triangle member of the edges array: edges := ElementByPath(tri, 'Edges'); edgeTri := ElementByIndex(edges, 0); ExtNumber := GetElementNativeValues(edgeTri, '(0 <-> 1)'); Link to comment Share on other sites More sharing options...
zilav Posted May 18, 2014 Author Share Posted May 18, 2014 After staring at navmeshes for some time, I'm actually thinking about making themt more linear It is easier on eyes, eaiser to access from script, 2 less rows per triangle so more fit on screen. The only drawback is incompatibility with scripts working with navmeshes, but I don't know of any. Also since there is no easy way to change node names in xEdit (wbUnions are bad idea here with hundreds of elements), I think of naming flags as in screenshot. It clearly tells that edge is an index, not triangle. Any thoughts? Dragonblood 1 Link to comment Share on other sites More sharing options...
DayDreamer Posted May 18, 2014 Share Posted May 18, 2014 After staring at navmeshes for some time, I'm actually thinking about making themt more linear It is easier on eyes, eaiser to access from script, 2 less rows per triangle so more fit on screen. The only drawback is incompatibility with scripts working with navmeshes, but I don't know of any. Also since there is no easy way to change node names in xEdit (wbUnions are bad idea here with hundreds of elements), I think of naming flags as in screenshot. It clearly tells that edge is an index, not triangle. Any thoughts? Looks OK. I don't know of any scripts for navmeshes other than the ones we've been trading. How would I know the flag numbers? Are there constants we can OR together to make 7, but also use them for "flags and 'Edge 1 <-> 2 external index'"? Please, just get rid of the "external index" -- since I've now determined that they are sometimes internal (one-way jumps within the same Mesh). We could rename the External Connections table to Edge Links, and the flags to 'Edge 1..2 link'. Pascal syntax would be a heck of a lot easier to type than '1 <-> 2'. (I kept getting the shifts and spacing wrong in my efforts: 1 space shift < unshift - shift > space 2.) EDIT: or Edge 1_2 (say edge 1 bar 2). Link to comment Share on other sites More sharing options...
DayDreamer Posted May 19, 2014 Share Posted May 19, 2014 You need to access the triangle member of the edges array: edges := ElementByPath(tri, 'Edges'); edgeTri := ElementByIndex(edges, 0); ExtNumber := GetElementNativeValues(edgeTri, '(0 <-> 1)'); Using a variant of this, I've been able to re-build the (Zilav) script to test bi-directional external connections (or lack thereof). It should be easily modifiable for the new layout and names, too. Takes my machine 48 minutes to run. But might be speedier: Zilav looped through the tri table. Next run, I'm going to try it without a loop, just a simpler bounds check instead. Link to comment Share on other sites More sharing options...
zilav Posted May 19, 2014 Author Share Posted May 19, 2014 Uploaded a new version with performance issue fix when copying records and renamed NAVM fields. Using a variant of this, I've been able to re-build the (Zilav) script to test bi-directional external connections (or lack thereof). It should be easily modifiable for the new layout and names, too. Takes my machine 48 minutes to run. But might be speedier: Zilav looped through the tri table. Next run, I'm going to try it without a loop, just a simpler bounds check instead.It is slow because I thought that external connection in triangle IS triangle index, so to get an index in connections I needed to loop through all triangles pripor to it and count the number of external ones. Now this loop can be removed entirely and should speed up script by a lot. You can (and have to) use binary arithmetics so AND 7 > 0 will work to check edge link flags. Dragonblood 1 Link to comment Share on other sites More sharing options...
DayDreamer Posted May 19, 2014 Share Posted May 19, 2014 Now this loop can be removed entirely and should speed up script by a lot. You can (and have to) use binary arithmetics so AND 7 > 0 will work to check edge link flags. Yeah, without the loop cut time to 21:19.Either there are more things to decode, or Skyrim.esm is in terrible shape. Roughly 32,800 errors! Since I tested for everything, here are some amazing problems: Line 4888: Referenced triangle (1012 > 988) in [NAVM:000EAECC] (in GRUP Cell Temporary Children of IlinaltasDeepExterior01 [CELL:00009B36] (in Tamriel "Skyrim" [WRLD:0000003C] at -8,-12)) is too large! Line 4891: Referenced triangle (1011 > 988) in [NAVM:000EAECC] (in GRUP Cell Temporary Children of IlinaltasDeepExterior01 [CELL:00009B36] (in Tamriel "Skyrim" [WRLD:0000003C] at -8,-12)) is too large! Line 24020: Referenced triangle (422 > 415) in [NAVM:0010F989] (in GRUP Cell Temporary Children of [CELL:00009698] (in Tamriel "Skyrim" [WRLD:0000003C] at 3,-7)) is too large! Line 24022: Referenced triangle (428 > 415) in [NAVM:0010F989] (in GRUP Cell Temporary Children of [CELL:00009698] (in Tamriel "Skyrim" [WRLD:0000003C] at 3,-7)) is too large! Line 24024: Referenced triangle (424 > 415) in [NAVM:0010F989] (in GRUP Cell Temporary Children of [CELL:00009698] (in Tamriel "Skyrim" [WRLD:0000003C] at 3,-7)) is too large! Line 24026: Referenced triangle (425 > 415) in [NAVM:0010F989] (in GRUP Cell Temporary Children of [CELL:00009698] (in Tamriel "Skyrim" [WRLD:0000003C] at 3,-7)) is too large! Line 24028: Referenced triangle (421 > 415) in [NAVM:0010F989] (in GRUP Cell Temporary Children of [CELL:00009698] (in Tamriel "Skyrim" [WRLD:0000003C] at 3,-7)) is too large! Line 24030: Referenced triangle (423 > 415) in [NAVM:0010F989] (in GRUP Cell Temporary Children of [CELL:00009698] (in Tamriel "Skyrim" [WRLD:0000003C] at 3,-7)) is too large! Line 24032: Referenced triangle (416 > 415) in [NAVM:0010F989] (in GRUP Cell Temporary Children of [CELL:00009698] (in Tamriel "Skyrim" [WRLD:0000003C] at 3,-7)) is too large! Line 24034: Referenced triangle (427 > 415) in [NAVM:0010F989] (in GRUP Cell Temporary Children of [CELL:00009698] (in Tamriel "Skyrim" [WRLD:0000003C] at 3,-7)) is too large! Line 24036: Referenced triangle (418 > 415) in [NAVM:0010F989] (in GRUP Cell Temporary Children of [CELL:00009698] (in Tamriel "Skyrim" [WRLD:0000003C] at 3,-7)) is too large! Line 24038: Referenced triangle (419 > 415) in [NAVM:0010F989] (in GRUP Cell Temporary Children of [CELL:00009698] (in Tamriel "Skyrim" [WRLD:0000003C] at 3,-7)) is too large! Line 24040: Referenced triangle (430 > 415) in [NAVM:0010F989] (in GRUP Cell Temporary Children of [CELL:00009698] (in Tamriel "Skyrim" [WRLD:0000003C] at 3,-7)) is too large! Examining one in detail, Triangle 22 in [NAVM:000FD7E8] (in GRUP Cell Temporary Children of [CELL:00009B37] (in Tamriel "Skyrim" [WRLD:0000003C] at -9,-12)) is broken Triangle 46 in [NAVM:000FD7E8] (in GRUP Cell Temporary Children of [CELL:00009B37] (in Tamriel "Skyrim" [WRLD:0000003C] at -9,-12)) is broken Triangle 157 in [NAVM:000FD7E8] (in GRUP Cell Temporary Children of [CELL:00009B37] (in Tamriel "Skyrim" [WRLD:0000003C] at -9,-12)) is broken Triangle 260 in [NAVM:000FD7E8] (in GRUP Cell Temporary Children of [CELL:00009B37] (in Tamriel "Skyrim" [WRLD:0000003C] at -9,-12)) is broken Referenced triangle (1012 > 988) in [NAVM:000EAECC] (in GRUP Cell Temporary Children of IlinaltasDeepExterior01 [CELL:00009B36] (in Tamriel "Skyrim" [WRLD:0000003C] at -8,-12)) is too large! Triangle 267 in [NAVM:000FD7E8] (in GRUP Cell Temporary Children of [CELL:00009B37] (in Tamriel "Skyrim" [WRLD:0000003C] at -9,-12)) is broken Triangle 519 in [NAVM:000FD7E8] (in GRUP Cell Temporary Children of [CELL:00009B37] (in Tamriel "Skyrim" [WRLD:0000003C] at -9,-12)) is broken Referenced triangle (1011 > 988) in [NAVM:000EAECC] (in GRUP Cell Temporary Children of IlinaltasDeepExterior01 [CELL:00009B36] (in Tamriel "Skyrim" [WRLD:0000003C] at -8,-12)) is too large! Triangle 16 in [NAVM:000FD7E9] (in GRUP Cell Temporary Children of [CELL:00009B37] (in Tamriel "Skyrim" [WRLD:0000003C] at -9,-12)) is broken Verified that Triangle 267 in [NAVM:000FD7E8] uses Edge Link #14, which does have 1012 value.Verified that Triangle 16 in [NAVM:000FD7E9] uses Edge Link #0, which does have 1011 value. Verified there are only 988 triangles in [NAVM:000EAECC]. In the CK, as soon as I load up that navmesh and use find triangle 267, it starts spamming PATHFINDING warnings. Looks like it's supposed to connect to 000EAECC Tri 209. Could somebody else verify these in their copy? Is mine corrupted? Link to comment Share on other sites More sharing options...
DayDreamer Posted May 19, 2014 Share Posted May 19, 2014 To keep it simpler, here's all the errors from Update.esm. "broken" means it couldn't find the matching link back. [EDIT: list removed] It looks to me that the whole point of these changes in Update.esm was to add Links. All of these navmesh blocks add new Edge links flags. But it looks like some adjacent navmeshes with the new links weren't added!?!? I've posted these examples here to ensure that folks can verify the problems, and because this verifies the new code for tables and flags is correct. For detailed analysis of bugs, should be a new thread. UPDATE: It appears that those errors have already been fixed by USKP, so I've removed them. So much can be done with a few well placed Finalizes. Link to comment Share on other sites More sharing options...
Arthmoor Posted May 19, 2014 Share Posted May 19, 2014 Yeah, without the loop cut time to 21:19. Either there are more things to decode, or Skyrim.esm is in terrible shape. Roughly 32,800 errors! Skyrim.esm is in terrible shape. Just about any time I have to finalize a navmesh somewhere, one or more of the adjacent cells begins throwing errors and I go to look and find things broken. 32800 errors may seem like a lot, but they pile up fast when each cell you run into has a dozen or more errors to fix. Link to comment Share on other sites More sharing options...
DayDreamer Posted May 19, 2014 Share Posted May 19, 2014 Skyrim.esm is in terrible shape. Just about any time I have to finalize a navmesh somewhere, one or more of the adjacent cells begins throwing errors and I go to look and find things broken. 32800 errors may seem like a lot, but they pile up fast when each cell you run into has a dozen or more errors to fix. And the actual number will be less than that, as the other side of the link may be pointing in the wrong place too, doubling the errors. But those I've examined don't have the other side. Also, some of the errors give 2 lines. Anyway, I'm going to reformat the output -- Zilav has the result at the far right, better to put it on the left to avoid scrolling. Then I'll post the data and a Meta tracker for cleaning things up. It's going to take awhile! Link to comment Share on other sites More sharing options...
DayDreamer Posted May 19, 2014 Share Posted May 19, 2014 After adding prettier multi-line error messages, my current run only found a few dozen errors total. My previous code must have had a false positive in it -- or my current code has a false negative.... { Check that Edge Linked triangles in navmeshes are pointing to each other } unit NavMeshCheckExternal; //=========================================================================== function Initialize: integer; begin if wbSimpleRecords then begin MessageDlg('Simple records must be unchecked in xEdit options', mtInformation, [mbOk], 0); Result := 1; Exit; end; end; //=========================================================================== // check that tri1 in navmesh navm1 points to tri2 in navmesh navm2 function CheckConnection(navm1, navm2: IInterface; tri1, tri2: integer): Boolean; var tris, tri, EdgeLinks, EdgeLink: IInterface; TriLimit, flags, EdgeLinkLimit, EdgeLinkIndex: integer; begin if Signature(navm1) <> 'NAVM' then begin AddMessage('Not NAVM!'); AddMessage(Format('Referenced triangle %d in %s', [tri1, Name(navm1)])); Exit; end; tris := ElementByPath(navm1, 'NVNM\Triangles'); TriLimit := Pred(ElementCount(tris)); EdgeLinks := ElementByPath(navm1, 'NVNM\Edge Links'); EdgeLinkLimit := Pred(ElementCount(EdgeLinks)); if tri1 > TriLimit then begin AddMessage(Format('Referenced triangle (%d > %d) in %s', [tri1, TriLimit, Name(navm1)])); Exit; end; tri := ElementByIndex(tris, tri1); flags := GetElementNativeValues(tri, 'Flags'); if flags and 7 = 0 then begin AddMessage('No Edge Links'); AddMessage(Format('Referenced triangle %d in %s', [tri1, Name(navm1)])); Exit; end; if flags and 1 > 0 then begin EdgeLinkIndex := GetElementNativeValues(tri, 'Edge 0-1'); if EdgeLinkIndex > EdgeLinkLimit then begin AddMessage(Format('Bad Edge 0-1 link (%d > %d)!', [EdgeLinkIndex, EdgeLinkLimit])); AddMessage(Format('Referenced triangle %d in %s', [tri1, Name(navm1)])); end else begin EdgeLink := ElementByIndex(EdgeLinks, EdgeLinkIndex); if (FormID(LinksTo(ElementByName(EdgeLink, 'Mesh'))) = FormID(navm2)) and (GetElementNativeValues(EdgeLink, 'Triangle') = tri2) then begin Result := True; Exit; end; end; end; if flags and 2 > 0 then begin EdgeLinkIndex := GetElementNativeValues(tri, 'Edge 1-2'); if EdgeLinkIndex > EdgeLinkLimit then begin AddMessage(Format('Bad Edge 1-2 link (%d > %d)!', [EdgeLinkIndex, EdgeLinkLimit])); AddMessage(Format('Referenced triangle %d in %s', [tri1, Name(navm1)])); end else begin EdgeLink := ElementByIndex(EdgeLinks, EdgeLinkIndex); if (FormID(LinksTo(ElementByName(EdgeLink, 'Mesh'))) = FormID(navm2)) and (GetElementNativeValues(EdgeLink, 'Triangle') = tri2) then begin Result := True; Exit; end; end; end; if flags and 4 > 0 then begin EdgeLinkIndex := GetElementNativeValues(tri, 'Edge 2-0'); if EdgeLinkIndex > EdgeLinkLimit then begin AddMessage(Format('Bad Edge 2-0 link (%d > %d)!', [EdgeLinkIndex, EdgeLinkLimit])); AddMessage(Format('Referenced triangle %d in %s', [tri1, Name(navm1)])); end else begin EdgeLink := ElementByIndex(EdgeLinks, EdgeLinkIndex); if (FormID(LinksTo(ElementByName(EdgeLink, 'Mesh'))) = FormID(navm2)) and (GetElementNativeValues(EdgeLink, 'Triangle') = tri2) then begin Result := True; Exit; end; end; end; AddMessage('No Edge Link match!'); AddMessage(Format('Referenced triangle %d in %s', [tri1, Name(navm1)])); end; //=========================================================================== function Process(e: IInterface): integer; var tris, tri, EdgeLinks, EdgeLink: IInterface; i, flags, EdgeLinkLimit, EdgeLinkIndex, EdgeLinkFound, EdgeLinkCount, errors: integer; begin if Signature(e) <> 'NAVM' then Exit; tris := ElementByPath(e, 'NVNM\Triangles'); EdgeLinks := ElementByPath(e, 'NVNM\Edge Links'); EdgeLinkCount := ElementCount(EdgeLinks); EdgeLinkLimit := Pred(ElementCount(EdgeLinks)); EdgeLinkFound := 0; // iterate through triangles for i := 0 to Pred(ElementCount(tris)) do begin errors := 0; tri := ElementByIndex(tris, i); flags := GetElementNativeValues(tri, 'Flags'); // triangle has EdgeLinks? if flags and 1 > 0 then begin EdgeLinkIndex := GetElementNativeValues(tri, 'Edge 0-1'); if EdgeLinkIndex > EdgeLinkLimit then begin AddMessage(Format('Bad Edge 0-1 link (%d > %d)!', [EdgeLinkIndex, EdgeLinkLimit])); end else begin EdgeLink := ElementByIndex(EdgeLinks, EdgeLinkIndex); if not CheckConnection(LinksTo(ElementByName(EdgeLink, 'Mesh')), e, GetElementNativeValues(EdgeLink, 'Triangle'), i) then begin AddMessage(Format('via Edge 0-1 link %d', [EdgeLinkIndex])); Inc(errors); end; end; Inc(EdgeLinkFound); end; if flags and 2 > 0 then begin EdgeLinkIndex := GetElementNativeValues(tri, 'Edge 1-2'); if EdgeLinkIndex > EdgeLinkLimit then begin AddMessage(Format('Bad Edge 1-2 link (%d > %d)!', [EdgeLinkIndex, EdgeLinkLimit])); end else begin EdgeLink := ElementByIndex(EdgeLinks, EdgeLinkIndex); if not CheckConnection(LinksTo(ElementByName(EdgeLink, 'Mesh')), e, GetElementNativeValues(EdgeLink, 'Triangle'), i) then begin AddMessage(Format('via Edge 1-2 link %d', [EdgeLinkIndex])); Inc(errors); end; end; Inc(EdgeLinkFound); end; if flags and 4 > 0 then begin EdgeLinkIndex := GetElementNativeValues(tri, 'Edge 2-0'); if EdgeLinkIndex > EdgeLinkLimit then begin AddMessage(Format('Bad Edge 2-0 link (%d > %d)!', [EdgeLinkIndex, EdgeLinkLimit])); end else begin EdgeLink := ElementByIndex(EdgeLinks, EdgeLinkIndex); if not CheckConnection(LinksTo(ElementByName(EdgeLink, 'Mesh')), e, GetElementNativeValues(EdgeLink, 'Triangle'), i) then begin AddMessage(Format('via Edge 2-0 link %d', [EdgeLinkIndex])); Inc(errors); end; end; Inc(EdgeLinkFound); end; if errors > 0 then begin AddMessage(Format('^^^ Error triangle %d in %s', [i, Name(e)])); //Result := 1; //Exit; end; end; if (EdgeLinkFound > 0) and (EdgeLinkFound > EdgeLinkCount) then begin AddMessage(Format('Too many Edges Linked (%d > %d) in %s', [EdgeLinkFound, EdgeLinkCount, Name(e)])); //Result := 1; //Exit; end; end; end. Link to comment Share on other sites More sharing options...
zilav Posted May 19, 2014 Author Share Posted May 19, 2014 Took 13 minutes to scan Skyrim.esm on my PC. Also refactored it a bit, and probably going to include with TES5Edit if you don't mind. p.s. sorry for refactoring, I just not used to your identations style. But it is smaller now, so won't be much work to change it back. { Check that Edge Linked triangles in navmeshes are pointing to each other } unit NavMeshCheckExternal; var arEdge: array [0..2] of string; //=========================================================================== function Initialize: integer; begin if wbSimpleRecords then begin MessageDlg('Simple records must be unchecked in xEdit options', mtInformation, [mbOk], 0); Result := 1; Exit; end; arEdge[0] := '0-1'; arEdge[1] := '1-2'; arEdge[2] := '2-0'; end; //=========================================================================== // check that tri1 in navmesh navm1 points to tri2 in navmesh navm2 function CheckConnection(navm1, navm2: IInterface; tri1, tri2: integer): Boolean; var tris, tri, EdgeLinks, EdgeLink: IInterface; TriLimit, j, flags, EdgeLinkLimit, EdgeLinkIndex: integer; begin if Signature(navm1) <> 'NAVM' then begin AddMessage('Not NAVM!'); AddMessage(Format('Referenced triangle %d in %s', [tri1, Name(navm1)])); Exit; end; tris := ElementByPath(navm1, 'NVNM\Triangles'); TriLimit := Pred(ElementCount(tris)); EdgeLinks := ElementByPath(navm1, 'NVNM\Edge Links'); EdgeLinkLimit := Pred(ElementCount(EdgeLinks)); if tri1 > TriLimit then begin AddMessage(Format('Referenced triangle (%d > %d) in %s', [tri1, TriLimit, Name(navm1)])); Exit; end; tri := ElementByIndex(tris, tri1); flags := GetElementNativeValues(tri, 'Flags'); if flags and 7 = 0 then begin AddMessage('No Edge Links'); AddMessage(Format('Referenced triangle %d in %s', [tri1, Name(navm1)])); Exit; end; for j := 0 to 2 do if flags and (1 shl j) > 0 then begin EdgeLinkIndex := GetElementNativeValues(tri, 'Edge ' + arEdge[j]); if EdgeLinkIndex > EdgeLinkLimit then begin AddMessage(Format('Bad Edge %s link (%d > %d)!', [arEdge[j], EdgeLinkIndex, EdgeLinkLimit])); AddMessage(Format('Referenced triangle %d in %s', [tri1, Name(navm1)])); end else begin EdgeLink := ElementByIndex(EdgeLinks, EdgeLinkIndex); if (FormID(LinksTo(ElementByName(EdgeLink, 'Mesh'))) = FormID(navm2)) and (GetElementNativeValues(EdgeLink, 'Triangle') = tri2) then begin Result := True; Exit; end; end; end; AddMessage('No Edge Link match!'); AddMessage(Format('Referenced triangle %d in %s', [tri1, Name(navm1)])); end; //=========================================================================== function Process(e: IInterface): integer; var tris, tri, EdgeLinks, EdgeLink: IInterface; i, j, flags, EdgeLinkLimit, EdgeLinkIndex, EdgeLinkFound, EdgeLinkCount, errors: integer; begin if Signature(e) <> 'NAVM' then Exit; tris := ElementByPath(e, 'NVNM\Triangles'); EdgeLinks := ElementByPath(e, 'NVNM\Edge Links'); EdgeLinkCount := ElementCount(EdgeLinks); EdgeLinkLimit := Pred(ElementCount(EdgeLinks)); EdgeLinkFound := 0; // iterate through triangles for i := 0 to Pred(ElementCount(tris)) do begin errors := 0; tri := ElementByIndex(tris, i); flags := GetElementNativeValues(tri, 'Flags'); for j := 0 to 2 do // triangle has EdgeLinks? if flags and (1 shl j) > 0 then begin EdgeLinkIndex := GetElementNativeValues(tri, 'Edge ' + arEdge[j]); if EdgeLinkIndex > EdgeLinkLimit then AddMessage(Format('Bad Edge %s link (%d > %d)!', [arEdge[j], EdgeLinkIndex, EdgeLinkLimit])) else begin Inc(EdgeLinkFound); EdgeLink := ElementByIndex(EdgeLinks, EdgeLinkIndex); if not CheckConnection(LinksTo(ElementByName(EdgeLink, 'Mesh')), e, GetElementNativeValues(EdgeLink, 'Triangle'), i) then begin AddMessage(Format('via Edge %s link %d', [arEdge[j], EdgeLinkIndex])); Inc(errors); end; end; end; if errors > 0 then AddMessage(Format('^^^ Error triangle %d in %s', [i, Name(e)])); end; if (EdgeLinkFound > 0) and (EdgeLinkFound > EdgeLinkCount) then begin AddMessage(Format('Too many Edges Linked (%d > %d) in %s', [EdgeLinkFound, EdgeLinkCount, Name(e)])); //Result := 1; //Exit; end; end; end. Dragonblood 1 Link to comment Share on other sites More sharing options...
DayDreamer Posted May 20, 2014 Share Posted May 20, 2014 Took 13 minutes to scan Skyrim.esm on my PC. Also refactored it a bit, and probably going to include with TES5Edit if you don't mind. p.s. sorry for refactoring, I just not used to your identations style. But it is smaller now, so won't be much work to change it back. Sure, go ahead and include it! Likewise, your indentation style looks odd to me, too. (I've been doing Pascal since 1976, UCSD Pascal on the Terak circa 1978, then Borland in the 80s.) The PC editor automatically prefers 4 space indentation, which is what we used on the Terak. And we always taught "then begin" matching "else begin" on a new line. But as long as it works, I doubt anybody will be looking at it. How would I get it to run over the whole Skyrim, but using the selected plugins? If I load USKP, and run it on USKP, I get only the USKP NAVM records. If I load USKP, and run it on Skyrim.esm, I get the same identical results as running without USKP loaded. I'd like to put my effort into fixing those that haven't already been fixed by USKP. Of course, maybe these haven't been fixed, so they really are identical. Next up, I'm going to write NavMeshCheckInternal to bulk find all the bad internal edges.... Link to comment Share on other sites More sharing options...
DayDreamer Posted May 20, 2014 Share Posted May 20, 2014 I'm beginning to suspect a pattern in the fixes. Deleting a triangle during editing causes renumbering; looks like CK will simply grab the highest number and change it to the number just deleted (keeping the table compact and sequential). However, that number could be a border triangle -- but obviously the CK doesn't then automatically Finalize the cell to update the link table in adjoining cells, it depends on the intelligent user to do it. Running a script on a plugin, it only "sees" the plugin tables. How do I access the underlying master record tables to see whether a triangle with the same border vertices has changed its number? Also, how do I test whether the table I'm accessing is in the plugin or falling through to the master? Link to comment Share on other sites More sharing options...
DayDreamer Posted May 20, 2014 Share Posted May 20, 2014 Also, how do I test whether the table I'm accessing is in the plugin or falling through to the master?It's definitely *NOT* falling through to the master. Running the script on a plugin generates errors for all the border connections. How to I make LinksTo(ElementByName(EdgeLink, 'Mesh')) return tables from Update and Skyrim? And again, how do I know it has? Link to comment Share on other sites More sharing options...
zilav Posted May 20, 2014 Author Share Posted May 20, 2014 Updated it to check only winning overrides of navmeshes (last loaded) http://pastebin.com/RCZYMVAM Dragonblood 1 Link to comment Share on other sites More sharing options...
DayDreamer Posted May 21, 2014 Share Posted May 21, 2014 Updated it to check only winning overrides of navmeshes (last loaded) http://pastebin.com/RCZYMVAM Thanks. Next up, I'm going to write NavMeshCheckInternal to bulk find all the bad internal edges.... Here's my replacement for both external and internal. Since we're looping through all the triangles in the game, might as well check all the edges at once. I've tried to stick to your style. But it reminded me why we taught that all <statement> should have "begin" <statements> "end", even for single statements. Damn difficult to keep track of dangling semi-colons, and annoying to have to change program structure merely to add debugging. [old code removed] Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now