z sort portal gun

This commit is contained in:
James Lambert 2023-08-18 22:11:57 -06:00
parent adff490004
commit e4d12713ec
8 changed files with 199 additions and 4 deletions

View file

@ -1 +1 @@
-m assets/materials/objects.skm.yaml
-m assets/materials/objects.skm.yaml --sort-dir 0.029977,0.118112,0.030978

View file

@ -111,6 +111,7 @@ int main(int argc, char *argv[]) {
settings.mForcePallete = args.mForcePallete;
settings.mTargetCIBuffer = args.mTargetCIBuffer;
settings.mTicksPerSecond = args.mFPS;
settings.mSortDirection = args.mSortDirection;
bool hasError = false;

View file

@ -1,7 +1,7 @@
#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 secondComma = input.find(',', firstComma + 1);
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") {
output.mMaterialFiles.push_back(curr);
} 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") {
output.mDefaultMaterial = curr;
} else if (lastParameter == "force-material") {
@ -91,6 +93,8 @@ bool parseCommandLineArguments(int argc, char *argv[], struct CommandLineArgumen
strcmp(curr, "-r") == 0 ||
strcmp(curr, "--rotate") == 0) {
lastParameter = "rotate";
} else if (strcmp(curr, "--sort-dir") == 0) {
lastParameter = "sort-dir";
} else if (
strcmp(curr, "--pallete") == 0) {
lastParameter = "pallete";

View file

@ -33,6 +33,7 @@ struct CommandLineArguments {
bool mTargetCIBuffer;
bool mProcessAsModel;
aiVector3D mEulerAngles;
aiVector3D mSortDirection;
};
bool parseCommandLineArguments(int argc, char *argv[], struct CommandLineArguments& output);

View file

@ -33,6 +33,8 @@ struct DisplayListSettings {
bool mBonesAsVertexGroups;
bool mTargetCIBuffer;
aiVector3D mSortDirection;
aiMatrix4x4 CreateGlobalTransform() const;
aiMatrix4x4 CreateCollisionTransform() const;

174
skelatool64/src/ZSorter.cpp Normal file
View 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;
}

View 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

View file

@ -6,6 +6,7 @@
#include "../StringUtils.h"
#include "MaterialGenerator.h"
#include "../RenderChunkOrder.h"
#include "../ZSorter.h"
bool extractMaterialAutoTileParameters(Material* material, double& sTile, double& tTile) {
if (!material) {
@ -156,7 +157,11 @@ MeshDefinitionResults MeshDefinitionGenerator::GenerateDefinitionsWithResults(co
AppendRenderChunks(scene, *node, fileDefinition, mSettings, renderChunks);
}
orderRenderChunks(renderChunks, mSettings);
if (mSettings.mSortDirection.SquareLength() > 0.0) {
renderChunks = renderChunksSortByZ(renderChunks, mSettings.mSortDirection, mSettings.mVertexCacheSize, fileDefinition.GetBoneHierarchy());
} else {
orderRenderChunks(renderChunks, mSettings);
}
MeshDefinitionResults result;