-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathObj.h
140 lines (121 loc) · 5.45 KB
/
Obj.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//
// Created by rthier on 2016.04.08..
//
#ifndef NFTSIMPLEPROJ_OBJ_CPP_H
#define NFTSIMPLEPROJ_OBJ_CPP_H
#include "ObjectMaterialFaceGroup.h"
#include "VertexElement.h"
#include "VertexTextureElement.h"
#include "VertexNormalElement.h"
#include "FaceElement.h"
#include "ObjCommon.h"
#include "AssetLibrary.h"
#include "MtlLib.h"
#include <memory>
#include <vector>
#include <unordered_map>
namespace ObjMaster {
/**
* Represents a *.obj file. The semantic structure of the object is the same as the file. So
* the resulting representation after parsing is generally still not feasible for rendering.
* See ObjMeshObject and similar classes for the rendering possibilities using this model.
*/
class Obj final {
public:
/**
* Used to initialize the vectors for vertices / normals / texture coordinates for models
*/
static const int EXPECTED_VERTEX_DATA_NUM = 256;
/** Used to initialize the vectorfor faces - should be reasonable for usual models */
static const int EXPECTED_FACES_NUM = 128;
// Various geometry elements
std::vector<VertexElement> vs;
std::vector<VertexTextureElement> vts;
std::vector<VertexNormalElement> vns;
std::vector<FaceElement> fs;
/** The given path - saved on construction made nullptr in case of runtime generated or copied objects */
std::string objPath;
/** The material library for this obj. It can be an empty material library. */
MtlLib mtlLib;
/** (objectgroup-name:material-name) -> (objectgroup-name, material, faces) */
std::unordered_map<std::string, ObjectMaterialFaceGroup> objectMaterialGroups;
/** Create an empty - non-loaded - obj representation */
Obj() {}
// Copies are defeaulted
Obj(const Obj &other) = default;
Obj& operator=(const Obj &other) = default;
// Moves are defaulted
Obj(Obj &&other) = default;
Obj& operator=(Obj &&other) = default;
/**
* Creates an Obj for the given asset. The given asset library is only used for construction
* and is not stored so the ownership of the referenced object stays at the host code!
*/
Obj(const AssetLibrary &assetLibrary, const char* path, const char* fileName);
/**
* Creates an Obj for the given asset. The given vertex and face data
* numbers are used when parsing the file but the object will be constructed even when
* the file contains more data than the expectations! These values are used to instrument
* the default allocations so it is helpful when optimizing for memory or speed.
* The given asset library is only used for construction and is not stored so the ownership
* of the referenced object stays at the host code!
*/
Obj(const AssetLibrary &assetLibrary, const char *path, const char *fileName,
int expectedVertexDataNum, int expectedFaceNum);
// Rem.: bit trickery here
/** Defines the saving mode */
enum ObjSaveModeFlags{
/** Only vertices, texcoords and normals plus the faces. No grouping and no materials. */
ONLY_UNGROUPED_GEOMETRY = 0,
/** Saving materials - no grouping */
MATERIALS_GEOMETRY = 1,
/** Saving 'o' groups - no materials */
GROUPS_GEOMETRY = 2,
/** Both materials and 'o' groups */
MATERIALS_AND_GROUPS = 3,
// 4) Rem.: bit at position 3 means using 'g' instead of 'o'
/** !!UNUSED!! */
G = 4,
/** Saving 'g' groups - no materials */
G_GROUPS_GEOMETRY = 2+4,
/** Both materials and 'g' groups */
MATERIALS_AND_G_GROUPS = 3+4,
};
/** Save this Obj as a (relative) *.obj - using the given fileName and the provided asset-out library. By default this also saves the *.mtl */
inline void saveAs(const AssetOutputLibrary &assetOutputLibrary, const char* fileName, bool saveAsMtlToo = true, ObjSaveModeFlags saveMode = ObjSaveModeFlags::MATERIALS_AND_GROUPS) {
// Just delegate to the real method
saveAs(assetOutputLibrary, "", fileName, saveAsMtlToo, saveMode);
}
/** Save this Obj as an (absolute) *.obj - using the given path, fileName and the provided asset-out library. By default this also saves the *.mtl */
void saveAs(const AssetOutputLibrary &assetOutputLibrary, const char* path, const char* fileName, bool saveAsMtlToo = true, ObjSaveModeFlags saveMode = ObjSaveModeFlags::MATERIALS_AND_GROUPS);
private:
void constructionHelper(const AssetLibrary &assetLibrary,
const char *path, const char *fileName,
int expectedVertexDataNum, int expectedFaceNum);
/**
* Helper method used to extend the material face groups with the given data.
*/
void extendObjectMaterialGroups(std::string ¤tObjectGroupName,
TextureDataHoldingMaterial ¤tMaterial,
int currentObjectMaterialFacesPointer,
int sizeOfFaceStripe);
friend class ObjCreator;
};
/** Run tests for underlying elements */
static bool TEST_Obj() {
#ifdef DEBUG
OMLOGI("TEST_Obj...");
#endif
bool res = true;
res &= ObjMaster::TEST_VertexElement();
res &= ObjMaster::TEST_VertexNormalElement();
res &= ObjMaster::TEST_VertexTextureElement();
res &= ObjMaster::TEST_FaceElement();
res &= ObjMaster::TEST_FacePoint();
#ifdef DEBUG
OMLOGI("...TEST_Obj ended!");
#endif
return res;
}
}
#endif //NFTSIMPLEPROJ_OBJ_CPP_H