|
|
@@ -18,6 +18,8 @@ bool hasWeights = false;
|
|
|
vector<aiBone*> bones;
|
|
|
unsigned int numBones = 0;
|
|
|
|
|
|
+std::vector<String> materialsInFile;
|
|
|
+
|
|
|
|
|
|
bool writeNormals = false;
|
|
|
bool writeTangents = false;
|
|
|
@@ -26,6 +28,14 @@ bool writeBoneWeights = false;
|
|
|
bool writeUVs = false;
|
|
|
bool writeSecondaryUVs = false;
|
|
|
|
|
|
+bool hasMaterial(String materialName) {
|
|
|
+ for(int i=0; i < materialsInFile.size(); i++) {
|
|
|
+ if(materialsInFile[i] == materialName) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
|
|
|
unsigned int addBone(aiBone *bone) {
|
|
|
for(int i=0; i < bones.size(); i++) {
|
|
|
@@ -36,7 +46,7 @@ unsigned int addBone(aiBone *bone) {
|
|
|
return bones.size()-1;
|
|
|
}
|
|
|
|
|
|
-void addToMesh(String prefix, Polycode::Mesh *tmesh, const struct aiScene *sc, const struct aiNode* nd, bool swapZY, bool addSubmeshes, bool listOnly, ObjectEntry *parentSceneObject) {
|
|
|
+void addToMesh(String prefix, Polycode::Mesh *tmesh, const struct aiScene *sc, const struct aiNode* nd, bool swapZY, bool addSubmeshes, bool listOnly, ObjectEntry *parentSceneObject, String overrideMaterial, ObjectEntry *materialsParent, String assetPrefixPath) {
|
|
|
int i, nIgnoredPolygons = 0;
|
|
|
unsigned int n = 0, t;
|
|
|
// draw all meshes assigned to this node
|
|
|
@@ -112,13 +122,13 @@ void addToMesh(String prefix, Polycode::Mesh *tmesh, const struct aiScene *sc, c
|
|
|
}
|
|
|
|
|
|
if(fabs(vertex->x) > bBox.x) {
|
|
|
- bBox.x = vertex->x;
|
|
|
+ bBox.x = fabs(vertex->x);
|
|
|
}
|
|
|
if(fabs(vertex->y) > bBox.y) {
|
|
|
- bBox.y = vertex->y;
|
|
|
+ bBox.y = fabs(vertex->y);
|
|
|
}
|
|
|
if(fabs(vertex->z) > bBox.z) {
|
|
|
- bBox.z = vertex->z;
|
|
|
+ bBox.z = fabs(vertex->z);
|
|
|
}
|
|
|
|
|
|
tmesh->addVertex(vertex);
|
|
|
@@ -161,24 +171,54 @@ void addToMesh(String prefix, Polycode::Mesh *tmesh, const struct aiScene *sc, c
|
|
|
nd->mTransformation.Decompose(s, r, p);
|
|
|
|
|
|
meshEntry->addChild("sX", s.x);
|
|
|
- meshEntry->addChild("sY", s.y);
|
|
|
- meshEntry->addChild("sZ", s.z);
|
|
|
-
|
|
|
+
|
|
|
+ if(swapZY) {
|
|
|
+ meshEntry->addChild("sY", s.z);
|
|
|
+ meshEntry->addChild("sZ", s.y);
|
|
|
+ } else {
|
|
|
+ meshEntry->addChild("sY", s.y);
|
|
|
+ meshEntry->addChild("sZ", s.z);
|
|
|
+ }
|
|
|
+
|
|
|
meshEntry->addChild("rX", r.x);
|
|
|
- meshEntry->addChild("rY", r.y);
|
|
|
- meshEntry->addChild("rZ", r.z);
|
|
|
+
|
|
|
+ if(swapZY) {
|
|
|
+ meshEntry->addChild("rY", r.z);
|
|
|
+ meshEntry->addChild("rZ", -r.y);
|
|
|
+ } else {
|
|
|
+ meshEntry->addChild("rY", r.y);
|
|
|
+ meshEntry->addChild("rZ", r.z);
|
|
|
+ }
|
|
|
meshEntry->addChild("rW", r.w);
|
|
|
|
|
|
meshEntry->addChild("pX", p.x);
|
|
|
- meshEntry->addChild("pY", p.y);
|
|
|
- meshEntry->addChild("pZ", p.z);
|
|
|
+
|
|
|
+ if(swapZY) {
|
|
|
+ meshEntry->addChild("pY", p.z);
|
|
|
+ meshEntry->addChild("pZ", -p.y);
|
|
|
+ } else{
|
|
|
+ meshEntry->addChild("pY", p.y);
|
|
|
+ meshEntry->addChild("pZ", p.z);
|
|
|
+ }
|
|
|
+
|
|
|
+ bBox = bBox * 2.0;
|
|
|
+
|
|
|
+ if(bBox.x == 0.0) {
|
|
|
+ bBox.x = 0.001;
|
|
|
+ }
|
|
|
+ if(bBox.y == 0.0) {
|
|
|
+ bBox.y = 0.001;
|
|
|
+ }
|
|
|
+ if(bBox.z == 0.0) {
|
|
|
+ bBox.z = 0.001;
|
|
|
+ }
|
|
|
|
|
|
meshEntry->addChild("bbX", bBox.x);
|
|
|
meshEntry->addChild("bbY", bBox.y);
|
|
|
meshEntry->addChild("bbZ", bBox.z);
|
|
|
|
|
|
ObjectEntry *sceneMeshEntry = meshEntry->addChild("SceneMesh");
|
|
|
- sceneMeshEntry->addChild("file", fileNameMesh);
|
|
|
+ sceneMeshEntry->addChild("file", assetPrefixPath+fileNameMesh);
|
|
|
|
|
|
String materialName = "Default";
|
|
|
int materialIndex = mesh->mMaterialIndex;
|
|
|
@@ -189,7 +229,26 @@ void addToMesh(String prefix, Polycode::Mesh *tmesh, const struct aiScene *sc, c
|
|
|
materialName = String(name.data);
|
|
|
}
|
|
|
}
|
|
|
- sceneMeshEntry->addChild("material", materialName);
|
|
|
+
|
|
|
+ if(materialsParent && materialName != "Default") {
|
|
|
+ if(!hasMaterial(materialName)) {
|
|
|
+ ObjectEntry *materialEntry = materialsParent->addChild("material");
|
|
|
+ materialEntry->addChild("name", materialName);
|
|
|
+ materialEntry->addChild("blendingMode", 0);
|
|
|
+ materialEntry->addChild("blendingMode", 0);
|
|
|
+ ObjectEntry *shaderEntry = materialEntry->addChild("shader");
|
|
|
+ shaderEntry->addChild("name", "DefaultShaderNoTexture");
|
|
|
+ materialsInFile.push_back(materialName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(overrideMaterial != "") {
|
|
|
+ sceneMeshEntry->addChild("material", overrideMaterial);
|
|
|
+ } else {
|
|
|
+ sceneMeshEntry->addChild("material", materialName);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
if (nIgnoredPolygons) {
|
|
|
printf("Ignored %d non-triangular polygons\n", nIgnoredPolygons);
|
|
|
@@ -198,7 +257,7 @@ void addToMesh(String prefix, Polycode::Mesh *tmesh, const struct aiScene *sc, c
|
|
|
|
|
|
// draw all children
|
|
|
for (n = 0; n < nd->mNumChildren; ++n) {
|
|
|
- addToMesh(prefix, tmesh, sc, nd->mChildren[n], swapZY, addSubmeshes, listOnly, parentSceneObject);
|
|
|
+ addToMesh(prefix, tmesh, sc, nd->mChildren[n], swapZY, addSubmeshes, listOnly, parentSceneObject, overrideMaterial, materialsParent, assetPrefixPath);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -229,10 +288,19 @@ void addToISkeleton(ISkeleton *skel, IBone *parent, const struct aiScene *sc, co
|
|
|
skel->addIBone(bone, getBoneID(bone->name));
|
|
|
}
|
|
|
|
|
|
-int exportToFile(String prefix, bool swapZY, bool addSubmeshes, bool listOnly, bool exportEntity) {
|
|
|
+int exportToFile(String prefix, bool swapZY, bool addSubmeshes, bool listOnly, bool exportEntity, bool generateMaterialFile, String overrideMaterial, String assetPrefixPath, String baseFileName) {
|
|
|
|
|
|
+ Object materialObject;
|
|
|
+ ObjectEntry *materialsParent = NULL;;
|
|
|
+
|
|
|
+ if(generateMaterialFile) {
|
|
|
+ materialObject.root.name = "polycode";
|
|
|
+ materialsParent = materialObject.root.addChild("materials");
|
|
|
+ }
|
|
|
+
|
|
|
Object sceneObject;
|
|
|
sceneObject.root.name = "entity";
|
|
|
+ sceneObject.root.addChild("version", 2);
|
|
|
ObjectEntry *parentEntry = sceneObject.root.addChild("root");
|
|
|
|
|
|
parentEntry->addChild("id", "");
|
|
|
@@ -265,7 +333,7 @@ int exportToFile(String prefix, bool swapZY, bool addSubmeshes, bool listOnly, b
|
|
|
|
|
|
Polycode::Mesh *mesh = new Polycode::Mesh(Mesh::TRI_MESH);
|
|
|
mesh->indexedMesh = true;
|
|
|
- addToMesh(prefix, mesh, scene, scene->mRootNode, swapZY, addSubmeshes, listOnly, children);
|
|
|
+ addToMesh(prefix, mesh, scene, scene->mRootNode, swapZY, addSubmeshes, listOnly, children, overrideMaterial, materialsParent, assetPrefixPath);
|
|
|
|
|
|
|
|
|
if(addSubmeshes) {
|
|
|
@@ -349,13 +417,23 @@ int exportToFile(String prefix, bool swapZY, bool addSubmeshes, bool listOnly, b
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ String matFileName = baseFileName+".mat";
|
|
|
+ if(!listOnly && materialsParent) {
|
|
|
+ materialObject.saveToXML(matFileName);
|
|
|
+ }
|
|
|
+
|
|
|
if(!listOnly && exportEntity) {
|
|
|
- String entityFileName;
|
|
|
- if(prefix != "") {
|
|
|
- entityFileName = prefix+".entity";
|
|
|
- } else {
|
|
|
- entityFileName = "out.entity";
|
|
|
- } sceneObject.saveToXML(entityFileName);
|
|
|
+
|
|
|
+ if(materialsParent) {
|
|
|
+ ObjectEntry *settings = sceneObject.root.addChild("settings");
|
|
|
+ ObjectEntry *matFiles = settings->addChild("matFiles");
|
|
|
+ ObjectEntry *matFile = matFiles->addChild("matFile");
|
|
|
+ matFile->addChild("path", assetPrefixPath+matFileName);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ String entityFileName = baseFileName+".entity";
|
|
|
+ sceneObject.saveToXML(entityFileName);
|
|
|
}
|
|
|
|
|
|
if(mesh) {
|
|
|
@@ -377,11 +455,14 @@ int main(int argc, char **argv) {
|
|
|
bool showAssimpDebug = false;
|
|
|
bool generateNormals = false;
|
|
|
bool exportEntity = false;
|
|
|
-
|
|
|
+ bool generateMaterialFile = false;
|
|
|
+ String overrideMaterial;
|
|
|
+
|
|
|
String prefix;
|
|
|
+ String assetPrefixPath;
|
|
|
|
|
|
int opt;
|
|
|
- while ((opt = getopt(argc, argv, "engcwuvadlhp:stm")) != -1) {
|
|
|
+ while ((opt = getopt(argc, argv, "engcwuvadlhp:stmfo:x:")) != -1) {
|
|
|
switch ((char)opt) {
|
|
|
case 'e':
|
|
|
exportEntity = true;
|
|
|
@@ -427,7 +508,16 @@ int main(int argc, char **argv) {
|
|
|
break;
|
|
|
case 'h':
|
|
|
showHelp = true;
|
|
|
- break;
|
|
|
+ break;
|
|
|
+ case 'f':
|
|
|
+ generateMaterialFile = true;
|
|
|
+ break;
|
|
|
+ case 'o':
|
|
|
+ overrideMaterial = String(optarg);
|
|
|
+ break;
|
|
|
+ case 'x':
|
|
|
+ assetPrefixPath = String(optarg)+"/";
|
|
|
+ break;
|
|
|
default:
|
|
|
argsValid = false;
|
|
|
break;
|
|
|
@@ -448,25 +538,29 @@ int main(int argc, char **argv) {
|
|
|
}
|
|
|
|
|
|
if(showHelp || argc < 2) {
|
|
|
- printf("usage: polyimport [-adhlstngcwuvme] [-p output_prefix] source_file\n\n");
|
|
|
+ printf("usage: polyimport [-adhlstngcwuvmef] [-o override_material] [-p output_prefix] [-x asset_path] source_file\n\n");
|
|
|
printf("Misc options:\n");
|
|
|
printf("d: Show Assimp debug info.\n");
|
|
|
printf("h: Show this help.\n");
|
|
|
printf("l: List output files, but do not convert.\n");
|
|
|
- printf("p: Specify a file prefix for exported files.\n\n");
|
|
|
- printf("Mesh import options:\n");
|
|
|
+ printf("p: Specify a file prefix for exported files.\n");
|
|
|
+ printf("\nMesh import options:\n");
|
|
|
printf("a: Add all meshes to a single mesh.\n");
|
|
|
printf("s: Swap Z/Y axis (e.g. import from Blender)\n");
|
|
|
printf("m: Generate normals.\n");
|
|
|
- printf("t: Generate tangents.\n\n");
|
|
|
- printf("Mesh export options:\n");
|
|
|
+ printf("t: Generate tangents.\n");
|
|
|
+ printf("\nMesh export options:\n");
|
|
|
printf("n: Export normals\n");
|
|
|
printf("g: Export tangents\n");
|
|
|
printf("c: Export colors\n");
|
|
|
printf("w: Export bone weights\n");
|
|
|
printf("u: Export UV coordinates\n");
|
|
|
printf("v: Export secondary UV coordinates\n");
|
|
|
+ printf("\nEntity export options:\n");
|
|
|
printf("e: Export entity scene\n");
|
|
|
+ printf("f: Generate material file\n");
|
|
|
+ printf("o: Specify override material.\n");
|
|
|
+ printf("x: Specify asset prefix path.\n");
|
|
|
printf("\n");
|
|
|
return 0;
|
|
|
}
|
|
|
@@ -484,7 +578,16 @@ int main(int argc, char **argv) {
|
|
|
if(!listOnly) {
|
|
|
printf("Loading %s...\n", argv[inputArg]);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ String baseFileName = String(argv[inputArg]);
|
|
|
+
|
|
|
+ std::vector<String> parts = baseFileName.split("/");
|
|
|
+ if(parts.size() > 1) {
|
|
|
+ baseFileName = parts[parts.size()-1];
|
|
|
+ }
|
|
|
+
|
|
|
+ baseFileName = baseFileName.substr(0, baseFileName.find_last_of("."));
|
|
|
+
|
|
|
scene = aiImportFile(argv[inputArg], aiProcess_JoinIdenticalVertices|
|
|
|
aiProcess_Triangulate);
|
|
|
|
|
|
@@ -498,7 +601,7 @@ int main(int argc, char **argv) {
|
|
|
aiApplyPostProcessing(scene, aiProcess_GenSmoothNormals);
|
|
|
}
|
|
|
|
|
|
- exportToFile(prefix, swapZYAxis, addSubmeshes, listOnly, exportEntity);
|
|
|
+ exportToFile(prefix, swapZYAxis, addSubmeshes, listOnly, exportEntity, generateMaterialFile, overrideMaterial, assetPrefixPath, baseFileName);
|
|
|
} else {
|
|
|
printf("Error opening scene (%s)\n", aiGetErrorString());
|
|
|
}
|