@@ -50,6 +50,82 @@ static String readString(File f)
50
50
return s;
51
51
}
52
52
53
+ static void readMatrix (File f, Matrix matrix)
54
+ {
55
+ int i;
56
+
57
+ for (i = 0 ; i < 16 ; i++)
58
+ {
59
+ float v;
60
+ f.Read (&v, sizeof (float ), 1 );
61
+ matrix.array [i] = (double )v;
62
+ }
63
+ }
64
+
65
+ static void readTCBEase (File f, FrameTrack track)
66
+ {
67
+ int i;
68
+
69
+ for (i = 0 ; i < track.numKeys ; i++)
70
+ {
71
+ f.Read (&track.keys [i].tension , sizeof (float ), 1 );
72
+ f.Read (&track.keys [i].continuity , sizeof (float ), 1 );
73
+ f.Read (&track.keys [i].bias , sizeof (float ), 1 );
74
+ f.Read (&track.keys [i].easeFrom , sizeof (float ), 1 );
75
+ f.Read (&track.keys [i].easeTo , sizeof (float ), 1 );
76
+ }
77
+ }
78
+
79
+ static void readFTKVector3Df (File f, FrameTrack track)
80
+ {
81
+ int i;
82
+
83
+ for (i = 0 ; i < track.numKeys ; i++)
84
+ f.Read (&track.keys [i].scaling .x , sizeof (float ), 3 );
85
+ }
86
+
87
+ static void readFTKQuaternionf (File f, FrameTrack track)
88
+ {
89
+ int i;
90
+
91
+ for (i = 0 ; i < track.numKeys ; i++)
92
+ {
93
+ Quaternion qd = track.keys [i].orientation ;
94
+ float q[4 ] = { (float )qd.w , (float )qd.x , (float )qd.y , (float )qd.z };
95
+ f.Read (q, sizeof (float ), 4 );
96
+ }
97
+ }
98
+
99
+ static void readFTKFloat (File f, FrameTrack track)
100
+ {
101
+ int i;
102
+
103
+ for (i = 0 ; i < track.numKeys ; i++)
104
+ f.Read (&track.keys [i].roll , sizeof (float ), 1 );
105
+ }
106
+
107
+ static void readFTKBool (File f, FrameTrack track)
108
+ {
109
+ int i;
110
+
111
+ for (i = 0 ; i < track.numKeys ; i++)
112
+ {
113
+ byte hide = bool ::false ;
114
+ f.Read (&hide, sizeof (byte ), 1 );
115
+ // track.keys[i].hide = hide; // TODO: no hide keys yet?
116
+ }
117
+ }
118
+
119
+ static void readFTKMorph (File f, FrameTrack track)
120
+ {
121
+ int i;
122
+
123
+ for (i = 0 ; i < track.numKeys ; i++)
124
+ {
125
+ // TODO:
126
+ }
127
+ }
128
+
53
129
#if defined(__GNOSIS3__)
54
130
TempFile downloadFile (const String url);
55
131
#else
@@ -170,6 +246,38 @@ static void readBlocks(E3DContext ctx, File f, DisplaySystem displaySystem, E3DB
170
246
readSubBlocks = true ;
171
247
break ;
172
248
}
249
+ case nodeID:
250
+ {
251
+ uint id = 0 ;
252
+ f.Read (&id, sizeof (uint ), 1 );
253
+ if (containerType == animationTrack)
254
+ {
255
+ FrameTrack track = (FrameTrack)data;
256
+ Object object = ctx.nodesByID [id];
257
+ if (object)
258
+ object.tracks ->Add (track);
259
+ else
260
+ {
261
+ PrintLn (" WARNING: Node not found for animation track" );
262
+ // delete track; // TODO: How to free this?
263
+ }
264
+ }
265
+ else if (object)
266
+ ctx.nodesByID [id] = object;
267
+ break ;
268
+ }
269
+ case nodeName:
270
+ {
271
+ Object p = object.parent ;
272
+ String name = readString (f);
273
+ if (p)
274
+ {
275
+ p.Remove (object);
276
+ p.AddName (object, name);
277
+ }
278
+ delete name;
279
+ break ;
280
+ }
173
281
case scaling:
174
282
{
175
283
Vector3Df v;
@@ -479,12 +587,21 @@ static void readBlocks(E3DContext ctx, File f, DisplaySystem displaySystem, E3DB
479
587
int nVertices = mesh.nVertices ;
480
588
// bool qVerts = false;
481
589
uint vSize = 0 ;
482
- uint vOffset = 0 , nOffset = 0 , t1Offset = 0 , t2Offset = 0 , tnOffset = 0 , cOffset = 0 ;
590
+ uint vOffset = 0 , nOffset = 0 , t1Offset = 0 , t2Offset = 0 , tnOffset = 0 , cOffset = 0 , bOffset = 0 ;
483
591
bool signBitan = false ;
592
+ bool lastWasBones = false ;
593
+ uint maxBones = 0 ;
594
+ MeshSkin skin = null ;
595
+
484
596
while (pos < bEnd && f.Read (&type, sizeof (E3DBlockType), 1 ))
485
597
{
486
598
uint16 offset = 0 ;
487
599
f.Read (&offset, sizeof (uint16 ), 1 );
600
+ if (lastWasBones)
601
+ {
602
+ maxBones = (offset - bOffset) / 2 ;
603
+ lastWasBones = false ;
604
+ }
488
605
pos += 4 ;
489
606
if (!type)
490
607
{
@@ -501,8 +618,16 @@ static void readBlocks(E3DContext ctx, File f, DisplaySystem displaySystem, E3DB
501
618
case attrColors: features.colors = true ; cOffset = offset; break ;
502
619
case attrTangentsSign: features.tangents = true ; tnOffset = offset; signBitan = true ; break ;
503
620
case attrTangentsBT: features.tangents = true ; tnOffset = offset; break ;
621
+ case attrBoneWeights:
622
+ // features.bones = true;
623
+ bOffset = offset;
624
+ lastWasBones = true ;
625
+ skin = { };
626
+ skin.skinVerts .size = nVertices;
627
+ break ;
504
628
}
505
629
}
630
+ mesh.skin = skin;
506
631
allocedFeatures = features;
507
632
allocedFeatures.vertices = true ;
508
633
if (allocedFeatures == { vertices = true , normals = true , texCoords1 = true })
@@ -514,6 +639,7 @@ static void readBlocks(E3DContext ctx, File f, DisplaySystem displaySystem, E3DB
514
639
Vector3Df * vertex = null , * normal = null , * tangent = null , * bitangent = null ;
515
640
Pointf * texCoord = null , * texCoord2 = null ;
516
641
ColorRGBAf * color = null ;
642
+ SkinVert * bones = null ;
517
643
int i;
518
644
519
645
if (allocedFeatures.interleaved )
@@ -533,7 +659,8 @@ static void readBlocks(E3DContext ctx, File f, DisplaySystem displaySystem, E3DB
533
659
if (!signBitan && features.tangents ) bitangent = mesh.tangents +1 ;
534
660
if (features.texCoords1 ) texCoord = (Pointf*)((byte *)mesh.texCoords );
535
661
// if(features.texCoords2) texCoord2 = (Pointf*)((byte *)mesh.texCoords2);
536
- if (features.colors ) color = (ColorRGBAf*)((byte *)mesh.colors + cOffset);
662
+ if (features.colors ) color = (ColorRGBAf*)((byte *)mesh.colors /* + cOffset*/ ); // REVIEW: cOffset here?
663
+ if (skin /* features.bones*/ ) bones = skin.skinVerts .array ;
537
664
}
538
665
539
666
for (i = 0 ; i < nVertices; i++)
@@ -561,6 +688,12 @@ static void readBlocks(E3DContext ctx, File f, DisplaySystem displaySystem, E3DB
561
688
f.Seek (vStart + cOffset, start), f.Read (&c, sizeof (uint32 ), 1 );
562
689
*color = { c.r /255 .0f , c.g /255 .0f , c.b /255 .0f , c.a /255 .0f };
563
690
}
691
+ if (skin) // features.bones)
692
+ {
693
+ f.Seek (vStart + bOffset, start);
694
+ f.Read (bones->bones , sizeof (byte ), maxBones); // Asuming maxBones is 10 for now
695
+ f.Read (bones->weights , sizeof (byte ), maxBones);
696
+ }
564
697
if (tangent)
565
698
{
566
699
uint32 t, bt;
@@ -578,6 +711,7 @@ static void readBlocks(E3DContext ctx, File f, DisplaySystem displaySystem, E3DB
578
711
if (texCoord2)texCoord2= (void *)((byte *)texCoord2+ (loadIL ? 32 : 8 ));
579
712
if (tangent) tangent = (void *)((byte *)tangent + (loadIL ? 32 : signBitan ? 12 : 24 ));
580
713
if (bitangent)bitangent= (void *)((byte *)bitangent+ (loadIL ? 32 : 24 ));
714
+ if (bones) bones = bones + 1 ;
581
715
}
582
716
}
583
717
break ;
@@ -719,6 +853,93 @@ static void readBlocks(E3DContext ctx, File f, DisplaySystem displaySystem, E3DB
719
853
mesh.FreePrimitiveGroup (group);
720
854
break ;
721
855
}
856
+ case meshDuplVerts:
857
+ {
858
+ // PrintLn("Duplicate Vertices!");
859
+ break ;
860
+ }
861
+ case skin:
862
+ readSubBlocks = true ;
863
+ break ;
864
+ case skinBindMatrix:
865
+ {
866
+ MeshSkin skin = mesh.skin ;
867
+
868
+ readMatrix (f, skin.bindShapeMatrix );
869
+ skin.bsIsIdentity = skin.bindShapeMatrix .isIdentity ();
870
+ if (skin.bsIsIdentity )
871
+ skin.invShape .Identity ();
872
+ else
873
+ skin.invShape .Inverse (skin.bindShapeMatrix );
874
+ break ;
875
+ }
876
+ case skinBones:
877
+ {
878
+ byte count;
879
+ int i;
880
+ MeshSkin skin = mesh.skin ;
881
+ Array<SkinBone> bones = skin.bones ;
882
+
883
+ f.Read (&count, sizeof (byte ), 1 );
884
+ bones.size = count;
885
+
886
+ for (i = 0 ; i < count; i++)
887
+ {
888
+ bones[i].name = readString (f); // Could also be nodeID
889
+ readMatrix (f, bones[i].invBindMatrix );
890
+ bones[i].bsInvBindMatrix .Multiply (skin.bindShapeMatrix , bones[i].invBindMatrix );
891
+ }
892
+ break ;
893
+ }
894
+ case animations: readSubBlocks = true ; break ;
895
+ case animation: readSubBlocks = true ; break ;
896
+ case animationName:
897
+ break ;
898
+ case animationFrames:
899
+ {
900
+ int frame;
901
+ f.Read (&frame, sizeof (int ), 1 );
902
+ object.startFrame = frame;
903
+ f.Read (&frame, sizeof (int ), 1 );
904
+ object.endFrame = frame;
905
+ f.Read (&frame, sizeof (int ), 1 );
906
+ object.frame = frame;
907
+ break ;
908
+ }
909
+ case animationTrack:
910
+ {
911
+ uint loop;
912
+ FrameTrack track { };
913
+ int i;
914
+
915
+ f.Read (&track.numKeys , sizeof (uint ), 1 );
916
+ pos += 4 ;
917
+ f.Read (&loop, sizeof (byte ), 1 );
918
+ pos ++;
919
+ track.type .loop = loop != 0 ;
920
+ track.keys = new0 FrameKey[track.numKeys ];
921
+ for (i = 0 ; i < track.numKeys ; i++)
922
+ f.Read (&track.keys [i].frame , sizeof (uint ), 1 );
923
+ pos += sizeof (uint ) * track.numKeys ;
924
+
925
+ readSubBlocks = true ;
926
+ subData = track;
927
+ break ;
928
+ }
929
+ case frameTCBEase: { FrameTrack track = (FrameTrack) data; readTCBEase (f, track); break ; }
930
+ case ftkPosition: { FrameTrack track = (FrameTrack) data; track.type .type = position; readFTKVector3Df (f, track); break ; }
931
+ case ftkScaling: { FrameTrack track = (FrameTrack) data; track.type .type = scaling; readFTKVector3Df (f, track); break ; }
932
+ case ftkRotation: { FrameTrack track = (FrameTrack) data; track.type .type = rotation; readFTKQuaternionf (f, track); break ; }
933
+ case ftkYaw: { FrameTrack track = (FrameTrack) data; track.type .type = rYaw; readFTKFloat (f, track); break ; }
934
+ case ftkPitch: { FrameTrack track = (FrameTrack) data; track.type .type = rPitch; readFTKFloat (f, track); break ; }
935
+ case ftkRoll: { FrameTrack track = (FrameTrack) data; track.type .type = rRoll; readFTKFloat (f, track); break ; }
936
+ case ftkCameraFieldOfView: { FrameTrack track = (FrameTrack) data; track.type .type = fov; readFTKFloat (f, track); break ; }
937
+ case ftkCameraRoll: { FrameTrack track = (FrameTrack) data; track.type .type = roll; readFTKFloat (f, track); break ; }
938
+ case ftkLightHotSpot: { FrameTrack track = (FrameTrack) data; track.type .type = hotSpot; readFTKFloat (f, track); break ; }
939
+ case ftkLightFallOff: { FrameTrack track = (FrameTrack) data; track.type .type = fallOff; readFTKFloat (f, track); break ; }
940
+ case ftkLightColor: { FrameTrack track = (FrameTrack) data; track.type .type = colorChange; readFTKVector3Df (f, track); break ; }
941
+ case ftkHide: { FrameTrack track = (FrameTrack) data; track.type .type = hide; readFTKBool (f, track); break ; }
942
+ case ftkMorph: { FrameTrack track = (FrameTrack) data; track.type .type = morph; readFTKMorph (f, track); break ; }
722
943
case parts:
723
944
{
724
945
uint nParts = (uint )((bEnd - pos) / sizeof (MeshPart));
@@ -955,6 +1176,26 @@ void listTexturesReadBlocks(E3DContext ctx, File f, E3DBlockType containerType,
955
1176
indent--;
956
1177
}
957
1178
1179
+ static void resolveBones (Object root, Object object)
1180
+ {
1181
+ Object c;
1182
+ if (object.mesh && object.mesh .skin )
1183
+ {
1184
+ int i;
1185
+
1186
+ for (i = 0 ; i < object.mesh .skin .bones .count ; i++)
1187
+ {
1188
+ SkinBone * bone = &object.mesh .skin .bones [i];
1189
+ String name = bone->name ;
1190
+ Object o = root.Find (name);
1191
+ bone->object = o;
1192
+ }
1193
+ }
1194
+
1195
+ for (c = object.firstChild ; c; c = c.next )
1196
+ resolveBones (root, c);
1197
+ }
1198
+
958
1199
void readE3D (File f, const String fileName, Object object, DisplaySystem displaySystem, E3DOptions options)
959
1200
{
960
1201
char path[MAX_LOCATION];
@@ -983,6 +1224,7 @@ void readE3D(File f, const String fileName, Object object, DisplaySystem display
983
1224
984
1225
StripLastDirectory (fileName, path);
985
1226
readBlocks (ctx, f, displaySystem, 0 , 0 , f.GetSize (), object);
1227
+ resolveBones (object, object);
986
1228
987
1229
if (freeTexturesByID)
988
1230
delete ctx.texturesByID ;
0 commit comments