|
@@ -716,6 +716,72 @@ struct AnimDispatch_t {
|
716
|
716
|
: low(l), high(h), nextAnimation(na), nextFrame(nf) { }
|
717
|
717
|
};
|
718
|
718
|
|
|
719
|
+void LoaderTR2::loadAngleSet(BoneFrame* bf, BinaryReader& frame, uint16_t numMeshes,
|
|
720
|
+ uint16_t startingMesh, uint32_t meshTree,
|
|
721
|
+ uint32_t numMeshTrees, std::vector<int32_t> meshTrees) {
|
|
722
|
+ for (int i = 0; i < numMeshes; i++) {
|
|
723
|
+ int mesh = startingMesh + i;
|
|
724
|
+ glm::vec3 offset(0.0f, 0.0f, 0.0f);
|
|
725
|
+ float rotation[3] = { 0.0f, 0.0f, 0.0f };
|
|
726
|
+ char flag = (i == 0) ? 2 : 0;
|
|
727
|
+
|
|
728
|
+ // Nonprimary tag - positioned relative to first tag
|
|
729
|
+ if (i != 0) {
|
|
730
|
+ char* tmp = reinterpret_cast<char*>(&meshTrees[0]) + meshTree; // TODO (meshTree * 4)?
|
|
731
|
+ tmp += (i - 1) * 16; // TODO ?
|
|
732
|
+ BinaryMemory tree(tmp, (numMeshTrees * 4) - meshTree - ((i - 1) * 16));
|
|
733
|
+ flag = (char)tree.readU32();
|
|
734
|
+ offset.x = tree.read32();
|
|
735
|
+ offset.y = tree.read32();
|
|
736
|
+ offset.z = tree.read32();
|
|
737
|
+
|
|
738
|
+ uint16_t a = frame.readU16();
|
|
739
|
+ if (a & 0xC000) {
|
|
740
|
+ // Single angle
|
|
741
|
+ int index = 0;
|
|
742
|
+ if ((a & 0x8000) && (a & 0x4000))
|
|
743
|
+ index = 2;
|
|
744
|
+ else if (a & 0x4000)
|
|
745
|
+ index = 1;
|
|
746
|
+ rotation[index] = ((float)(a & 0x03FF)) * 360.0f / 1024.0f;
|
|
747
|
+ } else {
|
|
748
|
+ // Three angles
|
|
749
|
+ uint16_t b = frame.readU16();
|
|
750
|
+ rotation[0] = (a & 0x3FF0) >> 4;
|
|
751
|
+ rotation[1] = ((a & 0x000F) << 6) | ((b & 0xFC00) >> 10);
|
|
752
|
+ rotation[2] = b & 0x03FF;
|
|
753
|
+ for (int i = 0; i < 3; i++)
|
|
754
|
+ rotation[i] = rotation[i] * 360.0f / 1024.0f;
|
|
755
|
+ }
|
|
756
|
+ }
|
|
757
|
+
|
|
758
|
+ glm::vec3 rot(rotation[0], rotation[1], rotation[2]);
|
|
759
|
+ BoneTag* bt = new BoneTag(mesh, offset, rot, flag);
|
|
760
|
+ bf->add(bt);
|
|
761
|
+ }
|
|
762
|
+}
|
|
763
|
+
|
|
764
|
+BoneFrame* LoaderTR2::loadFrame(BinaryReader& frame, uint16_t numMeshes,
|
|
765
|
+ uint16_t startingMesh, uint32_t meshTree,
|
|
766
|
+ uint32_t numMeshTrees, std::vector<int32_t> meshTrees) {
|
|
767
|
+ int16_t bb1x = frame.read16();
|
|
768
|
+ int16_t bb1y = frame.read16();
|
|
769
|
+ int16_t bb1z = frame.read16();
|
|
770
|
+ int16_t bb2x = frame.read16();
|
|
771
|
+ int16_t bb2y = frame.read16();
|
|
772
|
+ int16_t bb2z = frame.read16();
|
|
773
|
+
|
|
774
|
+ glm::vec3 pos;
|
|
775
|
+ pos.x = frame.read16();
|
|
776
|
+ pos.y = frame.read16();
|
|
777
|
+ pos.z = frame.read16();
|
|
778
|
+
|
|
779
|
+ BoneFrame* bf = new BoneFrame(pos);
|
|
780
|
+ loadAngleSet(bf, frame, numMeshes, startingMesh, meshTree, numMeshTrees, meshTrees);
|
|
781
|
+
|
|
782
|
+ return bf;
|
|
783
|
+}
|
|
784
|
+
|
719
|
785
|
void LoaderTR2::loadMoveables() {
|
720
|
786
|
uint32_t numAnimations = file.readU32();
|
721
|
787
|
std::vector<Animation_t> animations;
|
|
@@ -862,70 +928,43 @@ void LoaderTR2::loadMoveables() {
|
862
|
928
|
// animated by the engine (ponytail)
|
863
|
929
|
uint16_t animation = file.readU16();
|
864
|
930
|
|
865
|
|
- // TODO load all animations, not only the first frame!
|
866
|
|
- //if (animation == 0xFFFF) {
|
867
|
|
-
|
868
|
|
- // Just add the frame indicated in frameOffset, nothing else
|
869
|
|
- char* tmp = reinterpret_cast<char*>(&frames[0]) + frameOffset;
|
870
|
|
- BinaryMemory frame(tmp + 12, (numFrames * 2) - frameOffset - 12); // skip two BBs
|
871
|
|
- glm::vec3 pos;
|
872
|
|
- pos.x = frame.read16();
|
873
|
|
- pos.y = frame.read16();
|
874
|
|
- pos.z = frame.read16();
|
875
|
|
- // TODO frame data format different for TR1!
|
876
|
|
- BoneFrame* bf = new BoneFrame(pos);
|
877
|
|
-
|
878
|
|
- for (int i = 0; i < numMeshes; i++) {
|
879
|
|
- int mesh = startingMesh + i;
|
880
|
|
- glm::vec3 offset;
|
881
|
|
- float rotation[3] = { 0.0f, 0.0f, 0.0f };
|
882
|
|
- char flag = (i == 0) ? 2 : 0;
|
883
|
|
-
|
884
|
|
- // Nonprimary tag - positioned relative to first tag
|
885
|
|
- if (i != 0) {
|
886
|
|
- tmp = reinterpret_cast<char*>(&meshTrees[0]) + meshTree; // TODO (meshTree * 4)?
|
887
|
|
- tmp += (i - 1) * 16; // TODO ?
|
888
|
|
- BinaryMemory tree(tmp, (numMeshTrees * 4) - meshTree - ((i - 1) * 16));
|
889
|
|
- flag = (char)tree.readU32();
|
890
|
|
- offset.x = tree.read32();
|
891
|
|
- offset.y = tree.read32();
|
892
|
|
- offset.z = tree.read32();
|
893
|
|
-
|
894
|
|
- uint16_t a = frame.readU16();
|
895
|
|
- if (a & 0xC000) {
|
896
|
|
- // Single angle
|
897
|
|
- int index = 0;
|
898
|
|
- if ((a & 0x8000) && (a & 0x4000))
|
899
|
|
- index = 2;
|
900
|
|
- else if (a & 0x4000)
|
901
|
|
- index = 1;
|
902
|
|
- rotation[index] = ((float)(a & 0x03FF)) * 360.0f / 1024.0f;
|
903
|
|
- } else {
|
904
|
|
- // Three angles
|
905
|
|
- uint16_t b = frame.readU16();
|
906
|
|
- rotation[0] = (a & 0x3FF0) >> 4;
|
907
|
|
- rotation[1] = ((a & 0x000F) << 6) | ((b & 0xFC00) >> 10);
|
908
|
|
- rotation[2] = b & 0x03FF;
|
909
|
|
- for (int i = 0; i < 3; i++)
|
910
|
|
- rotation[i] = rotation[i] * 360.0f / 1024.0f;
|
911
|
|
- }
|
|
931
|
+ /*
|
|
932
|
+ if (animation == 0xFFFF) {
|
|
933
|
+ */
|
|
934
|
+ // Just add the frame indicated in frameOffset, nothing else
|
|
935
|
+ char* tmp = reinterpret_cast<char*>(&frames[0]) + frameOffset;
|
|
936
|
+ BinaryMemory frame(tmp, (numFrames * 2) - frameOffset);
|
|
937
|
+
|
|
938
|
+ if (((numFrames * 2) - frameOffset) <= 0)
|
|
939
|
+ continue; // TR1/LEVEL3A crashes without this?!
|
|
940
|
+
|
|
941
|
+ BoneFrame* bf = loadFrame(frame, numMeshes, startingMesh, meshTree, numMeshTrees, meshTrees);
|
|
942
|
+ AnimationFrame* af = new AnimationFrame(0);
|
|
943
|
+ af->add(bf);
|
|
944
|
+
|
|
945
|
+ SkeletalModel* sm = new SkeletalModel(objectID);
|
|
946
|
+ sm->add(af);
|
|
947
|
+ getWorld().addSkeletalModel(sm);
|
|
948
|
+ /*
|
|
949
|
+ } else {
|
|
950
|
+ // TODO Add the whole animation hierarchy
|
|
951
|
+ auto& anim = animations.at(animation);
|
|
952
|
+
|
|
953
|
+ char* tmp = reinterpret_cast<char*>(&frames[0]) + anim.frameOffset;
|
|
954
|
+ BinaryMemory frame(tmp, (numFrames * 2) - anim.frameOffset);
|
|
955
|
+ AnimationFrame* af = new AnimationFrame(0);
|
|
956
|
+
|
|
957
|
+ for (int i = 0; i < ((anim.frameEnd - anim.frameStart) + 1); i++) {
|
|
958
|
+ BoneFrame* bf = loadFrame(frame, numMeshes, startingMesh,
|
|
959
|
+ meshTree, numMeshTrees, meshTrees);
|
|
960
|
+ af->add(bf);
|
912
|
961
|
}
|
913
|
962
|
|
914
|
|
- glm::vec3 rot(rotation[0], rotation[1], rotation[2]);
|
915
|
|
- BoneTag* bt = new BoneTag(mesh, offset, rot, flag);
|
916
|
|
- bf->add(bt);
|
|
963
|
+ SkeletalModel* sm = new SkeletalModel(objectID);
|
|
964
|
+ sm->add(af);
|
|
965
|
+ getWorld().addSkeletalModel(sm);
|
917
|
966
|
}
|
918
|
|
-
|
919
|
|
- AnimationFrame* af = new AnimationFrame(0);
|
920
|
|
- af->add(bf);
|
921
|
|
-
|
922
|
|
- SkeletalModel* sm = new SkeletalModel(objectID);
|
923
|
|
- sm->add(af);
|
924
|
|
- getWorld().addSkeletalModel(sm);
|
925
|
|
-
|
926
|
|
- //} else {
|
927
|
|
- // Add the whole animation hierarchy
|
928
|
|
- //}
|
|
967
|
+ */
|
929
|
968
|
}
|
930
|
969
|
|
931
|
970
|
if (numMoveables > 0)
|