AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
M2Stores.cpp File Reference
#include "DBCStores.h"
#include "Common.h"
#include "Containers.h"
#include "Log.h"
#include "M2Structure.h"
#include "M2Stores.h"
#include "World.h"
#include <boost/filesystem/path.hpp>
#include <fstream>
#include <iostream>
#include <iomanip>

Go to the source code of this file.

Typedefs

typedef std::vector< FlyByCameraFlyByCameraCollection
 

Functions

G3D::Vector3 TranslateLocation (G3D::Vector4 const *DBCPosition, G3D::Vector3 const *basePosition, G3D::Vector3 const *splineVector)
 
bool readCamera (M2Camera const *cam, uint32 buffSize, M2Header const *header, CinematicCameraEntry const *dbcentry)
 
void LoadM2Cameras (std::string const &dataPath)
 
std::vector< FlyByCamera > const * GetFlyByCameras (uint32 cinematicCameraId)
 

Variables

std::unordered_map< uint32, FlyByCameraCollectionsFlyByCameraStore
 

Typedef Documentation

◆ FlyByCameraCollection

typedef std::vector<FlyByCamera> FlyByCameraCollection

Function Documentation

◆ GetFlyByCameras()

std::vector< FlyByCamera > const * GetFlyByCameras ( uint32  cinematicCameraId)
258{
259 return Acore::Containers::MapGetValuePtr(sFlyByCameraStore, cinematicCameraId);
260}
std::unordered_map< uint32, FlyByCameraCollection > sFlyByCameraStore
Definition: M2Stores.cpp:31
auto MapGetValuePtr(M &map, typename M::key_type const &key) -> decltype(AddressOrSelf(map.find(key) ->second))
Definition: Containers.h:208

References Acore::Containers::MapGetValuePtr(), and sFlyByCameraStore.

Referenced by CinematicMgr::BeginCinematic(), and debug_commandscript::HandleDebugPlayCinematicCommand().

◆ LoadM2Cameras()

void LoadM2Cameras ( std::string const &  dataPath)
177{
178 sFlyByCameraStore.clear();
179 LOG_INFO("server.loading", ">> Loading Cinematic Camera files");
180
181 uint32 oldMSTime = getMSTime();
182 for (CinematicCameraEntry const* dbcentry : sCinematicCameraStore)
183 {
184 std::string filenameWork = dataPath;
185 filenameWork.append(dbcentry->Model);
186
187 // Replace slashes (always to forward slash, because boost!)
188 std::replace(filenameWork.begin(), filenameWork.end(), '\\', '/');
189
190 boost::filesystem::path filename = filenameWork;
191
192 // Convert to native format
193 filename.make_preferred();
194
195 // Replace mdx to .m2
196 filename.replace_extension("m2");
197
198 std::ifstream m2file(filename.string().c_str(), std::ios::in | std::ios::binary);
199 if (!m2file.is_open())
200 continue;
201
202 // Get file size
203 m2file.seekg(0, std::ios::end);
204 std::streamoff fileSize = m2file.tellg();
205
206 // Reject if not at least the size of the header
207 if (static_cast<uint32>(fileSize) < sizeof(M2Header))
208 {
209 LOG_ERROR("server.loading", "Camera file %s is damaged. File is smaller than header size", filename.string().c_str());
210 m2file.close();
211 continue;
212 }
213
214 // Read 4 bytes (signature)
215 m2file.seekg(0, std::ios::beg);
216 char fileCheck[5];
217 m2file.read(fileCheck, 4);
218 fileCheck[4] = 0;
219
220 // Check file has correct magic (MD20)
221 if (strcmp(fileCheck, "MD20"))
222 {
223 LOG_ERROR("server.loading", "Camera file %s is damaged. File identifier not found", filename.string().c_str());
224 m2file.close();
225 continue;
226 }
227
228 // Now we have a good file, read it all into a vector of char's, then close the file.
229 std::vector<char> buffer(fileSize);
230 m2file.seekg(0, std::ios::beg);
231 if (!m2file.read(buffer.data(), fileSize))
232 {
233 m2file.close();
234 continue;
235 }
236 m2file.close();
237
238 // Read header
239 M2Header const* header = reinterpret_cast<M2Header const*>(buffer.data());
240
241 if (header->ofsCameras + sizeof(M2Camera) > static_cast<uint32>(fileSize))
242 {
243 LOG_ERROR("server.loading", "Camera file %s is damaged. Camera references position beyond file end", filename.string().c_str());
244 continue;
245 }
246
247 // Get camera(s) - Main header, then dump them.
248 M2Camera const* cam = reinterpret_cast<M2Camera const*>(buffer.data() + header->ofsCameras);
249 if (!readCamera(cam, fileSize, header, dbcentry))
250 LOG_ERROR("server.loading", "Camera file %s is damaged. Camera references position beyond file end", filename.string().c_str());
251 }
252
253 LOG_INFO("server.loading", ">> Loaded {} Cinematic Waypoint Sets in {} ms", (uint32)sFlyByCameraStore.size(), GetMSTimeDiffToNow(oldMSTime));
254 LOG_INFO("server.loading", " ");
255}
std::uint32_t uint32
Definition: Define.h:108
#define LOG_INFO(filterType__,...)
Definition: Log.h:167
#define LOG_ERROR(filterType__,...)
Definition: Log.h:159
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:131
uint32 getMSTime()
Definition: Timer.h:103
DBCStorage< CinematicCameraEntry > sCinematicCameraStore(CinematicCameraEntryfmt)
bool readCamera(M2Camera const *cam, uint32 buffSize, M2Header const *header, CinematicCameraEntry const *dbcentry)
Definition: M2Stores.cpp:53
Definition: M2Structure.h:35
uint32 ofsCameras
Definition: M2Structure.h:95
Definition: M2Structure.h:120
Definition: DBCStructure.h:704

References getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, M2Header::ofsCameras, readCamera(), sCinematicCameraStore, and sFlyByCameraStore.

Referenced by World::SetInitialWorldSettings().

◆ readCamera()

bool readCamera ( M2Camera const *  cam,
uint32  buffSize,
M2Header const *  header,
CinematicCameraEntry const *  dbcentry 
)
54{
55 char const* buffer = reinterpret_cast<char const*>(header);
56
58 FlyByCameraCollection targetcam;
59
60 G3D::Vector4 DBCData;
61 DBCData.x = dbcentry->Origin.X;
62 DBCData.y = dbcentry->Origin.Y;
63 DBCData.z = dbcentry->Origin.Z;
64 DBCData.w = dbcentry->OriginFacing;
65
66 // Read target locations, only so that we can calculate orientation
67 for (uint32 k = 0; k < cam->target_positions.timestamps.number; ++k)
68 {
69 // Extract Target positions
70 if (cam->target_positions.timestamps.offset_elements + sizeof(M2Array) > buffSize)
71 return false;
72 M2Array const* targTsArray = reinterpret_cast<M2Array const*>(buffer + cam->target_positions.timestamps.offset_elements);
73 if (targTsArray->offset_elements + sizeof(uint32) > buffSize || cam->target_positions.values.offset_elements + sizeof(M2Array) > buffSize)
74 return false;
75 uint32 const* targTimestamps = reinterpret_cast<uint32 const*>(buffer + targTsArray->offset_elements);
76 M2Array const* targArray = reinterpret_cast<M2Array const*>(buffer + cam->target_positions.values.offset_elements);
77
78 if (targArray->offset_elements + sizeof(M2SplineKey<G3D::Vector3>) > buffSize)
79 return false;
80 M2SplineKey<G3D::Vector3> const* targPositions = reinterpret_cast<M2SplineKey<G3D::Vector3> const*>(buffer + targArray->offset_elements);
81
82 // Read the data for this set
83 uint32 currPos = targArray->offset_elements;
84 for (uint32 i = 0; i < targTsArray->number; ++i)
85 {
86 if (currPos + sizeof(M2SplineKey<G3D::Vector3>) > buffSize)
87 return false;
88 // Translate co-ordinates
89 G3D::Vector3 newPos = TranslateLocation(&DBCData, &cam->target_position_base, &targPositions->p0);
90
91 // Add to vector
92 FlyByCamera thisCam;
93 thisCam.timeStamp = targTimestamps[i];
94 thisCam.locations.Relocate(newPos.x, newPos.y, newPos.z, 0.0f);
95 targetcam.push_back(thisCam);
96 targPositions++;
97 currPos += sizeof(M2SplineKey<G3D::Vector3>);
98 }
99 }
100
101 // Read camera positions and timestamps (translating first position of 3 only, we don't need to translate the whole spline)
102 for (uint32 k = 0; k < cam->positions.timestamps.number; ++k)
103 {
104 // Extract Camera positions for this set
105 if (cam->positions.timestamps.offset_elements + sizeof(M2Array) > buffSize)
106 return false;
107 M2Array const* posTsArray = reinterpret_cast<M2Array const*>(buffer + cam->positions.timestamps.offset_elements);
108 if (posTsArray->offset_elements + sizeof(uint32) > buffSize || cam->positions.values.offset_elements + sizeof(M2Array) > buffSize)
109 return false;
110 uint32 const* posTimestamps = reinterpret_cast<uint32 const*>(buffer + posTsArray->offset_elements);
111 M2Array const* posArray = reinterpret_cast<M2Array const*>(buffer + cam->positions.values.offset_elements);
112 if (posArray->offset_elements + sizeof(M2SplineKey<G3D::Vector3>) > buffSize)
113 return false;
114 M2SplineKey<G3D::Vector3> const* positions = reinterpret_cast<M2SplineKey<G3D::Vector3> const*>(buffer + posArray->offset_elements);
115
116 // Read the data for this set
117 uint32 currPos = posArray->offset_elements;
118 for (uint32 i = 0; i < posTsArray->number; ++i)
119 {
120 if (currPos + sizeof(M2SplineKey<G3D::Vector3>) > buffSize)
121 return false;
122 // Translate co-ordinates
123 G3D::Vector3 newPos = TranslateLocation(&DBCData, &cam->position_base, &positions->p0);
124
125 // Add to vector
126 FlyByCamera thisCam;
127 thisCam.timeStamp = posTimestamps[i];
128 thisCam.locations.Relocate(newPos.x, newPos.y, newPos.z);
129
130 if (targetcam.size() > 0)
131 {
132 // Find the target camera before and after this camera
133 FlyByCamera lastTarget;
134 FlyByCamera nextTarget;
135
136 // Pre-load first item
137 lastTarget = targetcam[0];
138 nextTarget = targetcam[0];
139 for (uint32 j = 0; j < targetcam.size(); ++j)
140 {
141 nextTarget = targetcam[j];
142 if (targetcam[j].timeStamp > posTimestamps[i])
143 break;
144
145 lastTarget = targetcam[j];
146 }
147
148 float x, y, z;
149 lastTarget.locations.GetPosition(x, y, z);
150
151 // Now, the timestamps for target cam and position can be different. So, if they differ we interpolate
152 if (lastTarget.timeStamp != posTimestamps[i])
153 {
154 uint32 timeDiffTarget = nextTarget.timeStamp - lastTarget.timeStamp;
155 uint32 timeDiffThis = posTimestamps[i] - lastTarget.timeStamp;
156 float xDiff = nextTarget.locations.GetPositionX() - lastTarget.locations.GetPositionX();
157 float yDiff = nextTarget.locations.GetPositionY() - lastTarget.locations.GetPositionY();
158 x = lastTarget.locations.GetPositionX() + (xDiff * (float(timeDiffThis) / float(timeDiffTarget)));
159 y = lastTarget.locations.GetPositionY() + (yDiff * (float(timeDiffThis) / float(timeDiffTarget)));
160 }
161 float xDiff = x - thisCam.locations.GetPositionX();
162 float yDiff = y - thisCam.locations.GetPositionY();
163 thisCam.locations.SetOrientation(std::atan2(yDiff, xDiff));
164 }
165
166 cameras.push_back(thisCam);
167 positions++;
168 currPos += sizeof(M2SplineKey<G3D::Vector3>);
169 }
170 }
171
172 sFlyByCameraStore[dbcentry->ID] = cameras;
173 return true;
174}
std::vector< FlyByCamera > FlyByCameraCollection
Definition: M2Stores.cpp:30
G3D::Vector3 TranslateLocation(G3D::Vector4 const *DBCPosition, G3D::Vector3 const *basePosition, G3D::Vector3 const *splineVector)
Definition: M2Stores.cpp:34
const Position positions[MAX_SUMMONS]
Definition: boss_lurker_below.cpp:49
Definition: M2Stores.h:26
uint32 timeStamp
Definition: M2Stores.h:27
Position locations
Definition: M2Stores.h:28
Definition: M2Structure.h:28
T p0
Definition: M2Structure.h:29
Definition: M2Structure.h:107
uint32 offset_elements
Definition: M2Structure.h:109
uint32_t number
Definition: M2Structure.h:108
void SetOrientation(float orientation)
Definition: Position.h:112
float GetPositionX() const
Definition: Position.h:117
void GetPosition(float &x, float &y) const
Definition: Position.h:122
float GetPositionY() const
Definition: Position.h:118
void Relocate(float x, float y)
Definition: Position.h:73

References Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), CinematicCameraEntry::ID, FlyByCamera::locations, M2Array::number, M2Array::offset_elements, CinematicCameraEntry::Origin, CinematicCameraEntry::OriginFacing, M2SplineKey< T >::p0, M2Camera::position_base, M2Camera::positions, positions, Position::Relocate(), Position::SetOrientation(), sFlyByCameraStore, M2Camera::target_position_base, M2Camera::target_positions, FlyByCamera::timeStamp, M2Track::timestamps, TranslateLocation(), M2Track::values, DBCPosition3D::X, DBCPosition3D::Y, and DBCPosition3D::Z.

Referenced by LoadM2Cameras().

◆ TranslateLocation()

G3D::Vector3 TranslateLocation ( G3D::Vector4 const *  DBCPosition,
G3D::Vector3 const *  basePosition,
G3D::Vector3 const *  splineVector 
)
35{
36 G3D::Vector3 work;
37 float x = basePosition->x + splineVector->x;
38 float y = basePosition->y + splineVector->y;
39 float z = basePosition->z + splineVector->z;
40 float const distance = std::sqrt((x * x) + (y * y));
41 float angle = std::atan2(x, y) - DBCPosition->w;
42
43 if (angle < 0)
44 angle += 2 * float(M_PI);
45
46 work.x = DBCPosition->x + (distance * sin(angle));
47 work.y = DBCPosition->y + (distance * cos(angle));
48 work.z = DBCPosition->z + z;
49 return work;
50}

Referenced by readCamera().

Variable Documentation

◆ sFlyByCameraStore

std::unordered_map<uint32, FlyByCameraCollection> sFlyByCameraStore