mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-20 10:37:37 -04:00
z sort portal gun
This commit is contained in:
parent
adff490004
commit
e4d12713ec
|
@ -1 +1 @@
|
||||||
-m assets/materials/objects.skm.yaml
|
-m assets/materials/objects.skm.yaml --sort-dir 0.029977,0.118112,0.030978
|
|
@ -111,6 +111,7 @@ int main(int argc, char *argv[]) {
|
||||||
settings.mForcePallete = args.mForcePallete;
|
settings.mForcePallete = args.mForcePallete;
|
||||||
settings.mTargetCIBuffer = args.mTargetCIBuffer;
|
settings.mTargetCIBuffer = args.mTargetCIBuffer;
|
||||||
settings.mTicksPerSecond = args.mFPS;
|
settings.mTicksPerSecond = args.mFPS;
|
||||||
|
settings.mSortDirection = args.mSortDirection;
|
||||||
|
|
||||||
bool hasError = false;
|
bool hasError = false;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
#include "CommandLineParser.h"
|
#include "CommandLineParser.h"
|
||||||
|
|
||||||
void parseEulerAngles(const std::string& input, aiVector3D& output) {
|
void parseVector3(const std::string& input, aiVector3D& output) {
|
||||||
std::size_t firstComma = input.find(',');
|
std::size_t firstComma = input.find(',');
|
||||||
std::size_t secondComma = input.find(',', firstComma + 1);
|
std::size_t secondComma = input.find(',', firstComma + 1);
|
||||||
output.x = (float)atof(input.substr(0, firstComma).c_str());
|
output.x = (float)atof(input.substr(0, firstComma).c_str());
|
||||||
|
@ -53,7 +53,9 @@ bool parseCommandLineArguments(int argc, char *argv[], struct CommandLineArgumen
|
||||||
} else if (lastParameter == "materials") {
|
} else if (lastParameter == "materials") {
|
||||||
output.mMaterialFiles.push_back(curr);
|
output.mMaterialFiles.push_back(curr);
|
||||||
} else if (lastParameter == "rotate") {
|
} else if (lastParameter == "rotate") {
|
||||||
parseEulerAngles(curr, output.mEulerAngles);
|
parseVector3(curr, output.mEulerAngles);
|
||||||
|
} else if (lastParameter == "sort-dir") {
|
||||||
|
parseVector3(curr, output.mSortDirection);
|
||||||
} else if (lastParameter == "default-material") {
|
} else if (lastParameter == "default-material") {
|
||||||
output.mDefaultMaterial = curr;
|
output.mDefaultMaterial = curr;
|
||||||
} else if (lastParameter == "force-material") {
|
} else if (lastParameter == "force-material") {
|
||||||
|
@ -91,6 +93,8 @@ bool parseCommandLineArguments(int argc, char *argv[], struct CommandLineArgumen
|
||||||
strcmp(curr, "-r") == 0 ||
|
strcmp(curr, "-r") == 0 ||
|
||||||
strcmp(curr, "--rotate") == 0) {
|
strcmp(curr, "--rotate") == 0) {
|
||||||
lastParameter = "rotate";
|
lastParameter = "rotate";
|
||||||
|
} else if (strcmp(curr, "--sort-dir") == 0) {
|
||||||
|
lastParameter = "sort-dir";
|
||||||
} else if (
|
} else if (
|
||||||
strcmp(curr, "--pallete") == 0) {
|
strcmp(curr, "--pallete") == 0) {
|
||||||
lastParameter = "pallete";
|
lastParameter = "pallete";
|
||||||
|
|
|
@ -33,6 +33,7 @@ struct CommandLineArguments {
|
||||||
bool mTargetCIBuffer;
|
bool mTargetCIBuffer;
|
||||||
bool mProcessAsModel;
|
bool mProcessAsModel;
|
||||||
aiVector3D mEulerAngles;
|
aiVector3D mEulerAngles;
|
||||||
|
aiVector3D mSortDirection;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool parseCommandLineArguments(int argc, char *argv[], struct CommandLineArguments& output);
|
bool parseCommandLineArguments(int argc, char *argv[], struct CommandLineArguments& output);
|
||||||
|
|
|
@ -33,6 +33,8 @@ struct DisplayListSettings {
|
||||||
bool mBonesAsVertexGroups;
|
bool mBonesAsVertexGroups;
|
||||||
bool mTargetCIBuffer;
|
bool mTargetCIBuffer;
|
||||||
|
|
||||||
|
aiVector3D mSortDirection;
|
||||||
|
|
||||||
aiMatrix4x4 CreateGlobalTransform() const;
|
aiMatrix4x4 CreateGlobalTransform() const;
|
||||||
aiMatrix4x4 CreateCollisionTransform() const;
|
aiMatrix4x4 CreateCollisionTransform() const;
|
||||||
|
|
||||||
|
|
174
skelatool64/src/ZSorter.cpp
Normal file
174
skelatool64/src/ZSorter.cpp
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
#include "ZSorter.h"
|
||||||
|
|
||||||
|
struct SingleFace {
|
||||||
|
aiFace* face;
|
||||||
|
std::pair<Bone*, Bone*> bonePair;
|
||||||
|
ExtendedMesh* mesh;
|
||||||
|
Material* material;
|
||||||
|
aiNode* meshRoot;
|
||||||
|
ai_real sortKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FaceIndices {
|
||||||
|
unsigned indices[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EditableMesh {
|
||||||
|
std::vector<unsigned> sourceIndex;
|
||||||
|
std::vector<FaceIndices> faces;
|
||||||
|
};
|
||||||
|
|
||||||
|
void renderChunksFlush(EditableMesh& target, std::vector<SingleFace>::iterator start, std::vector<SingleFace>::iterator end, std::map<unsigned, unsigned>& indexMapping) {
|
||||||
|
for (auto face = start; face != end; ++face) {
|
||||||
|
FaceIndices newFace;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < 3 && i < face->face->mNumIndices; ++i) {
|
||||||
|
auto index = indexMapping.find(face->face->mIndices[i]);
|
||||||
|
|
||||||
|
if (index == indexMapping.end()) {
|
||||||
|
newFace.indices[i] = 0;
|
||||||
|
} else {
|
||||||
|
newFace.indices[i] = index->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
target.faces.push_back(newFace);
|
||||||
|
}
|
||||||
|
|
||||||
|
indexMapping.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderChunk renderChunksRebuildFromFaces(std::vector<SingleFace>::iterator start, std::vector<SingleFace>::iterator end, unsigned chunkIndex, unsigned maxBufferSize, BoneHierarchy& boneHeirarchy) {
|
||||||
|
std::map<unsigned, unsigned> indexMapping;
|
||||||
|
|
||||||
|
EditableMesh mesh;
|
||||||
|
|
||||||
|
std::vector<SingleFace>::iterator lastFlushStart = start;
|
||||||
|
|
||||||
|
ExtendedMesh* source = lastFlushStart->mesh;
|
||||||
|
|
||||||
|
for (auto face = start; face != end; ++face) {
|
||||||
|
unsigned neededIndices = 0;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < face->face->mNumIndices; ++i) {
|
||||||
|
if (indexMapping.find(face->face->mIndices[i]) == indexMapping.end()) {
|
||||||
|
++neededIndices;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (neededIndices + indexMapping.size() > maxBufferSize) {
|
||||||
|
renderChunksFlush(mesh, lastFlushStart, face, indexMapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < face->face->mNumIndices; ++i) {
|
||||||
|
if (indexMapping.find(face->face->mIndices[i]) != indexMapping.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned index = face->face->mIndices[i];
|
||||||
|
unsigned newIndex = mesh.sourceIndex.size();
|
||||||
|
indexMapping[index] = newIndex;
|
||||||
|
mesh.sourceIndex.push_back(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderChunksFlush(mesh, lastFlushStart, end, indexMapping);
|
||||||
|
|
||||||
|
aiMesh* newAiMesh = new aiMesh();
|
||||||
|
newAiMesh->mNumVertices = mesh.sourceIndex.size();
|
||||||
|
|
||||||
|
newAiMesh->mVertices = new aiVector3D[newAiMesh->mNumVertices];
|
||||||
|
|
||||||
|
if (source->mMesh->mNormals) {
|
||||||
|
newAiMesh->mNormals = new aiVector3D[newAiMesh->mNumVertices];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; ++i) {
|
||||||
|
if (source->mMesh->mTextureCoords[i]) {
|
||||||
|
newAiMesh->mTextureCoords[i] = new aiVector3D[newAiMesh->mNumVertices];
|
||||||
|
}
|
||||||
|
if (source->mMesh->mColors[i]) {
|
||||||
|
newAiMesh->mColors[i] = new aiColor4D[newAiMesh->mNumVertices];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newAiMesh->mAABB = source->mMesh->mAABB;
|
||||||
|
newAiMesh->mName = source->mMesh->mName;
|
||||||
|
newAiMesh->mMaterialIndex = source->mMesh->mMaterialIndex;
|
||||||
|
|
||||||
|
char indexAsString[10];
|
||||||
|
sprintf(indexAsString, "_%d", chunkIndex);
|
||||||
|
newAiMesh->mName.Append(indexAsString);
|
||||||
|
|
||||||
|
for (unsigned newIndex = 0; newIndex < newAiMesh->mNumVertices; ++newIndex) {
|
||||||
|
unsigned sourceIndex = mesh.sourceIndex[newIndex];
|
||||||
|
newAiMesh->mVertices[newIndex] = source->mMesh->mVertices[sourceIndex];
|
||||||
|
if (newAiMesh->mNormals) newAiMesh->mNormals[newIndex] = source->mMesh->mNormals[sourceIndex];
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; ++i) {
|
||||||
|
if (newAiMesh->mTextureCoords[i]) newAiMesh->mTextureCoords[i][newIndex] = source->mMesh->mTextureCoords[i][sourceIndex];
|
||||||
|
if (newAiMesh->mColors[i]) newAiMesh->mColors[i][newIndex] = source->mMesh->mColors[i][sourceIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newAiMesh->mNumFaces = mesh.faces.size();
|
||||||
|
newAiMesh->mFaces = new aiFace[newAiMesh->mNumFaces];
|
||||||
|
|
||||||
|
for (unsigned faceIndex = 0; faceIndex < newAiMesh->mNumFaces; ++faceIndex) {
|
||||||
|
newAiMesh->mFaces[faceIndex].mNumIndices = 3;
|
||||||
|
newAiMesh->mFaces[faceIndex].mIndices = new unsigned[3];
|
||||||
|
std::copy(mesh.faces[faceIndex].indices, mesh.faces[faceIndex].indices + 3, newAiMesh->mFaces[faceIndex].mIndices);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ExtendedMesh> newMesh(new ExtendedMesh(newAiMesh, boneHeirarchy));
|
||||||
|
|
||||||
|
return RenderChunk(start->bonePair, newMesh, start->meshRoot, start->material);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<RenderChunk> renderChunksSortByZ(const std::vector<RenderChunk>& source, const aiVector3D& direction, unsigned maxBufferSize, BoneHierarchy& boneHeirarchy) {
|
||||||
|
std::vector<SingleFace> faces;
|
||||||
|
|
||||||
|
for (auto chunk : source) {
|
||||||
|
for (auto face : chunk.GetFaces()) {
|
||||||
|
SingleFace singleFace;
|
||||||
|
|
||||||
|
aiVector3D faceAverage;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < face->mNumIndices; ++i) {
|
||||||
|
faceAverage = faceAverage + chunk.mMesh->mMesh->mVertices[face->mIndices[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
faceAverage = (1.0f / (ai_real)face->mNumIndices) * faceAverage;
|
||||||
|
|
||||||
|
singleFace.face = face;
|
||||||
|
singleFace.mesh = chunk.mMesh.get();
|
||||||
|
singleFace.material = chunk.mMaterial;
|
||||||
|
singleFace.meshRoot = chunk.mMeshRoot;
|
||||||
|
singleFace.sortKey = faceAverage * direction;
|
||||||
|
|
||||||
|
faces.push_back(singleFace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(faces.begin(), faces.end(), [](const SingleFace& a, const SingleFace& b) {
|
||||||
|
return a.sortKey < b.sortKey;
|
||||||
|
});
|
||||||
|
|
||||||
|
std::vector<RenderChunk> result;
|
||||||
|
|
||||||
|
auto lastStart = faces.begin();
|
||||||
|
|
||||||
|
int chunkIndex = 0;
|
||||||
|
|
||||||
|
for (auto it = faces.begin(); it != faces.end(); ++it) {
|
||||||
|
if (lastStart->mesh != it->mesh || lastStart->material != it->material || lastStart->meshRoot != it->meshRoot) {
|
||||||
|
result.push_back(renderChunksRebuildFromFaces(lastStart, it, chunkIndex, maxBufferSize, boneHeirarchy));
|
||||||
|
lastStart = it;
|
||||||
|
++chunkIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push_back(renderChunksRebuildFromFaces(lastStart, faces.end(), chunkIndex, maxBufferSize, boneHeirarchy));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
8
skelatool64/src/ZSorter.h
Normal file
8
skelatool64/src/ZSorter.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef __ZSORTER_H__
|
||||||
|
#define __ZSORTER_H__
|
||||||
|
|
||||||
|
#include "./RenderChunk.h"
|
||||||
|
|
||||||
|
std::vector<RenderChunk> renderChunksSortByZ(const std::vector<RenderChunk>& source, const aiVector3D& direction, unsigned maxBufferSize, BoneHierarchy& boneHeirarchy);
|
||||||
|
|
||||||
|
#endif
|
|
@ -6,6 +6,7 @@
|
||||||
#include "../StringUtils.h"
|
#include "../StringUtils.h"
|
||||||
#include "MaterialGenerator.h"
|
#include "MaterialGenerator.h"
|
||||||
#include "../RenderChunkOrder.h"
|
#include "../RenderChunkOrder.h"
|
||||||
|
#include "../ZSorter.h"
|
||||||
|
|
||||||
bool extractMaterialAutoTileParameters(Material* material, double& sTile, double& tTile) {
|
bool extractMaterialAutoTileParameters(Material* material, double& sTile, double& tTile) {
|
||||||
if (!material) {
|
if (!material) {
|
||||||
|
@ -156,7 +157,11 @@ MeshDefinitionResults MeshDefinitionGenerator::GenerateDefinitionsWithResults(co
|
||||||
AppendRenderChunks(scene, *node, fileDefinition, mSettings, renderChunks);
|
AppendRenderChunks(scene, *node, fileDefinition, mSettings, renderChunks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mSettings.mSortDirection.SquareLength() > 0.0) {
|
||||||
|
renderChunks = renderChunksSortByZ(renderChunks, mSettings.mSortDirection, mSettings.mVertexCacheSize, fileDefinition.GetBoneHierarchy());
|
||||||
|
} else {
|
||||||
orderRenderChunks(renderChunks, mSettings);
|
orderRenderChunks(renderChunks, mSettings);
|
||||||
|
}
|
||||||
|
|
||||||
MeshDefinitionResults result;
|
MeshDefinitionResults result;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue