|
@@ -1,9 +1,10 @@
|
|
var BABYLON;
|
|
var BABYLON;
|
|
(function (BABYLON) {
|
|
(function (BABYLON) {
|
|
var SimplificationSettings = (function () {
|
|
var SimplificationSettings = (function () {
|
|
- function SimplificationSettings(quality, distance) {
|
|
|
|
|
|
+ function SimplificationSettings(quality, distance, optimizeMesh) {
|
|
this.quality = quality;
|
|
this.quality = quality;
|
|
this.distance = distance;
|
|
this.distance = distance;
|
|
|
|
+ this.optimizeMesh = optimizeMesh;
|
|
}
|
|
}
|
|
return SimplificationSettings;
|
|
return SimplificationSettings;
|
|
})();
|
|
})();
|
|
@@ -99,16 +100,18 @@ var BABYLON;
|
|
})();
|
|
})();
|
|
BABYLON.DecimationTriangle = DecimationTriangle;
|
|
BABYLON.DecimationTriangle = DecimationTriangle;
|
|
var DecimationVertex = (function () {
|
|
var DecimationVertex = (function () {
|
|
- function DecimationVertex(position, normal, uv, id) {
|
|
|
|
|
|
+ function DecimationVertex(position, id) {
|
|
this.position = position;
|
|
this.position = position;
|
|
- this.normal = normal;
|
|
|
|
- this.uv = uv;
|
|
|
|
this.id = id;
|
|
this.id = id;
|
|
this.isBorder = true;
|
|
this.isBorder = true;
|
|
this.q = new QuadraticMatrix();
|
|
this.q = new QuadraticMatrix();
|
|
this.triangleCount = 0;
|
|
this.triangleCount = 0;
|
|
this.triangleStart = 0;
|
|
this.triangleStart = 0;
|
|
|
|
+ this.originalOffsets = [];
|
|
}
|
|
}
|
|
|
|
+ DecimationVertex.prototype.updatePosition = function (newPosition) {
|
|
|
|
+ this.position.copyFrom(newPosition);
|
|
|
|
+ };
|
|
return DecimationVertex;
|
|
return DecimationVertex;
|
|
})();
|
|
})();
|
|
BABYLON.DecimationVertex = DecimationVertex;
|
|
BABYLON.DecimationVertex = DecimationVertex;
|
|
@@ -172,7 +175,7 @@ var BABYLON;
|
|
var QuadraticErrorSimplification = (function () {
|
|
var QuadraticErrorSimplification = (function () {
|
|
function QuadraticErrorSimplification(_mesh) {
|
|
function QuadraticErrorSimplification(_mesh) {
|
|
this._mesh = _mesh;
|
|
this._mesh = _mesh;
|
|
- this.initialised = false;
|
|
|
|
|
|
+ this.initialized = false;
|
|
this.syncIterations = 5000;
|
|
this.syncIterations = 5000;
|
|
this.aggressiveness = 7;
|
|
this.aggressiveness = 7;
|
|
this.decimationIterations = 100;
|
|
this.decimationIterations = 100;
|
|
@@ -183,11 +186,11 @@ var BABYLON;
|
|
this.initDecimatedMesh();
|
|
this.initDecimatedMesh();
|
|
//iterating through the submeshes array, one after the other.
|
|
//iterating through the submeshes array, one after the other.
|
|
BABYLON.AsyncLoop.Run(this._mesh.subMeshes.length, function (loop) {
|
|
BABYLON.AsyncLoop.Run(this._mesh.subMeshes.length, function (loop) {
|
|
- _this.initWithMesh(_this._mesh, loop.index, function () {
|
|
|
|
|
|
+ _this.initWithMesh(loop.index, function () {
|
|
_this.runDecimation(settings, loop.index, function () {
|
|
_this.runDecimation(settings, loop.index, function () {
|
|
loop.executeNext();
|
|
loop.executeNext();
|
|
});
|
|
});
|
|
- });
|
|
|
|
|
|
+ }, settings.optimizeMesh);
|
|
}, function () {
|
|
}, function () {
|
|
setTimeout(function () {
|
|
setTimeout(function () {
|
|
successCallback(_this._reconstructedMesh);
|
|
successCallback(_this._reconstructedMesh);
|
|
@@ -197,9 +200,9 @@ var BABYLON;
|
|
QuadraticErrorSimplification.prototype.isTriangleOnBoundingBox = function (triangle) {
|
|
QuadraticErrorSimplification.prototype.isTriangleOnBoundingBox = function (triangle) {
|
|
var _this = this;
|
|
var _this = this;
|
|
var gCount = 0;
|
|
var gCount = 0;
|
|
- triangle.vertices.forEach(function (vId) {
|
|
|
|
|
|
+ triangle.vertices.forEach(function (vertex) {
|
|
var count = 0;
|
|
var count = 0;
|
|
- var vPos = _this.vertices[vId].position;
|
|
|
|
|
|
+ var vPos = vertex.position;
|
|
var bbox = _this._mesh.getBoundingInfo().boundingBox;
|
|
var bbox = _this._mesh.getBoundingInfo().boundingBox;
|
|
if (bbox.maximum.x - vPos.x < _this.boundingBoxEpsilon || vPos.x - bbox.minimum.x > _this.boundingBoxEpsilon)
|
|
if (bbox.maximum.x - vPos.x < _this.boundingBoxEpsilon || vPos.x - bbox.minimum.x > _this.boundingBoxEpsilon)
|
|
++count;
|
|
++count;
|
|
@@ -243,10 +246,8 @@ var BABYLON;
|
|
if (t.error[j] < threshold) {
|
|
if (t.error[j] < threshold) {
|
|
var deleted0 = [];
|
|
var deleted0 = [];
|
|
var deleted1 = [];
|
|
var deleted1 = [];
|
|
- var i0 = t.vertices[j];
|
|
|
|
- var i1 = t.vertices[(j + 1) % 3];
|
|
|
|
- var v0 = _this.vertices[i0];
|
|
|
|
- var v1 = _this.vertices[i1];
|
|
|
|
|
|
+ var v0 = t.vertices[j];
|
|
|
|
+ var v1 = t.vertices[(j + 1) % 3];
|
|
if (v0.isBorder !== v1.isBorder)
|
|
if (v0.isBorder !== v1.isBorder)
|
|
continue;
|
|
continue;
|
|
var p = BABYLON.Vector3.Zero();
|
|
var p = BABYLON.Vector3.Zero();
|
|
@@ -255,9 +256,9 @@ var BABYLON;
|
|
var color = new BABYLON.Color4(0, 0, 0, 1);
|
|
var color = new BABYLON.Color4(0, 0, 0, 1);
|
|
_this.calculateError(v0, v1, p, n, uv, color);
|
|
_this.calculateError(v0, v1, p, n, uv, color);
|
|
var delTr = [];
|
|
var delTr = [];
|
|
- if (_this.isFlipped(v0, i1, p, deleted0, t.borderFactor, delTr))
|
|
|
|
|
|
+ if (_this.isFlipped(v0, v1, p, deleted0, t.borderFactor, delTr))
|
|
continue;
|
|
continue;
|
|
- if (_this.isFlipped(v1, i0, p, deleted1, t.borderFactor, delTr))
|
|
|
|
|
|
+ if (_this.isFlipped(v1, v0, p, deleted1, t.borderFactor, delTr))
|
|
continue;
|
|
continue;
|
|
if (deleted0.indexOf(true) < 0 || deleted1.indexOf(true) < 0)
|
|
if (deleted0.indexOf(true) < 0 || deleted1.indexOf(true) < 0)
|
|
continue;
|
|
continue;
|
|
@@ -271,16 +272,11 @@ var BABYLON;
|
|
if (uniqueArray.length % 2 != 0) {
|
|
if (uniqueArray.length % 2 != 0) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
- v0.normal = n;
|
|
|
|
- if (v0.uv)
|
|
|
|
- v0.uv = uv;
|
|
|
|
- else if (v0.color)
|
|
|
|
- v0.color = color;
|
|
|
|
v0.q = v1.q.add(v0.q);
|
|
v0.q = v1.q.add(v0.q);
|
|
- v0.position = p;
|
|
|
|
|
|
+ v0.updatePosition(p);
|
|
var tStart = _this.references.length;
|
|
var tStart = _this.references.length;
|
|
- deletedTriangles = _this.updateTriangles(v0.id, v0, deleted0, deletedTriangles);
|
|
|
|
- deletedTriangles = _this.updateTriangles(v0.id, v1, deleted1, deletedTriangles);
|
|
|
|
|
|
+ deletedTriangles = _this.updateTriangles(v0, v0, deleted0, deletedTriangles);
|
|
|
|
+ deletedTriangles = _this.updateTriangles(v0, v1, deleted1, deletedTriangles);
|
|
var tCount = _this.references.length - tStart;
|
|
var tCount = _this.references.length - tStart;
|
|
if (tCount <= v0.triangleCount) {
|
|
if (tCount <= v0.triangleCount) {
|
|
if (tCount) {
|
|
if (tCount) {
|
|
@@ -318,41 +314,48 @@ var BABYLON;
|
|
}, 0);
|
|
}, 0);
|
|
});
|
|
});
|
|
};
|
|
};
|
|
- QuadraticErrorSimplification.prototype.initWithMesh = function (mesh, submeshIndex, callback) {
|
|
|
|
|
|
+ QuadraticErrorSimplification.prototype.initWithMesh = function (submeshIndex, callback, optimizeMesh) {
|
|
var _this = this;
|
|
var _this = this;
|
|
- if (!mesh)
|
|
|
|
- return;
|
|
|
|
this.vertices = [];
|
|
this.vertices = [];
|
|
this.triangles = [];
|
|
this.triangles = [];
|
|
- this._mesh = mesh;
|
|
|
|
- //It is assumed that a mesh has positions, normals and either uvs or colors.
|
|
|
|
var positionData = this._mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
|
|
var positionData = this._mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
|
|
- var normalData = this._mesh.getVerticesData(BABYLON.VertexBuffer.NormalKind);
|
|
|
|
- var uvs = this._mesh.getVerticesData(BABYLON.VertexBuffer.UVKind);
|
|
|
|
- var colorsData = this._mesh.getVerticesData(BABYLON.VertexBuffer.ColorKind);
|
|
|
|
- var indices = mesh.getIndices();
|
|
|
|
- var submesh = mesh.subMeshes[submeshIndex];
|
|
|
|
|
|
+ var indices = this._mesh.getIndices();
|
|
|
|
+ var submesh = this._mesh.subMeshes[submeshIndex];
|
|
|
|
+ var findInVertices = function (positionToSearch) {
|
|
|
|
+ if (optimizeMesh) {
|
|
|
|
+ for (var ii = 0; ii < _this.vertices.length; ++ii) {
|
|
|
|
+ if (_this.vertices[ii].position.equals(positionToSearch)) {
|
|
|
|
+ return _this.vertices[ii];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ };
|
|
|
|
+ var vertexReferences = [];
|
|
var vertexInit = function (i) {
|
|
var vertexInit = function (i) {
|
|
var offset = i + submesh.verticesStart;
|
|
var offset = i + submesh.verticesStart;
|
|
- var vertex = new DecimationVertex(BABYLON.Vector3.FromArray(positionData, offset * 3), BABYLON.Vector3.FromArray(normalData, offset * 3), null, i);
|
|
|
|
- if (_this._mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
|
|
|
|
- vertex.uv = BABYLON.Vector2.FromArray(uvs, offset * 2);
|
|
|
|
|
|
+ var position = BABYLON.Vector3.FromArray(positionData, offset * 3);
|
|
|
|
+ var vertex = findInVertices(position) || new DecimationVertex(position, _this.vertices.length);
|
|
|
|
+ vertex.originalOffsets.push(offset);
|
|
|
|
+ if (vertex.id == _this.vertices.length) {
|
|
|
|
+ _this.vertices.push(vertex);
|
|
}
|
|
}
|
|
- else if (_this._mesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
|
|
|
|
- vertex.color = BABYLON.Color4.FromArray(colorsData, offset * 4);
|
|
|
|
- }
|
|
|
|
- _this.vertices.push(vertex);
|
|
|
|
|
|
+ vertexReferences.push(vertex.id);
|
|
};
|
|
};
|
|
//var totalVertices = mesh.getTotalVertices();
|
|
//var totalVertices = mesh.getTotalVertices();
|
|
var totalVertices = submesh.verticesCount;
|
|
var totalVertices = submesh.verticesCount;
|
|
- BABYLON.AsyncLoop.SyncAsyncForLoop(totalVertices, this.syncIterations, vertexInit, function () {
|
|
|
|
|
|
+ BABYLON.AsyncLoop.SyncAsyncForLoop(totalVertices, (this.syncIterations / 4) >> 0, vertexInit, function () {
|
|
var indicesInit = function (i) {
|
|
var indicesInit = function (i) {
|
|
var offset = (submesh.indexStart / 3) + i;
|
|
var offset = (submesh.indexStart / 3) + i;
|
|
var pos = (offset * 3);
|
|
var pos = (offset * 3);
|
|
- var i0 = indices[pos + 0] - submesh.verticesStart;
|
|
|
|
- var i1 = indices[pos + 1] - submesh.verticesStart;
|
|
|
|
- var i2 = indices[pos + 2] - submesh.verticesStart;
|
|
|
|
- var triangle = new DecimationTriangle([_this.vertices[i0].id, _this.vertices[i1].id, _this.vertices[i2].id]);
|
|
|
|
|
|
+ var i0 = indices[pos + 0];
|
|
|
|
+ var i1 = indices[pos + 1];
|
|
|
|
+ var i2 = indices[pos + 2];
|
|
|
|
+ var v0 = _this.vertices[vertexReferences[i0 - submesh.verticesStart]];
|
|
|
|
+ var v1 = _this.vertices[vertexReferences[i1 - submesh.verticesStart]];
|
|
|
|
+ var v2 = _this.vertices[vertexReferences[i2 - submesh.verticesStart]];
|
|
|
|
+ var triangle = new DecimationTriangle([v0, v1, v2]);
|
|
|
|
+ triangle.originalOffset = pos;
|
|
_this.triangles.push(triangle);
|
|
_this.triangles.push(triangle);
|
|
};
|
|
};
|
|
BABYLON.AsyncLoop.SyncAsyncForLoop(submesh.indexCount / 3, _this.syncIterations, indicesInit, function () {
|
|
BABYLON.AsyncLoop.SyncAsyncForLoop(submesh.indexCount / 3, _this.syncIterations, indicesInit, function () {
|
|
@@ -364,21 +367,21 @@ var BABYLON;
|
|
var _this = this;
|
|
var _this = this;
|
|
var triangleInit1 = function (i) {
|
|
var triangleInit1 = function (i) {
|
|
var t = _this.triangles[i];
|
|
var t = _this.triangles[i];
|
|
- t.normal = BABYLON.Vector3.Cross(_this.vertices[t.vertices[1]].position.subtract(_this.vertices[t.vertices[0]].position), _this.vertices[t.vertices[2]].position.subtract(_this.vertices[t.vertices[0]].position)).normalize();
|
|
|
|
|
|
+ t.normal = BABYLON.Vector3.Cross(t.vertices[1].position.subtract(t.vertices[0].position), t.vertices[2].position.subtract(t.vertices[0].position)).normalize();
|
|
for (var j = 0; j < 3; j++) {
|
|
for (var j = 0; j < 3; j++) {
|
|
- _this.vertices[t.vertices[j]].q.addArrayInPlace(QuadraticMatrix.DataFromNumbers(t.normal.x, t.normal.y, t.normal.z, -(BABYLON.Vector3.Dot(t.normal, _this.vertices[t.vertices[0]].position))));
|
|
|
|
|
|
+ t.vertices[j].q.addArrayInPlace(QuadraticMatrix.DataFromNumbers(t.normal.x, t.normal.y, t.normal.z, -(BABYLON.Vector3.Dot(t.normal, t.vertices[0].position))));
|
|
}
|
|
}
|
|
};
|
|
};
|
|
BABYLON.AsyncLoop.SyncAsyncForLoop(this.triangles.length, this.syncIterations, triangleInit1, function () {
|
|
BABYLON.AsyncLoop.SyncAsyncForLoop(this.triangles.length, this.syncIterations, triangleInit1, function () {
|
|
var triangleInit2 = function (i) {
|
|
var triangleInit2 = function (i) {
|
|
var t = _this.triangles[i];
|
|
var t = _this.triangles[i];
|
|
for (var j = 0; j < 3; ++j) {
|
|
for (var j = 0; j < 3; ++j) {
|
|
- t.error[j] = _this.calculateError(_this.vertices[t.vertices[j]], _this.vertices[t.vertices[(j + 1) % 3]]);
|
|
|
|
|
|
+ t.error[j] = _this.calculateError(t.vertices[j], t.vertices[(j + 1) % 3]);
|
|
}
|
|
}
|
|
t.error[3] = Math.min(t.error[0], t.error[1], t.error[2]);
|
|
t.error[3] = Math.min(t.error[0], t.error[1], t.error[2]);
|
|
};
|
|
};
|
|
BABYLON.AsyncLoop.SyncAsyncForLoop(_this.triangles.length, _this.syncIterations, triangleInit2, function () {
|
|
BABYLON.AsyncLoop.SyncAsyncForLoop(_this.triangles.length, _this.syncIterations, triangleInit2, function () {
|
|
- _this.initialised = true;
|
|
|
|
|
|
+ _this.initialized = true;
|
|
callback();
|
|
callback();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
@@ -395,52 +398,42 @@ var BABYLON;
|
|
if (!this.triangles[i].deleted) {
|
|
if (!this.triangles[i].deleted) {
|
|
t = this.triangles[i];
|
|
t = this.triangles[i];
|
|
for (j = 0; j < 3; ++j) {
|
|
for (j = 0; j < 3; ++j) {
|
|
- this.vertices[t.vertices[j]].triangleCount = 1;
|
|
|
|
|
|
+ t.vertices[j].triangleCount = 1;
|
|
}
|
|
}
|
|
newTriangles.push(t);
|
|
newTriangles.push(t);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- var newVerticesOrder = [];
|
|
|
|
- //compact vertices, get the IDs of the vertices used.
|
|
|
|
- var dst = 0;
|
|
|
|
- for (i = 0; i < this.vertices.length; ++i) {
|
|
|
|
- if (this.vertices[i].triangleCount) {
|
|
|
|
- this.vertices[i].triangleStart = dst;
|
|
|
|
- this.vertices[dst].position = this.vertices[i].position;
|
|
|
|
- this.vertices[dst].normal = this.vertices[i].normal;
|
|
|
|
- this.vertices[dst].uv = this.vertices[i].uv;
|
|
|
|
- this.vertices[dst].color = this.vertices[i].color;
|
|
|
|
- newVerticesOrder.push(dst);
|
|
|
|
- dst++;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- for (i = 0; i < newTriangles.length; ++i) {
|
|
|
|
- t = newTriangles[i];
|
|
|
|
- for (j = 0; j < 3; ++j) {
|
|
|
|
- t.vertices[j] = this.vertices[t.vertices[j]].triangleStart;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- this.vertices = this.vertices.slice(0, dst);
|
|
|
|
var newPositionData = this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.PositionKind) || [];
|
|
var newPositionData = this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.PositionKind) || [];
|
|
var newNormalData = this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.NormalKind) || [];
|
|
var newNormalData = this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.NormalKind) || [];
|
|
var newUVsData = this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.UVKind) || [];
|
|
var newUVsData = this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.UVKind) || [];
|
|
var newColorsData = this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.ColorKind) || [];
|
|
var newColorsData = this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.ColorKind) || [];
|
|
- for (i = 0; i < newVerticesOrder.length; ++i) {
|
|
|
|
- newPositionData.push(this.vertices[i].position.x);
|
|
|
|
- newPositionData.push(this.vertices[i].position.y);
|
|
|
|
- newPositionData.push(this.vertices[i].position.z);
|
|
|
|
- newNormalData.push(this.vertices[i].normal.x);
|
|
|
|
- newNormalData.push(this.vertices[i].normal.y);
|
|
|
|
- newNormalData.push(this.vertices[i].normal.z);
|
|
|
|
- if (this.vertices[i].uv) {
|
|
|
|
- newUVsData.push(this.vertices[i].uv.x);
|
|
|
|
- newUVsData.push(this.vertices[i].uv.y);
|
|
|
|
- }
|
|
|
|
- else if (this.vertices[i].color) {
|
|
|
|
- newColorsData.push(this.vertices[i].color.r);
|
|
|
|
- newColorsData.push(this.vertices[i].color.g);
|
|
|
|
- newColorsData.push(this.vertices[i].color.b);
|
|
|
|
- newColorsData.push(this.vertices[i].color.a);
|
|
|
|
|
|
+ var normalData = this._mesh.getVerticesData(BABYLON.VertexBuffer.NormalKind);
|
|
|
|
+ var uvs = this._mesh.getVerticesData(BABYLON.VertexBuffer.UVKind);
|
|
|
|
+ var colorsData = this._mesh.getVerticesData(BABYLON.VertexBuffer.ColorKind);
|
|
|
|
+ var vertexCount = 0;
|
|
|
|
+ for (i = 0; i < this.vertices.length; ++i) {
|
|
|
|
+ var vertex = this.vertices[i];
|
|
|
|
+ vertex.id = vertexCount;
|
|
|
|
+ if (vertex.triangleCount) {
|
|
|
|
+ vertex.originalOffsets.forEach(function (originalOffset) {
|
|
|
|
+ newPositionData.push(vertex.position.x);
|
|
|
|
+ newPositionData.push(vertex.position.y);
|
|
|
|
+ newPositionData.push(vertex.position.z);
|
|
|
|
+ newNormalData.push(normalData[originalOffset * 3]);
|
|
|
|
+ newNormalData.push(normalData[(originalOffset * 3) + 1]);
|
|
|
|
+ newNormalData.push(normalData[(originalOffset * 3) + 2]);
|
|
|
|
+ if (uvs && uvs.length) {
|
|
|
|
+ newUVsData.push(uvs[(originalOffset * 2)]);
|
|
|
|
+ newUVsData.push(uvs[(originalOffset * 2) + 1]);
|
|
|
|
+ }
|
|
|
|
+ else if (colorsData && colorsData.length) {
|
|
|
|
+ newColorsData.push(colorsData[(originalOffset * 4)]);
|
|
|
|
+ newColorsData.push(colorsData[(originalOffset * 4) + 1]);
|
|
|
|
+ newColorsData.push(colorsData[(originalOffset * 4) + 2]);
|
|
|
|
+ newColorsData.push(colorsData[(originalOffset * 4) + 3]);
|
|
|
|
+ }
|
|
|
|
+ ++vertexCount;
|
|
|
|
+ });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var startingIndex = this._reconstructedMesh.getTotalIndices();
|
|
var startingIndex = this._reconstructedMesh.getTotalIndices();
|
|
@@ -448,10 +441,17 @@ var BABYLON;
|
|
var submeshesArray = this._reconstructedMesh.subMeshes;
|
|
var submeshesArray = this._reconstructedMesh.subMeshes;
|
|
this._reconstructedMesh.subMeshes = [];
|
|
this._reconstructedMesh.subMeshes = [];
|
|
var newIndicesArray = this._reconstructedMesh.getIndices(); //[];
|
|
var newIndicesArray = this._reconstructedMesh.getIndices(); //[];
|
|
|
|
+ var originalIndices = this._mesh.getIndices();
|
|
for (i = 0; i < newTriangles.length; ++i) {
|
|
for (i = 0; i < newTriangles.length; ++i) {
|
|
- newIndicesArray.push(newTriangles[i].vertices[0] + startingVertex);
|
|
|
|
- newIndicesArray.push(newTriangles[i].vertices[1] + startingVertex);
|
|
|
|
- newIndicesArray.push(newTriangles[i].vertices[2] + startingVertex);
|
|
|
|
|
|
+ var t = newTriangles[i];
|
|
|
|
+ //now get the new referencing point for each vertex
|
|
|
|
+ [0, 1, 2].forEach(function (idx) {
|
|
|
|
+ var id = originalIndices[t.originalOffset + idx];
|
|
|
|
+ var offset = t.vertices[idx].originalOffsets.indexOf(id);
|
|
|
|
+ if (offset < 0)
|
|
|
|
+ offset = 0;
|
|
|
|
+ newIndicesArray.push(t.vertices[idx].id + offset + startingVertex);
|
|
|
|
+ });
|
|
}
|
|
}
|
|
//overwriting the old vertex buffers and indices.
|
|
//overwriting the old vertex buffers and indices.
|
|
this._reconstructedMesh.setIndices(newIndicesArray);
|
|
this._reconstructedMesh.setIndices(newIndicesArray);
|
|
@@ -468,7 +468,7 @@ var BABYLON;
|
|
submeshesArray.forEach(function (submesh) {
|
|
submeshesArray.forEach(function (submesh) {
|
|
new BABYLON.SubMesh(submesh.materialIndex, submesh.verticesStart, submesh.verticesCount, submesh.indexStart, submesh.indexCount, submesh.getMesh());
|
|
new BABYLON.SubMesh(submesh.materialIndex, submesh.verticesStart, submesh.verticesCount, submesh.indexStart, submesh.indexCount, submesh.getMesh());
|
|
});
|
|
});
|
|
- var newSubmesh = new BABYLON.SubMesh(originalSubmesh.materialIndex, startingVertex, newVerticesOrder.length, startingIndex, newTriangles.length * 3, this._reconstructedMesh);
|
|
|
|
|
|
+ var newSubmesh = new BABYLON.SubMesh(originalSubmesh.materialIndex, startingVertex, vertexCount, startingIndex, newTriangles.length * 3, this._reconstructedMesh);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
QuadraticErrorSimplification.prototype.initDecimatedMesh = function () {
|
|
QuadraticErrorSimplification.prototype.initDecimatedMesh = function () {
|
|
@@ -477,22 +477,22 @@ var BABYLON;
|
|
this._reconstructedMesh.parent = this._mesh.parent;
|
|
this._reconstructedMesh.parent = this._mesh.parent;
|
|
this._reconstructedMesh.isVisible = false;
|
|
this._reconstructedMesh.isVisible = false;
|
|
};
|
|
};
|
|
- QuadraticErrorSimplification.prototype.isFlipped = function (vertex1, index2, point, deletedArray, borderFactor, delTr) {
|
|
|
|
|
|
+ QuadraticErrorSimplification.prototype.isFlipped = function (vertex1, vertex2, point, deletedArray, borderFactor, delTr) {
|
|
for (var i = 0; i < vertex1.triangleCount; ++i) {
|
|
for (var i = 0; i < vertex1.triangleCount; ++i) {
|
|
var t = this.triangles[this.references[vertex1.triangleStart + i].triangleId];
|
|
var t = this.triangles[this.references[vertex1.triangleStart + i].triangleId];
|
|
if (t.deleted)
|
|
if (t.deleted)
|
|
continue;
|
|
continue;
|
|
var s = this.references[vertex1.triangleStart + i].vertexId;
|
|
var s = this.references[vertex1.triangleStart + i].vertexId;
|
|
- var id1 = t.vertices[(s + 1) % 3];
|
|
|
|
- var id2 = t.vertices[(s + 2) % 3];
|
|
|
|
- if ((id1 === index2 || id2 === index2)) {
|
|
|
|
|
|
+ var v1 = t.vertices[(s + 1) % 3];
|
|
|
|
+ var v2 = t.vertices[(s + 2) % 3];
|
|
|
|
+ if ((v1 === vertex2 || v2 === vertex2)) {
|
|
deletedArray[i] = true;
|
|
deletedArray[i] = true;
|
|
delTr.push(t);
|
|
delTr.push(t);
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
- var d1 = this.vertices[id1].position.subtract(point);
|
|
|
|
|
|
+ var d1 = v1.position.subtract(point);
|
|
d1 = d1.normalize();
|
|
d1 = d1.normalize();
|
|
- var d2 = this.vertices[id2].position.subtract(point);
|
|
|
|
|
|
+ var d2 = v2.position.subtract(point);
|
|
d2 = d2.normalize();
|
|
d2 = d2.normalize();
|
|
if (Math.abs(BABYLON.Vector3.Dot(d1, d2)) > 0.999)
|
|
if (Math.abs(BABYLON.Vector3.Dot(d1, d2)) > 0.999)
|
|
return true;
|
|
return true;
|
|
@@ -503,7 +503,7 @@ var BABYLON;
|
|
}
|
|
}
|
|
return false;
|
|
return false;
|
|
};
|
|
};
|
|
- QuadraticErrorSimplification.prototype.updateTriangles = function (vertexId, vertex, deletedArray, deletedTriangles) {
|
|
|
|
|
|
+ QuadraticErrorSimplification.prototype.updateTriangles = function (origVertex, vertex, deletedArray, deletedTriangles) {
|
|
var newDeleted = deletedTriangles;
|
|
var newDeleted = deletedTriangles;
|
|
for (var i = 0; i < vertex.triangleCount; ++i) {
|
|
for (var i = 0; i < vertex.triangleCount; ++i) {
|
|
var ref = this.references[vertex.triangleStart + i];
|
|
var ref = this.references[vertex.triangleStart + i];
|
|
@@ -515,11 +515,11 @@ var BABYLON;
|
|
newDeleted++;
|
|
newDeleted++;
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
- t.vertices[ref.vertexId] = vertexId;
|
|
|
|
|
|
+ t.vertices[ref.vertexId] = origVertex;
|
|
t.isDirty = true;
|
|
t.isDirty = true;
|
|
- t.error[0] = this.calculateError(this.vertices[t.vertices[0]], this.vertices[t.vertices[1]]) + (t.borderFactor / 2);
|
|
|
|
- t.error[1] = this.calculateError(this.vertices[t.vertices[1]], this.vertices[t.vertices[2]]) + (t.borderFactor / 2);
|
|
|
|
- t.error[2] = this.calculateError(this.vertices[t.vertices[2]], this.vertices[t.vertices[0]]) + (t.borderFactor / 2);
|
|
|
|
|
|
+ t.error[0] = this.calculateError(t.vertices[0], t.vertices[1]) + (t.borderFactor / 2);
|
|
|
|
+ t.error[1] = this.calculateError(t.vertices[1], t.vertices[2]) + (t.borderFactor / 2);
|
|
|
|
+ t.error[2] = this.calculateError(t.vertices[2], t.vertices[0]) + (t.borderFactor / 2);
|
|
t.error[3] = Math.min(t.error[0], t.error[1], t.error[2]);
|
|
t.error[3] = Math.min(t.error[0], t.error[1], t.error[2]);
|
|
this.references.push(ref);
|
|
this.references.push(ref);
|
|
}
|
|
}
|
|
@@ -535,15 +535,15 @@ var BABYLON;
|
|
var triangle = this.triangles[this.references[v.triangleStart + j].triangleId];
|
|
var triangle = this.triangles[this.references[v.triangleStart + j].triangleId];
|
|
for (var ii = 0; ii < 3; ii++) {
|
|
for (var ii = 0; ii < 3; ii++) {
|
|
var ofs = 0;
|
|
var ofs = 0;
|
|
- var id = triangle.vertices[ii];
|
|
|
|
|
|
+ var vv = triangle.vertices[ii];
|
|
while (ofs < vCount.length) {
|
|
while (ofs < vCount.length) {
|
|
- if (vId[ofs] === id)
|
|
|
|
|
|
+ if (vId[ofs] === vv.id)
|
|
break;
|
|
break;
|
|
++ofs;
|
|
++ofs;
|
|
}
|
|
}
|
|
if (ofs === vCount.length) {
|
|
if (ofs === vCount.length) {
|
|
vCount.push(1);
|
|
vCount.push(1);
|
|
- vId.push(id);
|
|
|
|
|
|
+ vId.push(vv.id);
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
vCount[ofs]++;
|
|
vCount[ofs]++;
|
|
@@ -582,7 +582,7 @@ var BABYLON;
|
|
for (i = 0; i < this.triangles.length; ++i) {
|
|
for (i = 0; i < this.triangles.length; ++i) {
|
|
t = this.triangles[i];
|
|
t = this.triangles[i];
|
|
for (j = 0; j < 3; ++j) {
|
|
for (j = 0; j < 3; ++j) {
|
|
- v = this.vertices[t.vertices[j]];
|
|
|
|
|
|
+ v = t.vertices[j];
|
|
v.triangleCount++;
|
|
v.triangleCount++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -596,7 +596,7 @@ var BABYLON;
|
|
for (i = 0; i < this.triangles.length; ++i) {
|
|
for (i = 0; i < this.triangles.length; ++i) {
|
|
t = this.triangles[i];
|
|
t = this.triangles[i];
|
|
for (j = 0; j < 3; ++j) {
|
|
for (j = 0; j < 3; ++j) {
|
|
- v = this.vertices[t.vertices[j]];
|
|
|
|
|
|
+ v = t.vertices[j];
|
|
newReferences[v.triangleStart + v.triangleCount] = new Reference(j, i);
|
|
newReferences[v.triangleStart + v.triangleCount] = new Reference(j, i);
|
|
v.triangleCount++;
|
|
v.triangleCount++;
|
|
}
|
|
}
|
|
@@ -625,14 +625,6 @@ var BABYLON;
|
|
pointResult.y = 1 / qDet * (q.det(0, 2, 3, 1, 5, 6, 2, 7, 8));
|
|
pointResult.y = 1 / qDet * (q.det(0, 2, 3, 1, 5, 6, 2, 7, 8));
|
|
pointResult.z = -1 / qDet * (q.det(0, 1, 3, 1, 4, 6, 2, 5, 8));
|
|
pointResult.z = -1 / qDet * (q.det(0, 1, 3, 1, 4, 6, 2, 5, 8));
|
|
error = this.vertexError(q, pointResult);
|
|
error = this.vertexError(q, pointResult);
|
|
- //TODO this should be correctly calculated
|
|
|
|
- if (normalResult) {
|
|
|
|
- normalResult.copyFrom(vertex1.normal);
|
|
|
|
- if (vertex1.uv)
|
|
|
|
- uvResult.copyFrom(vertex1.uv);
|
|
|
|
- else if (vertex1.color)
|
|
|
|
- colorResult.copyFrom(vertex1.color);
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
var p3 = (vertex1.position.add(vertex2.position)).divide(new BABYLON.Vector3(2, 2, 2));
|
|
var p3 = (vertex1.position.add(vertex2.position)).divide(new BABYLON.Vector3(2, 2, 2));
|
|
@@ -644,31 +636,16 @@ var BABYLON;
|
|
if (error === error1) {
|
|
if (error === error1) {
|
|
if (pointResult) {
|
|
if (pointResult) {
|
|
pointResult.copyFrom(vertex1.position);
|
|
pointResult.copyFrom(vertex1.position);
|
|
- normalResult.copyFrom(vertex1.normal);
|
|
|
|
- if (vertex1.uv)
|
|
|
|
- uvResult.copyFrom(vertex1.uv);
|
|
|
|
- else if (vertex1.color)
|
|
|
|
- colorResult.copyFrom(vertex1.color);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (error === error2) {
|
|
else if (error === error2) {
|
|
if (pointResult) {
|
|
if (pointResult) {
|
|
pointResult.copyFrom(vertex2.position);
|
|
pointResult.copyFrom(vertex2.position);
|
|
- normalResult.copyFrom(vertex2.normal);
|
|
|
|
- if (vertex2.uv)
|
|
|
|
- uvResult.copyFrom(vertex2.uv);
|
|
|
|
- else if (vertex2.color)
|
|
|
|
- colorResult.copyFrom(vertex2.color);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
if (pointResult) {
|
|
if (pointResult) {
|
|
pointResult.copyFrom(p3);
|
|
pointResult.copyFrom(p3);
|
|
- normalResult.copyFrom(vertex1.normal);
|
|
|
|
- if (vertex1.uv)
|
|
|
|
- uvResult.copyFrom(vertex1.uv);
|
|
|
|
- else if (vertex1.color)
|
|
|
|
- colorResult.copyFrom(vertex1.color);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|