|
2 | 2 |
|
3 | 3 | #include <map> |
4 | 4 | #include <memory> |
5 | | -#include "../lib/bStream/bstream.h" |
| 5 | +#include <bstream.h> |
| 6 | +#include <vector> |
| 7 | +#include "Util.hpp" |
6 | 8 | #include "io/KeyframeIO.hpp" |
7 | 9 |
|
8 | | -enum class GXAttribute : int { |
9 | | - PositionMatrixIndex, |
10 | | - Tex0MatrixIndex, |
11 | | - Tex1MatrixIndex, |
12 | | - Tex2MatrixIndex, |
13 | | - Tex3MatrixIndex, |
14 | | - Tex4MatrixIndex, |
15 | | - Tex5MatrixIndex, |
16 | | - Tex6MatrixIndex, |
17 | | - Tex7MatrixIndex, |
18 | | - Position, |
19 | | - Normal, |
20 | | - Color0, |
21 | | - Color1, |
22 | | - Tex0, |
23 | | - Tex1, |
24 | | - Tex2, |
25 | | - Tex3, |
26 | | - Tex4, |
27 | | - Tex5, |
28 | | - Tex6, |
29 | | - Tex7, |
30 | | - PositionMatrixArray, |
31 | | - NormalMatrixArray, |
32 | | - TextureMatrixArray, |
33 | | - LitMatrixArray, |
34 | | - NormalBinormalTangent, |
35 | | - NullAttr = 0xFF |
36 | | -}; |
37 | | - |
38 | | -enum GXPrimitiveType { |
39 | | - Points = 0xB8, |
40 | | - Lines = 0xA8, |
41 | | - LineStrip = 0xB0, |
42 | | - Triangles = 0x90, |
43 | | - TriangleStrip = 0x98, |
44 | | - TriangleFan = 0xA0, |
45 | | - Quads = 0x80, |
46 | | - PrimitiveNone = 0x00 |
47 | | -}; |
48 | | - |
49 | | -class BinMaterial { |
50 | | - uint32_t mTexture; |
51 | | - uint8_t mWrap; |
52 | | - |
53 | | -public: |
54 | | - |
55 | | - static void DecodeCMPR(bStream::CStream* stream, uint16_t width, uint16_t height, uint8_t* imageData); |
56 | | - static void DecodeRGB5A3(bStream::CStream* stream, uint16_t width, uint16_t height, uint8_t* imageData); |
57 | | - static void DecodeRGB565(bStream::CStream* stream, uint16_t width, uint16_t height, uint8_t* imageData); |
58 | | - |
59 | | - static uint8_t* DecodeCMPRSubBlock(bStream::CStream* stream); |
60 | | - static uint32_t RGB565toRGBA8(uint16_t data); |
61 | | - static uint32_t RGB5A3toRGBA8(uint16_t data); |
62 | | - |
63 | | - void Bind(); |
64 | | - BinMaterial(bStream::CStream* stream, uint32_t textureOffset); |
65 | | - ~BinMaterial(); |
66 | | -}; |
67 | | - |
68 | | -class BinSampler { |
69 | | - |
70 | | -public: |
71 | | - glm::vec4 mAmbientColor; |
72 | | - uint16_t mTextureID; |
73 | | - BinSampler(bStream::CStream* stream); |
74 | | - BinSampler(){} |
75 | | - ~BinSampler(){} |
76 | | -}; |
77 | | - |
78 | | -class BinMesh { |
79 | | - uint32_t mVbo; |
80 | | - uint32_t mVao; |
81 | | - |
82 | | -public: |
83 | | - uint32_t mVertexCount; |
84 | | - |
85 | | - void Bind(); |
86 | | - |
87 | | - BinMesh(bStream::CStream* stream, uint32_t offset, std::vector<glm::vec3>& vertexData, std::vector<glm::vec2>& texcoordData); |
88 | | - |
89 | | - BinMesh(){} |
90 | | - ~BinMesh(); |
91 | | - |
92 | | -}; |
93 | | - |
94 | | -struct BinAnimInfo { |
95 | | - bool mLoop { 0 }; |
96 | | - bool mPlaying { false }; |
97 | | - bool mLoaded { false }; |
98 | | - float mCurrentFrame { 0.0f }; // float so that we can change speed more easily |
99 | | - float mPlaybackSpeed { 0.5f }; |
100 | | - uint32_t mFrameCount { 0 }; |
101 | | -}; |
102 | | - |
103 | | -class BinModel; |
104 | | - |
105 | | -class BinScenegraphNode { |
106 | | - friend BinModel; |
107 | | - std::vector<std::pair<int16_t, int16_t>> meshes; |
108 | | - |
109 | | - void LoadNodeTracks(bStream::CStream* stream, uint32_t& idx, uint32_t groupOffset, uint32_t scaleKeysOffset, uint32_t rotateKeysOffset, uint32_t translateKeysOffset); |
110 | | - |
111 | | - uint32_t mNextScaleKeyX { 1 }; |
112 | | - uint32_t mNextScaleKeyY { 1 }; |
113 | | - uint32_t mNextScaleKeyZ { 1 }; |
114 | | - LTrackCommon mXScaleTrack; |
115 | | - LTrackCommon mYScaleTrack; |
116 | | - LTrackCommon mZScaleTrack; |
117 | | - |
118 | | - uint32_t mNextRotKeyX { 1 }; |
119 | | - uint32_t mNextRotKeyY { 1 }; |
120 | | - uint32_t mNextRotKeyZ { 1 }; |
121 | | - LTrackCommon mXRotTrack; |
122 | | - LTrackCommon mYRotTrack; |
123 | | - LTrackCommon mZRotTrack; |
| 10 | +namespace BIN { |
| 11 | + |
| 12 | + struct AnimInfo { |
| 13 | + bool mLoop { 0 }; |
| 14 | + bool mPlaying { false }; |
| 15 | + bool mLoaded { false }; |
| 16 | + float mCurrentFrame { 0.0f }; // float so that we can change speed more easily |
| 17 | + float mPlaybackSpeed { 0.5f }; |
| 18 | + uint32_t mFrameCount { 0 }; |
| 19 | + }; |
| 20 | + |
| 21 | + #pragma pack(push, 1) |
| 22 | + struct Header { |
| 23 | + uint8_t Version; |
| 24 | + std::string Name; |
| 25 | + uint32_t TextureOffset; // 0 |
| 26 | + uint32_t SamplerOffset; // 1 |
| 27 | + uint32_t PositionOffset; // 2 |
| 28 | + uint32_t NormalOffset; // 3 |
| 29 | + uint32_t Color0Offset; // 4 |
| 30 | + uint32_t Color1Offest; // 5 |
| 31 | + uint32_t TexCoord0Offset; // 6 |
| 32 | + uint32_t TexCoord1Offset; // 7 |
| 33 | + uint32_t UnknownOffsets[2]; // 8, 9 |
| 34 | + uint32_t MaterialOffset; // 10 |
| 35 | + uint32_t BatchOffset; // 11 |
| 36 | + uint32_t SceneGraphOffset; // 12 |
| 37 | + }; |
| 38 | + #pragma pack(pop) |
| 39 | + |
| 40 | + struct DrawElement : Readable { |
| 41 | + int16_t MaterialIndex, BatchIndex; |
| 42 | + |
| 43 | + void Read(bStream::CStream* stream) override; |
| 44 | + }; |
| 45 | + |
| 46 | + struct TextureHeader : Readable { |
| 47 | + uint16_t Width; |
| 48 | + uint16_t Height; |
| 49 | + uint8_t Format; |
| 50 | + uint16_t Unknown; |
| 51 | + |
| 52 | + uint32_t ImageOffset; |
| 53 | + uint32_t TextureID { UINT32_MAX }; // Bind this for rendering |
| 54 | + uint8_t* ImageData; |
| 55 | + |
| 56 | + void Read(bStream::CStream* stream) override; |
| 57 | + void Write(bStream::CStream* stream); |
| 58 | + void Save(bStream::CStream* stream); |
| 59 | + void Load(bStream::CStream* stream); |
| 60 | + |
| 61 | + void Destroy(); |
| 62 | + }; |
| 63 | + |
| 64 | + struct Sampler : Readable { |
| 65 | + int16_t TextureIndex; |
| 66 | + uint16_t PaletteIndex; |
| 67 | + uint8_t WrapU; |
| 68 | + uint8_t WrapV; |
| 69 | + uint16_t Unk; |
| 70 | + |
| 71 | + void Read(bStream::CStream* stream) override; |
| 72 | + void Write(bStream::CStream* stream); |
| 73 | + }; |
| 74 | + |
| 75 | + struct Material : Readable { |
| 76 | + uint8_t LightEnabled; |
| 77 | + uint8_t Unk0, Unk1; |
| 78 | + glm::vec4 Color; |
| 79 | + int16_t SamplerIndices[8]; |
| 80 | + //uint16_t Unk2, Unk3; |
| 81 | + |
| 82 | + void Read(bStream::CStream* stream) override; |
| 83 | + void Write(bStream::CStream* stream); |
| 84 | + }; |
| 85 | + |
| 86 | + struct Primitive { |
| 87 | + uint8_t Opcode; |
| 88 | + std::vector<Vertex> Vertices; |
| 89 | + }; |
| 90 | + |
| 91 | + struct Batch : Readable { |
| 92 | + uint16_t TriangleCount; |
| 93 | + uint16_t DisplayListSize; |
| 94 | + uint32_t VertexAttributes; |
| 95 | + |
| 96 | + uint8_t NormalFlag; |
| 97 | + uint8_t PositionFlag; |
| 98 | + uint8_t TexCoordFlag; |
| 99 | + uint8_t NBTFlag; |
| 100 | + |
| 101 | + uint32_t Vao; |
| 102 | + uint32_t Vbo; |
| 103 | + uint32_t VertexCount; |
| 104 | + uint32_t PrimitiveOffset; |
| 105 | + |
| 106 | + std::vector<Primitive> Primitives; |
| 107 | + |
| 108 | + void Read(bStream::CStream* stream) override; |
| 109 | + void Write(bStream::CStream* stream); |
| 110 | + void Destroy(); |
| 111 | + }; |
| 112 | + |
| 113 | + struct SceneGraphNode : Readable { |
| 114 | + int16_t Index; |
| 115 | + |
| 116 | + int16_t ParentIndex { -1 }; |
| 117 | + int16_t ChildIndex { -1 }; |
| 118 | + int16_t NextSibIndex { -1 }; |
| 119 | + int16_t PreviousSibIndex { -1 }; |
| 120 | + |
| 121 | + uint8_t RenderFlags; |
| 122 | + |
| 123 | + glm::vec3 Scale, Rotation, Position; |
| 124 | + glm::vec3 BoundingBoxMin, BoundingBoxMax; |
| 125 | + float Radius; |
| 126 | + glm::mat4 Transform { 1.0f }; |
| 127 | + |
| 128 | + int16_t ElementCount; |
| 129 | + int32_t ElementOffset; |
| 130 | + std::vector<DrawElement> mDrawElements; |
| 131 | + |
| 132 | + inline bool CastShadow() { return (RenderFlags & (1 << 1)) != 0; } |
| 133 | + inline bool FourthWall() { return (RenderFlags & (1 << 2)) != 0; } |
| 134 | + inline bool Transparent() { return (RenderFlags & (1 << 3)) != 0; } |
| 135 | + inline bool FullBright() { return (RenderFlags & (1 << 6)) != 0; } |
| 136 | + inline bool Ceiling() { return (RenderFlags & (1 << 7)) != 0; } |
124 | 137 |
|
125 | | - uint32_t mNextPosKeyX { 1 }; |
126 | | - uint32_t mNextPosKeyY { 1 }; |
127 | | - uint32_t mNextPosKeyZ { 1 }; |
128 | | - LTrackCommon mXPosTrack; |
129 | | - LTrackCommon mYPosTrack; |
130 | | - LTrackCommon mZPosTrack; |
131 | | -public: |
132 | | - std::shared_ptr<BinScenegraphNode> parent; |
133 | | - std::shared_ptr<BinScenegraphNode> child; |
134 | | - std::shared_ptr<BinScenegraphNode> next; |
135 | | - std::shared_ptr<BinScenegraphNode> prev; |
| 138 | + inline bool CastShadow(bool set) { if (set) { RenderFlags |= (1 << 1); } else { RenderFlags &= ~(1 << 1); } return set; } |
| 139 | + inline bool FourthWall(bool set) { if (set) { RenderFlags |= (1 << 2); } else { RenderFlags &= ~(1 << 2); } return set; } |
| 140 | + inline bool Transparent(bool set) { if (set) { RenderFlags |= (1 << 3); } else { RenderFlags &= ~(1 << 3); } return set; } |
| 141 | + inline bool FullBright(bool set) { if (set) { RenderFlags |= (1 << 6); } else { RenderFlags &= ~(1 << 6); } return set; } |
| 142 | + inline bool Ceiling(bool set) { if (set) { RenderFlags |= (1 << 7); } else { RenderFlags &= ~(1 << 7); } return set; } |
136 | 143 |
|
| 144 | + void Read(bStream::CStream* stream) override; |
| 145 | + void Write(bStream::CStream* stream); |
| 146 | + }; |
137 | 147 |
|
138 | | - glm::mat4 transform; |
139 | | - glm::vec3 mScale, mRotation, mTranslation; |
140 | | - float mBoundingSphereRadius; |
| 148 | + struct GraphNodeTrack { |
| 149 | + LTrackCommon mXScaleTrack; |
| 150 | + LTrackCommon mYScaleTrack; |
| 151 | + LTrackCommon mZScaleTrack; |
141 | 152 |
|
142 | | - void ResetAnimation(); |
| 153 | + LTrackCommon mXRotTrack; |
| 154 | + LTrackCommon mYRotTrack; |
| 155 | + LTrackCommon mZRotTrack; |
143 | 156 |
|
144 | | - void AddMesh(int16_t material, int16_t mesh); |
145 | | - void Draw(glm::mat4 localTransform, glm::mat4* instance, BinModel* bin, bool ignoreTransforms = false, bool animate = false); |
146 | | - BinScenegraphNode(); |
147 | | - ~BinScenegraphNode(); |
| 157 | + LTrackCommon mXPosTrack; |
| 158 | + LTrackCommon mYPosTrack; |
| 159 | + LTrackCommon mZPosTrack; |
148 | 160 |
|
149 | | -}; |
| 161 | + uint32_t mNextScaleKeyX { 1 }; |
| 162 | + uint32_t mNextScaleKeyY { 1 }; |
| 163 | + uint32_t mNextScaleKeyZ { 1 }; |
150 | 164 |
|
151 | | -class BinModel { |
152 | | - friend BinScenegraphNode; |
153 | | - std::map<int16_t, std::shared_ptr<BinMesh>> mMeshes; |
154 | | - std::map<int16_t, std::shared_ptr<BinSampler>> mSamplers; |
155 | | - std::vector<std::shared_ptr<BinMaterial>> mMaterials; |
156 | | - std::shared_ptr<BinScenegraphNode> mRoot; |
| 165 | + uint32_t mNextPosKeyX { 1 }; |
| 166 | + uint32_t mNextPosKeyY { 1 }; |
| 167 | + uint32_t mNextPosKeyZ { 1 }; |
157 | 168 |
|
158 | | - std::shared_ptr<BinScenegraphNode> ParseSceneraph(bStream::CStream* stream, uint32_t* offsets, uint16_t index, std::vector<glm::vec3>& vertexData, std::vector<glm::vec2>& texcoordData, std::shared_ptr<BinScenegraphNode> parent = nullptr, std::shared_ptr<BinScenegraphNode> previous = nullptr); |
| 169 | + uint32_t mNextRotKeyX { 1 }; |
| 170 | + uint32_t mNextRotKeyY { 1 }; |
| 171 | + uint32_t mNextRotKeyZ { 1 }; |
| 172 | + }; |
159 | 173 |
|
| 174 | + static uint32_t mProgram { UINT32_MAX }; |
160 | 175 |
|
161 | | -public: |
162 | | - BinAnimInfo mAnimationInformation; |
| 176 | + void InitShaders(); |
| 177 | + void DestroyShaders(); |
163 | 178 |
|
164 | | - static void InitShaders(); |
165 | | - static void DestroyShaders(); |
| 179 | + class Model |
| 180 | + { |
| 181 | + public: |
| 182 | + Header mHeader; |
166 | 183 |
|
167 | | - bool BindMesh(uint16_t id); |
| 184 | + AnimInfo mAnim; |
168 | 185 |
|
169 | | - bool BindMaterial(uint16_t id); |
| 186 | + std::map<uint16_t, TextureHeader> mTexturesHeaders; |
170 | 187 |
|
171 | | - void Draw(glm::mat4* transform, int32_t id, bool selected, bool ignoreTransforms = false, bool animate = false); |
| 188 | + std::map<uint16_t, Sampler> mSamplers; |
| 189 | + std::map<uint16_t, Batch> mBatches; |
172 | 190 |
|
173 | | - void ResetAnimation(){ mRoot->ResetAnimation(); } |
| 191 | + std::map<uint16_t, Material> mMaterials; |
| 192 | + std::map<uint16_t, SceneGraphNode> mGraphNodes; |
| 193 | + std::map<uint16_t, GraphNodeTrack> mAnimationTracks; |
174 | 194 |
|
175 | | - void TranslateRoot(glm::vec3 translation); |
| 195 | + std::vector<glm::vec3> mPositions; |
| 196 | + std::vector<glm::vec3> mNormals; |
| 197 | + std::vector<glm::vec2> mTexCoords; |
176 | 198 |
|
177 | | - float GetRootBoundingSphere() { return mRoot->mBoundingSphereRadius; } |
| 199 | + void ReadSceneGraphNode(bStream::CStream* stream, uint32_t index); |
| 200 | + void DrawScenegraphNode(uint32_t idx, glm::mat4 transform); |
178 | 201 |
|
179 | | - glm::vec3 GetRootPosition() { return mRoot->transform[3]; } |
| 202 | + glm::vec3 bbMax {0, 0, 0}, bbMin {0, 0, 0}; |
180 | 203 |
|
181 | | - void LoadAnimation(bStream::CStream* stream); |
182 | | - void ClearAnimation(); |
| 204 | + void LoadAnimation(bStream::CStream* stream); |
| 205 | + void ClearAnimation(); |
183 | 206 |
|
184 | | - std::shared_ptr<BinMesh> GetMesh(uint32_t id) { return mMeshes.at(id); } |
185 | | - std::shared_ptr<BinSampler> GetSampler(uint32_t id) { return mSamplers.at(id); } |
| 207 | + void Draw(glm::mat4* transform, int32_t id, bool selected); |
186 | 208 |
|
187 | | - BinModel(bStream::CStream* stream); |
| 209 | + void Load(bStream::CStream* stream); |
| 210 | + void Write(bStream::CStream* stream); |
188 | 211 |
|
189 | | - ~BinModel(); |
190 | | -}; |
| 212 | + Model(bStream::CStream* stream){ Load(stream); } |
| 213 | + Model(){} |
| 214 | + ~Model(); |
| 215 | + }; |
| 216 | + |
| 217 | +} |
0 commit comments