Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
CinematicPathMgr.cpp
Go to the documentation of this file.
1#include "CinematicPathMgr.h"
2#include "DBCStores.h"
3#include "G3D/AABox.h"
4#include "G3D/Any.h"
5#include "G3D/Box.h"
6#include "G3D/Capsule.h"
7#include "G3D/CoordinateFrame.h"
8#include "G3D/Cylinder.h"
9#include "G3D/Matrix4.h"
10#include "G3D/PhysicsFrame.h"
11#include "G3D/platform.h"
12#include "G3D/Quat.h"
13#include "G3D/Ray.h"
14#include "G3D/Sphere.h"
15#include "G3D/stringutils.h"
16#include "G3D/Triangle.h"
17#include "G3D/UprightFrame.h"
18#include "G3D/UprightFrame.h"
19#include "World.h"
20#include <algorithm>
21#include <fstream>
22#include <ObjectMgr.h>
23#include <stdint.h>
24
25enum
26{
31};
32
33#pragma pack(push, 1)
34
35struct Sphere
36{
37 /*0x00*/ float Min[3];
38 /*0x0C*/ float Max[3];
39 /*0x18*/ float Radius;
40};
41
43{
44 char id[4];
48 uint32 GlobalModelFlags; // 1: tilt x, 2: tilt y, 4:, 8: add another field in header, 16: ; (no other flags as of 3.1.1);
49
50 uint32 nGlobalSequences; // AnimationRelated
51 uint32 ofsGlobalSequences; // A list of timestamps.
52 uint32 nAnimations; // AnimationRelated
53 uint32 ofsAnimations; // Information about the animations in the model.
54 uint32 nAnimationLookup; // AnimationRelated
55 uint32 ofsAnimationLookup; // Mapping of global IDs to the entries in the Animation sequences block.
56 //uint32 nD;
57 //uint32 ofsD;
58 uint32 nBones; // BonesAndLookups
59 uint32 ofsBones; // Information about the bones in this model.
60 uint32 nKeyBoneLookup; // BonesAndLookups
61 uint32 ofsKeyBoneLookup; // Lookup table for key skeletal bones.
62
63 uint32 nVertices; // GeometryAndRendering
64 uint32 ofsVertices; // Vertices of the model.
65 uint32 nViews; // GeometryAndRendering
66 //uint32 ofsViews; // Views (LOD) are now in .skins.
67
68 uint32 nColors; // ColorsAndTransparency
69 uint32 ofsColors; // Color definitions.
70
71 uint32 nTextures; // TextureAndTheifAnimation
72 uint32 ofsTextures; // Textures of this model.
73
74 uint32 nTransparency; // H, ColorsAndTransparency
75 uint32 ofsTransparency; // Transparency of textures.
76 //uint32 nI; // always unused ?
77 //uint32 ofsI;
78 uint32 nTexAnims; // J, TextureAndTheifAnimation
80 uint32 nTexReplace; // TextureAndTheifAnimation
81 uint32 ofsTexReplace; // Replaceable Textures.
82
83 uint32 nTexFlags; // Render Flags
84 uint32 ofsTexFlags; // Blending modes / render flags.
85 uint32 nBoneLookup; // BonesAndLookups
86 uint32 ofsBoneLookup; // A bone lookup table.
87
88 uint32 nTexLookup; // TextureAndTheifAnimation
89 uint32 ofsTexLookup; // The same for textures.
90
91 uint32 nTexUnitLookup; // L, TextureAndTheifAnimation, seems gone after Cataclysm
92 uint32 ofsTexUnitLookup; // And texture units. Somewhere they have to be too.
93 uint32 nTransparencyLookup; // M, ColorsAndTransparency
94 uint32 ofsTransparencyLookup; // Everything needs its lookup. Here are the transparencies.
95 uint32 nTexAnimLookup; // TextureAndTheifAnimation
96 uint32 ofsTexAnimLookup; // Wait. Do we have animated Textures? Wasn't ofsTexAnims deleted? oO
97
100
101 uint32 nBoundingTriangles; // Miscellaneous
103 uint32 nBoundingVertices; // Miscellaneous
105 uint32 nBoundingNormals; // Miscellaneous
107
108 uint32 nAttachments; // O, Miscellaneous
109 uint32 ofsAttachments; // Attachments are for weapons etc.
110 uint32 nAttachLookup; // P, Miscellaneous
111 uint32 ofsAttachLookup; // Of course with a lookup.
113 uint32 ofsEvents; // Used for playing sounds when dying and a lot else.
115 uint32 ofsLights; // Lights are mainly used in loginscreens but in wands and some doodads too.
116 uint32 CameraCount; // S, Miscellaneous
117 uint32 CameraOffset; // The cameras are present in most models for having a model in the Character-Tab.
118 uint32 nCameraLookup; // Miscellaneous
119 uint32 ofsCameraLookup; // And lookup-time again, unit16
120 uint32 nRibbonEmitters; // U, Effects
121 uint32 ofsRibbonEmitters; // Things swirling around. See the CoT-entrance for light-trails.
123 uint32 ofsParticleEmitters; // Spells and weapons, doodads and loginscreens use them. Blood dripping of a blade? Particles.
124};
125
126struct Pair
127{
128 uint32_t Number;
129 uint32_t Offset;
130};
131
141
142struct Camera
143{
144 int32_t Type;
145 float fov;
152 struct AnimationBlock rotations; // Quaternion
153};
154
167#pragma pack(pop)
168
171
174{
175 for (std::map<uint32, CinematicSequence*>::iterator itr = m_Sequences.begin(); itr != m_Sequences.end(); ++itr)
176 delete itr->second;
177}
178
181
184{
185 uint32 oldMSTime = getMSTime();
186 uint32 count = 0;
187 m_Sequences.clear();
188
189 for (uint32 itr = 0; itr < sCinematicSequencesStore.GetNumRows(); itr++)
190 {
191 CinematicSequencesEntry const* cinematicSequecenes = sCinematicSequencesStore.LookupEntry(itr);
192
193 if (!cinematicSequecenes || !cinematicSequecenes->cinematicCamera)
194 continue;
195
196 CinematicCameraEntry const* cinematicCamera = sCinematicCameraStore.LookupEntry(cinematicSequecenes->cinematicCamera);
197 if (!cinematicCamera || !cinematicCamera->filename[sObjectMgr->GetDBCLocaleIndex()])
198 continue;
199
200 std::string modelFileName = cinematicCamera->filename;
201 modelFileName = modelFileName.substr(modelFileName.find('\\') + 1);
202 modelFileName = modelFileName.substr(0, modelFileName.find("mdx"));
203 modelFileName += "m2";
204 modelFileName = sWorld->GetDataPath() + "cameras/" + modelFileName;
205
206 FILE* modelFile = fopen(modelFileName.c_str(), "rb");
207 if (!modelFile)
208 {
209 SF_LOG_INFO("server.loading", "Cinematic camera '%s': does not exist!", modelFileName.c_str());
210 continue;
211 }
212
213 size_t fileSize = 0;
214 char* fileBuffer = 0;
215 char magicHeader[4];
216
217 // Check magic
218 fread(magicHeader, 1, sizeof(magicHeader), modelFile);
219
220 if (0 != memcmp(magicHeader, "MD20", sizeof(magicHeader)))
221 {
222 SF_LOG_INFO("server.loading", "Cinematic camera '%s': invalid magic header!", modelFileName.c_str());
223 continue;
224 }
225
226 // Get file size
227 fseek(modelFile, 0, SEEK_END);
228 fileSize = ftell(modelFile);
229 fseek(modelFile, 0, SEEK_SET);
230
231 // Map file into memory
232 fileBuffer = (char*)malloc(fileSize);
233 fread(fileBuffer, 1, fileSize, modelFile);
234 fclose(modelFile);
235
236 // Check number of cameras
237 ModelHeader* modelHeader = (ModelHeader*)fileBuffer;
238
239 if (!modelHeader->CameraCount || !modelHeader->CameraOffset)
240 {
241 free(fileBuffer);
242
243 SF_LOG_INFO("server.loading", "Cinematic camera '%s': no cameras!", modelFileName.c_str());
244 continue;
245 }
246
247 AnimationBlock* animationBlock;
248 float sourcePosition[3];
249
250 if (modelHeader->Version[0] <= 9)
251 {
252 Camera* camera = (Camera*)(fileBuffer + modelHeader->CameraOffset);
253 Camera* endCamera = camera + modelHeader->CameraCount;
254
255 for (; camera != endCamera; ++camera)
256 {
257 if (camera->Type != -1)
258 continue;
259
260 animationBlock = &camera->SourceTranslations;
261 memcpy(sourcePosition, camera->SourcePosition, sizeof(sourcePosition));
262
263 break;
264 }
265 }
266 else
267 {
268 CameraV10* cameraV10 = (CameraV10*)(fileBuffer + modelHeader->CameraOffset);
269 CameraV10* endCameraV10 = cameraV10 + modelHeader->CameraCount;
270
271 for (; cameraV10 != endCameraV10; ++cameraV10)
272 {
273 if (cameraV10->Type != -1)
274 continue;
275
276 animationBlock = &cameraV10->SourceTranslations;
277 memcpy(sourcePosition, cameraV10->SourcePosition, sizeof(sourcePosition));
278
279 break;
280 }
281 }
282
283 if (!animationBlock ||
284 !animationBlock->FramePairsOffset || !animationBlock->TransPairsOffset
285 || animationBlock->FramePairsCount != animationBlock->TransPairsCount)
286 {
287 SF_LOG_INFO("server.loading", "Cinematic camera '%s': no translations!", modelFileName.c_str());
288 free(fileBuffer);
289 continue;
290 }
291
292 CinematicSequence* cinematicSequence = new CinematicSequence();
293
294 cinematicSequence->Duration = 0;
295 cinematicSequence->KeyFramesCount = 0;
296
297 size_t blockSize = 3 * sizeof(float);
298
299 if (animationBlock->interpolation_type == INTERPOLATION_HERMITE || animationBlock->interpolation_type == INTERPOLATION_BEZIER)
300 blockSize *= 3;
301
302 G3D::Matrix3 matrix = G3D::Matrix3::identity();
303 matrix = matrix.fromAxisAngle(G3D::Vector3(0, 0, 1), cinematicCamera->GlobalRotation);
304
305 if (animationBlock->FramePairsOffset)
306 {
307 Pair* framePairs = (struct Pair*)(fileBuffer + animationBlock->FramePairsOffset);
308 Pair* transPairs = (struct Pair*)(fileBuffer + animationBlock->TransPairsOffset);
309
310 cinematicSequence->KeyFramesCount = framePairs->Number;
311 cinematicSequence->KeyFrames = new CinematicKeyFrame[cinematicSequence->KeyFramesCount];
312
313 for (uint32 i = 0; i < animationBlock->FramePairsCount; i++)
314 {
315 Pair* framePair = framePairs + i;
316 Pair* transPair = transPairs + i;
317
318 for (uint32 j = 0; j < framePair->Number; j++)
319 {
320 cinematicSequence->KeyFrames[j].Frame = ((uint32*)(fileBuffer + framePair->Offset))[j];
321 cinematicSequence->Duration = std::max(cinematicSequence->Duration, cinematicSequence->KeyFrames[j].Frame);
322
323 memcpy(cinematicSequence->KeyFrames[j].Position, (fileBuffer + transPair->Offset) + j * blockSize, sizeof(cinematicSequence->KeyFrames[j].Position));
324 cinematicSequence->KeyFrames[j].Position[0] = sourcePosition[0] + cinematicSequence->KeyFrames[j].Position[0];
325 cinematicSequence->KeyFrames[j].Position[1] = sourcePosition[1] + cinematicSequence->KeyFrames[j].Position[1];
326 cinematicSequence->KeyFrames[j].Position[2] = sourcePosition[2] + cinematicSequence->KeyFrames[j].Position[2];
327
328 G3D::Vector3 pt(cinematicSequence->KeyFrames[j].Position[0], cinematicSequence->KeyFrames[j].Position[1], cinematicSequence->KeyFrames[j].Position[2]);
329 G3D::Vector3 result = matrix * pt;
330
331 cinematicSequence->KeyFrames[j].Position[0] = cinematicCamera->EndPosX + result.x;
332 cinematicSequence->KeyFrames[j].Position[1] = cinematicCamera->EndPosY + result.y;
333 cinematicSequence->KeyFrames[j].Position[2] = cinematicCamera->EndPosZ + result.z;
334 }
335 }
336 }
337
338 m_Sequences[itr] = cinematicSequence;
339
340 free(fileBuffer);
341
342 count++;
343 }
344
345 SF_LOG_INFO("server.loading", ">> Loaded %u Cinematic cameras in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
346
347 return m_Sequences.size();
348}
349
352
355{
356 std::map<uint32, CinematicSequence*>::iterator itr = m_Sequences.find(sequenceID);
357
358 return (itr != m_Sequences.end()) ? itr->second : NULL;
359}
360
365
372
375
377void CinematicSequence::GetPositionAtTime(uint32 time, float* x, float* y, float* z) const
378{
379 *x = 0;
380 *y = 0;
381 *z = 0;
382
383 for (CinematicKeyFrame* cinematicKeyFrame = KeyFrames; cinematicKeyFrame != KeyFrames + KeyFramesCount; ++cinematicKeyFrame)
384 {
385 CinematicKeyFrame* nextCinematicKeyFrame = (cinematicKeyFrame + 1 != KeyFrames + KeyFramesCount) ? cinematicKeyFrame + 1 : NULL;
386
387 if (!nextCinematicKeyFrame || cinematicKeyFrame->Frame == time)
388 {
389 *x = cinematicKeyFrame->Position[0];
390 *y = cinematicKeyFrame->Position[1];
391 *z = cinematicKeyFrame->Position[2];
392
393 return;
394 }
395 else if (nextCinematicKeyFrame && cinematicKeyFrame->Frame < time && nextCinematicKeyFrame->Frame > time)
396 {
398 if (nextCinematicKeyFrame->Frame == cinematicKeyFrame->Frame)
399 {
400 *x = cinematicKeyFrame->Position[0];
401 *y = cinematicKeyFrame->Position[1];
402 *z = cinematicKeyFrame->Position[2];
403 return;
404 }
405
406 float l_Progress = (float(time) - float(cinematicKeyFrame->Frame)) / (float(nextCinematicKeyFrame->Frame) - float(cinematicKeyFrame->Frame));
407
408 *x = cinematicKeyFrame->Position[0] + (l_Progress * (nextCinematicKeyFrame->Position[0] - cinematicKeyFrame->Position[0]));
409 *y = cinematicKeyFrame->Position[1] + (l_Progress * (nextCinematicKeyFrame->Position[1] - cinematicKeyFrame->Position[1]));
410 *z = cinematicKeyFrame->Position[2] + (l_Progress * (nextCinematicKeyFrame->Position[2] - cinematicKeyFrame->Position[2]));
411
412 return;
413 }
414 }
415
416 CinematicKeyFrame* lastGood = 0;
417
418 for (CinematicKeyFrame* cinematicKeyFrame = KeyFrames; cinematicKeyFrame != KeyFrames + KeyFramesCount; ++cinematicKeyFrame)
419 {
420 if (cinematicKeyFrame->Frame < time)
421 lastGood = cinematicKeyFrame;
422 }
423
424 if (lastGood)
425 {
426 *x = lastGood->Position[0];
427 *y = lastGood->Position[1];
428 *z = lastGood->Position[2];
429 }
430}
@ INTERPOLATION_LINEAR
@ INTERPOLATION_NONE
@ INTERPOLATION_HERMITE
@ INTERPOLATION_BEZIER
DBCStorage< CinematicSequencesEntry > sCinematicSequencesStore(CinematicSequencesEntryfmt)
DBCStorage< CinematicCameraEntry > sCinematicCameraStore(CinematicCameraEntryfmt)
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::int16_t int16
Definition Define.h:74
#define SF_LOG_INFO(filterType__,...)
Definition Log.h:137
#define sObjectMgr
Definition ObjectMgr.h:1617
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:22
uint32 getMSTime()
Definition Timer.h:12
Cinematic sequence.
void GetPositionAtTime(uint32 time, float *x, float *y, float *z) const
Get position at time.
CinematicKeyFrame * KeyFrames
Key frames.
~CinematicSequence()
Destructor.
size_t KeyFramesCount
Key Frame count.
uint32 Duration
Sequence durations.
std::map< uint32, CinematicSequence * > m_Sequences
size_t Load()
Load all sequence.
CinematicSequence * GetSequence(uint32 sequenceID)
Get a sequence by his id.
~CinematicSequenceMgr()
Destructor.
#define sWorld
Definition World.h:910
struct AnimationBlock SourceTranslations
float target_position[3]
float SourcePosition[3]
struct AnimationBlock rotations
struct AnimationBlock target_translations
float near_clipping
float target_position[3]
struct AnimationBlock unknown_block_4
struct AnimationBlock target_translations
struct AnimationBlock SourceTranslations
struct AnimationBlock rotations
float SourcePosition[3]
float EndPosY
float EndPosZ
float GlobalRotation
char * filename
float EndPosX
Cinematic sequence key frame.
uint32 cinematicCamera
uint32 ofsAnimationLookup
uint32 ofsTransparencyLookup
uint32 nTransparencyLookup
struct Sphere BoundSphere
uint32 ofsGlobalSequences
struct Sphere CollisionSphere
uint32 ofsBoundingTriangles
uint32_t Offset
uint32_t Number
float Min[3]
float Max[3]