xoreos  0.0.5
room.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include "glm/mat4x4.hpp"
26 #include "glm/gtc/matrix_transform.hpp"
27 #include "glm/gtx/matrix_interpolation.hpp"
28 
29 #include "src/common/util.h"
30 #include "src/common/strutil.h"
31 #include "src/common/maths.h"
32 #include "src/common/error.h"
33 
34 #include "src/aurora/resman.h"
35 #include "src/aurora/gff4file.h"
36 
38 
39 #include "src/events/events.h"
40 
42 
44 
45 namespace Engines {
46 
47 namespace DragonAge2 {
48 
49 static const uint32 kRMLID = MKTAG('R', 'M', 'L', ' ');
50 static const uint32 kVersion40 = MKTAG('V', '4', '.', '0');
51 
52 static const uint32 kMDLID = MKTAG('M', 'D', 'L', ' ');
53 
54 using ::Aurora::GFF4File;
55 using ::Aurora::GFF4Struct;
57 
58 using namespace ::Aurora::GFF4FieldNamesEnum;
59 
61  try {
62  load(room);
63  } catch (...) {
64  clean();
65  throw;
66  }
67 }
68 
70  hide();
71  clean();
72 }
73 
74 int32 Room::getID() const {
75  return _id;
76 }
77 
78 void Room::clean() {
79  try {
81  } catch (...) {
82  }
83 }
84 
85 void Room::load(const GFF4Struct &room) {
86  _id = room.getSint(kGFF4EnvRoomID, -1);
87 
88  const Common::UString roomFile = room.getString(kGFF4EnvRoomFile);
89 
90  indexOptionalArchive(roomFile + ".rim" , 12000, _resources);
91  indexOptionalArchive(roomFile + ".gpu.rim" , 12001, _resources);
92  indexOptionalArchive(roomFile + "_0.rim" , 12002, _resources);
93  indexOptionalArchive(roomFile + "_0.gpu.rim", 12003, _resources);
94 
95  loadLayout(roomFile);
96  loadLayout(roomFile + "_0");
97  loadLayout(roomFile + "_1");
98 }
99 
100 void Room::loadLayout(const Common::UString &roomFile) {
101  if (!ResMan.hasResource(roomFile, Aurora::kFileTypeRML) || EventMan.quitRequested())
102  return;
103 
104  GFF4File rml(roomFile, Aurora::kFileTypeRML, kRMLID);
105  if (rml.getTypeVersion() != kVersion40)
106  throw Common::Exception("Unsupported RML version %s", Common::debugTag(rml.getTypeVersion()).c_str());
107 
108  const GFF4Struct &rmlTop = rml.getTopLevel();
109 
110  float roomPos[3] = { 0.0f, 0.0f, 0.0f };
111  rmlTop.getVector3(kGFF4Position, roomPos[0], roomPos[1], roomPos[2]);
112 
113  float roomOrient[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
114  rmlTop.getVector4(kGFF4Orientation, roomOrient[0], roomOrient[1], roomOrient[2], roomOrient[3]);
115  roomOrient[3] = Common::rad2deg(acos(roomOrient[3]) * 2.0);
116 
117  glm::mat4 roomTransform;
118 
119  roomTransform = glm::translate(roomTransform, glm::vec3(roomPos[0], roomPos[1], roomPos[2]));
120 
121  if (roomOrient[0] != 0 || roomOrient[1] != 0 || roomOrient[2] != 0)
122  roomTransform = glm::rotate(roomTransform,
123  Common::deg2rad(roomOrient[3]),
124  glm::vec3(roomOrient[0], roomOrient[1], roomOrient[2]));
125 
126  status("Loading room \"%s\" (%d)", roomFile.c_str(), _id);
127 
128  const GFF4List &models = rmlTop.getList(kGFF4EnvRoomModelList);
129  _models.reserve(models.size());
130 
131  for (GFF4List::const_iterator m = models.begin(); m != models.end(); ++m) {
132  if (!*m || ((*m)->getLabel() != kMDLID))
133  continue;
134 
135  float scale = (*m)->getFloat(kGFF4EnvModelScale);
136 
137  float pos[3] = { 0.0f, 0.0f, 0.0f };
138  (*m)->getVector3(kGFF4Position, pos[0], pos[1], pos[2]);
139 
140  float orient[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
141  (*m)->getVector4(kGFF4Orientation, orient[0], orient[1], orient[2], orient[3]);
142  orient[3] = Common::rad2deg(acos(orient[3]) * 2.0);
143 
144  // TODO: Instances
145 
146  Graphics::Aurora::Model *model = loadModelObject((*m)->getString(kGFF4EnvModelFile));
147  if (!model)
148  continue;
149 
150  _models.push_back(model);
151 
152  glm::mat4 modelTransform(roomTransform);
153 
154  modelTransform = glm::translate(modelTransform, glm::vec3(pos[0], pos[1], pos[2]));
155 
156  if (orient[0] != 0 || orient[1] != 0 || orient[2] != 0)
157  modelTransform = glm::rotate(modelTransform,
158  Common::deg2rad(orient[3]),
159  glm::vec3(orient[0], orient[1], orient[2]));
160 
161  pos[0] = modelTransform[3][0];
162  pos[1] = modelTransform[3][1];
163  pos[2] = modelTransform[3][2];
164 
165  glm::vec3 axis;
166  glm::axisAngle(modelTransform, axis, orient[3]);
167  orient[3] = Common::rad2deg(orient[3]);
168  orient[0] = axis.x;
169  orient[1] = axis.y;
170  orient[2] = axis.z;
171 
172  model->setPosition(pos[0], pos[1], pos[2]);
173  model->setOrientation(orient[0], orient[1], orient[2], orient[3]);
174  model->setScale(scale, scale, scale);
175  }
176 }
177 
178 void Room::show() {
179  for (Models::iterator m = _models.begin(); m != _models.end(); ++m)
180  (*m)->show();
181 }
182 
183 void Room::hide() {
184  for (Models::iterator m = _models.begin(); m != _models.end(); ++m)
185  (*m)->hide();
186 }
187 
188 } // End of namespace DragonAge2
189 
190 } // End of namespace Engines
Room(const Aurora::GFF4Struct &room)
Definition: room.cpp:60
#define ResMan
Shortcut for accessing the sound manager.
Definition: resman.h:557
#define MKTAG(a0, a1, a2, a3)
A wrapper macro used around four character constants, like &#39;DATA&#39;, to ensure portability.
Definition: endianness.h:140
A class holding an UTF-8 string.
Definition: ustring.h:48
static const uint32 kVersion40
Definition: area.cpp:55
bool indexOptionalArchive(const Common::UString &file, uint32 priority, const std::vector< byte > &password, Common::ChangeID *changeID)
Definition: resources.cpp:69
Mathematical helpers.
void load(const Aurora::GFF4Struct &room)
static const uint32 kMDLID
Definition: room.cpp:52
Utility templates and functions for working with strings and streams.
Exception that provides a stack of explanations.
Definition: error.h:36
void deindexResources(Common::ChangeID &changeID)
Remove previously added resources from the ResourceManager.
Definition: resources.cpp:164
std::vector< const GFF4Struct * > GFF4List
Definition: types.h:453
Handling version V4.0/V4.1 of BioWare&#39;s GFFs (generic file format).
Basic exceptions to throw.
void setOrientation(float x, float y, float z, float angle)
Set the current orientation of the model.
Definition: model.cpp:234
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
Utility templates and functions.
The global events manager.
A 3D model of an object.
void setPosition(float x, float y, float z)
Set the current position of the model.
Definition: model.cpp:250
#define EventMan
Shortcut for accessing the events manager.
Definition: events.h:210
void loadLayout(const Common::UString &roomFile)
Definition: room.cpp:100
int32 getID() const
Definition: room.cpp:74
uint32_t uint32
Definition: types.h:204
UString debugTag(uint32 tag, bool trim)
Create an elaborate string from an integer tag, for debugging purposes.
Definition: strutil.cpp:117
A room in a Dragon Age II area.
static const uint32 kRMLID
Definition: room.cpp:49
void status(const char *s,...)
Definition: util.cpp:52
static float rad2deg(float rad)
Definition: maths.h:93
Graphics::Aurora::Model * loadModelObject(const Common::UString &resref, const Common::UString &texture)
Definition: model.cpp:47
ChangeList _resources
Definition: room.h:60
static float deg2rad(float deg)
Definition: maths.h:97
void setScale(float x, float y, float z)
Set the current scale of the model.
Definition: model.cpp:219
The global resource manager for Aurora resources.
int32_t int32
Definition: types.h:203
Generic Aurora engines model functions.