Export vertex colors to glTF.

This commit is contained in:
kovacsv 2021-12-28 21:55:53 +01:00
parent 0eee801446
commit 10f7df63bc
2 changed files with 80 additions and 38 deletions

View File

@ -209,6 +209,9 @@ OV.ExporterGltf = class extends OV.ExporterBase
for (let i = 0; i < primitive.vertices.length; i++) {
writer.WriteFloat32 (primitive.vertices[i]);
}
for (let i = 0; i < primitive.colors.length; i++) {
writer.WriteFloat32 (OV.SRGBToLinear (primitive.colors[i]));
}
for (let i = 0; i < primitive.normals.length; i++) {
writer.WriteFloat32 (primitive.normals[i]);
}
@ -245,6 +248,7 @@ OV.ExporterGltf = class extends OV.ExporterBase
byteLength : byteLength,
});
this.byteOffset += byteLength;
return this.mainJson.bufferViews.length - 1;
}
}
@ -282,33 +286,38 @@ OV.ExporterGltf = class extends OV.ExporterBase
for (let primitiveIndex = 0; primitiveIndex < primitives.length; primitiveIndex++) {
let primitive = primitives[primitiveIndex];
let bufferViewIndex = mainJson.bufferViews.length;
let bufferViewCreator = new BufferViewCreator (mainJson, meshData.offsets[primitiveIndex]);
bufferViewCreator.AddBufferView (primitive.indices.length * this.components.index.size);
bufferViewCreator.AddBufferView (primitive.vertices.length * this.components.number.size);
bufferViewCreator.AddBufferView (primitive.normals.length * this.components.number.size);
let indicesBufferView = bufferViewCreator.AddBufferView (primitive.indices.length * this.components.index.size);
let verticesBufferView = bufferViewCreator.AddBufferView (primitive.vertices.length * this.components.number.size);
let colorsBufferView = null;
if (primitive.colors.length > 0) {
colorsBufferView = bufferViewCreator.AddBufferView (primitive.colors.length * this.components.number.size);
}
let normalsBufferView = bufferViewCreator.AddBufferView (primitive.normals.length * this.components.number.size);
let uvsBufferView = null;
if (primitive.uvs.length > 0) {
uvsBufferView = bufferViewCreator.AddBufferView (primitive.uvs.length * this.components.number.size);
}
let accessorIndex = mainJson.accessors.length;
let jsonPrimitive = {
attributes : {
POSITION : accessorIndex + 1,
NORMAL : accessorIndex + 2
},
indices : accessorIndex,
attributes : {},
mode : 4,
material : primitive.material
};
let bounds = primitive.GetBounds ();
mainJson.accessors.push ({
bufferView : bufferViewIndex,
bufferView : indicesBufferView,
byteOffset : 0,
componentType : this.components.index.type,
count : primitive.indices.length,
type : 'SCALAR'
});
jsonPrimitive.indices = mainJson.accessors.length - 1;
mainJson.accessors.push ({
bufferView : bufferViewIndex + 1,
bufferView : verticesBufferView,
byteOffset : 0,
componentType : this.components.number.type,
count : primitive.vertices.length / 3,
@ -316,23 +325,37 @@ OV.ExporterGltf = class extends OV.ExporterBase
max : bounds.max,
type : 'VEC3'
});
jsonPrimitive.attributes.POSITION = mainJson.accessors.length - 1;
if (colorsBufferView !== null) {
mainJson.accessors.push ({
bufferView : colorsBufferView,
byteOffset : 0,
componentType : this.components.number.type,
count : primitive.colors.length / 3,
type : 'VEC3'
});
jsonPrimitive.attributes.COLOR_0 = mainJson.accessors.length - 1;
}
mainJson.accessors.push ({
bufferView : bufferViewIndex + 2,
bufferView : normalsBufferView,
byteOffset : 0,
componentType : this.components.number.type,
count : primitive.normals.length / 3,
type : 'VEC3'
});
if (primitive.uvs.length > 0) {
bufferViewCreator.AddBufferView (primitive.uvs.length * this.components.number.size);
jsonPrimitive.attributes.NORMAL = mainJson.accessors.length - 1;
if (uvsBufferView !== null) {
mainJson.accessors.push ({
bufferView : bufferViewIndex + 3,
bufferView : uvsBufferView,
byteOffset : 0,
componentType : this.components.number.type,
count : primitive.uvs.length / 2,
type : 'VEC2'
});
jsonPrimitive.attributes.TEXCOORD_0 = accessorIndex + 3;
jsonPrimitive.attributes.TEXCOORD_0 = mainJson.accessors.length - 1;
}
jsonMesh.primitives.push (jsonPrimitive);

View File

@ -64,7 +64,7 @@ OV.MeshBuffer = class
OV.ConvertMeshToMeshBuffer = function (mesh)
{
function AddVertexToPrimitiveBuffer (mesh, vertexIndex, vertexColorIndex, normalIndex, uvIndex, primitiveBuffer, meshToPrimitiveVertices)
function AddVertexToPrimitiveBuffer (mesh, indices, primitiveBuffer, meshVertexToPrimitiveVertices)
{
function GetVertexColorOrDefault (mesh, vertexColorIndex, forceVertexColors)
{
@ -88,26 +88,26 @@ OV.ConvertMeshToMeshBuffer = function (mesh)
}
}
function AddVertex (mesh, vertexIndex, vertexColorIndex, normalIndex, uvIndex, primitiveBuffer)
function AddVertex (mesh, indices, primitiveBuffer)
{
let forceVertexColors = mesh.VertexColorCount () > 0;
let forceUVs = mesh.TextureUVCount () > 0;
let vertex = mesh.GetVertex (vertexIndex);
let normal = mesh.GetNormal (normalIndex);
let vertex = mesh.GetVertex (indices.vertex);
let normal = mesh.GetNormal (indices.normal);
let primitiveVertexIndex = primitiveBuffer.vertices.length / 3;
primitiveBuffer.indices.push (primitiveVertexIndex);
primitiveBuffer.vertices.push (vertex.x, vertex.y, vertex.z);
let vertexColor = GetVertexColorOrDefault (mesh, vertexColorIndex, forceVertexColors);
let vertexColor = GetVertexColorOrDefault (mesh, indices.color, forceVertexColors);
if (vertexColor !== null) {
primitiveBuffer.colors.push (vertexColor.r / 255.0, vertexColor.g / 255.0, vertexColor.b / 255.0);
}
primitiveBuffer.normals.push (normal.x, normal.y, normal.z);
let uv = GetUVOrDefault (mesh, uvIndex, forceUVs);
let uv = GetUVOrDefault (mesh, indices.uv, forceUVs);
if (uv !== null) {
primitiveBuffer.uvs.push (uv.x, uv.y);
}
@ -120,7 +120,7 @@ OV.ConvertMeshToMeshBuffer = function (mesh)
};
}
function FindMatchingPrimitiveVertex (mesh, primitiveVertices, vertexColorIndex, normalIndex, uvIndex)
function FindMatchingPrimitiveVertex (mesh, primitiveVertices, indices)
{
function IsEqualVertexColor (mesh, vertexColorIndex, existingVertexColor)
{
@ -148,9 +148,9 @@ OV.ConvertMeshToMeshBuffer = function (mesh)
for (let i = 0; i < primitiveVertices.length; i++) {
let primitiveVertex = primitiveVertices[i];
let equalVertexColor = IsEqualVertexColor (mesh, vertexColorIndex, primitiveVertex.vertexColor);
let equalNormal = IsEqualNormal (mesh, normalIndex, primitiveVertex.normal);
let equalUv = IsEqualUV (mesh, uvIndex, primitiveVertex.uv);
let equalVertexColor = IsEqualVertexColor (mesh, indices.color, primitiveVertex.vertexColor);
let equalNormal = IsEqualNormal (mesh, indices.normal, primitiveVertex.normal);
let equalUv = IsEqualUV (mesh, indices.uv, primitiveVertex.uv);
if (equalVertexColor && equalNormal && equalUv) {
return primitiveVertex;
}
@ -158,18 +158,18 @@ OV.ConvertMeshToMeshBuffer = function (mesh)
return null;
}
if (meshToPrimitiveVertices.has (vertexIndex)) {
let primitiveVertices = meshToPrimitiveVertices.get (vertexIndex);
let existingPrimitiveVertex = FindMatchingPrimitiveVertex (mesh, primitiveVertices, vertexColorIndex, normalIndex, uvIndex);
if (meshVertexToPrimitiveVertices.has (indices.vertex)) {
let primitiveVertices = meshVertexToPrimitiveVertices.get (indices.vertex);
let existingPrimitiveVertex = FindMatchingPrimitiveVertex (mesh, primitiveVertices, indices);
if (existingPrimitiveVertex !== null) {
primitiveBuffer.indices.push (existingPrimitiveVertex.index);
} else {
let primitiveVertex = AddVertex (mesh, vertexIndex, vertexColorIndex, normalIndex, uvIndex, primitiveBuffer);
let primitiveVertex = AddVertex (mesh, indices, primitiveBuffer);
primitiveVertices.push (primitiveVertex);
}
} else {
let primitiveVertex = AddVertex (mesh, vertexIndex, vertexColorIndex, normalIndex, uvIndex, primitiveBuffer);
meshToPrimitiveVertices.set (vertexIndex, [primitiveVertex]);
let primitiveVertex = AddVertex (mesh, indices, primitiveBuffer);
meshVertexToPrimitiveVertices.set (indices.vertex, [primitiveVertex]);
}
}
@ -191,19 +191,38 @@ OV.ConvertMeshToMeshBuffer = function (mesh)
});
let primitiveBuffer = null;
let meshToPrimitiveVertices = null;
let meshVertexToPrimitiveVertices = null;
for (let i = 0; i < triangleIndices.length; i++) {
let triangleIndex = triangleIndices[i];
let triangle = mesh.GetTriangle (triangleIndex);
if (primitiveBuffer === null || primitiveBuffer.material !== triangle.mat) {
primitiveBuffer = new OV.MeshPrimitiveBuffer ();
primitiveBuffer.material = triangle.mat;
meshToPrimitiveVertices = new Map ();
meshVertexToPrimitiveVertices = new Map ();
meshBuffer.primitives.push (primitiveBuffer);
}
AddVertexToPrimitiveBuffer (mesh, triangle.v0, triangle.c0, triangle.n0, triangle.u0, primitiveBuffer, meshToPrimitiveVertices);
AddVertexToPrimitiveBuffer (mesh, triangle.v1, triangle.c1, triangle.n1, triangle.u1, primitiveBuffer, meshToPrimitiveVertices);
AddVertexToPrimitiveBuffer (mesh, triangle.v2, triangle.c2, triangle.n2, triangle.u2, primitiveBuffer, meshToPrimitiveVertices);
let v0Indices = {
vertex : triangle.v0,
color : triangle.c0,
normal : triangle.n0,
uv : triangle.u0
};
let v1Indices = {
vertex : triangle.v1,
color : triangle.c1,
normal : triangle.n1,
uv : triangle.u1
};
let v2Indices = {
vertex : triangle.v2,
color : triangle.c2,
normal : triangle.n2,
uv : triangle.u2
};
AddVertexToPrimitiveBuffer (mesh, v0Indices, primitiveBuffer, meshVertexToPrimitiveVertices);
AddVertexToPrimitiveBuffer (mesh, v1Indices, primitiveBuffer, meshVertexToPrimitiveVertices);
AddVertexToPrimitiveBuffer (mesh, v2Indices, primitiveBuffer, meshVertexToPrimitiveVertices);
}
return meshBuffer;