/** * @class Model */ Model::Model(const Common::String &filename, const char *data, int len, CMap *cmap, Model *parent) : Object(), _parent(parent), _numMaterials(0), _numGeosets(0), _cmap(cmap) { _fname = filename; if (g_grim->getGameType() == GType_MONKEY4) { Common::MemoryReadStream ms((const byte *)data, len); loadEMI(ms); } else if (len >= 4 && READ_BE_UINT32(data) == MKTAG('L','D','O','M')) loadBinary(data, cmap); else { TextSplitter ts(data, len); loadText(&ts, cmap); } Math::Vector3d max; _rootHierNode->update(); bool first = true; for (int i = 0; i < _numHierNodes; ++i) { ModelNode &node = _rootHierNode[i]; if (node._mesh) { Mesh &mesh = *node._mesh; //NOTE: Setting p to mesh._matrix._pos seems more similar to original // but, as in original, it also stops manny quite far away from the // bone wagon when approaching it from behind in set sg. // Using the node position looks instead more realistic, but, on the // other hand, it may not work right in all cases. Math::Vector3d p = node._matrix.getPosition(); float x = p.x(); float y = p.y(); float z = p.z(); for (int k = 0; k < mesh._numVertices * 3; k += 3) { if (first || mesh._vertices[k] + x < _bboxPos.x()) _bboxPos.x() = mesh._vertices[k] + x; if (mesh._vertices[k + 1] + y < _bboxPos.y()) _bboxPos.y() = mesh._vertices[k + 1] + y; if (mesh._vertices[k + 2] + z < _bboxPos.z()) _bboxPos.z() = mesh._vertices[k + 2] + z; if (first || mesh._vertices[k] + x > max.x()) max.x() = mesh._vertices[k] + x; if (mesh._vertices[k + 1] + y > max.y()) max.y() = mesh._vertices[k + 1] + y; if (mesh._vertices[k + 2] + z > max.z()) max.z() = mesh._vertices[k + 2] + z; first = false; } } } _bboxSize = max - _bboxPos; }
Costume::Costume(const Common::String &fname, const char *data, int len, Costume *prevCost) : Object(), _head(new Head()) { _fname = fname; _lookAtRate = 200; _prevCostume = prevCost; if (g_grim->getGameType() == GType_MONKEY4) { Common::MemoryReadStream ms((const byte *)data, len); loadEMI(ms, prevCost); } else { TextSplitter ts(data, len); loadGRIM(ts, prevCost); } }
/** * @class Model */ Model::Model(const Common::String &filename, Common::SeekableReadStream *data, CMap *cmap, Model *parent) : Object(), _parent(parent), _numMaterials(0), _numGeosets(0), _cmap(cmap) { _fname = filename; if (g_grim->getGameType() == GType_MONKEY4) { loadEMI(data); } else if (data->readUint32BE() == MKTAG('L','D','O','M')) loadBinary(data, cmap); else { data->seek(0, SEEK_SET); TextSplitter ts(data); loadText(&ts, cmap); } delete data; Math::Vector3d max; _rootHierNode->update(); bool first = true; for (int i = 0; i < _numHierNodes; ++i) { ModelNode &node = _rootHierNode[i]; if (node._mesh) { Mesh &mesh = *node._mesh; Math::Vector3d p = mesh._matrix.getPosition(); float x = p.x(); float y = p.y(); float z = p.z(); for (int k = 0; k < mesh._numVertices * 3; k += 3) { if (first || mesh._vertices[k] + x < _bboxPos.x()) _bboxPos.x() = mesh._vertices[k] + x; if (first || mesh._vertices[k + 1] + y < _bboxPos.y()) _bboxPos.y() = mesh._vertices[k + 1] + y; if (first || mesh._vertices[k + 2] + z < _bboxPos.z()) _bboxPos.z() = mesh._vertices[k + 2] + z; if (first || mesh._vertices[k] + x > max.x()) max.x() = mesh._vertices[k] + x; if (first || mesh._vertices[k + 1] + y > max.y()) max.y() = mesh._vertices[k + 1] + y; if (first || mesh._vertices[k + 2] + z > max.z()) max.z() = mesh._vertices[k + 2] + z; first = false; } } } _bboxSize = max - _bboxPos; }