Store vertex colors for triangles.

This commit is contained in:
kovacsv 2021-12-28 21:15:33 +01:00
parent 53d30d0b64
commit 0eee801446
9 changed files with 155 additions and 44 deletions

View File

@ -406,6 +406,7 @@ OV.GltfExtensions = class
}
let vertexOffset = mesh.VertexCount ();
let vertexColorOffset = mesh.VertexColorCount ();
let normalOffset = mesh.NormalCount ();
let uvOffset = mesh.TextureUVCount ();
@ -443,7 +444,7 @@ OV.GltfExtensions = class
let v0 = indexArray[i];
let v1 = indexArray[i + 1];
let v2 = indexArray[i + 2];
importer.AddTriangle (primitive, mesh, v0, v1, v2, hasNormals, hasUVs, vertexOffset, normalOffset, uvOffset);
importer.AddTriangle (primitive, mesh, v0, v1, v2, hasVertexColors, hasNormals, hasUVs, vertexOffset, vertexColorOffset, normalOffset, uvOffset);
}
this.draco._free (indexDataPtr);
@ -795,6 +796,7 @@ OV.ImporterGltf = class extends OV.ImporterBase
}
let vertexOffset = mesh.VertexCount ();
let vertexColorOffset = mesh.VertexColorCount ();
let normalOffset = mesh.NormalCount ();
let uvOffset = mesh.TextureUVCount ();
@ -867,7 +869,7 @@ OV.ImporterGltf = class extends OV.ImporterBase
let v0 = vertexIndices[i];
let v1 = vertexIndices[i + 1];
let v2 = vertexIndices[i + 2];
this.AddTriangle (primitive, mesh, v0, v1, v2, hasNormals, hasUVs, vertexOffset, normalOffset, uvOffset);
this.AddTriangle (primitive, mesh, v0, v1, v2, hasVertexColors, hasNormals, hasUVs, vertexOffset, vertexColorOffset, normalOffset, uvOffset);
}
} else if (mode === OV.GltfRenderMode.TRIANGLE_STRIP) {
for (let i = 0; i < vertexIndices.length - 2; i++) {
@ -879,21 +881,28 @@ OV.ImporterGltf = class extends OV.ImporterBase
v1 = v2;
v2 = tmp;
}
this.AddTriangle (primitive, mesh, v0, v1, v2, hasNormals, hasUVs, vertexOffset, normalOffset, uvOffset);
this.AddTriangle (primitive, mesh, v0, v1, v2, hasVertexColors, hasNormals, hasUVs, vertexOffset, vertexColorOffset, normalOffset, uvOffset);
}
} else if (mode === OV.GltfRenderMode.TRIANGLE_FAN) {
for (let i = 1; i < vertexIndices.length - 1; i++) {
let v0 = vertexIndices[0];
let v1 = vertexIndices[i];
let v2 = vertexIndices[i + 1];
this.AddTriangle (primitive, mesh, v0, v1, v2, hasNormals, hasUVs, vertexOffset, normalOffset, uvOffset);
this.AddTriangle (primitive, mesh, v0, v1, v2, hasVertexColors, hasNormals, hasUVs, vertexOffset, vertexColorOffset, normalOffset, uvOffset);
}
}
}
AddTriangle (primitive, mesh, v0, v1, v2, hasNormals, hasUVs, vertexOffset, normalOffset, uvOffset)
AddTriangle (primitive, mesh, v0, v1, v2, hasVertexColors, hasNormals, hasUVs, vertexOffset, vertexColorOffset, normalOffset, uvOffset)
{
let triangle = new OV.Triangle (vertexOffset + v0, vertexOffset + v1, vertexOffset + v2);
if (hasVertexColors) {
triangle.SetVertexColors (
vertexColorOffset + v0,
vertexColorOffset + v1,
vertexColorOffset + v2
);
}
if (hasNormals) {
triangle.SetNormals (
normalOffset + v0,

View File

@ -383,6 +383,8 @@ OV.ImporterPly = class extends OV.ImporterBase
let triangle = new OV.Triangle (v0, v1, v2);
if (faceColor !== null) {
triangle.mat = materialHandler.GetMaterialIndexByColor (faceColor);
} else if (this.mesh.VertexColorCount () > 0) {
triangle.SetVertexColors (v0, v1, v2);
}
this.mesh.AddTriangle (triangle);
}

View File

@ -4,6 +4,7 @@ OV.MeshPrimitiveBuffer = class
{
this.indices = [];
this.vertices = [];
this.colors = [];
this.normals = [];
this.uvs = [];
this.material = null;
@ -28,7 +29,7 @@ OV.MeshPrimitiveBuffer = class
GetByteLength (indexTypeSize, numberTypeSize)
{
let indexCount = this.indices.length;
let numberCount = this.vertices.length + this.normals.length + this.uvs.length;
let numberCount = this.vertices.length + this.colors.length + this.normals.length + this.uvs.length;
return indexCount * indexTypeSize + numberCount * numberTypeSize;
}
};
@ -63,8 +64,19 @@ OV.MeshBuffer = class
OV.ConvertMeshToMeshBuffer = function (mesh)
{
function AddVertexToPrimitiveBuffer (mesh, vertexIndex, normalIndex, uvIndex, primitiveBuffer, meshToPrimitiveVertices)
function AddVertexToPrimitiveBuffer (mesh, vertexIndex, vertexColorIndex, normalIndex, uvIndex, primitiveBuffer, meshToPrimitiveVertices)
{
function GetVertexColorOrDefault (mesh, vertexColorIndex, forceVertexColors)
{
if (vertexColorIndex !== null) {
return mesh.GetVertexColor (vertexColorIndex);
} else if (forceVertexColors) {
return new OV.Color (0, 0, 0);
} else {
return null;
}
}
function GetUVOrDefault (mesh, uvIndex, forceUVs)
{
if (uvIndex !== null) {
@ -76,58 +88,88 @@ OV.ConvertMeshToMeshBuffer = function (mesh)
}
}
function AddVertex (mesh, vertexIndex, normalIndex, uvIndex, primitiveBuffer)
function AddVertex (mesh, vertexIndex, vertexColorIndex, normalIndex, uvIndex, primitiveBuffer)
{
let forceVertexColors = mesh.VertexColorCount () > 0;
let forceUVs = mesh.TextureUVCount () > 0;
let vertex = mesh.GetVertex (vertexIndex);
let normal = mesh.GetNormal (normalIndex);
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);
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);
if (uv !== null) {
primitiveBuffer.uvs.push (uv.x, uv.y);
}
return {
index : primitiveVertexIndex,
vertexColor : vertexColor,
normal : normal,
uv : uv
};
}
function FindMatchingPrimitiveVertex (mesh, primitiveVertices, normalIndex, uvIndex)
function FindMatchingPrimitiveVertex (mesh, primitiveVertices, vertexColorIndex, normalIndex, uvIndex)
{
function IsEqualVertexColor (mesh, vertexColorIndex, existingVertexColor)
{
if (existingVertexColor === null && vertexColorIndex === null) {
return true;
}
let vertexColor = GetVertexColorOrDefault (mesh, vertexColorIndex, true);
return OV.ColorIsEqual (existingVertexColor, vertexColor);
}
function IsEqualNormal (mesh, normalIndex, existingNormal)
{
let normal = mesh.GetNormal (normalIndex);
return OV.CoordIsEqual3D (existingNormal, normal);
}
function IsEqualUV (mesh, uvIndex, existingUv)
{
if (existingUv === null && uvIndex === null) {
return true;
}
let uv = GetUVOrDefault (mesh, uvIndex, true);
return OV.CoordIsEqual2D (existingUv, uv);
}
for (let i = 0; i < primitiveVertices.length; i++) {
let primitiveVertex = primitiveVertices[i];
let normal = mesh.GetNormal (normalIndex);
let equalNormal = OV.CoordIsEqual3D (primitiveVertex.normal, normal);
let equalUv = false;
if (primitiveVertex.uv === null && uvIndex === null) {
equalUv = true;
} else {
let uv = GetUVOrDefault (mesh, uvIndex, true);
equalUv = OV.CoordIsEqual2D (primitiveVertex.uv, uv);
}
if (equalNormal && equalUv) {
let equalVertexColor = IsEqualVertexColor (mesh, vertexColorIndex, primitiveVertex.vertexColor);
let equalNormal = IsEqualNormal (mesh, normalIndex, primitiveVertex.normal);
let equalUv = IsEqualUV (mesh, uvIndex, primitiveVertex.uv);
if (equalVertexColor && equalNormal && equalUv) {
return primitiveVertex;
}
}
return null;
}
let primitiveVertices = meshToPrimitiveVertices[vertexIndex];
if (primitiveVertices === undefined) {
let primitiveVertex = AddVertex (mesh, vertexIndex, normalIndex, uvIndex, primitiveBuffer);
meshToPrimitiveVertices[vertexIndex] = [primitiveVertex];
} else {
let existingPrimitiveVertex = FindMatchingPrimitiveVertex (mesh, primitiveVertices, normalIndex, uvIndex);
if (meshToPrimitiveVertices.has (vertexIndex)) {
let primitiveVertices = meshToPrimitiveVertices.get (vertexIndex);
let existingPrimitiveVertex = FindMatchingPrimitiveVertex (mesh, primitiveVertices, vertexColorIndex, normalIndex, uvIndex);
if (existingPrimitiveVertex !== null) {
primitiveBuffer.indices.push (existingPrimitiveVertex.index);
} else {
let primitiveVertex = AddVertex (mesh, vertexIndex, normalIndex, uvIndex, primitiveBuffer);
let primitiveVertex = AddVertex (mesh, vertexIndex, vertexColorIndex, normalIndex, uvIndex, primitiveBuffer);
primitiveVertices.push (primitiveVertex);
}
} else {
let primitiveVertex = AddVertex (mesh, vertexIndex, vertexColorIndex, normalIndex, uvIndex, primitiveBuffer);
meshToPrimitiveVertices.set (vertexIndex, [primitiveVertex]);
}
}
@ -156,12 +198,12 @@ OV.ConvertMeshToMeshBuffer = function (mesh)
if (primitiveBuffer === null || primitiveBuffer.material !== triangle.mat) {
primitiveBuffer = new OV.MeshPrimitiveBuffer ();
primitiveBuffer.material = triangle.mat;
meshToPrimitiveVertices = {};
meshToPrimitiveVertices = new Map ();
meshBuffer.primitives.push (primitiveBuffer);
}
AddVertexToPrimitiveBuffer (mesh, triangle.v0, triangle.n0, triangle.u0, primitiveBuffer, meshToPrimitiveVertices);
AddVertexToPrimitiveBuffer (mesh, triangle.v1, triangle.n1, triangle.u1, primitiveBuffer, meshToPrimitiveVertices);
AddVertexToPrimitiveBuffer (mesh, triangle.v2, triangle.n2, triangle.u2, primitiveBuffer, meshToPrimitiveVertices);
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);
}
return meshBuffer;

View File

@ -96,11 +96,10 @@ OV.FinalizeModel = function (model, getDefaultMaterial)
calculateCurveNormals : false
};
let hasVertexColors = (mesh.VertexCount () === mesh.VertexColorCount ());
for (let i = 0; i < mesh.TriangleCount (); i++) {
let triangle = mesh.GetTriangle (i);
FinalizeTriangle (mesh, triangle, status);
if (hasVertexColors) {
if (triangle.HasVertexColors ()) {
let material = model.GetMaterial (triangle.mat);
material.vertexColors = true;
}

View File

@ -35,6 +35,11 @@ OV.TransformMesh = function (mesh, transformation)
}
};
OV.MeshHasVertexColors = function (mesh)
{
return mesh.VertexCount () === mesh.VertexColorCount ();
};
OV.FlipMeshTrianglesOrientation = function (mesh)
{
for (let i = 0; i < mesh.TriangleCount (); i++) {
@ -67,6 +72,11 @@ OV.CloneMesh = function (mesh)
cloned.AddVertex (vertex.Clone ());
}
for (let i = 0; i < mesh.VertexColorCount (); i++) {
let color = mesh.GetVertexColor (i);
cloned.AddVertexColor (color.Clone ());
}
for (let i = 0; i < mesh.NormalCount (); i++) {
let normal = mesh.GetNormal (i);
cloned.AddNormal (normal.Clone ());

View File

@ -5,15 +5,19 @@ OV.Triangle = class
this.v0 = v0;
this.v1 = v1;
this.v2 = v2;
this.c0 = null;
this.c1 = null;
this.c2 = null;
this.n0 = null;
this.n1 = null;
this.n2 = null;
this.u0 = null;
this.u1 = null;
this.u2 = null;
this.mat = null;
this.curve = null;
}
@ -23,6 +27,11 @@ OV.Triangle = class
return this.v0 !== null && this.v1 !== null && this.v2 !== null;
}
HasVertexColors ()
{
return this.c0 !== null && this.c1 !== null && this.c2 !== null;
}
HasNormals ()
{
return this.n0 !== null && this.n1 !== null && this.n2 !== null;
@ -31,7 +40,7 @@ OV.Triangle = class
HasTextureUVs ()
{
return this.u0 !== null && this.u1 !== null && this.u2 !== null;
}
}
SetVertices (v0, v1, v2)
{
@ -40,7 +49,15 @@ OV.Triangle = class
this.v2 = v2;
return this;
}
SetVertexColors (c0, c1, c2)
{
this.c0 = c0;
this.c1 = c1;
this.c2 = c2;
return this;
}
SetNormals (n0, n1, n2)
{
this.n0 = n0;
@ -48,7 +65,7 @@ OV.Triangle = class
this.n2 = n2;
return this;
}
SetTextureUVs (u0, u1, u2)
{
this.u0 = u0;
@ -62,7 +79,7 @@ OV.Triangle = class
this.mat = mat;
return this;
}
SetCurve (curve)
{
this.curve = curve;
@ -72,6 +89,7 @@ OV.Triangle = class
Clone ()
{
let cloned = new OV.Triangle (this.v0, this.v1, this.v2);
cloned.SetVertexColors (this.c0, this.c1, this.c2);
cloned.SetNormals (this.n0, this.n1, this.n2);
cloned.SetTextureUVs (this.u0, this.u1, this.u2);
cloned.SetMaterial (this.mat);

View File

@ -227,7 +227,7 @@ OV.ConvertModelToThreeObject = function (model, params, output, callbacks)
end : -1
});
let meshHasVertexColors = (mesh.VertexCount () === mesh.VertexColorCount ());
let meshHasVertexColors = OV.MeshHasVertexColors (mesh);
let meshHasUVs = (mesh.TextureUVCount () > 0);
for (let i = 0; i < triangleIndices.length; i++) {
let triangleIndex = triangleIndices[i];
@ -238,15 +238,21 @@ OV.ConvertModelToThreeObject = function (model, params, output, callbacks)
let v2 = mesh.GetVertex (triangle.v2);
vertices.push (v0.x, v0.y, v0.z, v1.x, v1.y, v1.z, v2.x, v2.y, v2.z);
if (meshHasVertexColors) {
let vc0 = OV.ConvertColorToThreeColor (mesh.GetVertexColor (triangle.v0));
let vc1 = OV.ConvertColorToThreeColor (mesh.GetVertexColor (triangle.v1));
let vc2 = OV.ConvertColorToThreeColor (mesh.GetVertexColor (triangle.v2));
if (triangle.HasVertexColors ()) {
let vc0 = OV.ConvertColorToThreeColor (mesh.GetVertexColor (triangle.c0));
let vc1 = OV.ConvertColorToThreeColor (mesh.GetVertexColor (triangle.c1));
let vc2 = OV.ConvertColorToThreeColor (mesh.GetVertexColor (triangle.c2));
vertexColors.push (
vc0.r, vc0.g, vc0.b,
vc1.r, vc1.g, vc1.b,
vc2.r, vc2.g, vc2.b
);
} else if (meshHasVertexColors) {
vertexColors.push (
0.0, 0.0, 0.0,
0.0, 0.0, 0.0,
0.0, 0.0, 0.0
);
}
let n0 = mesh.GetNormal (triangle.n0);

View File

@ -156,6 +156,9 @@ OV.ConvertThreeGeometryToMesh = function (threeGeometry, materialIndex)
let v1 = indices[i + 1];
let v2 = indices[i + 2];
let triangle = new OV.Triangle (v0, v1, v2);
if (hasVertexColors) {
triangle.SetVertexColors (v0, v1, v2);
}
if (hasNormals) {
triangle.SetNormals (v0, v1, v2);
}

View File

@ -30,6 +30,28 @@ describe ('Mesh Buffer', function () {
assert.strictEqual (buffer.primitives[1].uvs.length, 0);
});
it ('Mesh To Buffer Different Colors', function () {
var mesh = new OV.Mesh ();
mesh.AddVertex (new OV.Coord3D (0.0, 0.0, 0.0));
mesh.AddVertex (new OV.Coord3D (1.0, 0.0, 0.0));
mesh.AddVertex (new OV.Coord3D (1.0, 1.0, 0.0));
mesh.AddVertex (new OV.Coord3D (0.0, 1.0, 0.0));
mesh.AddVertexColor (new OV.Color (0.1, 0.0, 0.0));
mesh.AddVertexColor (new OV.Color (0.2, 0.0, 0.0));
mesh.AddNormal (new OV.Coord3D (0.0, 0.0, 1.0));
mesh.AddTriangle (new OV.Triangle (0, 1, 2).SetVertexColors (0, 0, 0).SetNormals (0, 0, 0).SetMaterial (0));
mesh.AddTriangle (new OV.Triangle (0, 2, 3).SetVertexColors (1, 1, 1).SetNormals (0, 0, 0).SetMaterial (0));
let buffer = OV.ConvertMeshToMeshBuffer (mesh);
assert.strictEqual (buffer.primitives.length, 1);
assert.strictEqual (buffer.primitives[0].indices.length, 6);
assert.strictEqual (buffer.primitives[0].vertices.length, 6 * 3);
assert.strictEqual (buffer.primitives[0].normals.length, 6 * 3);
assert.strictEqual (buffer.primitives[0].uvs.length, 0);
});
it ('Mesh To Buffer Different Normals', function () {
var mesh = new OV.Mesh ();
mesh.AddVertex (new OV.Coord3D (0.0, 0.0, 0.0));