ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

biffmesh.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "engines/stark/formats/biffmesh.h"
00024 
00025 #include "engines/stark/formats/biff.h"
00026 #include "engines/stark/services/archiveloader.h"
00027 
00028 #include "common/hashmap.h"
00029 
00030 namespace Stark {
00031 namespace Formats {
00032 
00033 enum BiffMeshObjectType {
00034     kMeshObjectSceneData = 0x5a4aa94,
00035     kMeshObjectBase      = 0x5a4aa89,
00036     kMeshObjectTri       = 0x5a4aa8d,
00037     kMeshObjectMaterial  = 0x5a4aa8e
00038 };
00039 
00040 class MeshObjectSceneData : public BiffObject {
00041 public:
00042     static const uint32 TYPE = kMeshObjectSceneData;
00043 
00044     MeshObjectSceneData() :
00045             BiffObject(),
00046             _animStart(0),
00047             _animEnd(0) {
00048         _type = TYPE;
00049     }
00050 
00051     // BiffObject API
00052     void readData(ArchiveReadStream *stream, uint32 dataLength) override {
00053         _animStart = stream->readUint32LE();
00054         _animEnd = stream->readUint32LE();
00055     }
00056 
00057 private:
00058     uint32 _animStart;
00059     uint32 _animEnd;
00060 };
00061 
00062 class MeshObjectBase : public BiffObject {
00063 public:
00064     static const uint32 TYPE = kMeshObjectBase;
00065 
00066     MeshObjectBase() :
00067             BiffObject() {
00068         _type = TYPE;
00069     }
00070 
00071     // BiffObject API
00072     void readData(ArchiveReadStream *stream, uint32 dataLength) override {
00073         _name = stream->readString16();
00074     }
00075 
00076 private:
00077     Common::String _name;
00078 };
00079 
00080 class MeshObjectTri : public BiffObject {
00081 public:
00082     static const uint32 TYPE = kMeshObjectTri;
00083 
00084     MeshObjectTri() :
00085             BiffObject(),
00086             _hasPhysics(false) {
00087         _type = TYPE;
00088     }
00089 
00090     struct KeyFrame {
00091         uint32 time;
00092         Math::Quaternion essentialRotation;
00093         float determinant;
00094         Math::Quaternion stretchRotation;
00095         Math::Vector3d scale;
00096         Math::Vector3d translation;
00097     };
00098 
00099     struct Vertex {
00100         Common::String animName1;
00101         Common::String animName2;
00102         float animInfluence1;
00103         float animInfluence2;
00104         Math::Vector3d position;
00105     };
00106 
00107     struct RawFace {
00108         uint32 vertexIndex[3];
00109         uint32 normalIndex[3];
00110         uint32 textureVertexIndex[3];
00111         uint32 materialId;
00112         uint32 smoothingGroup;
00113     };
00114 
00115     // BiffObject API
00116     void readData(ArchiveReadStream *stream, uint32 dataLength) override {
00117         _name = stream->readString16();
00118 
00119         uint32 keyFrameCount = stream->readUint32LE();
00120         for (uint i = 0; i < keyFrameCount; i++) {
00121             KeyFrame keyFrame;
00122             keyFrame.time = stream->readUint32LE();
00123             keyFrame.essentialRotation = stream->readQuaternion();
00124             keyFrame.determinant = stream->readFloat();
00125             keyFrame.stretchRotation = stream->readQuaternion();
00126             keyFrame.scale = stream->readVector3();
00127             keyFrame.translation = stream->readVector3();
00128 
00129             _keyFrames.push_back(keyFrame);
00130         }
00131 
00132         if (_version >= 2) {
00133             uint32 uvKeyFrameCount = stream->readUint32LE();
00134             assert(uvKeyFrameCount == 0); // Reading the uv keyframes is not implemented
00135             uint32 attributeCount = stream->readUint32LE();
00136             assert(attributeCount == 0); // Reading the attributes is not implemented
00137         }
00138 
00139         uint32 vertexCount = stream->readUint32LE();
00140         for (uint i = 0; i < vertexCount; i++) {
00141             Vertex vertex;
00142             vertex.animName1 = stream->readString16();
00143             vertex.animName2 = stream->readString16();
00144             vertex.animInfluence1 = stream->readFloat();
00145             vertex.animInfluence2 = stream->readFloat();
00146             vertex.position = stream->readVector3();
00147 
00148             _rawVertices.push_back(vertex);
00149         }
00150 
00151         uint32 normalCount = stream->readUint32LE();
00152         for (uint i = 0; i < normalCount; i++) {
00153             _rawNormals.push_back(stream->readVector3());
00154         }
00155 
00156         uint32 textureVertexCount = stream->readUint32LE();
00157         for (uint i = 0; i < textureVertexCount; i++) {
00158             _rawTexturePositions.push_back(stream->readVector3());
00159         }
00160 
00161         uint32 faceCount = stream->readUint32LE();
00162         for (uint i = 0; i < faceCount; i++) {
00163             RawFace face;
00164             face.vertexIndex[0] = stream->readUint32LE();
00165             face.vertexIndex[1] = stream->readUint32LE();
00166             face.vertexIndex[2] = stream->readUint32LE();
00167             face.normalIndex[0] = stream->readUint32LE();
00168             face.normalIndex[1] = stream->readUint32LE();
00169             face.normalIndex[2] = stream->readUint32LE();
00170             face.textureVertexIndex[0] = stream->readUint32LE();
00171             face.textureVertexIndex[1] = stream->readUint32LE();
00172             face.textureVertexIndex[2] = stream->readUint32LE();
00173             face.materialId = stream->readUint32LE();
00174             face.smoothingGroup = stream->readUint32LE();
00175 
00176             _rawFaces.push_back(face);
00177         }
00178 
00179         _hasPhysics = stream->readByte();
00180     }
00181 
00182     void reindex() {
00183         // The raw data loaded from the BIFF archive needs to be split into faces of identical material.
00184         // Reserve enough faces in our faces array
00185         for (uint i = 0; i < _rawFaces.size(); i++) {
00186             if (_rawFaces[i].materialId >= _faces.size()) {
00187                 _faces.resize(_rawFaces[i].materialId + 1);
00188             }
00189             _faces[_rawFaces[i].materialId].materialId = _rawFaces[i].materialId;
00190         }
00191 
00192         // The raw data loaded from the BIFF archive is multi-indexed, which is not simple to use to draw.
00193         // Here, we reindex the data so that each vertex owns all of its related attributes, hence requiring
00194         // a single index list.
00195         Common::HashMap<VertexKey, uint32, VertexKey::Hash, VertexKey::EqualTo> vertexIndexMap;
00196         for (uint i = 0; i < _rawFaces.size(); i++) {
00197             for (uint j = 0; j < 3; j++) {
00198                 VertexKey vertexKey(_rawFaces[i].vertexIndex[j], _rawFaces[i].normalIndex[j], _rawFaces[i].textureVertexIndex[j]);
00199                 if (!vertexIndexMap.contains(vertexKey)) {
00200                     BiffMesh::Vertex vertex;
00201                     vertex.position = _rawVertices[_rawFaces[i].vertexIndex[j]].position;
00202                     vertex.normal = _rawNormals[_rawFaces[i].normalIndex[j]];
00203                     vertex.texturePosition = _rawTexturePositions[_rawFaces[i].textureVertexIndex[j]];
00204 
00205                     _vertices.push_back(vertex);
00206 
00207                     vertexIndexMap.setVal(vertexKey, _vertices.size() - 1);
00208                 }
00209 
00210                 uint32 vertexIndex = vertexIndexMap.getVal(vertexKey);
00211 
00212                 // Add the index to a face according to its material
00213                 _faces[_rawFaces[i].materialId].vertexIndices.push_back(vertexIndex);
00214             }
00215         }
00216 
00217         // Clear the raw data
00218         _rawVertices.clear();
00219         _rawNormals.clear();
00220         _rawTexturePositions.clear();
00221         _rawFaces.clear();
00222     }
00223 
00224     Math::Matrix4 getTransform(uint keyframeIndex) const {
00225         const KeyFrame &keyframe = _keyFrames[keyframeIndex];
00226 
00227         Math::Matrix4 translation;
00228         translation.setPosition(keyframe.translation);
00229 
00230         Math::Matrix4 essentialRotation = keyframe.essentialRotation.toMatrix();
00231 
00232         Math::Matrix4 determinant;
00233         determinant.setValue(0, 0, keyframe.determinant);
00234         determinant.setValue(1, 1, keyframe.determinant);
00235         determinant.setValue(2, 2, keyframe.determinant);
00236 
00237         Math::Matrix4 stretchRotation = keyframe.stretchRotation.toMatrix();
00238 
00239         Math::Matrix4 stretchRotationTransposed = stretchRotation;
00240         stretchRotationTransposed.transpose();
00241 
00242         Math::Matrix4 scale;
00243         scale.setValue(0, 0, keyframe.scale.x());
00244         scale.setValue(1, 1, keyframe.scale.y());
00245         scale.setValue(2, 2, keyframe.scale.z());
00246 
00247         return translation * essentialRotation * determinant * stretchRotationTransposed * scale * stretchRotation;
00248     }
00249 
00250     const Common::Array<BiffMesh::Vertex> &getVertices() const {
00251         return _vertices;
00252     }
00253 
00254     const Common::Array<Face> &getFaces() const {
00255         return _faces;
00256     }
00257 
00258 private:
00259     struct VertexKey {
00260         uint32 _vertexIndex;
00261         uint32 _normalIndex;
00262         uint32 _textureVertexIndex;
00263 
00264         VertexKey(uint32 vertexIndex, uint32 normalIndex, uint32 textureVertexIndex) {
00265             _vertexIndex = vertexIndex;
00266             _normalIndex = normalIndex;
00267             _textureVertexIndex = textureVertexIndex;
00268         }
00269 
00270         struct Hash {
00271             uint operator() (const VertexKey &x) const {
00272                 return x._vertexIndex + x._normalIndex + x._textureVertexIndex;
00273             }
00274         };
00275 
00276         struct EqualTo {
00277             bool operator() (const VertexKey &x, const VertexKey &y) const {
00278                 return x._vertexIndex == y._vertexIndex &&
00279                         x._normalIndex == y._normalIndex &&
00280                         x._textureVertexIndex == y._textureVertexIndex;
00281             }
00282         };
00283     };
00284 
00285     Common::String _name;
00286 
00287     Common::Array<KeyFrame> _keyFrames;
00288 
00289     Common::Array<Vertex> _rawVertices;
00290     Common::Array<RawFace> _rawFaces;
00291     Common::Array<Math::Vector3d> _rawNormals;
00292     Common::Array<Math::Vector3d> _rawTexturePositions;
00293 
00294     Common::Array<BiffMesh::Vertex> _vertices;
00295     Common::Array<Face> _faces;
00296 
00297     bool _hasPhysics;
00298 };
00299 
00300 class MeshObjectMaterial : public BiffObject {
00301 public:
00302     static const uint32 TYPE = kMeshObjectMaterial;
00303 
00304     MeshObjectMaterial() :
00305             BiffObject(),
00306             _shading(0),
00307             _shininess(0),
00308             _opacity(1),
00309             _doubleSided(false),
00310             _textureTiling(0),
00311             _alphaTiling(0),
00312             _environementTiling(0),
00313             _isColorKey(false),
00314             _colorKey(0) {
00315         _type = TYPE;
00316     }
00317 
00318     // BiffObject API
00319     void readData(ArchiveReadStream *stream, uint32 dataLength) override {
00320         _name = stream->readString16();
00321         _texture = stream->readString16();
00322         _alpha = stream->readString16();
00323         _environment = stream->readString16();
00324 
00325         _shading = stream->readUint32LE();
00326         _ambiant = stream->readVector3();
00327         _diffuse = stream->readVector3();
00328         _specular = stream->readVector3();
00329 
00330         _shininess = stream->readFloat();
00331         _opacity = stream->readFloat();
00332 
00333         _doubleSided = stream->readByte();
00334         _textureTiling = stream->readUint32LE();
00335         _alphaTiling = stream->readUint32LE();
00336         _environementTiling = stream->readUint32LE();
00337 
00338         _isColorKey = stream->readByte();
00339         _colorKey = stream->readUint32LE();
00340 
00341         uint32 attributeCount = stream->readUint32LE();
00342         assert(attributeCount == 0); // Reading the attributes is not implemented
00343     }
00344 
00345     Material toMaterial() const {
00346         Material material;
00347         material.name = _name;
00348         material.texture = _texture;
00349         material.r = _diffuse.x();
00350         material.g = _diffuse.y();
00351         material.b = _diffuse.z();
00352         material.doubleSided = _doubleSided;
00353 
00354         return material;
00355     }
00356 
00357 private:
00358     Common::String _name;
00359     Common::String _texture;
00360     Common::String _alpha;
00361     Common::String _environment;
00362 
00363     uint32 _shading;
00364     Math::Vector3d _ambiant;
00365     Math::Vector3d _diffuse;
00366     Math::Vector3d _specular;
00367 
00368     float _shininess;
00369     float _opacity;
00370 
00371     bool _doubleSided;
00372     uint32 _textureTiling;
00373     uint32 _alphaTiling;
00374     uint32 _environementTiling;
00375 
00376     bool _isColorKey;
00377     uint32 _colorKey;
00378 };
00379 
00380 BiffMesh *BiffMeshReader::read(ArchiveReadStream *stream) {
00381     BiffArchive archive = BiffArchive(stream, &biffObjectBuilder);
00382     Common::Array<MeshObjectTri *> tris = archive.listObjectsRecursive<MeshObjectTri>();
00383     Common::Array<MeshObjectMaterial *> materialObjects = archive.listObjectsRecursive<MeshObjectMaterial>();
00384 
00385     if (tris.size() != 1) {
00386         error("Unexpected tri count in BIFF archive: '%d'", tris.size());
00387     }
00388 
00389     tris[0]->reindex();
00390 
00391     Common::Array<Material> materials;
00392     for (uint i = 0; i < materialObjects.size(); i++) {
00393         materials.push_back(materialObjects[i]->toMaterial());
00394     }
00395 
00396     BiffMesh *mesh = new BiffMesh(tris[0]->getVertices(), tris[0]->getFaces(), materials);
00397     mesh->setTransform(tris[0]->getTransform(0));
00398     return mesh;
00399 }
00400 
00401 BiffObject *BiffMeshReader::biffObjectBuilder(uint32 type) {
00402     switch (type) {
00403         case kMeshObjectSceneData:
00404             return new MeshObjectSceneData();
00405         case kMeshObjectBase:
00406             return new MeshObjectBase();
00407         case kMeshObjectTri:
00408             return new MeshObjectTri();
00409         case kMeshObjectMaterial:
00410             return new MeshObjectMaterial();
00411         default:
00412             return nullptr;
00413     }
00414 }
00415 
00416 BiffMesh::BiffMesh(const Common::Array<Vertex> &vertices, const Common::Array<Face> &faces,
00417                    const Common::Array<Material> &materials) :
00418         _vertices(vertices),
00419         _faces(faces),
00420         _materials(materials) {
00421 }
00422 
00423 const Common::Array<BiffMesh::Vertex> &BiffMesh::getVertices() const {
00424     return _vertices;
00425 }
00426 
00427 const Common::Array<Face> &BiffMesh::getFaces() const {
00428     return _faces;
00429 }
00430 
00431 const Common::Array<Material> &BiffMesh::getMaterials() const {
00432     return _materials;
00433 }
00434 
00435 void BiffMesh::setTransform(const Math::Matrix4 &transform) {
00436     _transform = transform;
00437 }
00438 
00439 Math::Matrix4 BiffMesh::getTransform() const {
00440     return _transform;
00441 }
00442 
00443 } // End of namespace Formats
00444 } // End of namespace Stark


Generated on Sat Mar 16 2019 05:01:20 for ResidualVM by doxygen 1.7.1
curved edge   curved edge