Browse Source

Small fixes for TR1 moveable parsing

Thomas Buck 9 years ago
parent
commit
ae5868b708
5 changed files with 158 additions and 61 deletions
  1. 3
    0
      ChangeLog.md
  2. 3
    0
      include/loader/LoaderTR1.h
  3. 8
    0
      include/loader/LoaderTR2.h
  4. 44
    0
      src/loader/LoaderTR1.cpp
  5. 100
    61
      src/loader/LoaderTR2.cpp

+ 3
- 0
ChangeLog.md View File

@@ -2,6 +2,9 @@
2 2
 
3 3
 ## OpenRaider (0.1.3) xythobuz <xythobuz@xythobuz.de>
4 4
 
5
+    [ 20140310 ]
6
+    * Tried to fix moveable loading. Fixed TR1 angle parser, but still not working better.
7
+
5 8
     [ 20140309 ]
6 9
     * Removed (unused) SSE support script
7 10
     * Added level loading notification in main menu

+ 3
- 0
include/loader/LoaderTR1.h View File

@@ -26,6 +26,9 @@ class LoaderTR1 : public LoaderTR2 {
26 26
     virtual void loadSoundSamples();
27 27
 
28 28
     virtual int getPaletteIndex(uint16_t index);
29
+    virtual void loadAngleSet(BoneFrame* bf, BinaryReader& frame, uint16_t numMeshes,
30
+                              uint16_t startingMesh, uint32_t meshTree,
31
+                              uint32_t numMeshTrees, std::vector<int32_t> meshTrees);
29 32
 };
30 33
 
31 34
 #endif

+ 8
- 0
include/loader/LoaderTR2.h View File

@@ -13,6 +13,8 @@
13 13
 
14 14
 #include "RoomData.h"
15 15
 #include "RoomMesh.h"
16
+#include "SkeletalModel.h"
17
+#include "utils/binary.h"
16 18
 #include "loader/Loader.h"
17 19
 
18 20
 class LoaderTR2 : public Loader {
@@ -51,6 +53,12 @@ class LoaderTR2 : public Loader {
51 53
     virtual int loadSoundFiles(BinaryReader& sfx, unsigned int count = 0);
52 54
 
53 55
     virtual int getPaletteIndex(uint16_t index);
56
+    virtual void loadAngleSet(BoneFrame* bf, BinaryReader& frame, uint16_t numMeshes,
57
+                              uint16_t startingMesh, uint32_t meshTree,
58
+                              uint32_t numMeshTrees, std::vector<int32_t> meshTrees);
59
+    virtual BoneFrame* loadFrame(BinaryReader& frame, uint16_t numMeshes,
60
+                                 uint16_t startingMesh, uint32_t meshTree,
61
+                                 uint32_t numMeshTrees, std::vector<int32_t> meshTrees);
54 62
 };
55 63
 
56 64
 #endif

+ 44
- 0
src/loader/LoaderTR1.cpp View File

@@ -283,3 +283,47 @@ int LoaderTR1::getPaletteIndex(uint16_t index) {
283 283
     return index;
284 284
 }
285 285
 
286
+void LoaderTR1::loadAngleSet(BoneFrame* bf, BinaryReader& frame, uint16_t numMeshes,
287
+                             uint16_t startingMesh, uint32_t meshTree,
288
+                             uint32_t numMeshTrees, std::vector<int32_t> meshTrees) {
289
+    /*! \fixme
290
+     * The TR Rosetta Stone documentation says:
291
+     *     number of angle sets to follow;
292
+     *     these start with the first mesh, and meshes
293
+     *     without angles get zero angles.
294
+     * I'm not sure what this means. This code may be wrong.
295
+     */
296
+    uint16_t numValues = frame.readU16();
297
+
298
+    for (int i = 0; i < numValues; i++) {
299
+        int mesh = startingMesh + i;
300
+        glm::vec3 offset(0.0f, 0.0f, 0.0f);
301
+        float rotation[3] = { 0.0f, 0.0f, 0.0f };
302
+        char flag = (i == 0) ? 2 : 0;
303
+
304
+        // Nonprimary tag - positioned relative to first tag
305
+        if (i != 0) {
306
+            char* tmp = reinterpret_cast<char*>(&meshTrees[0]) + meshTree; // TODO (meshTree * 4)?
307
+            tmp += (i - 1) * 16; // TODO ?
308
+            BinaryMemory tree(tmp, (numMeshTrees * 4) - meshTree - ((i - 1) * 16));
309
+
310
+            flag = (char)tree.readU32();
311
+            offset.x = tree.read32();
312
+            offset.y = tree.read32();
313
+            offset.z = tree.read32();
314
+
315
+            uint16_t b = frame.readU16();
316
+            uint16_t a = frame.readU16();
317
+            rotation[0] = (a & 0x3FF0) >> 4;
318
+            rotation[1] = ((a & 0x000F) << 6) | ((b & 0xFC00) >> 10);
319
+            rotation[2] = b & 0x03FF;
320
+            for (int i = 0; i < 3; i++)
321
+                rotation[i] = rotation[i] * 360.0f / 1024.0f;
322
+        }
323
+
324
+        glm::vec3 rot(rotation[0], rotation[1], rotation[2]);
325
+        BoneTag* bt = new BoneTag(mesh, offset, rot, flag);
326
+        bf->add(bt);
327
+    }
328
+}
329
+

+ 100
- 61
src/loader/LoaderTR2.cpp View File

@@ -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)

Loading…
Cancel
Save