33using System . Collections . Generic ;
44using System . IO ;
55using System . Windows ;
6+ using BIS . Core . Math ;
67
78namespace ModelPropertyChecker
89{
@@ -164,6 +165,7 @@ public class LOD
164165 public LODResolution resolution { get ; set ; } = 0 ;
165166 public List < PropertyException > propertyExceptions { get ; set ; } = new List < PropertyException > ( ) ; //Set by PropertyVerifier
166167
168+ public Dictionary < string , List < Vector3P > > selections { get ; set ; } = new Dictionary < string , List < Vector3P > > ( ) ;
167169
168170 public int exceptionCount
169171 {
@@ -205,7 +207,7 @@ public bool hasWarnings
205207
206208
207209
208- public void loadFromODOL ( BinaryReaderEx reader )
210+ public void loadFromODOL ( BinaryReaderEx reader , bool readPoints = false )
209211 {
210212 var numProxies = reader . ReadUInt32 ( ) ;
211213 for ( int i = 0 ; i < numProxies ; i ++ )
@@ -313,6 +315,8 @@ public void loadFromODOL(BinaryReaderEx reader)
313315
314316 }
315317
318+
319+ var tempSelections = new Dictionary < string , List < UInt32 > > ( ) ;
316320 var numSelections = reader . ReadUInt32 ( ) ;
317321 for ( int i = 0 ; i < numSelections ; i ++ )
318322 {
@@ -338,7 +342,7 @@ public void loadFromODOL(BinaryReaderEx reader)
338342 {
339343 var b = reader . ReadByte ( ) ;
340344 var expectedDataSize = ( uint ) ( nElements * 4 ) ;
341- var stream = reader . ReadCompressed ( expectedDataSize , b == 2 ) ;
345+ var stream = reader . ReadCompressed ( expectedDataSize , b == 2 ) ;
342346 }
343347
344348 nElements = reader . ReadInt32 ( ) ; //vertices
@@ -347,8 +351,17 @@ public void loadFromODOL(BinaryReaderEx reader)
347351 var b = reader . ReadByte ( ) ;
348352 var expectedDataSize = ( uint ) ( nElements * 4 ) ;
349353 var stream = reader . ReadCompressed ( expectedDataSize , b == 2 ) ;
350- }
354+ if ( readPoints )
355+ {
356+ var streamB = new BinaryReaderEx ( new MemoryStream ( stream ) ) ;
351357
358+ List < UInt32 > pointList = new List < UInt32 > ( nElements ) ;
359+ for ( int i2 = 0 ; i2 < nElements ; i2 ++ )
360+ pointList . Add ( streamB . ReadUInt32 ( ) ) ;
361+ tempSelections . Add ( selectionName , pointList ) ;
362+ }
363+
364+ }
352365
353366 nElements = reader . ReadInt32 ( ) ; //weights
354367 if ( nElements != 0 )
@@ -381,65 +394,89 @@ public void loadFromODOL(BinaryReaderEx reader)
381394 }
382395
383396 reader . BaseStream . Seek ( 13 , SeekOrigin . Current ) ;
384- var stuff = reader . ReadUInt32 ( ) ;
385- reader . BaseStream . Seek ( stuff , SeekOrigin . Current ) ;
386-
387- /*
388397
389- var numPoints = reader.ReadUInt32();
390- reader.ReadByte();
391- if (numPoints != 0)
398+ var stuff = reader . ReadUInt32 ( ) ; //vertex table size, can jump directly to end
399+ if ( ! readPoints )
400+ {
401+ reader . BaseStream . Seek ( stuff , SeekOrigin . Current ) ;
402+ } else
392403 {
393- throw new NotImplementedException();
394- }
395404
405+ var numPoints = reader . ReadUInt32 ( ) ;
406+ if ( numPoints != 0 )
407+ {
408+ var b = reader . ReadByte ( ) ;
409+ var expectedDataSize = ( uint ) numPoints * 2 ;
410+ var stream = reader . ReadCompressed ( expectedDataSize ) ; // , b == 2
411+ }
396412
397- reader.BaseStream.Seek(16, SeekOrigin.Current); //uv limits
413+ reader . BaseStream . Seek ( 16 , SeekOrigin . Current ) ; //uv limits
398414
415+ var numUVs = reader . ReadUInt32 ( ) - 1 ;
416+ reader . ReadByte ( ) ;
417+ if ( numUVs != 0 )
418+ {
419+ //reader.ReadByte();
420+ reader . BaseStream . Seek ( 4 * numUVs , SeekOrigin . Current ) ; //uv limits
421+ }
399422
400- var numUVs = reader.ReadUInt32();
401- reader.ReadByte();
402- if (numUVs != 0)
403- {
404- reader.ReadByte();
405- reader.BaseStream.Seek(4*numUVs, SeekOrigin.Current); //uv limits
406- }
423+ var secondUV = reader . ReadUInt32 ( ) - 1 ;
407424
408- var secondUV = reader.ReadUInt32();
425+ if ( secondUV != 0 )
426+ {
427+ throw new NotImplementedException ( ) ;
428+ }
409429
410- if (secondUV != 0)
411- {
412- throw new NotImplementedException();
413- }
430+ var numPoints2 = reader . ReadUInt32 ( ) ;
431+ if ( numPoints2 != 0 )
432+ {
433+ var b = reader . ReadByte ( ) ;
434+ var expectedDataSize = ( uint ) numPoints2 * ( 3 * 4 ) ;
435+ var stream = reader . ReadCompressed ( expectedDataSize , b == 2 ) ;
414436
415- var numPoints2 = reader.ReadUInt32();
416- if (numPoints2 != 0)
417- reader.ReadByte();
418- for (int i = 0; i < numPoints2; i++)
419- {
420- reader.BaseStream.Seek((3*4 + 1)*numPoints2, SeekOrigin.Current);
421- }
437+ var streamB = new BinaryReaderEx ( new MemoryStream ( stream ) ) ;
422438
423- var numNormals = reader.ReadUInt32() ;
424- reader.ReadByte();
425- if (numNormals != 0)
426- reader.ReadByte();
427- for (int i = 0; i < numNormals; i++)
428- {
429- reader.BaseStream.Seek(4 * numNormals, SeekOrigin.Current);
430- }
439+ var array = new Vector3P [ numPoints2 ] ;
440+ for ( int i2 = 0 ; i2 < numPoints2 ; i2 ++ )
441+ array [ i2 ] = new Vector3P ( streamB . ReadSingle ( ) , streamB . ReadSingle ( ) , streamB . ReadSingle ( ) ) ;
442+
443+
444+ foreach ( KeyValuePair < string , List < UInt32 > > entry in tempSelections )
445+ {
446+ var selectionPoints = new List < Vector3P > ( entry . Value . Count ) ;
431447
448+ foreach ( UInt32 pointIndex in entry . Value )
449+ {
450+ selectionPoints . Add ( array [ pointIndex ] ) ;
451+ }
432452
433- reader.BaseStream.Seek(4, SeekOrigin.Current);
434- var numVertBone = reader.ReadUInt32();
435- if (numVertBone != 0)
453+
454+ selections . Add ( entry . Key , selectionPoints ) ;
455+ }
456+
457+
458+ }
459+ /*
460+ var numNormals = reader.ReadUInt32();
436461 reader.ReadByte();
462+ if (numNormals != 0)
463+ reader.ReadByte();
464+ for (int i = 0; i < numNormals; i++)
465+ {
466+ reader.BaseStream.Seek(4 * numNormals, SeekOrigin.Current);
467+ }
437468
438- for (int i = 0; i < numVertBone; i++)
439- {
440- reader.BaseStream.Seek(4 +(4*2), SeekOrigin.Current);
441- }*/
442469
470+ reader.BaseStream.Seek(4, SeekOrigin.Current);
471+ var numVertBone = reader.ReadUInt32();
472+ if (numVertBone != 0)
473+ reader.ReadByte();
474+
475+ for (int i = 0; i < numVertBone; i++)
476+ {
477+ reader.BaseStream.Seek(4 +(4*2), SeekOrigin.Current);
478+ }*/
479+ }
443480
444481 reader . BaseStream . Seek ( 4 + 4 + 1 , SeekOrigin . Current ) ;
445482
@@ -459,6 +496,18 @@ public float loadFromMLOD(BinaryReaderEx reader)
459496 var numNormals = reader . ReadUInt32 ( ) ;
460497 var numFaces = reader . ReadUInt32 ( ) ;
461498 reader . ReadUInt32 ( ) ;
499+
500+ List < Vector3P > pointList = new List < Vector3P > ( ( int ) numPoints ) ;
501+
502+ for ( int i = 0 ; i < numPoints ; i ++ )
503+ {
504+ var x = reader . ReadSingle ( ) ;
505+ var y = reader . ReadSingle ( ) ;
506+ var z = reader . ReadSingle ( ) ;
507+ var flags = reader . ReadUInt32 ( ) ;
508+ pointList . Add ( new Vector3P ( x , y , z ) ) ;
509+ }
510+
462511 reader . BaseStream . Seek ( numPoints * 16 , SeekOrigin . Current ) ;
463512 reader . BaseStream . Seek ( numNormals * 4 * 3 , SeekOrigin . Current ) ;
464513
@@ -494,6 +543,23 @@ public float loadFromMLOD(BinaryReaderEx reader)
494543 properties . Add ( key . ToLower ( ) , new Property ( value , valuePos ) ) ; //#TODO maybe we also want to keep a version with original casing?
495544 } else
496545 {
546+ if ( ! tagName . StartsWith ( "#" ) ) //It's a selection
547+ {
548+ var curPos = reader . BaseStream . Position ;
549+
550+ var points = new List < Vector3P > ( ) ;
551+
552+ for ( int i = 0 ; i < numPoints ; i ++ ) //Find the first point
553+ {
554+ if ( reader . ReadBoolean ( ) )
555+ {
556+ points . Add ( pointList [ i ] ) ;
557+ }
558+ }
559+ selections . Add ( tagName , points ) ;
560+ reader . BaseStream . Seek ( curPos + tagLen , SeekOrigin . Begin ) ;
561+ }
562+
497563 reader . BaseStream . Seek ( tagLen , SeekOrigin . Current ) ;
498564 }
499565 } while ( tagName != "#EndOfFile#" ) ; //tagName != "" &&
@@ -678,7 +744,6 @@ private void loadFromODOL(BinaryReaderEx reader)
678744 reader . BaseStream . Seek ( 16 , SeekOrigin . Current ) ;
679745 reader . BaseStream . Seek ( 4 , SeekOrigin . Current ) ; //#TODO only if >72
680746
681-
682747 reader . BaseStream . Seek ( 14
683748 + 4 + 1 , SeekOrigin . Current ) ; //#TODO only if >72
684749
@@ -693,9 +758,6 @@ private void loadFromODOL(BinaryReaderEx reader)
693758
694759 reader . BaseStream . Seek ( 12 * numLods , SeekOrigin . Current ) ;
695760
696-
697-
698-
699761 if ( reader . ReadByte ( ) != 0 )
700762 {
701763 skipAnimations ( reader ) ;
@@ -708,16 +770,13 @@ private void loadFromODOL(BinaryReaderEx reader)
708770 lodOffs [ i ] = reader . ReadUInt32 ( ) ;
709771 }
710772
711-
712-
713-
714773 reader . BaseStream . Seek ( numLods , SeekOrigin . Current ) ;
715774
716775 for ( int i = 0 ; i < numLods ; i ++ )
717776 {
718777 reader . BaseStream . Seek ( lodOffs [ i ] , SeekOrigin . Begin ) ;
719778 LOD x = new LOD ( ) ;
720- x . loadFromODOL ( reader ) ;
779+ x . loadFromODOL ( reader , Math . Abs ( lodResolutions [ i ] - 1e15f ) < 0.1 ) ;
721780 x . resolution = lodResolutions [ i ] ;
722781
723782 if ( lods . ContainsKey ( x . resolution ) )
0 commit comments