Я пытаюсь объединить несколько сеток с матрицей преобразования в одну сетку.Каждая сетка имеет 4 набора данных.
- Вершины
- Индексы
- Координаты текстуры
- Нормы
ПутьЯ пытаюсь сделать это должно быть ленивым и не стоить так много процессора.Это трехэтапный процесс.
- Умножьте каждую вершину и нормаль на матрицу преобразования.
- Объедините вершины, координаты текстуры и нормали каждой сетки в 3 больших массива.
- Объедините индексы каждой сетки в один массив, но используйте сумму предыдущих сеток в качестве смещения.Например: если сетка 1 имеет 800 индексов, то 800 необходимо добавить ко всем индексам из сетки 2.
У этого метода есть две большие проблемы.
- Дублироватьвершины не являются общими
- Части, которые невидимы из-за отсечения, не удаляются
Но это нормально, так как предполагается, что это ленивый метод с небольшим использованием ЦП.Он уже оптимален для создания сеток для травы и кустов.
Я попытался реализовать этот метод, который выглядит следующим образом:
public static final MeshData mergeLazy(List<MeshData> meshes, List<Matrix4f> transformations) {
int lengthVertices = 0;
int lengthNormals = 0;
int lengthTexCoords = 0;
int lengthIndices = 0;
ArrayList<Integer> indexLengths = new ArrayList<>();
for(MeshData mesh : meshes) {
lengthVertices += mesh.getVertices().length;
lengthNormals += mesh.getNormals().length;
lengthTexCoords += mesh.getTextureCoordinates().length;
int length = mesh.getIndices().length;
lengthIndices += length;
indexLengths.add(length);
}
float[] vertices = new float[lengthVertices];
float[] texCoords = new float[lengthTexCoords];
float[] normals = new float[lengthNormals];
int[] indices = new int[lengthIndices];
int iv = 0;
int ivt = 0;
int ivn = 0;
int i = 0;
int indexLength = 0;
for(int im = 0; im < meshes.size(); im++) {
MeshData mesh = meshes.get(im);
float[] mVertices = mesh.getVertices();
float[] mTexCoords = mesh.getTextureCoordinates();
float[] mNormals = mesh.getNormals();
int[] mIndices = mesh.getIndices();
Matrix4f transformation = transformations.get(im);
for(int index = 0; index < mVertices.length; index += 3) {
Vector3f vertex = MatrixUtil.multiply(transformation, mVertices[index], mVertices[index + 1], mVertices[index + 2]);
vertices[iv++] = vertex.x;
vertices[iv++] = vertex.y;
vertices[iv++] = vertex.z;
Vector3f normal = MatrixUtil.multiply(transformation, mNormals[index], mNormals[index + 1], mNormals[index + 2]);
normals[ivn++] = normal.x;
normals[ivn++] = normal.y;
normals[ivn++] = normal.z;
}
for(int index = 0; index < mTexCoords.length; index++) {
texCoords[ivt++] = mTexCoords[index];
}
for(int index = 0; index < mIndices.length; index++) {
indices[i++] = indexLength + mIndices[index];
}
indexLength += indexLengths.get(im);
}
MeshData data = new MeshData();
data.setIndices(indices);
data.setNormals(normals);
data.setTextureCoordinates(texCoords);
data.setVertices(vertices);
return data;
}
В конце концов, у меня фактически есть одна сетка иумножение преобразования также работает .... для вращения и масштабирования, но здесь возникают проблемы.
Умножение с преобразованием НЕ работает для перевода.Мой метод умножения матрицы на вектор выглядит следующим образом:
public static final Vector3f multiply(Matrix4f matrix, float x, float y, float z) {
Vector3f result = new Vector3f();
result.x = x * matrix.m00 + y * matrix.m01 + z * matrix.m02;
result.y = x * matrix.m10 + y * matrix.m11 + z * matrix.m12;
result.z = x * matrix.m20 + y * matrix.m21 + z * matrix.m22;
return result;
}
И вторая проблема заключается в том, что текстуры второй сетки несколько отключены.
Вот картинка: ![Error](https://i.stack.imgur.com/OWy8j.png)
Как вы можете видеть, вторая сетка имеет только около 1/4 фактической текстуры.
Код, который я использовал для генерации этой сетки, выглядит следующим образом:
Material grassMaterial = new Material();
grassMaterial.setMinBrightness(0.1F);
grassMaterial.setColorMap(new Texture(new XImgTextureReader().read(new FileInputStream("res/textures/grass2.ximg"))));
grassMaterial.setAffectedByLight(true);
grassMaterial.setTransparent(true);
grassMaterial.setUpwardsNormals(true);
grassMaterial.setFog(fog);
MeshData quad = Quad.generateMeshData(
new Vector3f(0.0F, 1F, 0.0F),
new Vector3f(0.0F, 0.0F, 0.0F),
new Vector3f(1F, 0.0F, 0.0F),
new Vector3f(1F, 1F, 0.0F)
);
StaticMesh grassMesh = new StaticMesh(MeshUtil.mergeLazy(Arrays.asList(quad, quad), Arrays.asList(
MatrixUtil.createTransformationMatrx(
new Vector3f(0.0F, 0.0F, 0.0F),
new Vector3f(0.0F, 0.0F, 0.0F),
new Vector3f(1.0F, 1.0F, 1.0F)
),
MatrixUtil.createTransformationMatrx(
new Vector3f(0F, 0.0F, -0F),
new Vector3f(0.0F, 90.0F, 0.0F),
new Vector3f(1.0F, 1.0F, 1.0F)
)
)));
grassMesh.setCullMode(StaticMesh.CULLING_DISABLED);
Entity grass = new Entity();
grass.setShaderPipeline(shaderPipeline);
grass.setMaterial(grassMaterial);
grass.setMesh(grassMesh);
grass.setTranslation(0, 0, 1);
Мой вопрос сейчас: что я сделал не так?Почему текстура такая странная и почему умножение с преобразованием не работает для перевода?
Если вам нужно больше кода, у меня есть репозиторий GitHub с проектом Eclipse: https://github.com/RalleYTN/Heroica-Fabulis