|
@@ -1,4 +1,4 @@
|
|
|
-var BABYLON;
|
|
|
+var BABYLON;
|
|
|
(function (BABYLON) {
|
|
|
var VertexData = (function () {
|
|
|
function VertexData() {
|
|
@@ -28,113 +28,86 @@
|
|
|
break;
|
|
|
}
|
|
|
};
|
|
|
-
|
|
|
VertexData.prototype.applyToMesh = function (mesh, updatable) {
|
|
|
this._applyTo(mesh, updatable);
|
|
|
};
|
|
|
-
|
|
|
VertexData.prototype.applyToGeometry = function (geometry, updatable) {
|
|
|
this._applyTo(geometry, updatable);
|
|
|
};
|
|
|
-
|
|
|
VertexData.prototype.updateMesh = function (mesh, updateExtends, makeItUnique) {
|
|
|
this._update(mesh);
|
|
|
};
|
|
|
-
|
|
|
VertexData.prototype.updateGeometry = function (geometry, updateExtends, makeItUnique) {
|
|
|
this._update(geometry);
|
|
|
};
|
|
|
-
|
|
|
VertexData.prototype._applyTo = function (meshOrGeometry, updatable) {
|
|
|
if (this.positions) {
|
|
|
meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.PositionKind, this.positions, updatable);
|
|
|
}
|
|
|
-
|
|
|
if (this.normals) {
|
|
|
meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.NormalKind, this.normals, updatable);
|
|
|
}
|
|
|
-
|
|
|
if (this.uvs) {
|
|
|
meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.UVKind, this.uvs, updatable);
|
|
|
}
|
|
|
-
|
|
|
if (this.uv2s) {
|
|
|
meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.UV2Kind, this.uv2s, updatable);
|
|
|
}
|
|
|
-
|
|
|
if (this.colors) {
|
|
|
meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.ColorKind, this.colors, updatable);
|
|
|
}
|
|
|
-
|
|
|
if (this.matricesIndices) {
|
|
|
meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.MatricesIndicesKind, this.matricesIndices, updatable);
|
|
|
}
|
|
|
-
|
|
|
if (this.matricesWeights) {
|
|
|
meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.MatricesWeightsKind, this.matricesWeights, updatable);
|
|
|
}
|
|
|
-
|
|
|
if (this.indices) {
|
|
|
meshOrGeometry.setIndices(this.indices);
|
|
|
}
|
|
|
};
|
|
|
-
|
|
|
VertexData.prototype._update = function (meshOrGeometry, updateExtends, makeItUnique) {
|
|
|
if (this.positions) {
|
|
|
meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.PositionKind, this.positions, updateExtends, makeItUnique);
|
|
|
}
|
|
|
-
|
|
|
if (this.normals) {
|
|
|
meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.NormalKind, this.normals, updateExtends, makeItUnique);
|
|
|
}
|
|
|
-
|
|
|
if (this.uvs) {
|
|
|
meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.UVKind, this.uvs, updateExtends, makeItUnique);
|
|
|
}
|
|
|
-
|
|
|
if (this.uv2s) {
|
|
|
meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.UV2Kind, this.uv2s, updateExtends, makeItUnique);
|
|
|
}
|
|
|
-
|
|
|
if (this.colors) {
|
|
|
meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.ColorKind, this.colors, updateExtends, makeItUnique);
|
|
|
}
|
|
|
-
|
|
|
if (this.matricesIndices) {
|
|
|
meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.MatricesIndicesKind, this.matricesIndices, updateExtends, makeItUnique);
|
|
|
}
|
|
|
-
|
|
|
if (this.matricesWeights) {
|
|
|
meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.MatricesWeightsKind, this.matricesWeights, updateExtends, makeItUnique);
|
|
|
}
|
|
|
-
|
|
|
if (this.indices) {
|
|
|
meshOrGeometry.setIndices(this.indices);
|
|
|
}
|
|
|
};
|
|
|
-
|
|
|
VertexData.prototype.transform = function (matrix) {
|
|
|
var transformed = BABYLON.Vector3.Zero();
|
|
|
-
|
|
|
if (this.positions) {
|
|
|
var position = BABYLON.Vector3.Zero();
|
|
|
-
|
|
|
for (var index = 0; index < this.positions.length; index += 3) {
|
|
|
BABYLON.Vector3.FromArrayToRef(this.positions, index, position);
|
|
|
-
|
|
|
BABYLON.Vector3.TransformCoordinatesToRef(position, matrix, transformed);
|
|
|
this.positions[index] = transformed.x;
|
|
|
this.positions[index + 1] = transformed.y;
|
|
|
this.positions[index + 2] = transformed.z;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
if (this.normals) {
|
|
|
var normal = BABYLON.Vector3.Zero();
|
|
|
-
|
|
|
for (index = 0; index < this.normals.length; index += 3) {
|
|
|
BABYLON.Vector3.FromArrayToRef(this.normals, index, normal);
|
|
|
-
|
|
|
BABYLON.Vector3.TransformNormalToRef(normal, matrix, transformed);
|
|
|
this.normals[index] = transformed.x;
|
|
|
this.normals[index + 1] = transformed.y;
|
|
@@ -142,29 +115,24 @@
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
-
|
|
|
VertexData.prototype.merge = function (other) {
|
|
|
if (other.indices) {
|
|
|
if (!this.indices) {
|
|
|
this.indices = [];
|
|
|
}
|
|
|
-
|
|
|
var offset = this.positions ? this.positions.length / 3 : 0;
|
|
|
for (var index = 0; index < other.indices.length; index++) {
|
|
|
this.indices.push(other.indices[index] + offset);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
if (other.positions) {
|
|
|
if (!this.positions) {
|
|
|
this.positions = [];
|
|
|
}
|
|
|
-
|
|
|
for (index = 0; index < other.positions.length; index++) {
|
|
|
this.positions.push(other.positions[index]);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
if (other.normals) {
|
|
|
if (!this.normals) {
|
|
|
this.normals = [];
|
|
@@ -173,7 +141,6 @@
|
|
|
this.normals.push(other.normals[index]);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
if (other.uvs) {
|
|
|
if (!this.uvs) {
|
|
|
this.uvs = [];
|
|
@@ -182,7 +149,6 @@
|
|
|
this.uvs.push(other.uvs[index]);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
if (other.uv2s) {
|
|
|
if (!this.uv2s) {
|
|
|
this.uv2s = [];
|
|
@@ -191,7 +157,6 @@
|
|
|
this.uv2s.push(other.uv2s[index]);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
if (other.matricesIndices) {
|
|
|
if (!this.matricesIndices) {
|
|
|
this.matricesIndices = [];
|
|
@@ -200,7 +165,6 @@
|
|
|
this.matricesIndices.push(other.matricesIndices[index]);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
if (other.matricesWeights) {
|
|
|
if (!this.matricesWeights) {
|
|
|
this.matricesWeights = [];
|
|
@@ -209,7 +173,6 @@
|
|
|
this.matricesWeights.push(other.matricesWeights[index]);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
if (other.colors) {
|
|
|
if (!this.colors) {
|
|
|
this.colors = [];
|
|
@@ -219,52 +182,39 @@
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
-
|
|
|
// Statics
|
|
|
VertexData.ExtractFromMesh = function (mesh) {
|
|
|
return VertexData._ExtractFrom(mesh);
|
|
|
};
|
|
|
-
|
|
|
VertexData.ExtractFromGeometry = function (geometry) {
|
|
|
return VertexData._ExtractFrom(geometry);
|
|
|
};
|
|
|
-
|
|
|
VertexData._ExtractFrom = function (meshOrGeometry) {
|
|
|
var result = new BABYLON.VertexData();
|
|
|
-
|
|
|
if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)) {
|
|
|
result.positions = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.PositionKind);
|
|
|
}
|
|
|
-
|
|
|
if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
|
|
|
result.normals = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.NormalKind);
|
|
|
}
|
|
|
-
|
|
|
if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
|
|
|
result.uvs = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.UVKind);
|
|
|
}
|
|
|
-
|
|
|
if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
|
|
|
result.uv2s = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.UV2Kind);
|
|
|
}
|
|
|
-
|
|
|
if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
|
|
|
result.colors = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.ColorKind);
|
|
|
}
|
|
|
-
|
|
|
if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind)) {
|
|
|
result.matricesIndices = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.MatricesIndicesKind);
|
|
|
}
|
|
|
-
|
|
|
if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind)) {
|
|
|
result.matricesWeights = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.MatricesWeightsKind);
|
|
|
}
|
|
|
-
|
|
|
result.indices = meshOrGeometry.getIndices();
|
|
|
-
|
|
|
return result;
|
|
|
};
|
|
|
-
|
|
|
VertexData.CreateBox = function (size) {
|
|
|
var normalsSource = [
|
|
|
new BABYLON.Vector3(0, 0, 1),
|
|
@@ -274,396 +224,309 @@
|
|
|
new BABYLON.Vector3(0, 1, 0),
|
|
|
new BABYLON.Vector3(0, -1, 0)
|
|
|
];
|
|
|
-
|
|
|
var indices = [];
|
|
|
var positions = [];
|
|
|
var normals = [];
|
|
|
var uvs = [];
|
|
|
-
|
|
|
size = size || 1;
|
|
|
-
|
|
|
for (var index = 0; index < normalsSource.length; index++) {
|
|
|
var normal = normalsSource[index];
|
|
|
-
|
|
|
// Get two vectors perpendicular to the face normal and to each other.
|
|
|
var side1 = new BABYLON.Vector3(normal.y, normal.z, normal.x);
|
|
|
var side2 = BABYLON.Vector3.Cross(normal, side1);
|
|
|
-
|
|
|
// Six indices (two triangles) per face.
|
|
|
var verticesLength = positions.length / 3;
|
|
|
indices.push(verticesLength);
|
|
|
indices.push(verticesLength + 1);
|
|
|
indices.push(verticesLength + 2);
|
|
|
-
|
|
|
indices.push(verticesLength);
|
|
|
indices.push(verticesLength + 2);
|
|
|
indices.push(verticesLength + 3);
|
|
|
-
|
|
|
// Four vertices per face.
|
|
|
var vertex = normal.subtract(side1).subtract(side2).scale(size / 2);
|
|
|
positions.push(vertex.x, vertex.y, vertex.z);
|
|
|
normals.push(normal.x, normal.y, normal.z);
|
|
|
uvs.push(1.0, 1.0);
|
|
|
-
|
|
|
vertex = normal.subtract(side1).add(side2).scale(size / 2);
|
|
|
positions.push(vertex.x, vertex.y, vertex.z);
|
|
|
normals.push(normal.x, normal.y, normal.z);
|
|
|
uvs.push(0.0, 1.0);
|
|
|
-
|
|
|
vertex = normal.add(side1).add(side2).scale(size / 2);
|
|
|
positions.push(vertex.x, vertex.y, vertex.z);
|
|
|
normals.push(normal.x, normal.y, normal.z);
|
|
|
uvs.push(0.0, 0.0);
|
|
|
-
|
|
|
vertex = normal.add(side1).subtract(side2).scale(size / 2);
|
|
|
positions.push(vertex.x, vertex.y, vertex.z);
|
|
|
normals.push(normal.x, normal.y, normal.z);
|
|
|
uvs.push(1.0, 0.0);
|
|
|
}
|
|
|
-
|
|
|
// Result
|
|
|
var vertexData = new BABYLON.VertexData();
|
|
|
-
|
|
|
vertexData.indices = indices;
|
|
|
vertexData.positions = positions;
|
|
|
vertexData.normals = normals;
|
|
|
vertexData.uvs = uvs;
|
|
|
-
|
|
|
return vertexData;
|
|
|
};
|
|
|
-
|
|
|
VertexData.CreateSphere = function (segments, diameter) {
|
|
|
segments = segments || 32;
|
|
|
diameter = diameter || 1;
|
|
|
-
|
|
|
var radius = diameter / 2;
|
|
|
-
|
|
|
var totalZRotationSteps = 2 + segments;
|
|
|
var totalYRotationSteps = 2 * totalZRotationSteps;
|
|
|
-
|
|
|
var indices = [];
|
|
|
var positions = [];
|
|
|
var normals = [];
|
|
|
var uvs = [];
|
|
|
-
|
|
|
for (var zRotationStep = 0; zRotationStep <= totalZRotationSteps; zRotationStep++) {
|
|
|
var normalizedZ = zRotationStep / totalZRotationSteps;
|
|
|
var angleZ = (normalizedZ * Math.PI);
|
|
|
-
|
|
|
for (var yRotationStep = 0; yRotationStep <= totalYRotationSteps; yRotationStep++) {
|
|
|
var normalizedY = yRotationStep / totalYRotationSteps;
|
|
|
-
|
|
|
var angleY = normalizedY * Math.PI * 2;
|
|
|
-
|
|
|
var rotationZ = BABYLON.Matrix.RotationZ(-angleZ);
|
|
|
var rotationY = BABYLON.Matrix.RotationY(angleY);
|
|
|
var afterRotZ = BABYLON.Vector3.TransformCoordinates(BABYLON.Vector3.Up(), rotationZ);
|
|
|
var complete = BABYLON.Vector3.TransformCoordinates(afterRotZ, rotationY);
|
|
|
-
|
|
|
var vertex = complete.scale(radius);
|
|
|
var normal = BABYLON.Vector3.Normalize(vertex);
|
|
|
-
|
|
|
positions.push(vertex.x, vertex.y, vertex.z);
|
|
|
normals.push(normal.x, normal.y, normal.z);
|
|
|
uvs.push(normalizedZ, normalizedY);
|
|
|
}
|
|
|
-
|
|
|
if (zRotationStep > 0) {
|
|
|
var verticesCount = positions.length / 3;
|
|
|
for (var firstIndex = verticesCount - 2 * (totalYRotationSteps + 1); (firstIndex + totalYRotationSteps + 2) < verticesCount; firstIndex++) {
|
|
|
indices.push((firstIndex));
|
|
|
indices.push((firstIndex + 1));
|
|
|
indices.push(firstIndex + totalYRotationSteps + 1);
|
|
|
-
|
|
|
indices.push((firstIndex + totalYRotationSteps + 1));
|
|
|
indices.push((firstIndex + 1));
|
|
|
indices.push((firstIndex + totalYRotationSteps + 2));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
// Result
|
|
|
var vertexData = new BABYLON.VertexData();
|
|
|
-
|
|
|
vertexData.indices = indices;
|
|
|
vertexData.positions = positions;
|
|
|
vertexData.normals = normals;
|
|
|
vertexData.uvs = uvs;
|
|
|
-
|
|
|
return vertexData;
|
|
|
};
|
|
|
-
|
|
|
VertexData.CreateCylinder = function (height, diameterTop, diameterBottom, tessellation, subdivisions) {
|
|
|
- if (typeof subdivisions === "undefined") { subdivisions = 1; }
|
|
|
+ if (subdivisions === void 0) { subdivisions = 1; }
|
|
|
var radiusTop = diameterTop / 2;
|
|
|
var radiusBottom = diameterBottom / 2;
|
|
|
var indices = [];
|
|
|
var positions = [];
|
|
|
var normals = [];
|
|
|
var uvs = [];
|
|
|
-
|
|
|
height = height || 1;
|
|
|
diameterTop = diameterTop || 0.5;
|
|
|
diameterBottom = diameterBottom || 1;
|
|
|
tessellation = tessellation || 16;
|
|
|
subdivisions = subdivisions || 1;
|
|
|
subdivisions = (subdivisions < 1) ? 1 : subdivisions;
|
|
|
-
|
|
|
var getCircleVector = function (i) {
|
|
|
var angle = (i * 2.0 * Math.PI / tessellation);
|
|
|
var dx = Math.cos(angle);
|
|
|
var dz = Math.sin(angle);
|
|
|
-
|
|
|
return new BABYLON.Vector3(dx, 0, dz);
|
|
|
};
|
|
|
-
|
|
|
var createCylinderCap = function (isTop) {
|
|
|
var radius = isTop ? radiusTop : radiusBottom;
|
|
|
-
|
|
|
if (radius == 0) {
|
|
|
return;
|
|
|
}
|
|
|
var vbase = positions.length / 3;
|
|
|
-
|
|
|
var offset = new BABYLON.Vector3(0, height / 2, 0);
|
|
|
var textureScale = new BABYLON.Vector2(0.5, 0.5);
|
|
|
-
|
|
|
if (!isTop) {
|
|
|
offset.scaleInPlace(-1);
|
|
|
textureScale.x = -textureScale.x;
|
|
|
}
|
|
|
-
|
|
|
for (i = 0; i < tessellation; i++) {
|
|
|
var circleVector = getCircleVector(i);
|
|
|
var position = circleVector.scale(radius).add(offset);
|
|
|
var textureCoordinate = new BABYLON.Vector2(circleVector.x * textureScale.x + 0.5, circleVector.z * textureScale.y + 0.5);
|
|
|
-
|
|
|
positions.push(position.x, position.y, position.z);
|
|
|
uvs.push(textureCoordinate.x, textureCoordinate.y);
|
|
|
}
|
|
|
-
|
|
|
for (var i = 0; i < tessellation - 2; i++) {
|
|
|
if (!isTop) {
|
|
|
indices.push(vbase);
|
|
|
indices.push(vbase + (i + 2) % tessellation);
|
|
|
indices.push(vbase + (i + 1) % tessellation);
|
|
|
- } else {
|
|
|
+ }
|
|
|
+ else {
|
|
|
indices.push(vbase);
|
|
|
indices.push(vbase + (i + 1) % tessellation);
|
|
|
indices.push(vbase + (i + 2) % tessellation);
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
-
|
|
|
var base = new BABYLON.Vector3(0, -1, 0).scale(height / 2);
|
|
|
var offset = new BABYLON.Vector3(0, 1, 0).scale(height / subdivisions);
|
|
|
var stride = tessellation + 1;
|
|
|
-
|
|
|
for (var i = 0; i <= tessellation; i++) {
|
|
|
var circleVector = getCircleVector(i);
|
|
|
var textureCoordinate = new BABYLON.Vector2(i / tessellation, 0);
|
|
|
var position, radius = radiusBottom;
|
|
|
-
|
|
|
for (var s = 0; s <= subdivisions; s++) {
|
|
|
// Update variables
|
|
|
position = circleVector.scale(radius);
|
|
|
position.addInPlace(base.add(offset.scale(s)));
|
|
|
textureCoordinate.y += 1 / subdivisions;
|
|
|
radius += (radiusTop - radiusBottom) / subdivisions;
|
|
|
-
|
|
|
// Push in arrays
|
|
|
positions.push(position.x, position.y, position.z);
|
|
|
uvs.push(textureCoordinate.x, textureCoordinate.y);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
subdivisions += 1;
|
|
|
-
|
|
|
for (var s = 0; s < subdivisions - 1; s++) {
|
|
|
for (var i = 0; i <= tessellation; i++) {
|
|
|
indices.push(i * subdivisions + s);
|
|
|
indices.push((i * subdivisions + (s + subdivisions)) % (stride * subdivisions));
|
|
|
indices.push(i * subdivisions + (s + 1));
|
|
|
-
|
|
|
indices.push(i * subdivisions + (s + 1));
|
|
|
indices.push((i * subdivisions + (s + subdivisions)) % (stride * subdivisions));
|
|
|
indices.push((i * subdivisions + (s + subdivisions + 1)) % (stride * subdivisions));
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
// Create flat triangle fan caps to seal the top and bottom.
|
|
|
createCylinderCap(true);
|
|
|
createCylinderCap(false);
|
|
|
-
|
|
|
// Normals
|
|
|
BABYLON.VertexData.ComputeNormals(positions, indices, normals);
|
|
|
-
|
|
|
// Result
|
|
|
var vertexData = new BABYLON.VertexData();
|
|
|
-
|
|
|
vertexData.indices = indices;
|
|
|
vertexData.positions = positions;
|
|
|
vertexData.normals = normals;
|
|
|
vertexData.uvs = uvs;
|
|
|
-
|
|
|
return vertexData;
|
|
|
};
|
|
|
-
|
|
|
VertexData.CreateTorus = function (diameter, thickness, tessellation) {
|
|
|
var indices = [];
|
|
|
var positions = [];
|
|
|
var normals = [];
|
|
|
var uvs = [];
|
|
|
-
|
|
|
diameter = diameter || 1;
|
|
|
thickness = thickness || 0.5;
|
|
|
tessellation = tessellation || 16;
|
|
|
-
|
|
|
var stride = tessellation + 1;
|
|
|
-
|
|
|
for (var i = 0; i <= tessellation; i++) {
|
|
|
var u = i / tessellation;
|
|
|
-
|
|
|
var outerAngle = i * Math.PI * 2.0 / tessellation - Math.PI / 2.0;
|
|
|
-
|
|
|
var transform = BABYLON.Matrix.Translation(diameter / 2.0, 0, 0).multiply(BABYLON.Matrix.RotationY(outerAngle));
|
|
|
-
|
|
|
for (var j = 0; j <= tessellation; j++) {
|
|
|
var v = 1 - j / tessellation;
|
|
|
-
|
|
|
var innerAngle = j * Math.PI * 2.0 / tessellation + Math.PI;
|
|
|
var dx = Math.cos(innerAngle);
|
|
|
var dy = Math.sin(innerAngle);
|
|
|
-
|
|
|
// Create a vertex.
|
|
|
var normal = new BABYLON.Vector3(dx, dy, 0);
|
|
|
var position = normal.scale(thickness / 2);
|
|
|
var textureCoordinate = new BABYLON.Vector2(u, v);
|
|
|
-
|
|
|
position = BABYLON.Vector3.TransformCoordinates(position, transform);
|
|
|
normal = BABYLON.Vector3.TransformNormal(normal, transform);
|
|
|
-
|
|
|
positions.push(position.x, position.y, position.z);
|
|
|
normals.push(normal.x, normal.y, normal.z);
|
|
|
uvs.push(textureCoordinate.x, textureCoordinate.y);
|
|
|
-
|
|
|
// And create indices for two triangles.
|
|
|
var nextI = (i + 1) % stride;
|
|
|
var nextJ = (j + 1) % stride;
|
|
|
-
|
|
|
indices.push(i * stride + j);
|
|
|
indices.push(i * stride + nextJ);
|
|
|
indices.push(nextI * stride + j);
|
|
|
-
|
|
|
indices.push(i * stride + nextJ);
|
|
|
indices.push(nextI * stride + nextJ);
|
|
|
indices.push(nextI * stride + j);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
// Result
|
|
|
var vertexData = new BABYLON.VertexData();
|
|
|
-
|
|
|
vertexData.indices = indices;
|
|
|
vertexData.positions = positions;
|
|
|
vertexData.normals = normals;
|
|
|
vertexData.uvs = uvs;
|
|
|
-
|
|
|
return vertexData;
|
|
|
};
|
|
|
-
|
|
|
VertexData.CreateLines = function (points) {
|
|
|
var indices = [];
|
|
|
var positions = [];
|
|
|
-
|
|
|
for (var index = 0; index < points.length; index++) {
|
|
|
positions.push(points[index].x, points[index].y, points[index].z);
|
|
|
-
|
|
|
if (index > 0) {
|
|
|
indices.push(index - 1);
|
|
|
indices.push(index);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
// Result
|
|
|
var vertexData = new BABYLON.VertexData();
|
|
|
-
|
|
|
vertexData.indices = indices;
|
|
|
vertexData.positions = positions;
|
|
|
-
|
|
|
return vertexData;
|
|
|
};
|
|
|
-
|
|
|
VertexData.CreateGround = function (width, height, subdivisions) {
|
|
|
var indices = [];
|
|
|
var positions = [];
|
|
|
var normals = [];
|
|
|
var uvs = [];
|
|
|
var row, col;
|
|
|
-
|
|
|
width = width || 1;
|
|
|
height = height || 1;
|
|
|
subdivisions = subdivisions || 1;
|
|
|
-
|
|
|
for (row = 0; row <= subdivisions; row++) {
|
|
|
for (col = 0; col <= subdivisions; col++) {
|
|
|
var position = new BABYLON.Vector3((col * width) / subdivisions - (width / 2.0), 0, ((subdivisions - row) * height) / subdivisions - (height / 2.0));
|
|
|
var normal = new BABYLON.Vector3(0, 1.0, 0);
|
|
|
-
|
|
|
positions.push(position.x, position.y, position.z);
|
|
|
normals.push(normal.x, normal.y, normal.z);
|
|
|
uvs.push(col / subdivisions, 1.0 - row / subdivisions);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
for (row = 0; row < subdivisions; row++) {
|
|
|
for (col = 0; col < subdivisions; col++) {
|
|
|
indices.push(col + 1 + (row + 1) * (subdivisions + 1));
|
|
|
indices.push(col + 1 + row * (subdivisions + 1));
|
|
|
indices.push(col + row * (subdivisions + 1));
|
|
|
-
|
|
|
indices.push(col + (row + 1) * (subdivisions + 1));
|
|
|
indices.push(col + 1 + (row + 1) * (subdivisions + 1));
|
|
|
indices.push(col + row * (subdivisions + 1));
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
// Result
|
|
|
var vertexData = new BABYLON.VertexData();
|
|
|
-
|
|
|
vertexData.indices = indices;
|
|
|
vertexData.positions = positions;
|
|
|
vertexData.normals = normals;
|
|
|
vertexData.uvs = uvs;
|
|
|
-
|
|
|
return vertexData;
|
|
|
};
|
|
|
-
|
|
|
VertexData.CreateTiledGround = function (xmin, zmin, xmax, zmax, subdivisions, precision) {
|
|
|
- if (typeof subdivisions === "undefined") { subdivisions = { w: 1, h: 1 }; }
|
|
|
- if (typeof precision === "undefined") { precision = { w: 1, h: 1 }; }
|
|
|
+ if (subdivisions === void 0) { subdivisions = { w: 1, h: 1 }; }
|
|
|
+ if (precision === void 0) { precision = { w: 1, h: 1 }; }
|
|
|
var indices = [];
|
|
|
var positions = [];
|
|
|
var normals = [];
|
|
|
var uvs = [];
|
|
|
var row, col, tileRow, tileCol;
|
|
|
-
|
|
|
subdivisions.h = (subdivisions.w < 1) ? 1 : subdivisions.h;
|
|
|
subdivisions.w = (subdivisions.w < 1) ? 1 : subdivisions.w;
|
|
|
precision.w = (precision.w < 1) ? 1 : precision.w;
|
|
|
precision.h = (precision.h < 1) ? 1 : precision.h;
|
|
|
-
|
|
|
var tileSize = {
|
|
|
'w': (xmax - xmin) / subdivisions.w,
|
|
|
'h': (zmax - zmin) / subdivisions.h
|
|
|
};
|
|
|
-
|
|
|
for (tileRow = 0; tileRow < subdivisions.h; tileRow++) {
|
|
|
for (tileCol = 0; tileCol < subdivisions.w; tileCol++) {
|
|
|
applyTile(xmin + tileCol * tileSize.w, zmin + tileRow * tileSize.h, xmin + (tileCol + 1) * tileSize.w, zmin + (tileRow + 1) * tileSize.h);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
function applyTile(xTileMin, zTileMin, xTileMax, zTileMax) {
|
|
|
// Indices
|
|
|
var base = positions.length / 3;
|
|
@@ -676,7 +539,6 @@
|
|
|
base + (col + 1) + (row + 1) * rowLength,
|
|
|
base + col + (row + 1) * rowLength
|
|
|
];
|
|
|
-
|
|
|
indices.push(square[1]);
|
|
|
indices.push(square[2]);
|
|
|
indices.push(square[3]);
|
|
@@ -685,7 +547,6 @@
|
|
|
indices.push(square[3]);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
// Position, normals and uvs
|
|
|
var position = BABYLON.Vector3.Zero();
|
|
|
var normal = new BABYLON.Vector3(0, 1.0, 0);
|
|
@@ -694,156 +555,122 @@
|
|
|
for (col = 0; col <= precision.w; col++) {
|
|
|
position.x = (col * (xTileMax - xTileMin)) / precision.w + xTileMin;
|
|
|
position.y = 0;
|
|
|
-
|
|
|
positions.push(position.x, position.y, position.z);
|
|
|
normals.push(normal.x, normal.y, normal.z);
|
|
|
uvs.push(col / precision.w, row / precision.h);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
// Result
|
|
|
var vertexData = new BABYLON.VertexData();
|
|
|
-
|
|
|
vertexData.indices = indices;
|
|
|
vertexData.positions = positions;
|
|
|
vertexData.normals = normals;
|
|
|
vertexData.uvs = uvs;
|
|
|
-
|
|
|
return vertexData;
|
|
|
};
|
|
|
-
|
|
|
VertexData.CreateGroundFromHeightMap = function (width, height, subdivisions, minHeight, maxHeight, buffer, bufferWidth, bufferHeight) {
|
|
|
var indices = [];
|
|
|
var positions = [];
|
|
|
var normals = [];
|
|
|
var uvs = [];
|
|
|
var row, col;
|
|
|
-
|
|
|
for (row = 0; row <= subdivisions; row++) {
|
|
|
for (col = 0; col <= subdivisions; col++) {
|
|
|
var position = new BABYLON.Vector3((col * width) / subdivisions - (width / 2.0), 0, ((subdivisions - row) * height) / subdivisions - (height / 2.0));
|
|
|
-
|
|
|
// Compute height
|
|
|
var heightMapX = (((position.x + width / 2) / width) * (bufferWidth - 1)) | 0;
|
|
|
var heightMapY = ((1.0 - (position.z + height / 2) / height) * (bufferHeight - 1)) | 0;
|
|
|
-
|
|
|
var pos = (heightMapX + heightMapY * bufferWidth) * 4;
|
|
|
var r = buffer[pos] / 255.0;
|
|
|
var g = buffer[pos + 1] / 255.0;
|
|
|
var b = buffer[pos + 2] / 255.0;
|
|
|
-
|
|
|
var gradient = r * 0.3 + g * 0.59 + b * 0.11;
|
|
|
-
|
|
|
position.y = minHeight + (maxHeight - minHeight) * gradient;
|
|
|
-
|
|
|
// Add vertex
|
|
|
positions.push(position.x, position.y, position.z);
|
|
|
normals.push(0, 0, 0);
|
|
|
uvs.push(col / subdivisions, 1.0 - row / subdivisions);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
for (row = 0; row < subdivisions; row++) {
|
|
|
for (col = 0; col < subdivisions; col++) {
|
|
|
indices.push(col + 1 + (row + 1) * (subdivisions + 1));
|
|
|
indices.push(col + 1 + row * (subdivisions + 1));
|
|
|
indices.push(col + row * (subdivisions + 1));
|
|
|
-
|
|
|
indices.push(col + (row + 1) * (subdivisions + 1));
|
|
|
indices.push(col + 1 + (row + 1) * (subdivisions + 1));
|
|
|
indices.push(col + row * (subdivisions + 1));
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
// Normals
|
|
|
BABYLON.VertexData.ComputeNormals(positions, indices, normals);
|
|
|
-
|
|
|
// Result
|
|
|
var vertexData = new BABYLON.VertexData();
|
|
|
-
|
|
|
vertexData.indices = indices;
|
|
|
vertexData.positions = positions;
|
|
|
vertexData.normals = normals;
|
|
|
vertexData.uvs = uvs;
|
|
|
-
|
|
|
return vertexData;
|
|
|
};
|
|
|
-
|
|
|
VertexData.CreatePlane = function (size) {
|
|
|
var indices = [];
|
|
|
var positions = [];
|
|
|
var normals = [];
|
|
|
var uvs = [];
|
|
|
-
|
|
|
size = size || 1;
|
|
|
-
|
|
|
// Vertices
|
|
|
var halfSize = size / 2.0;
|
|
|
positions.push(-halfSize, -halfSize, 0);
|
|
|
normals.push(0, 0, -1.0);
|
|
|
uvs.push(0.0, 0.0);
|
|
|
-
|
|
|
positions.push(halfSize, -halfSize, 0);
|
|
|
normals.push(0, 0, -1.0);
|
|
|
uvs.push(1.0, 0.0);
|
|
|
-
|
|
|
positions.push(halfSize, halfSize, 0);
|
|
|
normals.push(0, 0, -1.0);
|
|
|
uvs.push(1.0, 1.0);
|
|
|
-
|
|
|
positions.push(-halfSize, halfSize, 0);
|
|
|
normals.push(0, 0, -1.0);
|
|
|
uvs.push(0.0, 1.0);
|
|
|
-
|
|
|
// Indices
|
|
|
indices.push(0);
|
|
|
indices.push(1);
|
|
|
indices.push(2);
|
|
|
-
|
|
|
indices.push(0);
|
|
|
indices.push(2);
|
|
|
indices.push(3);
|
|
|
-
|
|
|
// Result
|
|
|
var vertexData = new BABYLON.VertexData();
|
|
|
-
|
|
|
vertexData.indices = indices;
|
|
|
vertexData.positions = positions;
|
|
|
vertexData.normals = normals;
|
|
|
vertexData.uvs = uvs;
|
|
|
-
|
|
|
return vertexData;
|
|
|
};
|
|
|
-
|
|
|
// based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3D/src/away3d/primitives/TorusKnot.as?spec=svn2473&r=2473
|
|
|
VertexData.CreateTorusKnot = function (radius, tube, radialSegments, tubularSegments, p, q) {
|
|
|
var indices = [];
|
|
|
var positions = [];
|
|
|
var normals = [];
|
|
|
var uvs = [];
|
|
|
-
|
|
|
radius = radius || 2;
|
|
|
tube = tube || 0.5;
|
|
|
radialSegments = radialSegments || 32;
|
|
|
tubularSegments = tubularSegments || 32;
|
|
|
p = p || 2;
|
|
|
q = q || 3;
|
|
|
-
|
|
|
// Helper
|
|
|
var getPos = function (angle) {
|
|
|
var cu = Math.cos(angle);
|
|
|
var su = Math.sin(angle);
|
|
|
var quOverP = q / p * angle;
|
|
|
var cs = Math.cos(quOverP);
|
|
|
-
|
|
|
var tx = radius * (2 + cs) * 0.5 * cu;
|
|
|
var ty = radius * (2 + cs) * su * 0.5;
|
|
|
var tz = radius * Math.sin(quOverP) * 0.5;
|
|
|
-
|
|
|
return new BABYLON.Vector3(tx, ty, tz);
|
|
|
};
|
|
|
-
|
|
|
for (var i = 0; i <= radialSegments; i++) {
|
|
|
var modI = i % radialSegments;
|
|
|
var u = modI / radialSegments * 2 * p * Math.PI;
|
|
@@ -851,28 +678,22 @@
|
|
|
var p2 = getPos(u + 0.01);
|
|
|
var tang = p2.subtract(p1);
|
|
|
var n = p2.add(p1);
|
|
|
-
|
|
|
var bitan = BABYLON.Vector3.Cross(tang, n);
|
|
|
n = BABYLON.Vector3.Cross(bitan, tang);
|
|
|
-
|
|
|
bitan.normalize();
|
|
|
n.normalize();
|
|
|
-
|
|
|
for (var j = 0; j < tubularSegments; j++) {
|
|
|
var modJ = j % tubularSegments;
|
|
|
var v = modJ / tubularSegments * 2 * Math.PI;
|
|
|
var cx = -tube * Math.cos(v);
|
|
|
var cy = tube * Math.sin(v);
|
|
|
-
|
|
|
positions.push(p1.x + cx * n.x + cy * bitan.x);
|
|
|
positions.push(p1.y + cx * n.y + cy * bitan.y);
|
|
|
positions.push(p1.z + cx * n.z + cy * bitan.z);
|
|
|
-
|
|
|
uvs.push(i / radialSegments);
|
|
|
uvs.push(j / tubularSegments);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
for (i = 0; i < radialSegments; i++) {
|
|
|
for (j = 0; j < tubularSegments; j++) {
|
|
|
var jNext = (j + 1) % tubularSegments;
|
|
@@ -880,7 +701,6 @@
|
|
|
var b = (i + 1) * tubularSegments + j;
|
|
|
var c = (i + 1) * tubularSegments + jNext;
|
|
|
var d = i * tubularSegments + jNext;
|
|
|
-
|
|
|
indices.push(d);
|
|
|
indices.push(b);
|
|
|
indices.push(a);
|
|
@@ -889,63 +709,49 @@
|
|
|
indices.push(b);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
// Normals
|
|
|
BABYLON.VertexData.ComputeNormals(positions, indices, normals);
|
|
|
-
|
|
|
// Result
|
|
|
var vertexData = new BABYLON.VertexData();
|
|
|
-
|
|
|
vertexData.indices = indices;
|
|
|
vertexData.positions = positions;
|
|
|
vertexData.normals = normals;
|
|
|
vertexData.uvs = uvs;
|
|
|
-
|
|
|
return vertexData;
|
|
|
};
|
|
|
-
|
|
|
// Tools
|
|
|
VertexData.ComputeNormals = function (positions, indices, normals) {
|
|
|
var positionVectors = [];
|
|
|
var facesOfVertices = [];
|
|
|
var index;
|
|
|
-
|
|
|
for (index = 0; index < positions.length; index += 3) {
|
|
|
var vector3 = new BABYLON.Vector3(positions[index], positions[index + 1], positions[index + 2]);
|
|
|
positionVectors.push(vector3);
|
|
|
facesOfVertices.push([]);
|
|
|
}
|
|
|
-
|
|
|
// Compute normals
|
|
|
var facesNormals = [];
|
|
|
for (index = 0; index < indices.length / 3; index++) {
|
|
|
var i1 = indices[index * 3];
|
|
|
var i2 = indices[index * 3 + 1];
|
|
|
var i3 = indices[index * 3 + 2];
|
|
|
-
|
|
|
var p1 = positionVectors[i1];
|
|
|
var p2 = positionVectors[i2];
|
|
|
var p3 = positionVectors[i3];
|
|
|
-
|
|
|
var p1p2 = p1.subtract(p2);
|
|
|
var p3p2 = p3.subtract(p2);
|
|
|
-
|
|
|
facesNormals[index] = BABYLON.Vector3.Normalize(BABYLON.Vector3.Cross(p1p2, p3p2));
|
|
|
facesOfVertices[i1].push(index);
|
|
|
facesOfVertices[i2].push(index);
|
|
|
facesOfVertices[i3].push(index);
|
|
|
}
|
|
|
-
|
|
|
for (index = 0; index < positionVectors.length; index++) {
|
|
|
var faces = facesOfVertices[index];
|
|
|
-
|
|
|
var normal = BABYLON.Vector3.Zero();
|
|
|
for (var faceIndex = 0; faceIndex < faces.length; faceIndex++) {
|
|
|
normal.addInPlace(facesNormals[faces[faceIndex]]);
|
|
|
}
|
|
|
-
|
|
|
normal = BABYLON.Vector3.Normalize(normal.scale(1.0 / faces.length));
|
|
|
-
|
|
|
normals[index * 3] = normal.x;
|
|
|
normals[index * 3 + 1] = normal.y;
|
|
|
normals[index * 3 + 2] = normal.z;
|
|
@@ -955,4 +761,4 @@
|
|
|
})();
|
|
|
BABYLON.VertexData = VertexData;
|
|
|
})(BABYLON || (BABYLON = {}));
|
|
|
-//# sourceMappingURL=babylon.mesh.vertexData.js.map
|
|
|
+//# sourceMappingURL=babylon.mesh.vertexData.js.map
|