David Catuhe 7 vuotta sitten
vanhempi
commit
43cea41531
24 muutettua tiedostoa jossa 14480 lisäystä ja 13845 poistoa
  1. 8424 8281
      Playground/babylon.d.txt
  2. 4529 4387
      dist/preview release/babylon.d.ts
  3. 28 28
      dist/preview release/babylon.js
  4. 332 91
      dist/preview release/babylon.max.js
  5. 24 24
      dist/preview release/babylon.worker.js
  6. 332 91
      dist/preview release/es6.js
  7. 10 12
      dist/preview release/loaders/babylon.glTF2FileLoader.d.ts
  8. 91 131
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  9. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  10. 10 12
      dist/preview release/loaders/babylon.glTFFileLoader.d.ts
  11. 91 131
      dist/preview release/loaders/babylon.glTFFileLoader.js
  12. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  13. 91 131
      dist/preview release/loaders/babylonjs.loaders.js
  14. 2 2
      dist/preview release/loaders/babylonjs.loaders.min.js
  15. 10 12
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  16. 1 2
      dist/preview release/serializers/babylon.glTF2Serializer.d.ts
  17. 59 75
      dist/preview release/serializers/babylon.glTF2Serializer.js
  18. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.min.js
  19. 59 75
      dist/preview release/serializers/babylonjs.serializers.js
  20. 1 1
      dist/preview release/serializers/babylonjs.serializers.min.js
  21. 1 2
      dist/preview release/serializers/babylonjs.serializers.module.d.ts
  22. 2 215
      dist/preview release/typedocValidationBaseline.json
  23. 45 45
      dist/preview release/viewer/babylon.viewer.js
  24. 332 91
      dist/preview release/viewer/babylon.viewer.max.js

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 8424 - 8281
Playground/babylon.d.txt


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 4529 - 4387
dist/preview release/babylon.d.ts


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 28 - 28
dist/preview release/babylon.js


+ 332 - 91
dist/preview release/babylon.max.js

@@ -7970,13 +7970,15 @@ var BABYLON;
         /**
          * Provides a slice function that will work even on IE
          * @param data defines the array to slice
+         * @param start defines the start of the data (optional)
+         * @param end defines the end of the data (optional)
          * @returns the new sliced array
          */
-        Tools.Slice = function (data) {
+        Tools.Slice = function (data, start, end) {
             if (data.slice) {
-                return data.slice();
+                return data.slice(start, end);
             }
-            return Array.prototype.slice.call(data);
+            return Array.prototype.slice.call(data, start, end);
         };
         Tools.SetImmediate = function (action) {
             if (window.setImmediate) {
@@ -12245,33 +12247,43 @@ var BABYLON;
             this.bindArrayBuffer(null);
             this._cachedVertexBuffers = null;
         };
-        Engine.prototype.createVertexBuffer = function (vertices) {
+        /**
+         * Creates a vertex buffer
+         * @param data the data for the vertex buffer
+         * @returns the new WebGL static buffer
+         */
+        Engine.prototype.createVertexBuffer = function (data) {
             var vbo = this._gl.createBuffer();
             if (!vbo) {
                 throw new Error("Unable to create vertex buffer");
             }
             this.bindArrayBuffer(vbo);
-            if (vertices instanceof Float32Array) {
-                this._gl.bufferData(this._gl.ARRAY_BUFFER, vertices, this._gl.STATIC_DRAW);
+            if (data instanceof Array) {
+                this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(data), this._gl.STATIC_DRAW);
             }
             else {
-                this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(vertices), this._gl.STATIC_DRAW);
+                this._gl.bufferData(this._gl.ARRAY_BUFFER, data, this._gl.STATIC_DRAW);
             }
             this._resetVertexBufferBinding();
             vbo.references = 1;
             return vbo;
         };
-        Engine.prototype.createDynamicVertexBuffer = function (vertices) {
+        /**
+         * Creates a dynamic vertex buffer
+         * @param data the data for the dynamic vertex buffer
+         * @returns the new WebGL dynamic buffer
+         */
+        Engine.prototype.createDynamicVertexBuffer = function (data) {
             var vbo = this._gl.createBuffer();
             if (!vbo) {
                 throw new Error("Unable to create dynamic vertex buffer");
             }
             this.bindArrayBuffer(vbo);
-            if (vertices instanceof Float32Array) {
-                this._gl.bufferData(this._gl.ARRAY_BUFFER, vertices, this._gl.DYNAMIC_DRAW);
+            if (data instanceof Array) {
+                this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(data), this._gl.DYNAMIC_DRAW);
             }
             else {
-                this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(vertices), this._gl.DYNAMIC_DRAW);
+                this._gl.bufferData(this._gl.ARRAY_BUFFER, data, this._gl.DYNAMIC_DRAW);
             }
             this._resetVertexBufferBinding();
             vbo.references = 1;
@@ -12292,25 +12304,38 @@ var BABYLON;
             this._gl.bufferData(this._gl.ELEMENT_ARRAY_BUFFER, arrayBuffer, this._gl.DYNAMIC_DRAW);
             this._resetIndexBufferBinding();
         };
-        Engine.prototype.updateDynamicVertexBuffer = function (vertexBuffer, vertices, offset, count) {
+        /**
+         * Updates a dynamic vertex buffer.
+         * @param vertexBuffer the vertex buffer to update
+         * @param data the data used to update the vertex buffer
+         * @param byteOffset the byte offset of the data (optional)
+         * @param byteLength the byte length of the data (optional)
+         */
+        Engine.prototype.updateDynamicVertexBuffer = function (vertexBuffer, data, byteOffset, byteLength) {
             this.bindArrayBuffer(vertexBuffer);
-            if (offset === undefined) {
-                offset = 0;
+            if (byteOffset === undefined) {
+                byteOffset = 0;
             }
-            if (count === undefined) {
-                if (vertices instanceof Float32Array) {
-                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, offset, vertices);
+            if (byteLength === undefined) {
+                if (data instanceof Array) {
+                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, byteOffset, new Float32Array(data));
                 }
                 else {
-                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, offset, new Float32Array(vertices));
+                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, byteOffset, data);
                 }
             }
             else {
-                if (vertices instanceof Float32Array) {
-                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, vertices.subarray(offset, offset + count));
+                if (data instanceof Array) {
+                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, new Float32Array(data).subarray(byteOffset, byteOffset + byteLength));
                 }
                 else {
-                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, new Float32Array(vertices).subarray(offset, offset + count));
+                    if (data instanceof ArrayBuffer) {
+                        data = new Uint8Array(data, byteOffset, byteLength);
+                    }
+                    else {
+                        data = new Uint8Array(data.buffer, data.byteOffset + byteOffset, byteLength);
+                    }
+                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, data);
                 }
             }
             this._resetVertexBufferBinding();
@@ -12466,7 +12491,7 @@ var BABYLON;
                     }
                     var buffer = vertexBuffer.getBuffer();
                     if (buffer) {
-                        this.vertexAttribPointer(buffer, order, vertexBuffer.getSize(), this._gl.FLOAT, false, vertexBuffer.getStrideSize() * 4, vertexBuffer.getOffset() * 4);
+                        this.vertexAttribPointer(buffer, order, vertexBuffer.getSize(), vertexBuffer.type, vertexBuffer.normalized, vertexBuffer.byteStride, vertexBuffer.byteOffset);
                         if (vertexBuffer.getIsInstanced()) {
                             this._gl.vertexAttribDivisor(order, vertexBuffer.getInstanceDivisor());
                             if (!this._vaoRecordInProgress) {
@@ -27100,8 +27125,21 @@ var BABYLON;
 var BABYLON;
 (function (BABYLON) {
     var Buffer = /** @class */ (function () {
-        function Buffer(engine, data, updatable, stride, postponeInternalCreation, instanced) {
+        /**
+         * Constructor
+         * @param engine the engine
+         * @param data the data to use for this buffer
+         * @param updatable whether the data is updatable
+         * @param stride the stride (optional)
+         * @param postponeInternalCreation whether to postpone creating the internal WebGL buffer (optional)
+         * @param instanced whether the buffer is instanced (optional)
+         * @param useBytes set to true if the stride in in bytes (optional)
+         */
+        function Buffer(engine, data, updatable, stride, postponeInternalCreation, instanced, useBytes) {
+            if (stride === void 0) { stride = 0; }
+            if (postponeInternalCreation === void 0) { postponeInternalCreation = false; }
             if (instanced === void 0) { instanced = false; }
+            if (useBytes === void 0) { useBytes = false; }
             if (engine instanceof BABYLON.Mesh) {
                 this._engine = engine.getScene().getEngine();
             }
@@ -27111,7 +27149,7 @@ var BABYLON;
             this._updatable = updatable;
             this._instanced = instanced;
             this._data = data;
-            this._strideSize = stride;
+            this.byteStride = useBytes ? stride : stride * 4;
             if (!postponeInternalCreation) {
                 this.create();
             }
@@ -27123,11 +27161,15 @@ var BABYLON;
          * @param size defines the size in floats of attributes (position is 3 for instance)
          * @param stride defines the stride size in floats in the buffer (the offset to apply to reach next value when data is interleaved)
          * @param instanced defines if the vertex buffer contains indexed data
+         * @param useBytes defines if the offset and stride are in bytes
          * @returns the new vertex buffer
          */
-        Buffer.prototype.createVertexBuffer = function (kind, offset, size, stride, instanced) {
+        Buffer.prototype.createVertexBuffer = function (kind, offset, size, stride, instanced, useBytes) {
+            if (useBytes === void 0) { useBytes = false; }
+            var byteOffset = useBytes ? offset : offset * 4;
+            var byteStride = stride ? (useBytes ? stride : stride * 4) : this.byteStride;
             // a lot of these parameters are ignored as they are overriden by the buffer
-            return new BABYLON.VertexBuffer(this._engine, this, kind, this._updatable, true, stride ? stride : this._strideSize, instanced === undefined ? this._instanced : instanced, offset, size);
+            return new BABYLON.VertexBuffer(this._engine, this, kind, this._updatable, true, byteStride, instanced === undefined ? this._instanced : instanced, byteOffset, size, undefined, undefined, true);
         };
         // Properties
         Buffer.prototype.isUpdatable = function () {
@@ -27139,23 +27181,15 @@ var BABYLON;
         Buffer.prototype.getBuffer = function () {
             return this._buffer;
         };
+        /**
+         * Gets the stride in float32 units (i.e. byte stride / 4).
+         * May not be an integer if the byte stride is not divisible by 4.
+         * DEPRECATED. Use byteStride instead.
+         * @returns the stride in float32 units
+         */
         Buffer.prototype.getStrideSize = function () {
-            return this._strideSize;
+            return this.byteStride / 4;
         };
-        // public getIsInstanced(): boolean {
-        //     return this._instanced;
-        // }
-        // public get instanceDivisor(): number {
-        //     return this._instanceDivisor;
-        // }
-        // public set instanceDivisor(value: number) {
-        //     this._instanceDivisor = value;
-        //     if (value == 0) {
-        //         this._instanced = false;
-        //     } else {
-        //         this._instanced = true;
-        //     }
-        // }
         // Methods
         Buffer.prototype.create = function (data) {
             if (data === void 0) { data = null; }
@@ -27187,12 +27221,20 @@ var BABYLON;
         Buffer.prototype.update = function (data) {
             this.create(data);
         };
-        Buffer.prototype.updateDirectly = function (data, offset, vertexCount) {
+        /**
+         * Updates the data directly.
+         * @param data the new data
+         * @param offset the new offset
+         * @param vertexCount the vertex count (optional)
+         * @param useBytes set to true if the offset is in bytes
+         */
+        Buffer.prototype.updateDirectly = function (data, offset, vertexCount, useBytes) {
+            if (useBytes === void 0) { useBytes = false; }
             if (!this._buffer) {
                 return;
             }
             if (this._updatable) {
-                this._engine.updateDynamicVertexBuffer(this._buffer, data, offset, (vertexCount ? vertexCount * this.getStrideSize() : undefined));
+                this._engine.updateDynamicVertexBuffer(this._buffer, data, useBytes ? offset : offset * 4, (vertexCount ? vertexCount * this.byteStride : undefined));
                 this._data = null;
             }
         };
@@ -27215,27 +27257,66 @@ var BABYLON;
 var BABYLON;
 (function (BABYLON) {
     var VertexBuffer = /** @class */ (function () {
-        function VertexBuffer(engine, data, kind, updatable, postponeInternalCreation, stride, instanced, offset, size) {
+        /**
+         * Constructor
+         * @param engine the engine
+         * @param data the data to use for this vertex buffer
+         * @param kind the vertex buffer kind
+         * @param updatable whether the data is updatable
+         * @param postponeInternalCreation whether to postpone creating the internal WebGL buffer (optional)
+         * @param stride the stride (optional)
+         * @param instanced whether the buffer is instanced (optional)
+         * @param offset the offset of the data (optional)
+         * @param size the number of components (optional)
+         * @param type the type of the component (optional)
+         * @param normalized whether the data contains normalized data (optional)
+         * @param useBytes set to true if stride and offset are in bytes (optional)
+         */
+        function VertexBuffer(engine, data, kind, updatable, postponeInternalCreation, stride, instanced, offset, size, type, normalized, useBytes) {
+            if (normalized === void 0) { normalized = false; }
+            if (useBytes === void 0) { useBytes = false; }
             if (data instanceof BABYLON.Buffer) {
-                if (!stride) {
-                    stride = data.getStrideSize();
-                }
                 this._buffer = data;
                 this._ownsBuffer = false;
             }
             else {
-                if (!stride) {
-                    stride = VertexBuffer.DeduceStride(kind);
-                }
-                this._buffer = new BABYLON.Buffer(engine, data, updatable, stride, postponeInternalCreation, instanced);
+                this._buffer = new BABYLON.Buffer(engine, data, updatable, stride, postponeInternalCreation, instanced, useBytes);
                 this._ownsBuffer = true;
             }
-            this._stride = stride;
+            this._kind = kind;
+            if (type == undefined) {
+                var data_1 = this.getData();
+                this.type = VertexBuffer.FLOAT;
+                if (data_1 instanceof Int8Array)
+                    this.type = VertexBuffer.BYTE;
+                else if (data_1 instanceof Uint8Array)
+                    this.type = VertexBuffer.UNSIGNED_BYTE;
+                else if (data_1 instanceof Int16Array)
+                    this.type = VertexBuffer.SHORT;
+                else if (data_1 instanceof Uint16Array)
+                    this.type = VertexBuffer.UNSIGNED_SHORT;
+                else if (data_1 instanceof Int32Array)
+                    this.type = VertexBuffer.INT;
+                else if (data_1 instanceof Uint32Array)
+                    this.type = VertexBuffer.UNSIGNED_INT;
+            }
+            else {
+                this.type = type;
+            }
+            var typeByteLength = VertexBuffer.GetTypeByteLength(this.type);
+            if (useBytes) {
+                this._size = size || (stride ? (stride / typeByteLength) : VertexBuffer.DeduceStride(kind));
+                this.byteStride = stride || this._buffer.byteStride || (this._size * typeByteLength);
+                this.byteOffset = offset || 0;
+            }
+            else {
+                this._size = size || stride || VertexBuffer.DeduceStride(kind);
+                this.byteStride = stride ? (stride * typeByteLength) : (this._buffer.byteStride || (this._size * typeByteLength));
+                this.byteOffset = (offset || 0) * typeByteLength;
+            }
+            this.normalized = normalized;
             this._instanced = instanced !== undefined ? instanced : false;
             this._instanceDivisor = instanced ? 1 : 0;
-            this._offset = offset ? offset : 0;
-            this._size = size ? size : stride;
-            this._kind = kind;
         }
         Object.defineProperty(VertexBuffer.prototype, "instanceDivisor", {
             /**
@@ -27276,7 +27357,7 @@ var BABYLON;
             return this._buffer.isUpdatable();
         };
         /**
-         * Returns an array of numbers or a Float32Array containing the VertexBuffer data.
+         * Returns an array of numbers or a typed array containing the VertexBuffer data.
          */
         VertexBuffer.prototype.getData = function () {
             return this._buffer.getData();
@@ -27288,19 +27369,21 @@ var BABYLON;
             return this._buffer.getBuffer();
         };
         /**
-         * Returns the stride of the VertexBuffer (integer).
+         * Returns the stride as a multiple of the type byte length.
+         * DEPRECATED. Use byteStride instead.
          */
         VertexBuffer.prototype.getStrideSize = function () {
-            return this._stride;
+            return this.byteStride / VertexBuffer.GetTypeByteLength(this.type);
         };
         /**
-         * Returns the offset (integer).
+         * Returns the offset as a multiple of the type byte length.
+         * DEPRECATED. Use byteOffset instead.
          */
         VertexBuffer.prototype.getOffset = function () {
-            return this._offset;
+            return this.byteOffset / VertexBuffer.GetTypeByteLength(this.type);
         };
         /**
-         * Returns the VertexBuffer total size (integer).
+         * Returns the number of components per vertex attribute (integer).
          */
         VertexBuffer.prototype.getSize = function () {
             return this._size;
@@ -27348,6 +27431,14 @@ var BABYLON;
                 this._buffer.dispose();
             }
         };
+        /**
+         * Enumerates each value of this vertex buffer as numbers.
+         * @param count the number of values to enumerate
+         * @param callback the callback function called for each value
+         */
+        VertexBuffer.prototype.forEach = function (count, callback) {
+            VertexBuffer.ForEach(this._buffer.getData(), this.byteOffset, this.byteStride, this._size, this.type, count, this.normalized, callback);
+        };
         Object.defineProperty(VertexBuffer, "PositionKind", {
             get: function () {
                 return VertexBuffer._PositionKind;
@@ -27474,6 +27565,128 @@ var BABYLON;
                     throw new Error("Invalid kind '" + kind + "'");
             }
         };
+        /**
+         * Gets the byte length of the given type.
+         * @param type the type
+         * @returns the number of bytes
+         */
+        VertexBuffer.GetTypeByteLength = function (type) {
+            switch (type) {
+                case VertexBuffer.BYTE:
+                case VertexBuffer.UNSIGNED_BYTE:
+                    return 1;
+                case VertexBuffer.SHORT:
+                case VertexBuffer.UNSIGNED_SHORT:
+                    return 2;
+                case VertexBuffer.INT:
+                case VertexBuffer.FLOAT:
+                    return 4;
+                default:
+                    throw new Error("Invalid type '" + type + "'");
+            }
+        };
+        /**
+         * Enumerates each value of the given parameters as numbers.
+         * @param data the data to enumerate
+         * @param byteOffset the byte offset of the data
+         * @param byteStride the byte stride of the data
+         * @param componentCount the number of components per element
+         * @param componentType the type of the component
+         * @param count the total number of components
+         * @param normalized whether the data is normalized
+         * @param callback the callback function called for each value
+         */
+        VertexBuffer.ForEach = function (data, byteOffset, byteStride, componentCount, componentType, count, normalized, callback) {
+            if (data instanceof Array) {
+                var offset = byteOffset / 4;
+                var stride = byteStride / 4;
+                for (var index = 0; index < count; index += componentCount) {
+                    for (var componentIndex = 0; componentIndex < componentCount; componentIndex++) {
+                        callback(data[offset + componentIndex], index + componentIndex);
+                    }
+                    offset += stride;
+                }
+            }
+            else {
+                var dataView = data instanceof ArrayBuffer ? new DataView(data) : new DataView(data.buffer, data.byteOffset, data.byteLength);
+                var componentByteLength = VertexBuffer.GetTypeByteLength(componentType);
+                for (var index = 0; index < count; index += componentCount) {
+                    var componentByteOffset = byteOffset;
+                    for (var componentIndex = 0; componentIndex < componentCount; componentIndex++) {
+                        var value = VertexBuffer._GetFloatValue(dataView, componentType, componentByteOffset, normalized);
+                        callback(value, index + componentIndex);
+                        componentByteOffset += componentByteLength;
+                    }
+                    byteOffset += byteStride;
+                }
+            }
+        };
+        VertexBuffer._GetFloatValue = function (dataView, type, byteOffset, normalized) {
+            switch (type) {
+                case VertexBuffer.BYTE: {
+                    var value = dataView.getInt8(byteOffset);
+                    if (normalized) {
+                        value = (value + 0.5) / 127.5;
+                    }
+                    return value;
+                }
+                case VertexBuffer.UNSIGNED_BYTE: {
+                    var value = dataView.getUint8(byteOffset);
+                    if (normalized) {
+                        value = value / 255;
+                    }
+                    return value;
+                }
+                case VertexBuffer.SHORT: {
+                    var value = dataView.getInt16(byteOffset, true);
+                    if (normalized) {
+                        value = (value + 0.5) / 16383.5;
+                    }
+                    return value;
+                }
+                case VertexBuffer.UNSIGNED_SHORT: {
+                    var value = dataView.getUint16(byteOffset, true);
+                    if (normalized) {
+                        value = value / 65535;
+                    }
+                    return value;
+                }
+                case VertexBuffer.FLOAT: {
+                    return dataView.getFloat32(byteOffset, true);
+                }
+                default: {
+                    throw new Error("Invalid component type " + type);
+                }
+            }
+        };
+        /**
+         * The byte type.
+         */
+        VertexBuffer.BYTE = 5120;
+        /**
+         * The unsigned byte type.
+         */
+        VertexBuffer.UNSIGNED_BYTE = 5121;
+        /**
+         * The short type.
+         */
+        VertexBuffer.SHORT = 5122;
+        /**
+         * The unsigned short type.
+         */
+        VertexBuffer.UNSIGNED_SHORT = 5123;
+        /**
+         * The integer type.
+         */
+        VertexBuffer.INT = 5124;
+        /**
+         * The unsigned integer type.
+         */
+        VertexBuffer.UNSIGNED_INT = 5125;
+        /**
+         * The float type.
+         */
+        VertexBuffer.FLOAT = 5126;
         // Enums
         VertexBuffer._PositionKind = "position";
         VertexBuffer._NormalKind = "normal";
@@ -29710,7 +29923,7 @@ var BABYLON;
         };
         Mesh.prototype._draw = function (subMesh, fillMode, instancesCount, alternate) {
             if (alternate === void 0) { alternate = false; }
-            if (!this._geometry || !this._geometry.getVertexBuffers() || !this._geometry.getIndexBuffer()) {
+            if (!this._geometry || !this._geometry.getVertexBuffers() || (!this._unIndexed && !this._geometry.getIndexBuffer())) {
                 return this;
             }
             this.onBeforeDrawObservable.notifyObservers(this);
@@ -29906,7 +30119,7 @@ var BABYLON;
                 return this;
             }
             // Checking geometry state
-            if (!this._geometry || !this._geometry.getVertexBuffers() || !this._geometry.getIndexBuffer()) {
+            if (!this._geometry || !this._geometry.getVertexBuffers() || (!this._unIndexed && !this._geometry.getIndexBuffer())) {
                 return this;
             }
             this.onBeforeRenderObservable.notifyObservers(this);
@@ -36145,7 +36358,7 @@ var BABYLON;
             if (mesh) {
                 if (mesh.getClassName() === "LinesMesh") {
                     this.boundingBias = new BABYLON.Vector2(0, mesh.intersectionThreshold);
-                    this.updateExtend();
+                    this._updateExtend();
                 }
                 this.applyToMesh(mesh);
                 mesh.computeWorldMatrix(true);
@@ -36166,7 +36379,7 @@ var BABYLON;
                     return;
                 }
                 this._boundingBias = value.clone();
-                this.updateBoundingInfo(true, null);
+                this._updateBoundingInfo(true, null);
             },
             enumerable: true,
             configurable: true
@@ -36260,6 +36473,9 @@ var BABYLON;
          */
         Geometry.prototype.setVerticesData = function (kind, data, updatable, stride) {
             if (updatable === void 0) { updatable = false; }
+            if (kind === BABYLON.VertexBuffer.PositionKind) {
+                this._totalVertices = data.length / (stride || 3);
+            }
             var buffer = new BABYLON.VertexBuffer(this._engine, data, kind, updatable, this._meshes.length === 0, stride);
             this.setVerticesBuffer(buffer);
         };
@@ -36276,18 +36492,20 @@ var BABYLON;
         /**
          * Affect a vertex buffer to the geometry. the vertexBuffer.getKind() function is used to determine where to store the data
          * @param buffer defines the vertex buffer to use
+         * @param totalVertices defines the total number of vertices for position kind (could be null)
          */
-        Geometry.prototype.setVerticesBuffer = function (buffer) {
+        Geometry.prototype.setVerticesBuffer = function (buffer, totalVertices) {
+            if (totalVertices === void 0) { totalVertices = null; }
             var kind = buffer.getKind();
             if (this._vertexBuffers[kind]) {
                 this._vertexBuffers[kind].dispose();
             }
             this._vertexBuffers[kind] = buffer;
             if (kind === BABYLON.VertexBuffer.PositionKind) {
-                var data = buffer.getData();
-                var stride = buffer.getStrideSize();
-                this._totalVertices = data.length / stride;
-                this.updateExtend(data, stride);
+                if (totalVertices != null) {
+                    this._totalVertices = totalVertices;
+                }
+                this._updateExtend();
                 this._resetPointsArrayCache();
                 var meshes = this._meshes;
                 var numOfMeshes = meshes.length;
@@ -36335,15 +36553,13 @@ var BABYLON;
             }
             vertexBuffer.update(data);
             if (kind === BABYLON.VertexBuffer.PositionKind) {
-                var stride = vertexBuffer.getStrideSize();
-                this._totalVertices = data.length / stride;
-                this.updateBoundingInfo(updateExtends, data);
+                this._updateBoundingInfo(updateExtends, data);
             }
             this.notifyUpdate(kind);
         };
-        Geometry.prototype.updateBoundingInfo = function (updateExtends, data) {
+        Geometry.prototype._updateBoundingInfo = function (updateExtends, data) {
             if (updateExtends) {
-                this.updateExtend(data);
+                this._updateExtend(data);
             }
             var meshes = this._meshes;
             var numOfMeshes = meshes.length;
@@ -36392,7 +36608,7 @@ var BABYLON;
             return this._totalVertices;
         };
         /**
-         * Gets a specific vertex data attached to this geometry
+         * Gets a specific vertex data attached to this geometry. Float data is constructed if the vertex buffer data cannot be returned directly.
          * @param kind defines the data kind (Position, normal, etc...)
          * @param copyWhenShared defines if the returned array must be cloned upon returning it if the current geometry is shared between multiple meshes
          * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it
@@ -36403,18 +36619,36 @@ var BABYLON;
             if (!vertexBuffer) {
                 return null;
             }
-            var orig = vertexBuffer.getData();
-            if (!forceCopy && (!copyWhenShared || this._meshes.length === 1)) {
-                return orig;
+            var data = vertexBuffer.getData();
+            if (!data) {
+                return null;
             }
-            else {
-                var len = orig.length;
-                var copy = [];
-                for (var i = 0; i < len; i++) {
-                    copy.push(orig[i]);
+            var defaultStride = BABYLON.VertexBuffer.DeduceStride(vertexBuffer.getKind());
+            var defaultByteStride = defaultStride * BABYLON.VertexBuffer.GetTypeByteLength(vertexBuffer.type);
+            var count = this._totalVertices * defaultStride;
+            if (vertexBuffer.type !== BABYLON.VertexBuffer.FLOAT || vertexBuffer.byteStride !== defaultByteStride) {
+                var copy_1 = new Array(count);
+                vertexBuffer.forEach(count, function (value, index) {
+                    copy_1[index] = value;
+                });
+                return copy_1;
+            }
+            if (!(data instanceof Array || data instanceof Float32Array) || vertexBuffer.byteOffset !== 0 || data.length !== count) {
+                if (data instanceof Array) {
+                    var offset = vertexBuffer.byteOffset / 4;
+                    return BABYLON.Tools.Slice(data, offset, offset + count);
                 }
-                return copy;
+                else if (data instanceof ArrayBuffer) {
+                    return new Float32Array(data, vertexBuffer.byteOffset, count);
+                }
+                else {
+                    return new Float32Array(data.buffer, data.byteOffset + vertexBuffer.byteOffset, count);
+                }
+            }
+            if (forceCopy || (copyWhenShared && this._meshes.length !== 1)) {
+                return BABYLON.Tools.Slice(data);
             }
+            return data;
         };
         /**
          * Returns a boolean defining if the vertex data for the requested `kind` is updatable
@@ -36620,12 +36854,12 @@ var BABYLON;
                 mesh._boundingInfo = this._boundingInfo;
             }
         };
-        Geometry.prototype.updateExtend = function (data, stride) {
+        Geometry.prototype._updateExtend = function (data) {
             if (data === void 0) { data = null; }
             if (!data) {
-                data = this._vertexBuffers[BABYLON.VertexBuffer.PositionKind].getData();
+                data = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
             }
-            this._extend = BABYLON.Tools.ExtractMinAndMax(data, 0, this._totalVertices, this.boundingBias, stride);
+            this._extend = BABYLON.Tools.ExtractMinAndMax(data, 0, this._totalVertices, this.boundingBias, 3);
         };
         Geometry.prototype._applyToMesh = function (mesh) {
             var numOfMeshes = this._meshes.length;
@@ -36639,7 +36873,7 @@ var BABYLON;
                     buffer.references = numOfMeshes;
                 if (kind === BABYLON.VertexBuffer.PositionKind) {
                     if (!this._extend) {
-                        this.updateExtend(this._vertexBuffers[kind].getData());
+                        this._updateExtend();
                     }
                     mesh._boundingInfo = new BABYLON.BoundingInfo(this._extend.minimum, this._extend.maximum);
                     mesh._createGlobalSubMesh(false);
@@ -57584,7 +57818,7 @@ var BABYLON;
             return this;
         };
         LinesMesh.prototype._draw = function (subMesh, fillMode, instancesCount) {
-            if (!this._geometry || !this._geometry.getVertexBuffers() || !this._geometry.getIndexBuffer()) {
+            if (!this._geometry || !this._geometry.getVertexBuffers() || (!this._unIndexed && !this._geometry.getIndexBuffer())) {
                 return this;
             }
             var engine = this.getScene().getEngine();
@@ -91448,7 +91682,14 @@ var BABYLON;
         NullEngine.prototype.updateDynamicIndexBuffer = function (indexBuffer, indices, offset) {
             if (offset === void 0) { offset = 0; }
         };
-        NullEngine.prototype.updateDynamicVertexBuffer = function (vertexBuffer, vertices, offset, count) {
+        /**
+         * Updates a dynamic vertex buffer.
+         * @param vertexBuffer the vertex buffer to update
+         * @param data the data used to update the vertex buffer
+         * @param byteOffset the byte offset of the data (optional)
+         * @param byteLength the byte length of the data (optional)
+         */
+        NullEngine.prototype.updateDynamicVertexBuffer = function (vertexBuffer, vertices, byteOffset, byteLength) {
         };
         NullEngine.prototype._bindTextureDirectly = function (target, texture) {
             if (this._boundTexturesCache[this._activeChannel] !== texture) {

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 24 - 24
dist/preview release/babylon.worker.js


+ 332 - 91
dist/preview release/es6.js

@@ -7937,13 +7937,15 @@ var BABYLON;
         /**
          * Provides a slice function that will work even on IE
          * @param data defines the array to slice
+         * @param start defines the start of the data (optional)
+         * @param end defines the end of the data (optional)
          * @returns the new sliced array
          */
-        Tools.Slice = function (data) {
+        Tools.Slice = function (data, start, end) {
             if (data.slice) {
-                return data.slice();
+                return data.slice(start, end);
             }
-            return Array.prototype.slice.call(data);
+            return Array.prototype.slice.call(data, start, end);
         };
         Tools.SetImmediate = function (action) {
             if (window.setImmediate) {
@@ -12212,33 +12214,43 @@ var BABYLON;
             this.bindArrayBuffer(null);
             this._cachedVertexBuffers = null;
         };
-        Engine.prototype.createVertexBuffer = function (vertices) {
+        /**
+         * Creates a vertex buffer
+         * @param data the data for the vertex buffer
+         * @returns the new WebGL static buffer
+         */
+        Engine.prototype.createVertexBuffer = function (data) {
             var vbo = this._gl.createBuffer();
             if (!vbo) {
                 throw new Error("Unable to create vertex buffer");
             }
             this.bindArrayBuffer(vbo);
-            if (vertices instanceof Float32Array) {
-                this._gl.bufferData(this._gl.ARRAY_BUFFER, vertices, this._gl.STATIC_DRAW);
+            if (data instanceof Array) {
+                this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(data), this._gl.STATIC_DRAW);
             }
             else {
-                this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(vertices), this._gl.STATIC_DRAW);
+                this._gl.bufferData(this._gl.ARRAY_BUFFER, data, this._gl.STATIC_DRAW);
             }
             this._resetVertexBufferBinding();
             vbo.references = 1;
             return vbo;
         };
-        Engine.prototype.createDynamicVertexBuffer = function (vertices) {
+        /**
+         * Creates a dynamic vertex buffer
+         * @param data the data for the dynamic vertex buffer
+         * @returns the new WebGL dynamic buffer
+         */
+        Engine.prototype.createDynamicVertexBuffer = function (data) {
             var vbo = this._gl.createBuffer();
             if (!vbo) {
                 throw new Error("Unable to create dynamic vertex buffer");
             }
             this.bindArrayBuffer(vbo);
-            if (vertices instanceof Float32Array) {
-                this._gl.bufferData(this._gl.ARRAY_BUFFER, vertices, this._gl.DYNAMIC_DRAW);
+            if (data instanceof Array) {
+                this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(data), this._gl.DYNAMIC_DRAW);
             }
             else {
-                this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(vertices), this._gl.DYNAMIC_DRAW);
+                this._gl.bufferData(this._gl.ARRAY_BUFFER, data, this._gl.DYNAMIC_DRAW);
             }
             this._resetVertexBufferBinding();
             vbo.references = 1;
@@ -12259,25 +12271,38 @@ var BABYLON;
             this._gl.bufferData(this._gl.ELEMENT_ARRAY_BUFFER, arrayBuffer, this._gl.DYNAMIC_DRAW);
             this._resetIndexBufferBinding();
         };
-        Engine.prototype.updateDynamicVertexBuffer = function (vertexBuffer, vertices, offset, count) {
+        /**
+         * Updates a dynamic vertex buffer.
+         * @param vertexBuffer the vertex buffer to update
+         * @param data the data used to update the vertex buffer
+         * @param byteOffset the byte offset of the data (optional)
+         * @param byteLength the byte length of the data (optional)
+         */
+        Engine.prototype.updateDynamicVertexBuffer = function (vertexBuffer, data, byteOffset, byteLength) {
             this.bindArrayBuffer(vertexBuffer);
-            if (offset === undefined) {
-                offset = 0;
+            if (byteOffset === undefined) {
+                byteOffset = 0;
             }
-            if (count === undefined) {
-                if (vertices instanceof Float32Array) {
-                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, offset, vertices);
+            if (byteLength === undefined) {
+                if (data instanceof Array) {
+                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, byteOffset, new Float32Array(data));
                 }
                 else {
-                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, offset, new Float32Array(vertices));
+                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, byteOffset, data);
                 }
             }
             else {
-                if (vertices instanceof Float32Array) {
-                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, vertices.subarray(offset, offset + count));
+                if (data instanceof Array) {
+                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, new Float32Array(data).subarray(byteOffset, byteOffset + byteLength));
                 }
                 else {
-                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, new Float32Array(vertices).subarray(offset, offset + count));
+                    if (data instanceof ArrayBuffer) {
+                        data = new Uint8Array(data, byteOffset, byteLength);
+                    }
+                    else {
+                        data = new Uint8Array(data.buffer, data.byteOffset + byteOffset, byteLength);
+                    }
+                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, data);
                 }
             }
             this._resetVertexBufferBinding();
@@ -12433,7 +12458,7 @@ var BABYLON;
                     }
                     var buffer = vertexBuffer.getBuffer();
                     if (buffer) {
-                        this.vertexAttribPointer(buffer, order, vertexBuffer.getSize(), this._gl.FLOAT, false, vertexBuffer.getStrideSize() * 4, vertexBuffer.getOffset() * 4);
+                        this.vertexAttribPointer(buffer, order, vertexBuffer.getSize(), vertexBuffer.type, vertexBuffer.normalized, vertexBuffer.byteStride, vertexBuffer.byteOffset);
                         if (vertexBuffer.getIsInstanced()) {
                             this._gl.vertexAttribDivisor(order, vertexBuffer.getInstanceDivisor());
                             if (!this._vaoRecordInProgress) {
@@ -27067,8 +27092,21 @@ var BABYLON;
 var BABYLON;
 (function (BABYLON) {
     var Buffer = /** @class */ (function () {
-        function Buffer(engine, data, updatable, stride, postponeInternalCreation, instanced) {
+        /**
+         * Constructor
+         * @param engine the engine
+         * @param data the data to use for this buffer
+         * @param updatable whether the data is updatable
+         * @param stride the stride (optional)
+         * @param postponeInternalCreation whether to postpone creating the internal WebGL buffer (optional)
+         * @param instanced whether the buffer is instanced (optional)
+         * @param useBytes set to true if the stride in in bytes (optional)
+         */
+        function Buffer(engine, data, updatable, stride, postponeInternalCreation, instanced, useBytes) {
+            if (stride === void 0) { stride = 0; }
+            if (postponeInternalCreation === void 0) { postponeInternalCreation = false; }
             if (instanced === void 0) { instanced = false; }
+            if (useBytes === void 0) { useBytes = false; }
             if (engine instanceof BABYLON.Mesh) {
                 this._engine = engine.getScene().getEngine();
             }
@@ -27078,7 +27116,7 @@ var BABYLON;
             this._updatable = updatable;
             this._instanced = instanced;
             this._data = data;
-            this._strideSize = stride;
+            this.byteStride = useBytes ? stride : stride * 4;
             if (!postponeInternalCreation) {
                 this.create();
             }
@@ -27090,11 +27128,15 @@ var BABYLON;
          * @param size defines the size in floats of attributes (position is 3 for instance)
          * @param stride defines the stride size in floats in the buffer (the offset to apply to reach next value when data is interleaved)
          * @param instanced defines if the vertex buffer contains indexed data
+         * @param useBytes defines if the offset and stride are in bytes
          * @returns the new vertex buffer
          */
-        Buffer.prototype.createVertexBuffer = function (kind, offset, size, stride, instanced) {
+        Buffer.prototype.createVertexBuffer = function (kind, offset, size, stride, instanced, useBytes) {
+            if (useBytes === void 0) { useBytes = false; }
+            var byteOffset = useBytes ? offset : offset * 4;
+            var byteStride = stride ? (useBytes ? stride : stride * 4) : this.byteStride;
             // a lot of these parameters are ignored as they are overriden by the buffer
-            return new BABYLON.VertexBuffer(this._engine, this, kind, this._updatable, true, stride ? stride : this._strideSize, instanced === undefined ? this._instanced : instanced, offset, size);
+            return new BABYLON.VertexBuffer(this._engine, this, kind, this._updatable, true, byteStride, instanced === undefined ? this._instanced : instanced, byteOffset, size, undefined, undefined, true);
         };
         // Properties
         Buffer.prototype.isUpdatable = function () {
@@ -27106,23 +27148,15 @@ var BABYLON;
         Buffer.prototype.getBuffer = function () {
             return this._buffer;
         };
+        /**
+         * Gets the stride in float32 units (i.e. byte stride / 4).
+         * May not be an integer if the byte stride is not divisible by 4.
+         * DEPRECATED. Use byteStride instead.
+         * @returns the stride in float32 units
+         */
         Buffer.prototype.getStrideSize = function () {
-            return this._strideSize;
+            return this.byteStride / 4;
         };
-        // public getIsInstanced(): boolean {
-        //     return this._instanced;
-        // }
-        // public get instanceDivisor(): number {
-        //     return this._instanceDivisor;
-        // }
-        // public set instanceDivisor(value: number) {
-        //     this._instanceDivisor = value;
-        //     if (value == 0) {
-        //         this._instanced = false;
-        //     } else {
-        //         this._instanced = true;
-        //     }
-        // }
         // Methods
         Buffer.prototype.create = function (data) {
             if (data === void 0) { data = null; }
@@ -27154,12 +27188,20 @@ var BABYLON;
         Buffer.prototype.update = function (data) {
             this.create(data);
         };
-        Buffer.prototype.updateDirectly = function (data, offset, vertexCount) {
+        /**
+         * Updates the data directly.
+         * @param data the new data
+         * @param offset the new offset
+         * @param vertexCount the vertex count (optional)
+         * @param useBytes set to true if the offset is in bytes
+         */
+        Buffer.prototype.updateDirectly = function (data, offset, vertexCount, useBytes) {
+            if (useBytes === void 0) { useBytes = false; }
             if (!this._buffer) {
                 return;
             }
             if (this._updatable) {
-                this._engine.updateDynamicVertexBuffer(this._buffer, data, offset, (vertexCount ? vertexCount * this.getStrideSize() : undefined));
+                this._engine.updateDynamicVertexBuffer(this._buffer, data, useBytes ? offset : offset * 4, (vertexCount ? vertexCount * this.byteStride : undefined));
                 this._data = null;
             }
         };
@@ -27182,27 +27224,66 @@ var BABYLON;
 var BABYLON;
 (function (BABYLON) {
     var VertexBuffer = /** @class */ (function () {
-        function VertexBuffer(engine, data, kind, updatable, postponeInternalCreation, stride, instanced, offset, size) {
+        /**
+         * Constructor
+         * @param engine the engine
+         * @param data the data to use for this vertex buffer
+         * @param kind the vertex buffer kind
+         * @param updatable whether the data is updatable
+         * @param postponeInternalCreation whether to postpone creating the internal WebGL buffer (optional)
+         * @param stride the stride (optional)
+         * @param instanced whether the buffer is instanced (optional)
+         * @param offset the offset of the data (optional)
+         * @param size the number of components (optional)
+         * @param type the type of the component (optional)
+         * @param normalized whether the data contains normalized data (optional)
+         * @param useBytes set to true if stride and offset are in bytes (optional)
+         */
+        function VertexBuffer(engine, data, kind, updatable, postponeInternalCreation, stride, instanced, offset, size, type, normalized, useBytes) {
+            if (normalized === void 0) { normalized = false; }
+            if (useBytes === void 0) { useBytes = false; }
             if (data instanceof BABYLON.Buffer) {
-                if (!stride) {
-                    stride = data.getStrideSize();
-                }
                 this._buffer = data;
                 this._ownsBuffer = false;
             }
             else {
-                if (!stride) {
-                    stride = VertexBuffer.DeduceStride(kind);
-                }
-                this._buffer = new BABYLON.Buffer(engine, data, updatable, stride, postponeInternalCreation, instanced);
+                this._buffer = new BABYLON.Buffer(engine, data, updatable, stride, postponeInternalCreation, instanced, useBytes);
                 this._ownsBuffer = true;
             }
-            this._stride = stride;
+            this._kind = kind;
+            if (type == undefined) {
+                var data_1 = this.getData();
+                this.type = VertexBuffer.FLOAT;
+                if (data_1 instanceof Int8Array)
+                    this.type = VertexBuffer.BYTE;
+                else if (data_1 instanceof Uint8Array)
+                    this.type = VertexBuffer.UNSIGNED_BYTE;
+                else if (data_1 instanceof Int16Array)
+                    this.type = VertexBuffer.SHORT;
+                else if (data_1 instanceof Uint16Array)
+                    this.type = VertexBuffer.UNSIGNED_SHORT;
+                else if (data_1 instanceof Int32Array)
+                    this.type = VertexBuffer.INT;
+                else if (data_1 instanceof Uint32Array)
+                    this.type = VertexBuffer.UNSIGNED_INT;
+            }
+            else {
+                this.type = type;
+            }
+            var typeByteLength = VertexBuffer.GetTypeByteLength(this.type);
+            if (useBytes) {
+                this._size = size || (stride ? (stride / typeByteLength) : VertexBuffer.DeduceStride(kind));
+                this.byteStride = stride || this._buffer.byteStride || (this._size * typeByteLength);
+                this.byteOffset = offset || 0;
+            }
+            else {
+                this._size = size || stride || VertexBuffer.DeduceStride(kind);
+                this.byteStride = stride ? (stride * typeByteLength) : (this._buffer.byteStride || (this._size * typeByteLength));
+                this.byteOffset = (offset || 0) * typeByteLength;
+            }
+            this.normalized = normalized;
             this._instanced = instanced !== undefined ? instanced : false;
             this._instanceDivisor = instanced ? 1 : 0;
-            this._offset = offset ? offset : 0;
-            this._size = size ? size : stride;
-            this._kind = kind;
         }
         Object.defineProperty(VertexBuffer.prototype, "instanceDivisor", {
             /**
@@ -27243,7 +27324,7 @@ var BABYLON;
             return this._buffer.isUpdatable();
         };
         /**
-         * Returns an array of numbers or a Float32Array containing the VertexBuffer data.
+         * Returns an array of numbers or a typed array containing the VertexBuffer data.
          */
         VertexBuffer.prototype.getData = function () {
             return this._buffer.getData();
@@ -27255,19 +27336,21 @@ var BABYLON;
             return this._buffer.getBuffer();
         };
         /**
-         * Returns the stride of the VertexBuffer (integer).
+         * Returns the stride as a multiple of the type byte length.
+         * DEPRECATED. Use byteStride instead.
          */
         VertexBuffer.prototype.getStrideSize = function () {
-            return this._stride;
+            return this.byteStride / VertexBuffer.GetTypeByteLength(this.type);
         };
         /**
-         * Returns the offset (integer).
+         * Returns the offset as a multiple of the type byte length.
+         * DEPRECATED. Use byteOffset instead.
          */
         VertexBuffer.prototype.getOffset = function () {
-            return this._offset;
+            return this.byteOffset / VertexBuffer.GetTypeByteLength(this.type);
         };
         /**
-         * Returns the VertexBuffer total size (integer).
+         * Returns the number of components per vertex attribute (integer).
          */
         VertexBuffer.prototype.getSize = function () {
             return this._size;
@@ -27315,6 +27398,14 @@ var BABYLON;
                 this._buffer.dispose();
             }
         };
+        /**
+         * Enumerates each value of this vertex buffer as numbers.
+         * @param count the number of values to enumerate
+         * @param callback the callback function called for each value
+         */
+        VertexBuffer.prototype.forEach = function (count, callback) {
+            VertexBuffer.ForEach(this._buffer.getData(), this.byteOffset, this.byteStride, this._size, this.type, count, this.normalized, callback);
+        };
         Object.defineProperty(VertexBuffer, "PositionKind", {
             get: function () {
                 return VertexBuffer._PositionKind;
@@ -27441,6 +27532,128 @@ var BABYLON;
                     throw new Error("Invalid kind '" + kind + "'");
             }
         };
+        /**
+         * Gets the byte length of the given type.
+         * @param type the type
+         * @returns the number of bytes
+         */
+        VertexBuffer.GetTypeByteLength = function (type) {
+            switch (type) {
+                case VertexBuffer.BYTE:
+                case VertexBuffer.UNSIGNED_BYTE:
+                    return 1;
+                case VertexBuffer.SHORT:
+                case VertexBuffer.UNSIGNED_SHORT:
+                    return 2;
+                case VertexBuffer.INT:
+                case VertexBuffer.FLOAT:
+                    return 4;
+                default:
+                    throw new Error("Invalid type '" + type + "'");
+            }
+        };
+        /**
+         * Enumerates each value of the given parameters as numbers.
+         * @param data the data to enumerate
+         * @param byteOffset the byte offset of the data
+         * @param byteStride the byte stride of the data
+         * @param componentCount the number of components per element
+         * @param componentType the type of the component
+         * @param count the total number of components
+         * @param normalized whether the data is normalized
+         * @param callback the callback function called for each value
+         */
+        VertexBuffer.ForEach = function (data, byteOffset, byteStride, componentCount, componentType, count, normalized, callback) {
+            if (data instanceof Array) {
+                var offset = byteOffset / 4;
+                var stride = byteStride / 4;
+                for (var index = 0; index < count; index += componentCount) {
+                    for (var componentIndex = 0; componentIndex < componentCount; componentIndex++) {
+                        callback(data[offset + componentIndex], index + componentIndex);
+                    }
+                    offset += stride;
+                }
+            }
+            else {
+                var dataView = data instanceof ArrayBuffer ? new DataView(data) : new DataView(data.buffer, data.byteOffset, data.byteLength);
+                var componentByteLength = VertexBuffer.GetTypeByteLength(componentType);
+                for (var index = 0; index < count; index += componentCount) {
+                    var componentByteOffset = byteOffset;
+                    for (var componentIndex = 0; componentIndex < componentCount; componentIndex++) {
+                        var value = VertexBuffer._GetFloatValue(dataView, componentType, componentByteOffset, normalized);
+                        callback(value, index + componentIndex);
+                        componentByteOffset += componentByteLength;
+                    }
+                    byteOffset += byteStride;
+                }
+            }
+        };
+        VertexBuffer._GetFloatValue = function (dataView, type, byteOffset, normalized) {
+            switch (type) {
+                case VertexBuffer.BYTE: {
+                    var value = dataView.getInt8(byteOffset);
+                    if (normalized) {
+                        value = (value + 0.5) / 127.5;
+                    }
+                    return value;
+                }
+                case VertexBuffer.UNSIGNED_BYTE: {
+                    var value = dataView.getUint8(byteOffset);
+                    if (normalized) {
+                        value = value / 255;
+                    }
+                    return value;
+                }
+                case VertexBuffer.SHORT: {
+                    var value = dataView.getInt16(byteOffset, true);
+                    if (normalized) {
+                        value = (value + 0.5) / 16383.5;
+                    }
+                    return value;
+                }
+                case VertexBuffer.UNSIGNED_SHORT: {
+                    var value = dataView.getUint16(byteOffset, true);
+                    if (normalized) {
+                        value = value / 65535;
+                    }
+                    return value;
+                }
+                case VertexBuffer.FLOAT: {
+                    return dataView.getFloat32(byteOffset, true);
+                }
+                default: {
+                    throw new Error("Invalid component type " + type);
+                }
+            }
+        };
+        /**
+         * The byte type.
+         */
+        VertexBuffer.BYTE = 5120;
+        /**
+         * The unsigned byte type.
+         */
+        VertexBuffer.UNSIGNED_BYTE = 5121;
+        /**
+         * The short type.
+         */
+        VertexBuffer.SHORT = 5122;
+        /**
+         * The unsigned short type.
+         */
+        VertexBuffer.UNSIGNED_SHORT = 5123;
+        /**
+         * The integer type.
+         */
+        VertexBuffer.INT = 5124;
+        /**
+         * The unsigned integer type.
+         */
+        VertexBuffer.UNSIGNED_INT = 5125;
+        /**
+         * The float type.
+         */
+        VertexBuffer.FLOAT = 5126;
         // Enums
         VertexBuffer._PositionKind = "position";
         VertexBuffer._NormalKind = "normal";
@@ -29677,7 +29890,7 @@ var BABYLON;
         };
         Mesh.prototype._draw = function (subMesh, fillMode, instancesCount, alternate) {
             if (alternate === void 0) { alternate = false; }
-            if (!this._geometry || !this._geometry.getVertexBuffers() || !this._geometry.getIndexBuffer()) {
+            if (!this._geometry || !this._geometry.getVertexBuffers() || (!this._unIndexed && !this._geometry.getIndexBuffer())) {
                 return this;
             }
             this.onBeforeDrawObservable.notifyObservers(this);
@@ -29873,7 +30086,7 @@ var BABYLON;
                 return this;
             }
             // Checking geometry state
-            if (!this._geometry || !this._geometry.getVertexBuffers() || !this._geometry.getIndexBuffer()) {
+            if (!this._geometry || !this._geometry.getVertexBuffers() || (!this._unIndexed && !this._geometry.getIndexBuffer())) {
                 return this;
             }
             this.onBeforeRenderObservable.notifyObservers(this);
@@ -36112,7 +36325,7 @@ var BABYLON;
             if (mesh) {
                 if (mesh.getClassName() === "LinesMesh") {
                     this.boundingBias = new BABYLON.Vector2(0, mesh.intersectionThreshold);
-                    this.updateExtend();
+                    this._updateExtend();
                 }
                 this.applyToMesh(mesh);
                 mesh.computeWorldMatrix(true);
@@ -36133,7 +36346,7 @@ var BABYLON;
                     return;
                 }
                 this._boundingBias = value.clone();
-                this.updateBoundingInfo(true, null);
+                this._updateBoundingInfo(true, null);
             },
             enumerable: true,
             configurable: true
@@ -36227,6 +36440,9 @@ var BABYLON;
          */
         Geometry.prototype.setVerticesData = function (kind, data, updatable, stride) {
             if (updatable === void 0) { updatable = false; }
+            if (kind === BABYLON.VertexBuffer.PositionKind) {
+                this._totalVertices = data.length / (stride || 3);
+            }
             var buffer = new BABYLON.VertexBuffer(this._engine, data, kind, updatable, this._meshes.length === 0, stride);
             this.setVerticesBuffer(buffer);
         };
@@ -36243,18 +36459,20 @@ var BABYLON;
         /**
          * Affect a vertex buffer to the geometry. the vertexBuffer.getKind() function is used to determine where to store the data
          * @param buffer defines the vertex buffer to use
+         * @param totalVertices defines the total number of vertices for position kind (could be null)
          */
-        Geometry.prototype.setVerticesBuffer = function (buffer) {
+        Geometry.prototype.setVerticesBuffer = function (buffer, totalVertices) {
+            if (totalVertices === void 0) { totalVertices = null; }
             var kind = buffer.getKind();
             if (this._vertexBuffers[kind]) {
                 this._vertexBuffers[kind].dispose();
             }
             this._vertexBuffers[kind] = buffer;
             if (kind === BABYLON.VertexBuffer.PositionKind) {
-                var data = buffer.getData();
-                var stride = buffer.getStrideSize();
-                this._totalVertices = data.length / stride;
-                this.updateExtend(data, stride);
+                if (totalVertices != null) {
+                    this._totalVertices = totalVertices;
+                }
+                this._updateExtend();
                 this._resetPointsArrayCache();
                 var meshes = this._meshes;
                 var numOfMeshes = meshes.length;
@@ -36302,15 +36520,13 @@ var BABYLON;
             }
             vertexBuffer.update(data);
             if (kind === BABYLON.VertexBuffer.PositionKind) {
-                var stride = vertexBuffer.getStrideSize();
-                this._totalVertices = data.length / stride;
-                this.updateBoundingInfo(updateExtends, data);
+                this._updateBoundingInfo(updateExtends, data);
             }
             this.notifyUpdate(kind);
         };
-        Geometry.prototype.updateBoundingInfo = function (updateExtends, data) {
+        Geometry.prototype._updateBoundingInfo = function (updateExtends, data) {
             if (updateExtends) {
-                this.updateExtend(data);
+                this._updateExtend(data);
             }
             var meshes = this._meshes;
             var numOfMeshes = meshes.length;
@@ -36359,7 +36575,7 @@ var BABYLON;
             return this._totalVertices;
         };
         /**
-         * Gets a specific vertex data attached to this geometry
+         * Gets a specific vertex data attached to this geometry. Float data is constructed if the vertex buffer data cannot be returned directly.
          * @param kind defines the data kind (Position, normal, etc...)
          * @param copyWhenShared defines if the returned array must be cloned upon returning it if the current geometry is shared between multiple meshes
          * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it
@@ -36370,18 +36586,36 @@ var BABYLON;
             if (!vertexBuffer) {
                 return null;
             }
-            var orig = vertexBuffer.getData();
-            if (!forceCopy && (!copyWhenShared || this._meshes.length === 1)) {
-                return orig;
+            var data = vertexBuffer.getData();
+            if (!data) {
+                return null;
             }
-            else {
-                var len = orig.length;
-                var copy = [];
-                for (var i = 0; i < len; i++) {
-                    copy.push(orig[i]);
+            var defaultStride = BABYLON.VertexBuffer.DeduceStride(vertexBuffer.getKind());
+            var defaultByteStride = defaultStride * BABYLON.VertexBuffer.GetTypeByteLength(vertexBuffer.type);
+            var count = this._totalVertices * defaultStride;
+            if (vertexBuffer.type !== BABYLON.VertexBuffer.FLOAT || vertexBuffer.byteStride !== defaultByteStride) {
+                var copy_1 = new Array(count);
+                vertexBuffer.forEach(count, function (value, index) {
+                    copy_1[index] = value;
+                });
+                return copy_1;
+            }
+            if (!(data instanceof Array || data instanceof Float32Array) || vertexBuffer.byteOffset !== 0 || data.length !== count) {
+                if (data instanceof Array) {
+                    var offset = vertexBuffer.byteOffset / 4;
+                    return BABYLON.Tools.Slice(data, offset, offset + count);
                 }
-                return copy;
+                else if (data instanceof ArrayBuffer) {
+                    return new Float32Array(data, vertexBuffer.byteOffset, count);
+                }
+                else {
+                    return new Float32Array(data.buffer, data.byteOffset + vertexBuffer.byteOffset, count);
+                }
+            }
+            if (forceCopy || (copyWhenShared && this._meshes.length !== 1)) {
+                return BABYLON.Tools.Slice(data);
             }
+            return data;
         };
         /**
          * Returns a boolean defining if the vertex data for the requested `kind` is updatable
@@ -36587,12 +36821,12 @@ var BABYLON;
                 mesh._boundingInfo = this._boundingInfo;
             }
         };
-        Geometry.prototype.updateExtend = function (data, stride) {
+        Geometry.prototype._updateExtend = function (data) {
             if (data === void 0) { data = null; }
             if (!data) {
-                data = this._vertexBuffers[BABYLON.VertexBuffer.PositionKind].getData();
+                data = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
             }
-            this._extend = BABYLON.Tools.ExtractMinAndMax(data, 0, this._totalVertices, this.boundingBias, stride);
+            this._extend = BABYLON.Tools.ExtractMinAndMax(data, 0, this._totalVertices, this.boundingBias, 3);
         };
         Geometry.prototype._applyToMesh = function (mesh) {
             var numOfMeshes = this._meshes.length;
@@ -36606,7 +36840,7 @@ var BABYLON;
                     buffer.references = numOfMeshes;
                 if (kind === BABYLON.VertexBuffer.PositionKind) {
                     if (!this._extend) {
-                        this.updateExtend(this._vertexBuffers[kind].getData());
+                        this._updateExtend();
                     }
                     mesh._boundingInfo = new BABYLON.BoundingInfo(this._extend.minimum, this._extend.maximum);
                     mesh._createGlobalSubMesh(false);
@@ -57551,7 +57785,7 @@ var BABYLON;
             return this;
         };
         LinesMesh.prototype._draw = function (subMesh, fillMode, instancesCount) {
-            if (!this._geometry || !this._geometry.getVertexBuffers() || !this._geometry.getIndexBuffer()) {
+            if (!this._geometry || !this._geometry.getVertexBuffers() || (!this._unIndexed && !this._geometry.getIndexBuffer())) {
                 return this;
             }
             var engine = this.getScene().getEngine();
@@ -91415,7 +91649,14 @@ var BABYLON;
         NullEngine.prototype.updateDynamicIndexBuffer = function (indexBuffer, indices, offset) {
             if (offset === void 0) { offset = 0; }
         };
-        NullEngine.prototype.updateDynamicVertexBuffer = function (vertexBuffer, vertices, offset, count) {
+        /**
+         * Updates a dynamic vertex buffer.
+         * @param vertexBuffer the vertex buffer to update
+         * @param data the data used to update the vertex buffer
+         * @param byteOffset the byte offset of the data (optional)
+         * @param byteLength the byte length of the data (optional)
+         */
+        NullEngine.prototype.updateDynamicVertexBuffer = function (vertexBuffer, vertices, byteOffset, byteLength) {
         };
         NullEngine.prototype._bindTextureDirectly = function (target, texture) {
             if (this._boundTexturesCache[this._activeChannel] !== texture) {

+ 10 - 12
dist/preview release/loaders/babylon.glTF2FileLoader.d.ts

@@ -176,9 +176,6 @@ declare module BABYLON {
 
 
 declare module BABYLON.GLTF2 {
-    interface TypedArray extends ArrayBufferView {
-        [index: number]: number;
-    }
     interface IArrayItem {
         _index: number;
     }
@@ -198,7 +195,8 @@ declare module BABYLON.GLTF2 {
 
 declare module BABYLON.GLTF2 {
     interface ILoaderAccessor extends IAccessor, IArrayItem {
-        _data?: Promise<TypedArray>;
+        _data?: Promise<ArrayBufferView>;
+        _babylonVertexBuffer?: Promise<VertexBuffer>;
     }
     interface ILoaderAnimationChannel extends IAnimationChannel, IArrayItem {
     }
@@ -220,6 +218,7 @@ declare module BABYLON.GLTF2 {
     }
     interface ILoaderBufferView extends IBufferView, IArrayItem {
         _data?: Promise<ArrayBufferView>;
+        _babylonBuffer?: Promise<Buffer>;
     }
     interface ILoaderCamera extends ICamera, IArrayItem {
     }
@@ -341,10 +340,8 @@ declare module BABYLON.GLTF2 {
         private _loadPrimitiveAsync(context, node, mesh, primitive, babylonMesh);
         private _loadVertexDataAsync(context, primitive, babylonMesh);
         private _createMorphTargets(context, node, mesh, primitive, babylonMesh);
-        private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);
-        private _loadMorphTargetVertexDataAsync(context, babylonVertexData, attributes, babylonMorphTarget);
-        private static _ConvertToFloat32Array(context, accessor, data);
-        private static _ConvertVec3ToVec4(context, data);
+        private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonGeometry);
+        private _loadMorphTargetVertexDataAsync(context, babylonGeometry, attributes, babylonMorphTarget);
         private static _LoadTransform(node, babylonNode);
         private _loadSkinAsync(context, node, mesh, skin);
         private _loadSkinInverseBindMatricesDataAsync(context, skin);
@@ -359,7 +356,8 @@ declare module BABYLON.GLTF2 {
         private _loadBufferAsync(context, buffer);
         _loadBufferViewAsync(context: string, bufferView: ILoaderBufferView): Promise<ArrayBufferView>;
         private _loadAccessorAsync(context, accessor);
-        private _buildArrayBuffer<T>(typedArray, data, byteOffset, count, numComponents, byteStride?);
+        _loadVertexBufferViewAsync(context: string, bufferView: ILoaderBufferView, kind: string): Promise<Buffer>;
+        private _loadVertexAccessorAsync(context, accessor, kind);
         private _getDefaultMaterial(drawMode);
         private _loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial);
         _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void>;
@@ -397,7 +395,7 @@ declare module BABYLON.GLTF2 {
         /** Override this method to modify the default behavior for loading nodes. */
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>>;
         /** Override this method to modify the default behavior for loading mesh primitive vertex data. */
-        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>>;
+        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         /** Override this method to modify the default behavior for loading materials. */
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         /** Override this method to modify the default behavior for loading uris. */
@@ -409,7 +407,7 @@ declare module BABYLON.GLTF2 {
         /** Helper method called by the loader to allow extensions to override loading nodes. */
         static _LoadNodeAsync(loader: GLTFLoader, context: string, node: ILoaderNode): Nullable<Promise<void>>;
         /** Helper method called by the loader to allow extensions to override loading mesh primitive vertex data. */
-        static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>>;
+        static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         /** Helper method called by the loader to allow extensions to override loading materials. */
         static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         /** Helper method called by the loader to allow extensions to override loading uris. */
@@ -446,7 +444,7 @@ declare module BABYLON.GLTF2.Extensions {
         private _dracoCompression;
         constructor(loader: GLTFLoader);
         dispose(): void;
-        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>>;
+        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
     }
 }
 

+ 91 - 131
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -946,9 +946,10 @@ var BABYLON;
                 var _this = this;
                 var promises = new Array();
                 this._createMorphTargets(context, node, mesh, primitive, babylonMesh);
-                promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonVertexData) {
-                    new BABYLON.Geometry(babylonMesh.name, _this._babylonScene, babylonVertexData, false, babylonMesh);
-                    return _this._loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);
+                promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonGeometry) {
+                    return _this._loadMorphTargetsAsync(context, primitive, babylonMesh, babylonGeometry).then(function () {
+                        babylonGeometry.applyToMesh(babylonMesh);
+                    });
                 }));
                 var babylonDrawMode = GLTFLoader._GetDrawMode(context, primitive.mode);
                 if (primitive.material == undefined) {
@@ -973,24 +974,17 @@ var BABYLON;
                     throw new Error(context + ": Attributes are missing");
                 }
                 var promises = new Array();
-                var babylonVertexData = new BABYLON.VertexData();
+                var babylonGeometry = new BABYLON.Geometry(babylonMesh.name, this._babylonScene);
                 if (primitive.indices == undefined) {
-                    var positionAccessorIndex = attributes["POSITION"];
-                    if (positionAccessorIndex != undefined) {
-                        var accessor = GLTFLoader._GetProperty(context + "/attributes/POSITION", this._gltf.accessors, positionAccessorIndex);
-                        babylonVertexData.indices = new Uint32Array(accessor.count);
-                        for (var i = 0; i < babylonVertexData.indices.length; i++) {
-                            babylonVertexData.indices[i] = i;
-                        }
-                    }
+                    babylonMesh.isUnIndexed = true;
                 }
                 else {
-                    var indicesAccessor = GLTFLoader._GetProperty(context + "/indices", this._gltf.accessors, primitive.indices);
-                    promises.push(this._loadAccessorAsync("#/accessors/" + indicesAccessor._index, indicesAccessor).then(function (data) {
-                        babylonVertexData.indices = data;
+                    var accessor = GLTFLoader._GetProperty(context + "/indices", this._gltf.accessors, primitive.indices);
+                    promises.push(this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
+                        babylonGeometry.setIndices(data);
                     }));
                 }
-                var loadAttribute = function (attribute, kind) {
+                var loadAttribute = function (attribute, kind, callback) {
                     if (attributes[attribute] == undefined) {
                         return;
                     }
@@ -998,18 +992,13 @@ var BABYLON;
                     if (babylonMesh._delayInfo.indexOf(kind) === -1) {
                         babylonMesh._delayInfo.push(kind);
                     }
-                    if (attribute === "COLOR_0") {
-                        // Assume vertex color has alpha on the mesh. The alphaMode of the material controls whether the material should use alpha or not.
-                        babylonMesh.hasVertexAlpha = true;
-                    }
                     var accessor = GLTFLoader._GetProperty(context + "/attributes/" + attribute, _this._gltf.accessors, attributes[attribute]);
-                    promises.push(_this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
-                        var attributeData = GLTFLoader._ConvertToFloat32Array(context, accessor, data);
-                        if (attribute === "COLOR_0" && accessor.type === "VEC3") {
-                            attributeData = GLTFLoader._ConvertVec3ToVec4(context, attributeData);
-                        }
-                        babylonVertexData.set(attributeData, kind);
+                    promises.push(_this._loadVertexAccessorAsync("#/accessors/" + accessor._index, accessor, kind).then(function (babylonVertexBuffer) {
+                        babylonGeometry.setVerticesBuffer(babylonVertexBuffer, accessor.count);
                     }));
+                    if (callback) {
+                        callback(accessor);
+                    }
                 };
                 loadAttribute("POSITION", BABYLON.VertexBuffer.PositionKind);
                 loadAttribute("NORMAL", BABYLON.VertexBuffer.NormalKind);
@@ -1018,9 +1007,13 @@ var BABYLON;
                 loadAttribute("TEXCOORD_1", BABYLON.VertexBuffer.UV2Kind);
                 loadAttribute("JOINTS_0", BABYLON.VertexBuffer.MatricesIndicesKind);
                 loadAttribute("WEIGHTS_0", BABYLON.VertexBuffer.MatricesWeightsKind);
-                loadAttribute("COLOR_0", BABYLON.VertexBuffer.ColorKind);
+                loadAttribute("COLOR_0", BABYLON.VertexBuffer.ColorKind, function (accessor) {
+                    if (accessor.type === "VEC4" /* VEC4 */) {
+                        babylonMesh.hasVertexAlpha = true;
+                    }
+                });
                 return Promise.all(promises).then(function () {
-                    return babylonVertexData;
+                    return babylonGeometry;
                 });
             };
             GLTFLoader.prototype._createMorphTargets = function (context, node, mesh, primitive, babylonMesh) {
@@ -1040,7 +1033,7 @@ var BABYLON;
                     // TODO: tell the target whether it has positions, normals, tangents
                 }
             };
-            GLTFLoader.prototype._loadMorphTargetsAsync = function (context, primitive, babylonMesh, babylonVertexData) {
+            GLTFLoader.prototype._loadMorphTargetsAsync = function (context, primitive, babylonMesh, babylonGeometry) {
                 if (!primitive.targets) {
                     return Promise.resolve();
                 }
@@ -1048,93 +1041,55 @@ var BABYLON;
                 var morphTargetManager = babylonMesh.morphTargetManager;
                 for (var index = 0; index < morphTargetManager.numTargets; index++) {
                     var babylonMorphTarget = morphTargetManager.getTarget(index);
-                    promises.push(this._loadMorphTargetVertexDataAsync(context + "/targets/" + index, babylonVertexData, primitive.targets[index], babylonMorphTarget));
+                    promises.push(this._loadMorphTargetVertexDataAsync(context + "/targets/" + index, babylonGeometry, primitive.targets[index], babylonMorphTarget));
                 }
                 return Promise.all(promises).then(function () { });
             };
-            GLTFLoader.prototype._loadMorphTargetVertexDataAsync = function (context, babylonVertexData, attributes, babylonMorphTarget) {
+            GLTFLoader.prototype._loadMorphTargetVertexDataAsync = function (context, babylonGeometry, attributes, babylonMorphTarget) {
                 var _this = this;
                 var promises = new Array();
-                var loadAttribute = function (attribute, setData) {
+                var loadAttribute = function (attribute, kind, setData) {
                     if (attributes[attribute] == undefined) {
                         return;
                     }
+                    var babylonVertexBuffer = babylonGeometry.getVertexBuffer(kind);
+                    if (!babylonVertexBuffer) {
+                        return;
+                    }
                     var accessor = GLTFLoader._GetProperty(context + "/" + attribute, _this._gltf.accessors, attributes[attribute]);
                     promises.push(_this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
-                        setData(data);
+                        if (!(data instanceof Float32Array)) {
+                            throw new Error(context + ": Morph target accessor must have float data");
+                        }
+                        setData(babylonVertexBuffer, data);
                     }));
                 };
-                loadAttribute("POSITION", function (data) {
-                    if (babylonVertexData.positions) {
-                        for (var i = 0; i < data.length; i++) {
-                            data[i] += babylonVertexData.positions[i];
-                        }
-                        babylonMorphTarget.setPositions(data);
-                    }
+                loadAttribute("POSITION", BABYLON.VertexBuffer.PositionKind, function (babylonVertexBuffer, data) {
+                    babylonVertexBuffer.forEach(data.length, function (value, index) {
+                        data[index] += value;
+                    });
+                    babylonMorphTarget.setPositions(data);
                 });
-                loadAttribute("NORMAL", function (data) {
-                    if (babylonVertexData.normals) {
-                        for (var i = 0; i < data.length; i++) {
-                            data[i] += babylonVertexData.normals[i];
-                        }
-                        babylonMorphTarget.setNormals(data);
-                    }
+                loadAttribute("NORMAL", BABYLON.VertexBuffer.NormalKind, function (babylonVertexBuffer, data) {
+                    babylonVertexBuffer.forEach(data.length, function (value, index) {
+                        data[index] += value;
+                    });
+                    babylonMorphTarget.setNormals(data);
                 });
-                loadAttribute("TANGENT", function (data) {
-                    if (babylonVertexData.tangents) {
+                loadAttribute("TANGENT", BABYLON.VertexBuffer.TangentKind, function (babylonVertexBuffer, data) {
+                    var dataIndex = 0;
+                    babylonVertexBuffer.forEach(data.length, function (value, index) {
                         // Tangent data for morph targets is stored as xyz delta.
                         // The vertexData.tangent is stored as xyzw.
                         // So we need to skip every fourth vertexData.tangent.
-                        for (var i = 0, j = 0; i < data.length; i++) {
-                            data[i] += babylonVertexData.tangents[j++];
-                            if ((i + 1) % 3 == 0) {
-                                j++;
-                            }
+                        if (((index + 1) % 4) !== 0) {
+                            data[dataIndex++] += value;
                         }
-                        babylonMorphTarget.setTangents(data);
-                    }
+                    });
+                    babylonMorphTarget.setTangents(data);
                 });
                 return Promise.all(promises).then(function () { });
             };
-            GLTFLoader._ConvertToFloat32Array = function (context, accessor, data) {
-                if (accessor.componentType == 5126 /* FLOAT */) {
-                    return data;
-                }
-                var factor = 1;
-                if (accessor.normalized) {
-                    switch (accessor.componentType) {
-                        case 5121 /* UNSIGNED_BYTE */: {
-                            factor = 1 / 255;
-                            break;
-                        }
-                        case 5123 /* UNSIGNED_SHORT */: {
-                            factor = 1 / 65535;
-                            break;
-                        }
-                        default: {
-                            throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
-                        }
-                    }
-                }
-                var result = new Float32Array(accessor.count * GLTFLoader._GetNumComponents(context, accessor.type));
-                for (var i = 0; i < result.length; i++) {
-                    result[i] = data[i] * factor;
-                }
-                return result;
-            };
-            GLTFLoader._ConvertVec3ToVec4 = function (context, data) {
-                var result = new Float32Array(data.length / 3 * 4);
-                var offset = 0;
-                for (var i = 0; i < result.length; i++) {
-                    if ((i + 1) % 4 === 0) {
-                        result[i] = 1;
-                    }
-                    else {
-                        result[i] = data[offset++];
-                    }
-                }
-                return result;
-            };
             GLTFLoader._LoadTransform = function (node, babylonNode) {
                 var position = BABYLON.Vector3.Zero();
                 var rotation = BABYLON.Quaternion.Identity();
@@ -1451,9 +1406,9 @@ var BABYLON;
                     return bufferView._data;
                 }
                 var buffer = GLTFLoader._GetProperty(context + "/buffer", this._gltf.buffers, bufferView.buffer);
-                bufferView._data = this._loadBufferAsync("#/buffers/" + buffer._index, buffer).then(function (bufferData) {
+                bufferView._data = this._loadBufferAsync("#/buffers/" + buffer._index, buffer).then(function (data) {
                     try {
-                        return new Uint8Array(bufferData.buffer, bufferData.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
+                        return new Uint8Array(data.buffer, data.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
                     }
                     catch (e) {
                         throw new Error(context + ": " + e.message);
@@ -1462,7 +1417,6 @@ var BABYLON;
                 return bufferView._data;
             };
             GLTFLoader.prototype._loadAccessorAsync = function (context, accessor) {
-                var _this = this;
                 if (accessor.sparse) {
                     throw new Error(context + ": Sparse accessors are not currently supported");
                 }
@@ -1470,63 +1424,65 @@ var BABYLON;
                     return accessor._data;
                 }
                 var bufferView = GLTFLoader._GetProperty(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
-                accessor._data = this._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(function (bufferViewData) {
-                    var numComponents = GLTFLoader._GetNumComponents(context, accessor.type);
-                    var byteOffset = accessor.byteOffset || 0;
-                    var byteStride = bufferView.byteStride;
-                    if (byteStride === 0) {
-                        BABYLON.Tools.Warn(context + ": Byte stride of 0 is not valid");
-                    }
+                accessor._data = this._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(function (data) {
+                    var buffer = data.buffer;
+                    var byteOffset = data.byteOffset + (accessor.byteOffset || 0);
+                    var length = GLTFLoader._GetNumComponents(context, accessor.type) * accessor.count;
                     try {
                         switch (accessor.componentType) {
                             case 5120 /* BYTE */: {
-                                return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Int8Array(buffer, byteOffset, length);
                             }
                             case 5121 /* UNSIGNED_BYTE */: {
-                                return _this._buildArrayBuffer(Uint8Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Uint8Array(buffer, byteOffset, length);
                             }
                             case 5122 /* SHORT */: {
-                                return _this._buildArrayBuffer(Int16Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Int16Array(buffer, byteOffset, length);
                             }
                             case 5123 /* UNSIGNED_SHORT */: {
-                                return _this._buildArrayBuffer(Uint16Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Uint16Array(buffer, byteOffset, length);
                             }
                             case 5125 /* UNSIGNED_INT */: {
-                                return _this._buildArrayBuffer(Uint32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Uint32Array(buffer, byteOffset, length);
                             }
                             case 5126 /* FLOAT */: {
-                                return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Float32Array(buffer, byteOffset, length);
                             }
                             default: {
-                                throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
+                                throw new Error(context + ": Invalid accessor component type " + accessor.componentType);
                             }
                         }
                     }
                     catch (e) {
-                        throw new Error(context + ": " + e.messsage);
+                        throw new Error(context + ": " + e);
                     }
                 });
                 return accessor._data;
             };
-            GLTFLoader.prototype._buildArrayBuffer = function (typedArray, data, byteOffset, count, numComponents, byteStride) {
-                byteOffset += data.byteOffset;
-                var targetLength = count * numComponents;
-                if (!byteStride || byteStride === numComponents * typedArray.BYTES_PER_ELEMENT) {
-                    return new typedArray(data.buffer, byteOffset, targetLength);
+            GLTFLoader.prototype._loadVertexBufferViewAsync = function (context, bufferView, kind) {
+                var _this = this;
+                if (bufferView._babylonBuffer) {
+                    return bufferView._babylonBuffer;
                 }
-                var elementStride = byteStride / typedArray.BYTES_PER_ELEMENT;
-                var sourceBuffer = new typedArray(data.buffer, byteOffset, elementStride * count);
-                var targetBuffer = new typedArray(targetLength);
-                var sourceIndex = 0;
-                var targetIndex = 0;
-                while (targetIndex < targetLength) {
-                    for (var componentIndex = 0; componentIndex < numComponents; componentIndex++) {
-                        targetBuffer[targetIndex] = sourceBuffer[sourceIndex + componentIndex];
-                        targetIndex++;
-                    }
-                    sourceIndex += elementStride;
+                bufferView._babylonBuffer = this._loadBufferViewAsync(context, bufferView).then(function (data) {
+                    return new BABYLON.Buffer(_this._babylonScene.getEngine(), data, false);
+                });
+                return bufferView._babylonBuffer;
+            };
+            GLTFLoader.prototype._loadVertexAccessorAsync = function (context, accessor, kind) {
+                var _this = this;
+                if (accessor.sparse) {
+                    throw new Error(context + ": Sparse accessors are not currently supported");
+                }
+                if (accessor._babylonVertexBuffer) {
+                    return accessor._babylonVertexBuffer;
                 }
-                return targetBuffer;
+                var bufferView = GLTFLoader._GetProperty(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
+                accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView, kind).then(function (buffer) {
+                    var size = GLTFLoader._GetNumComponents(context, accessor.type);
+                    return new BABYLON.VertexBuffer(_this._babylonScene.getEngine(), buffer, kind, false, false, bufferView.byteStride, false, accessor.byteOffset, size, accessor.componentType, accessor.normalized, true);
+                });
+                return accessor._babylonVertexBuffer;
             };
             GLTFLoader.prototype._getDefaultMaterial = function (drawMode) {
                 var babylonMaterial = this._defaultBabylonMaterials[drawMode];
@@ -2274,7 +2230,11 @@ var BABYLON;
                                 if (!_this._dracoCompression) {
                                     _this._dracoCompression = new BABYLON.DracoCompression();
                                 }
-                                return _this._dracoCompression.decodeMeshAsync(data, attributes);
+                                return _this._dracoCompression.decodeMeshAsync(data, attributes).then(function (babylonVertexData) {
+                                    var babylonGeometry = new BABYLON.Geometry(babylonMesh.name, _this._loader._babylonScene);
+                                    babylonVertexData.applyToGeometry(babylonGeometry);
+                                    return babylonGeometry;
+                                });
                             }
                             catch (e) {
                                 throw new Error(context + ": " + e.message);

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 10 - 12
dist/preview release/loaders/babylon.glTFFileLoader.d.ts

@@ -732,9 +732,6 @@ declare module BABYLON.GLTF1 {
 
 
 declare module BABYLON.GLTF2 {
-    interface TypedArray extends ArrayBufferView {
-        [index: number]: number;
-    }
     interface IArrayItem {
         _index: number;
     }
@@ -754,7 +751,8 @@ declare module BABYLON.GLTF2 {
 
 declare module BABYLON.GLTF2 {
     interface ILoaderAccessor extends IAccessor, IArrayItem {
-        _data?: Promise<TypedArray>;
+        _data?: Promise<ArrayBufferView>;
+        _babylonVertexBuffer?: Promise<VertexBuffer>;
     }
     interface ILoaderAnimationChannel extends IAnimationChannel, IArrayItem {
     }
@@ -776,6 +774,7 @@ declare module BABYLON.GLTF2 {
     }
     interface ILoaderBufferView extends IBufferView, IArrayItem {
         _data?: Promise<ArrayBufferView>;
+        _babylonBuffer?: Promise<Buffer>;
     }
     interface ILoaderCamera extends ICamera, IArrayItem {
     }
@@ -897,10 +896,8 @@ declare module BABYLON.GLTF2 {
         private _loadPrimitiveAsync(context, node, mesh, primitive, babylonMesh);
         private _loadVertexDataAsync(context, primitive, babylonMesh);
         private _createMorphTargets(context, node, mesh, primitive, babylonMesh);
-        private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);
-        private _loadMorphTargetVertexDataAsync(context, babylonVertexData, attributes, babylonMorphTarget);
-        private static _ConvertToFloat32Array(context, accessor, data);
-        private static _ConvertVec3ToVec4(context, data);
+        private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonGeometry);
+        private _loadMorphTargetVertexDataAsync(context, babylonGeometry, attributes, babylonMorphTarget);
         private static _LoadTransform(node, babylonNode);
         private _loadSkinAsync(context, node, mesh, skin);
         private _loadSkinInverseBindMatricesDataAsync(context, skin);
@@ -915,7 +912,8 @@ declare module BABYLON.GLTF2 {
         private _loadBufferAsync(context, buffer);
         _loadBufferViewAsync(context: string, bufferView: ILoaderBufferView): Promise<ArrayBufferView>;
         private _loadAccessorAsync(context, accessor);
-        private _buildArrayBuffer<T>(typedArray, data, byteOffset, count, numComponents, byteStride?);
+        _loadVertexBufferViewAsync(context: string, bufferView: ILoaderBufferView, kind: string): Promise<Buffer>;
+        private _loadVertexAccessorAsync(context, accessor, kind);
         private _getDefaultMaterial(drawMode);
         private _loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial);
         _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void>;
@@ -953,7 +951,7 @@ declare module BABYLON.GLTF2 {
         /** Override this method to modify the default behavior for loading nodes. */
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>>;
         /** Override this method to modify the default behavior for loading mesh primitive vertex data. */
-        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>>;
+        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         /** Override this method to modify the default behavior for loading materials. */
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         /** Override this method to modify the default behavior for loading uris. */
@@ -965,7 +963,7 @@ declare module BABYLON.GLTF2 {
         /** Helper method called by the loader to allow extensions to override loading nodes. */
         static _LoadNodeAsync(loader: GLTFLoader, context: string, node: ILoaderNode): Nullable<Promise<void>>;
         /** Helper method called by the loader to allow extensions to override loading mesh primitive vertex data. */
-        static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>>;
+        static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         /** Helper method called by the loader to allow extensions to override loading materials. */
         static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         /** Helper method called by the loader to allow extensions to override loading uris. */
@@ -1002,7 +1000,7 @@ declare module BABYLON.GLTF2.Extensions {
         private _dracoCompression;
         constructor(loader: GLTFLoader);
         dispose(): void;
-        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>>;
+        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
     }
 }
 

+ 91 - 131
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -3144,9 +3144,10 @@ var BABYLON;
                 var _this = this;
                 var promises = new Array();
                 this._createMorphTargets(context, node, mesh, primitive, babylonMesh);
-                promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonVertexData) {
-                    new BABYLON.Geometry(babylonMesh.name, _this._babylonScene, babylonVertexData, false, babylonMesh);
-                    return _this._loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);
+                promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonGeometry) {
+                    return _this._loadMorphTargetsAsync(context, primitive, babylonMesh, babylonGeometry).then(function () {
+                        babylonGeometry.applyToMesh(babylonMesh);
+                    });
                 }));
                 var babylonDrawMode = GLTFLoader._GetDrawMode(context, primitive.mode);
                 if (primitive.material == undefined) {
@@ -3171,24 +3172,17 @@ var BABYLON;
                     throw new Error(context + ": Attributes are missing");
                 }
                 var promises = new Array();
-                var babylonVertexData = new BABYLON.VertexData();
+                var babylonGeometry = new BABYLON.Geometry(babylonMesh.name, this._babylonScene);
                 if (primitive.indices == undefined) {
-                    var positionAccessorIndex = attributes["POSITION"];
-                    if (positionAccessorIndex != undefined) {
-                        var accessor = GLTFLoader._GetProperty(context + "/attributes/POSITION", this._gltf.accessors, positionAccessorIndex);
-                        babylonVertexData.indices = new Uint32Array(accessor.count);
-                        for (var i = 0; i < babylonVertexData.indices.length; i++) {
-                            babylonVertexData.indices[i] = i;
-                        }
-                    }
+                    babylonMesh.isUnIndexed = true;
                 }
                 else {
-                    var indicesAccessor = GLTFLoader._GetProperty(context + "/indices", this._gltf.accessors, primitive.indices);
-                    promises.push(this._loadAccessorAsync("#/accessors/" + indicesAccessor._index, indicesAccessor).then(function (data) {
-                        babylonVertexData.indices = data;
+                    var accessor = GLTFLoader._GetProperty(context + "/indices", this._gltf.accessors, primitive.indices);
+                    promises.push(this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
+                        babylonGeometry.setIndices(data);
                     }));
                 }
-                var loadAttribute = function (attribute, kind) {
+                var loadAttribute = function (attribute, kind, callback) {
                     if (attributes[attribute] == undefined) {
                         return;
                     }
@@ -3196,18 +3190,13 @@ var BABYLON;
                     if (babylonMesh._delayInfo.indexOf(kind) === -1) {
                         babylonMesh._delayInfo.push(kind);
                     }
-                    if (attribute === "COLOR_0") {
-                        // Assume vertex color has alpha on the mesh. The alphaMode of the material controls whether the material should use alpha or not.
-                        babylonMesh.hasVertexAlpha = true;
-                    }
                     var accessor = GLTFLoader._GetProperty(context + "/attributes/" + attribute, _this._gltf.accessors, attributes[attribute]);
-                    promises.push(_this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
-                        var attributeData = GLTFLoader._ConvertToFloat32Array(context, accessor, data);
-                        if (attribute === "COLOR_0" && accessor.type === "VEC3") {
-                            attributeData = GLTFLoader._ConvertVec3ToVec4(context, attributeData);
-                        }
-                        babylonVertexData.set(attributeData, kind);
+                    promises.push(_this._loadVertexAccessorAsync("#/accessors/" + accessor._index, accessor, kind).then(function (babylonVertexBuffer) {
+                        babylonGeometry.setVerticesBuffer(babylonVertexBuffer, accessor.count);
                     }));
+                    if (callback) {
+                        callback(accessor);
+                    }
                 };
                 loadAttribute("POSITION", BABYLON.VertexBuffer.PositionKind);
                 loadAttribute("NORMAL", BABYLON.VertexBuffer.NormalKind);
@@ -3216,9 +3205,13 @@ var BABYLON;
                 loadAttribute("TEXCOORD_1", BABYLON.VertexBuffer.UV2Kind);
                 loadAttribute("JOINTS_0", BABYLON.VertexBuffer.MatricesIndicesKind);
                 loadAttribute("WEIGHTS_0", BABYLON.VertexBuffer.MatricesWeightsKind);
-                loadAttribute("COLOR_0", BABYLON.VertexBuffer.ColorKind);
+                loadAttribute("COLOR_0", BABYLON.VertexBuffer.ColorKind, function (accessor) {
+                    if (accessor.type === "VEC4" /* VEC4 */) {
+                        babylonMesh.hasVertexAlpha = true;
+                    }
+                });
                 return Promise.all(promises).then(function () {
-                    return babylonVertexData;
+                    return babylonGeometry;
                 });
             };
             GLTFLoader.prototype._createMorphTargets = function (context, node, mesh, primitive, babylonMesh) {
@@ -3238,7 +3231,7 @@ var BABYLON;
                     // TODO: tell the target whether it has positions, normals, tangents
                 }
             };
-            GLTFLoader.prototype._loadMorphTargetsAsync = function (context, primitive, babylonMesh, babylonVertexData) {
+            GLTFLoader.prototype._loadMorphTargetsAsync = function (context, primitive, babylonMesh, babylonGeometry) {
                 if (!primitive.targets) {
                     return Promise.resolve();
                 }
@@ -3246,93 +3239,55 @@ var BABYLON;
                 var morphTargetManager = babylonMesh.morphTargetManager;
                 for (var index = 0; index < morphTargetManager.numTargets; index++) {
                     var babylonMorphTarget = morphTargetManager.getTarget(index);
-                    promises.push(this._loadMorphTargetVertexDataAsync(context + "/targets/" + index, babylonVertexData, primitive.targets[index], babylonMorphTarget));
+                    promises.push(this._loadMorphTargetVertexDataAsync(context + "/targets/" + index, babylonGeometry, primitive.targets[index], babylonMorphTarget));
                 }
                 return Promise.all(promises).then(function () { });
             };
-            GLTFLoader.prototype._loadMorphTargetVertexDataAsync = function (context, babylonVertexData, attributes, babylonMorphTarget) {
+            GLTFLoader.prototype._loadMorphTargetVertexDataAsync = function (context, babylonGeometry, attributes, babylonMorphTarget) {
                 var _this = this;
                 var promises = new Array();
-                var loadAttribute = function (attribute, setData) {
+                var loadAttribute = function (attribute, kind, setData) {
                     if (attributes[attribute] == undefined) {
                         return;
                     }
+                    var babylonVertexBuffer = babylonGeometry.getVertexBuffer(kind);
+                    if (!babylonVertexBuffer) {
+                        return;
+                    }
                     var accessor = GLTFLoader._GetProperty(context + "/" + attribute, _this._gltf.accessors, attributes[attribute]);
                     promises.push(_this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
-                        setData(data);
+                        if (!(data instanceof Float32Array)) {
+                            throw new Error(context + ": Morph target accessor must have float data");
+                        }
+                        setData(babylonVertexBuffer, data);
                     }));
                 };
-                loadAttribute("POSITION", function (data) {
-                    if (babylonVertexData.positions) {
-                        for (var i = 0; i < data.length; i++) {
-                            data[i] += babylonVertexData.positions[i];
-                        }
-                        babylonMorphTarget.setPositions(data);
-                    }
+                loadAttribute("POSITION", BABYLON.VertexBuffer.PositionKind, function (babylonVertexBuffer, data) {
+                    babylonVertexBuffer.forEach(data.length, function (value, index) {
+                        data[index] += value;
+                    });
+                    babylonMorphTarget.setPositions(data);
                 });
-                loadAttribute("NORMAL", function (data) {
-                    if (babylonVertexData.normals) {
-                        for (var i = 0; i < data.length; i++) {
-                            data[i] += babylonVertexData.normals[i];
-                        }
-                        babylonMorphTarget.setNormals(data);
-                    }
+                loadAttribute("NORMAL", BABYLON.VertexBuffer.NormalKind, function (babylonVertexBuffer, data) {
+                    babylonVertexBuffer.forEach(data.length, function (value, index) {
+                        data[index] += value;
+                    });
+                    babylonMorphTarget.setNormals(data);
                 });
-                loadAttribute("TANGENT", function (data) {
-                    if (babylonVertexData.tangents) {
+                loadAttribute("TANGENT", BABYLON.VertexBuffer.TangentKind, function (babylonVertexBuffer, data) {
+                    var dataIndex = 0;
+                    babylonVertexBuffer.forEach(data.length, function (value, index) {
                         // Tangent data for morph targets is stored as xyz delta.
                         // The vertexData.tangent is stored as xyzw.
                         // So we need to skip every fourth vertexData.tangent.
-                        for (var i = 0, j = 0; i < data.length; i++) {
-                            data[i] += babylonVertexData.tangents[j++];
-                            if ((i + 1) % 3 == 0) {
-                                j++;
-                            }
+                        if (((index + 1) % 4) !== 0) {
+                            data[dataIndex++] += value;
                         }
-                        babylonMorphTarget.setTangents(data);
-                    }
+                    });
+                    babylonMorphTarget.setTangents(data);
                 });
                 return Promise.all(promises).then(function () { });
             };
-            GLTFLoader._ConvertToFloat32Array = function (context, accessor, data) {
-                if (accessor.componentType == 5126 /* FLOAT */) {
-                    return data;
-                }
-                var factor = 1;
-                if (accessor.normalized) {
-                    switch (accessor.componentType) {
-                        case 5121 /* UNSIGNED_BYTE */: {
-                            factor = 1 / 255;
-                            break;
-                        }
-                        case 5123 /* UNSIGNED_SHORT */: {
-                            factor = 1 / 65535;
-                            break;
-                        }
-                        default: {
-                            throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
-                        }
-                    }
-                }
-                var result = new Float32Array(accessor.count * GLTFLoader._GetNumComponents(context, accessor.type));
-                for (var i = 0; i < result.length; i++) {
-                    result[i] = data[i] * factor;
-                }
-                return result;
-            };
-            GLTFLoader._ConvertVec3ToVec4 = function (context, data) {
-                var result = new Float32Array(data.length / 3 * 4);
-                var offset = 0;
-                for (var i = 0; i < result.length; i++) {
-                    if ((i + 1) % 4 === 0) {
-                        result[i] = 1;
-                    }
-                    else {
-                        result[i] = data[offset++];
-                    }
-                }
-                return result;
-            };
             GLTFLoader._LoadTransform = function (node, babylonNode) {
                 var position = BABYLON.Vector3.Zero();
                 var rotation = BABYLON.Quaternion.Identity();
@@ -3649,9 +3604,9 @@ var BABYLON;
                     return bufferView._data;
                 }
                 var buffer = GLTFLoader._GetProperty(context + "/buffer", this._gltf.buffers, bufferView.buffer);
-                bufferView._data = this._loadBufferAsync("#/buffers/" + buffer._index, buffer).then(function (bufferData) {
+                bufferView._data = this._loadBufferAsync("#/buffers/" + buffer._index, buffer).then(function (data) {
                     try {
-                        return new Uint8Array(bufferData.buffer, bufferData.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
+                        return new Uint8Array(data.buffer, data.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
                     }
                     catch (e) {
                         throw new Error(context + ": " + e.message);
@@ -3660,7 +3615,6 @@ var BABYLON;
                 return bufferView._data;
             };
             GLTFLoader.prototype._loadAccessorAsync = function (context, accessor) {
-                var _this = this;
                 if (accessor.sparse) {
                     throw new Error(context + ": Sparse accessors are not currently supported");
                 }
@@ -3668,63 +3622,65 @@ var BABYLON;
                     return accessor._data;
                 }
                 var bufferView = GLTFLoader._GetProperty(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
-                accessor._data = this._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(function (bufferViewData) {
-                    var numComponents = GLTFLoader._GetNumComponents(context, accessor.type);
-                    var byteOffset = accessor.byteOffset || 0;
-                    var byteStride = bufferView.byteStride;
-                    if (byteStride === 0) {
-                        BABYLON.Tools.Warn(context + ": Byte stride of 0 is not valid");
-                    }
+                accessor._data = this._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(function (data) {
+                    var buffer = data.buffer;
+                    var byteOffset = data.byteOffset + (accessor.byteOffset || 0);
+                    var length = GLTFLoader._GetNumComponents(context, accessor.type) * accessor.count;
                     try {
                         switch (accessor.componentType) {
                             case 5120 /* BYTE */: {
-                                return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Int8Array(buffer, byteOffset, length);
                             }
                             case 5121 /* UNSIGNED_BYTE */: {
-                                return _this._buildArrayBuffer(Uint8Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Uint8Array(buffer, byteOffset, length);
                             }
                             case 5122 /* SHORT */: {
-                                return _this._buildArrayBuffer(Int16Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Int16Array(buffer, byteOffset, length);
                             }
                             case 5123 /* UNSIGNED_SHORT */: {
-                                return _this._buildArrayBuffer(Uint16Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Uint16Array(buffer, byteOffset, length);
                             }
                             case 5125 /* UNSIGNED_INT */: {
-                                return _this._buildArrayBuffer(Uint32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Uint32Array(buffer, byteOffset, length);
                             }
                             case 5126 /* FLOAT */: {
-                                return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Float32Array(buffer, byteOffset, length);
                             }
                             default: {
-                                throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
+                                throw new Error(context + ": Invalid accessor component type " + accessor.componentType);
                             }
                         }
                     }
                     catch (e) {
-                        throw new Error(context + ": " + e.messsage);
+                        throw new Error(context + ": " + e);
                     }
                 });
                 return accessor._data;
             };
-            GLTFLoader.prototype._buildArrayBuffer = function (typedArray, data, byteOffset, count, numComponents, byteStride) {
-                byteOffset += data.byteOffset;
-                var targetLength = count * numComponents;
-                if (!byteStride || byteStride === numComponents * typedArray.BYTES_PER_ELEMENT) {
-                    return new typedArray(data.buffer, byteOffset, targetLength);
+            GLTFLoader.prototype._loadVertexBufferViewAsync = function (context, bufferView, kind) {
+                var _this = this;
+                if (bufferView._babylonBuffer) {
+                    return bufferView._babylonBuffer;
                 }
-                var elementStride = byteStride / typedArray.BYTES_PER_ELEMENT;
-                var sourceBuffer = new typedArray(data.buffer, byteOffset, elementStride * count);
-                var targetBuffer = new typedArray(targetLength);
-                var sourceIndex = 0;
-                var targetIndex = 0;
-                while (targetIndex < targetLength) {
-                    for (var componentIndex = 0; componentIndex < numComponents; componentIndex++) {
-                        targetBuffer[targetIndex] = sourceBuffer[sourceIndex + componentIndex];
-                        targetIndex++;
-                    }
-                    sourceIndex += elementStride;
+                bufferView._babylonBuffer = this._loadBufferViewAsync(context, bufferView).then(function (data) {
+                    return new BABYLON.Buffer(_this._babylonScene.getEngine(), data, false);
+                });
+                return bufferView._babylonBuffer;
+            };
+            GLTFLoader.prototype._loadVertexAccessorAsync = function (context, accessor, kind) {
+                var _this = this;
+                if (accessor.sparse) {
+                    throw new Error(context + ": Sparse accessors are not currently supported");
+                }
+                if (accessor._babylonVertexBuffer) {
+                    return accessor._babylonVertexBuffer;
                 }
-                return targetBuffer;
+                var bufferView = GLTFLoader._GetProperty(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
+                accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView, kind).then(function (buffer) {
+                    var size = GLTFLoader._GetNumComponents(context, accessor.type);
+                    return new BABYLON.VertexBuffer(_this._babylonScene.getEngine(), buffer, kind, false, false, bufferView.byteStride, false, accessor.byteOffset, size, accessor.componentType, accessor.normalized, true);
+                });
+                return accessor._babylonVertexBuffer;
             };
             GLTFLoader.prototype._getDefaultMaterial = function (drawMode) {
                 var babylonMaterial = this._defaultBabylonMaterials[drawMode];
@@ -4472,7 +4428,11 @@ var BABYLON;
                                 if (!_this._dracoCompression) {
                                     _this._dracoCompression = new BABYLON.DracoCompression();
                                 }
-                                return _this._dracoCompression.decodeMeshAsync(data, attributes);
+                                return _this._dracoCompression.decodeMeshAsync(data, attributes).then(function (babylonVertexData) {
+                                    var babylonGeometry = new BABYLON.Geometry(babylonMesh.name, _this._loader._babylonScene);
+                                    babylonVertexData.applyToGeometry(babylonGeometry);
+                                    return babylonGeometry;
+                                });
                             }
                             catch (e) {
                                 throw new Error(context + ": " + e.message);

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 3 - 3
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 91 - 131
dist/preview release/loaders/babylonjs.loaders.js

@@ -4123,9 +4123,10 @@ var BABYLON;
                 var _this = this;
                 var promises = new Array();
                 this._createMorphTargets(context, node, mesh, primitive, babylonMesh);
-                promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonVertexData) {
-                    new BABYLON.Geometry(babylonMesh.name, _this._babylonScene, babylonVertexData, false, babylonMesh);
-                    return _this._loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);
+                promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonGeometry) {
+                    return _this._loadMorphTargetsAsync(context, primitive, babylonMesh, babylonGeometry).then(function () {
+                        babylonGeometry.applyToMesh(babylonMesh);
+                    });
                 }));
                 var babylonDrawMode = GLTFLoader._GetDrawMode(context, primitive.mode);
                 if (primitive.material == undefined) {
@@ -4150,24 +4151,17 @@ var BABYLON;
                     throw new Error(context + ": Attributes are missing");
                 }
                 var promises = new Array();
-                var babylonVertexData = new BABYLON.VertexData();
+                var babylonGeometry = new BABYLON.Geometry(babylonMesh.name, this._babylonScene);
                 if (primitive.indices == undefined) {
-                    var positionAccessorIndex = attributes["POSITION"];
-                    if (positionAccessorIndex != undefined) {
-                        var accessor = GLTFLoader._GetProperty(context + "/attributes/POSITION", this._gltf.accessors, positionAccessorIndex);
-                        babylonVertexData.indices = new Uint32Array(accessor.count);
-                        for (var i = 0; i < babylonVertexData.indices.length; i++) {
-                            babylonVertexData.indices[i] = i;
-                        }
-                    }
+                    babylonMesh.isUnIndexed = true;
                 }
                 else {
-                    var indicesAccessor = GLTFLoader._GetProperty(context + "/indices", this._gltf.accessors, primitive.indices);
-                    promises.push(this._loadAccessorAsync("#/accessors/" + indicesAccessor._index, indicesAccessor).then(function (data) {
-                        babylonVertexData.indices = data;
+                    var accessor = GLTFLoader._GetProperty(context + "/indices", this._gltf.accessors, primitive.indices);
+                    promises.push(this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
+                        babylonGeometry.setIndices(data);
                     }));
                 }
-                var loadAttribute = function (attribute, kind) {
+                var loadAttribute = function (attribute, kind, callback) {
                     if (attributes[attribute] == undefined) {
                         return;
                     }
@@ -4175,18 +4169,13 @@ var BABYLON;
                     if (babylonMesh._delayInfo.indexOf(kind) === -1) {
                         babylonMesh._delayInfo.push(kind);
                     }
-                    if (attribute === "COLOR_0") {
-                        // Assume vertex color has alpha on the mesh. The alphaMode of the material controls whether the material should use alpha or not.
-                        babylonMesh.hasVertexAlpha = true;
-                    }
                     var accessor = GLTFLoader._GetProperty(context + "/attributes/" + attribute, _this._gltf.accessors, attributes[attribute]);
-                    promises.push(_this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
-                        var attributeData = GLTFLoader._ConvertToFloat32Array(context, accessor, data);
-                        if (attribute === "COLOR_0" && accessor.type === "VEC3") {
-                            attributeData = GLTFLoader._ConvertVec3ToVec4(context, attributeData);
-                        }
-                        babylonVertexData.set(attributeData, kind);
+                    promises.push(_this._loadVertexAccessorAsync("#/accessors/" + accessor._index, accessor, kind).then(function (babylonVertexBuffer) {
+                        babylonGeometry.setVerticesBuffer(babylonVertexBuffer, accessor.count);
                     }));
+                    if (callback) {
+                        callback(accessor);
+                    }
                 };
                 loadAttribute("POSITION", BABYLON.VertexBuffer.PositionKind);
                 loadAttribute("NORMAL", BABYLON.VertexBuffer.NormalKind);
@@ -4195,9 +4184,13 @@ var BABYLON;
                 loadAttribute("TEXCOORD_1", BABYLON.VertexBuffer.UV2Kind);
                 loadAttribute("JOINTS_0", BABYLON.VertexBuffer.MatricesIndicesKind);
                 loadAttribute("WEIGHTS_0", BABYLON.VertexBuffer.MatricesWeightsKind);
-                loadAttribute("COLOR_0", BABYLON.VertexBuffer.ColorKind);
+                loadAttribute("COLOR_0", BABYLON.VertexBuffer.ColorKind, function (accessor) {
+                    if (accessor.type === "VEC4" /* VEC4 */) {
+                        babylonMesh.hasVertexAlpha = true;
+                    }
+                });
                 return Promise.all(promises).then(function () {
-                    return babylonVertexData;
+                    return babylonGeometry;
                 });
             };
             GLTFLoader.prototype._createMorphTargets = function (context, node, mesh, primitive, babylonMesh) {
@@ -4217,7 +4210,7 @@ var BABYLON;
                     // TODO: tell the target whether it has positions, normals, tangents
                 }
             };
-            GLTFLoader.prototype._loadMorphTargetsAsync = function (context, primitive, babylonMesh, babylonVertexData) {
+            GLTFLoader.prototype._loadMorphTargetsAsync = function (context, primitive, babylonMesh, babylonGeometry) {
                 if (!primitive.targets) {
                     return Promise.resolve();
                 }
@@ -4225,93 +4218,55 @@ var BABYLON;
                 var morphTargetManager = babylonMesh.morphTargetManager;
                 for (var index = 0; index < morphTargetManager.numTargets; index++) {
                     var babylonMorphTarget = morphTargetManager.getTarget(index);
-                    promises.push(this._loadMorphTargetVertexDataAsync(context + "/targets/" + index, babylonVertexData, primitive.targets[index], babylonMorphTarget));
+                    promises.push(this._loadMorphTargetVertexDataAsync(context + "/targets/" + index, babylonGeometry, primitive.targets[index], babylonMorphTarget));
                 }
                 return Promise.all(promises).then(function () { });
             };
-            GLTFLoader.prototype._loadMorphTargetVertexDataAsync = function (context, babylonVertexData, attributes, babylonMorphTarget) {
+            GLTFLoader.prototype._loadMorphTargetVertexDataAsync = function (context, babylonGeometry, attributes, babylonMorphTarget) {
                 var _this = this;
                 var promises = new Array();
-                var loadAttribute = function (attribute, setData) {
+                var loadAttribute = function (attribute, kind, setData) {
                     if (attributes[attribute] == undefined) {
                         return;
                     }
+                    var babylonVertexBuffer = babylonGeometry.getVertexBuffer(kind);
+                    if (!babylonVertexBuffer) {
+                        return;
+                    }
                     var accessor = GLTFLoader._GetProperty(context + "/" + attribute, _this._gltf.accessors, attributes[attribute]);
                     promises.push(_this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
-                        setData(data);
+                        if (!(data instanceof Float32Array)) {
+                            throw new Error(context + ": Morph target accessor must have float data");
+                        }
+                        setData(babylonVertexBuffer, data);
                     }));
                 };
-                loadAttribute("POSITION", function (data) {
-                    if (babylonVertexData.positions) {
-                        for (var i = 0; i < data.length; i++) {
-                            data[i] += babylonVertexData.positions[i];
-                        }
-                        babylonMorphTarget.setPositions(data);
-                    }
+                loadAttribute("POSITION", BABYLON.VertexBuffer.PositionKind, function (babylonVertexBuffer, data) {
+                    babylonVertexBuffer.forEach(data.length, function (value, index) {
+                        data[index] += value;
+                    });
+                    babylonMorphTarget.setPositions(data);
                 });
-                loadAttribute("NORMAL", function (data) {
-                    if (babylonVertexData.normals) {
-                        for (var i = 0; i < data.length; i++) {
-                            data[i] += babylonVertexData.normals[i];
-                        }
-                        babylonMorphTarget.setNormals(data);
-                    }
+                loadAttribute("NORMAL", BABYLON.VertexBuffer.NormalKind, function (babylonVertexBuffer, data) {
+                    babylonVertexBuffer.forEach(data.length, function (value, index) {
+                        data[index] += value;
+                    });
+                    babylonMorphTarget.setNormals(data);
                 });
-                loadAttribute("TANGENT", function (data) {
-                    if (babylonVertexData.tangents) {
+                loadAttribute("TANGENT", BABYLON.VertexBuffer.TangentKind, function (babylonVertexBuffer, data) {
+                    var dataIndex = 0;
+                    babylonVertexBuffer.forEach(data.length, function (value, index) {
                         // Tangent data for morph targets is stored as xyz delta.
                         // The vertexData.tangent is stored as xyzw.
                         // So we need to skip every fourth vertexData.tangent.
-                        for (var i = 0, j = 0; i < data.length; i++) {
-                            data[i] += babylonVertexData.tangents[j++];
-                            if ((i + 1) % 3 == 0) {
-                                j++;
-                            }
+                        if (((index + 1) % 4) !== 0) {
+                            data[dataIndex++] += value;
                         }
-                        babylonMorphTarget.setTangents(data);
-                    }
+                    });
+                    babylonMorphTarget.setTangents(data);
                 });
                 return Promise.all(promises).then(function () { });
             };
-            GLTFLoader._ConvertToFloat32Array = function (context, accessor, data) {
-                if (accessor.componentType == 5126 /* FLOAT */) {
-                    return data;
-                }
-                var factor = 1;
-                if (accessor.normalized) {
-                    switch (accessor.componentType) {
-                        case 5121 /* UNSIGNED_BYTE */: {
-                            factor = 1 / 255;
-                            break;
-                        }
-                        case 5123 /* UNSIGNED_SHORT */: {
-                            factor = 1 / 65535;
-                            break;
-                        }
-                        default: {
-                            throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
-                        }
-                    }
-                }
-                var result = new Float32Array(accessor.count * GLTFLoader._GetNumComponents(context, accessor.type));
-                for (var i = 0; i < result.length; i++) {
-                    result[i] = data[i] * factor;
-                }
-                return result;
-            };
-            GLTFLoader._ConvertVec3ToVec4 = function (context, data) {
-                var result = new Float32Array(data.length / 3 * 4);
-                var offset = 0;
-                for (var i = 0; i < result.length; i++) {
-                    if ((i + 1) % 4 === 0) {
-                        result[i] = 1;
-                    }
-                    else {
-                        result[i] = data[offset++];
-                    }
-                }
-                return result;
-            };
             GLTFLoader._LoadTransform = function (node, babylonNode) {
                 var position = BABYLON.Vector3.Zero();
                 var rotation = BABYLON.Quaternion.Identity();
@@ -4628,9 +4583,9 @@ var BABYLON;
                     return bufferView._data;
                 }
                 var buffer = GLTFLoader._GetProperty(context + "/buffer", this._gltf.buffers, bufferView.buffer);
-                bufferView._data = this._loadBufferAsync("#/buffers/" + buffer._index, buffer).then(function (bufferData) {
+                bufferView._data = this._loadBufferAsync("#/buffers/" + buffer._index, buffer).then(function (data) {
                     try {
-                        return new Uint8Array(bufferData.buffer, bufferData.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
+                        return new Uint8Array(data.buffer, data.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
                     }
                     catch (e) {
                         throw new Error(context + ": " + e.message);
@@ -4639,7 +4594,6 @@ var BABYLON;
                 return bufferView._data;
             };
             GLTFLoader.prototype._loadAccessorAsync = function (context, accessor) {
-                var _this = this;
                 if (accessor.sparse) {
                     throw new Error(context + ": Sparse accessors are not currently supported");
                 }
@@ -4647,63 +4601,65 @@ var BABYLON;
                     return accessor._data;
                 }
                 var bufferView = GLTFLoader._GetProperty(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
-                accessor._data = this._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(function (bufferViewData) {
-                    var numComponents = GLTFLoader._GetNumComponents(context, accessor.type);
-                    var byteOffset = accessor.byteOffset || 0;
-                    var byteStride = bufferView.byteStride;
-                    if (byteStride === 0) {
-                        BABYLON.Tools.Warn(context + ": Byte stride of 0 is not valid");
-                    }
+                accessor._data = this._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(function (data) {
+                    var buffer = data.buffer;
+                    var byteOffset = data.byteOffset + (accessor.byteOffset || 0);
+                    var length = GLTFLoader._GetNumComponents(context, accessor.type) * accessor.count;
                     try {
                         switch (accessor.componentType) {
                             case 5120 /* BYTE */: {
-                                return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Int8Array(buffer, byteOffset, length);
                             }
                             case 5121 /* UNSIGNED_BYTE */: {
-                                return _this._buildArrayBuffer(Uint8Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Uint8Array(buffer, byteOffset, length);
                             }
                             case 5122 /* SHORT */: {
-                                return _this._buildArrayBuffer(Int16Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Int16Array(buffer, byteOffset, length);
                             }
                             case 5123 /* UNSIGNED_SHORT */: {
-                                return _this._buildArrayBuffer(Uint16Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Uint16Array(buffer, byteOffset, length);
                             }
                             case 5125 /* UNSIGNED_INT */: {
-                                return _this._buildArrayBuffer(Uint32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Uint32Array(buffer, byteOffset, length);
                             }
                             case 5126 /* FLOAT */: {
-                                return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Float32Array(buffer, byteOffset, length);
                             }
                             default: {
-                                throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
+                                throw new Error(context + ": Invalid accessor component type " + accessor.componentType);
                             }
                         }
                     }
                     catch (e) {
-                        throw new Error(context + ": " + e.messsage);
+                        throw new Error(context + ": " + e);
                     }
                 });
                 return accessor._data;
             };
-            GLTFLoader.prototype._buildArrayBuffer = function (typedArray, data, byteOffset, count, numComponents, byteStride) {
-                byteOffset += data.byteOffset;
-                var targetLength = count * numComponents;
-                if (!byteStride || byteStride === numComponents * typedArray.BYTES_PER_ELEMENT) {
-                    return new typedArray(data.buffer, byteOffset, targetLength);
+            GLTFLoader.prototype._loadVertexBufferViewAsync = function (context, bufferView, kind) {
+                var _this = this;
+                if (bufferView._babylonBuffer) {
+                    return bufferView._babylonBuffer;
                 }
-                var elementStride = byteStride / typedArray.BYTES_PER_ELEMENT;
-                var sourceBuffer = new typedArray(data.buffer, byteOffset, elementStride * count);
-                var targetBuffer = new typedArray(targetLength);
-                var sourceIndex = 0;
-                var targetIndex = 0;
-                while (targetIndex < targetLength) {
-                    for (var componentIndex = 0; componentIndex < numComponents; componentIndex++) {
-                        targetBuffer[targetIndex] = sourceBuffer[sourceIndex + componentIndex];
-                        targetIndex++;
-                    }
-                    sourceIndex += elementStride;
+                bufferView._babylonBuffer = this._loadBufferViewAsync(context, bufferView).then(function (data) {
+                    return new BABYLON.Buffer(_this._babylonScene.getEngine(), data, false);
+                });
+                return bufferView._babylonBuffer;
+            };
+            GLTFLoader.prototype._loadVertexAccessorAsync = function (context, accessor, kind) {
+                var _this = this;
+                if (accessor.sparse) {
+                    throw new Error(context + ": Sparse accessors are not currently supported");
+                }
+                if (accessor._babylonVertexBuffer) {
+                    return accessor._babylonVertexBuffer;
                 }
-                return targetBuffer;
+                var bufferView = GLTFLoader._GetProperty(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
+                accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView, kind).then(function (buffer) {
+                    var size = GLTFLoader._GetNumComponents(context, accessor.type);
+                    return new BABYLON.VertexBuffer(_this._babylonScene.getEngine(), buffer, kind, false, false, bufferView.byteStride, false, accessor.byteOffset, size, accessor.componentType, accessor.normalized, true);
+                });
+                return accessor._babylonVertexBuffer;
             };
             GLTFLoader.prototype._getDefaultMaterial = function (drawMode) {
                 var babylonMaterial = this._defaultBabylonMaterials[drawMode];
@@ -5433,7 +5389,11 @@ var BABYLON;
                                 if (!_this._dracoCompression) {
                                     _this._dracoCompression = new BABYLON.DracoCompression();
                                 }
-                                return _this._dracoCompression.decodeMeshAsync(data, attributes);
+                                return _this._dracoCompression.decodeMeshAsync(data, attributes).then(function (babylonVertexData) {
+                                    var babylonGeometry = new BABYLON.Geometry(babylonMesh.name, _this._loader._babylonScene);
+                                    babylonVertexData.applyToGeometry(babylonGeometry);
+                                    return babylonGeometry;
+                                });
                             }
                             catch (e) {
                                 throw new Error(context + ": " + e.message);

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 2 - 2
dist/preview release/loaders/babylonjs.loaders.min.js


+ 10 - 12
dist/preview release/loaders/babylonjs.loaders.module.d.ts

@@ -832,9 +832,6 @@ declare module BABYLON.GLTF1 {
 
 
 declare module BABYLON.GLTF2 {
-    interface TypedArray extends ArrayBufferView {
-        [index: number]: number;
-    }
     interface IArrayItem {
         _index: number;
     }
@@ -854,7 +851,8 @@ declare module BABYLON.GLTF2 {
 
 declare module BABYLON.GLTF2 {
     interface ILoaderAccessor extends IAccessor, IArrayItem {
-        _data?: Promise<TypedArray>;
+        _data?: Promise<ArrayBufferView>;
+        _babylonVertexBuffer?: Promise<VertexBuffer>;
     }
     interface ILoaderAnimationChannel extends IAnimationChannel, IArrayItem {
     }
@@ -876,6 +874,7 @@ declare module BABYLON.GLTF2 {
     }
     interface ILoaderBufferView extends IBufferView, IArrayItem {
         _data?: Promise<ArrayBufferView>;
+        _babylonBuffer?: Promise<Buffer>;
     }
     interface ILoaderCamera extends ICamera, IArrayItem {
     }
@@ -997,10 +996,8 @@ declare module BABYLON.GLTF2 {
         private _loadPrimitiveAsync(context, node, mesh, primitive, babylonMesh);
         private _loadVertexDataAsync(context, primitive, babylonMesh);
         private _createMorphTargets(context, node, mesh, primitive, babylonMesh);
-        private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);
-        private _loadMorphTargetVertexDataAsync(context, babylonVertexData, attributes, babylonMorphTarget);
-        private static _ConvertToFloat32Array(context, accessor, data);
-        private static _ConvertVec3ToVec4(context, data);
+        private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonGeometry);
+        private _loadMorphTargetVertexDataAsync(context, babylonGeometry, attributes, babylonMorphTarget);
         private static _LoadTransform(node, babylonNode);
         private _loadSkinAsync(context, node, mesh, skin);
         private _loadSkinInverseBindMatricesDataAsync(context, skin);
@@ -1015,7 +1012,8 @@ declare module BABYLON.GLTF2 {
         private _loadBufferAsync(context, buffer);
         _loadBufferViewAsync(context: string, bufferView: ILoaderBufferView): Promise<ArrayBufferView>;
         private _loadAccessorAsync(context, accessor);
-        private _buildArrayBuffer<T>(typedArray, data, byteOffset, count, numComponents, byteStride?);
+        _loadVertexBufferViewAsync(context: string, bufferView: ILoaderBufferView, kind: string): Promise<Buffer>;
+        private _loadVertexAccessorAsync(context, accessor, kind);
         private _getDefaultMaterial(drawMode);
         private _loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial);
         _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void>;
@@ -1053,7 +1051,7 @@ declare module BABYLON.GLTF2 {
         /** Override this method to modify the default behavior for loading nodes. */
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>>;
         /** Override this method to modify the default behavior for loading mesh primitive vertex data. */
-        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>>;
+        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         /** Override this method to modify the default behavior for loading materials. */
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         /** Override this method to modify the default behavior for loading uris. */
@@ -1065,7 +1063,7 @@ declare module BABYLON.GLTF2 {
         /** Helper method called by the loader to allow extensions to override loading nodes. */
         static _LoadNodeAsync(loader: GLTFLoader, context: string, node: ILoaderNode): Nullable<Promise<void>>;
         /** Helper method called by the loader to allow extensions to override loading mesh primitive vertex data. */
-        static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>>;
+        static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         /** Helper method called by the loader to allow extensions to override loading materials. */
         static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         /** Helper method called by the loader to allow extensions to override loading uris. */
@@ -1102,7 +1100,7 @@ declare module BABYLON.GLTF2.Extensions {
         private _dracoCompression;
         constructor(loader: GLTFLoader);
         dispose(): void;
-        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>>;
+        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
     }
 }
 

+ 1 - 2
dist/preview release/serializers/babylon.glTF2Serializer.d.ts

@@ -170,12 +170,11 @@ declare module BABYLON.GLTF2 {
          * Returns the bytelength of the data.
          * @param vertexBufferKind - Indicates what kind of vertex data is being passed in.
          * @param meshAttributeArray - Array containing the attribute data.
-         * @param strideSize - Represents the offset between consecutive attributes
          * @param byteOffset - The offset to start counting bytes from.
          * @param dataBuffer - The buffer to write the binary data to.
          * @returns - Byte length of the attribute data.
          */
-        private writeAttributeData(vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer);
+        private writeAttributeData(vertexBufferKind, meshAttributeArray, byteOffset, dataBuffer);
         /**
          * Generates glTF json data
          * @param shouldUseGlb - Indicates whether the json should be written for a glb file.

+ 59 - 75
dist/preview release/serializers/babylon.glTF2Serializer.js

@@ -193,17 +193,17 @@ var BABYLON;
              * Returns the bytelength of the data.
              * @param vertexBufferKind - Indicates what kind of vertex data is being passed in.
              * @param meshAttributeArray - Array containing the attribute data.
-             * @param strideSize - Represents the offset between consecutive attributes
              * @param byteOffset - The offset to start counting bytes from.
              * @param dataBuffer - The buffer to write the binary data to.
              * @returns - Byte length of the attribute data.
              */
-            _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer) {
+            _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, byteOffset, dataBuffer) {
                 var byteOff = byteOffset;
-                var end = meshAttributeArray.length / strideSize;
+                var stride = BABYLON.VertexBuffer.DeduceStride(vertexBufferKind);
+                var end = meshAttributeArray.length / stride;
                 var byteLength = 0;
                 for (var k = 0; k < end; ++k) {
-                    var index = k * strideSize;
+                    var index = k * stride;
                     var vector = [];
                     if (vertexBufferKind === BABYLON.VertexBuffer.PositionKind || vertexBufferKind === BABYLON.VertexBuffer.NormalKind) {
                         var vertexData = BABYLON.Vector3.FromArray(meshAttributeArray, index);
@@ -445,28 +445,17 @@ var BABYLON;
                     bufferMesh = babylonMesh.sourceMesh;
                 }
                 if (bufferMesh) {
-                    var vertexBuffer = null;
-                    var vertexBufferOffset = null;
-                    var vertexData = null;
-                    var vertexStrideSize = null;
-                    if (bufferMesh.isVerticesDataPresent(kind)) {
-                        vertexBuffer = bufferMesh.getVertexBuffer(kind);
-                        if (vertexBuffer) {
-                            vertexBufferOffset = vertexBuffer.getOffset();
-                            vertexData = vertexBuffer.getData();
-                            if (vertexData) {
-                                vertexStrideSize = vertexBuffer.getStrideSize();
-                                if (dataBuffer && vertexData) {
-                                    byteLength = this.writeAttributeData(kind, vertexData, vertexStrideSize, vertexBufferOffset, byteOffset, dataBuffer);
-                                    byteOffset += byteLength;
-                                }
-                                else {
-                                    byteLength = vertexData.length * 4;
-                                    var bufferView = this.createBufferView(0, byteOffset, byteLength, vertexStrideSize * 4, kind + " - " + bufferMesh.name);
-                                    byteOffset += byteLength;
-                                    this.bufferViews.push(bufferView);
-                                }
-                            }
+                    var vertexData = bufferMesh.getVerticesData(kind);
+                    if (vertexData) {
+                        if (dataBuffer && vertexData) {
+                            byteLength = this.writeAttributeData(kind, vertexData, byteOffset, dataBuffer);
+                            byteOffset += byteLength;
+                        }
+                        else {
+                            byteLength = vertexData.length * 4;
+                            var bufferView = this.createBufferView(0, byteOffset, byteLength, undefined, kind + " - " + bufferMesh.name);
+                            byteOffset += byteLength;
+                            this.bufferViews.push(bufferView);
                         }
                     }
                 }
@@ -539,55 +528,50 @@ var BABYLON;
                                 for (var _c = 0, attributeData_2 = attributeData; _c < attributeData_2.length; _c++) {
                                     var attribute = attributeData_2[_c];
                                     var attributeKind = attribute.kind;
-                                    if (bufferMesh.isVerticesDataPresent(attributeKind)) {
-                                        var vertexBuffer = bufferMesh.getVertexBuffer(attributeKind);
-                                        if (vertexBuffer) {
-                                            var bufferData = vertexBuffer.getData();
-                                            if (bufferData) {
-                                                var strideSize = vertexBuffer.getStrideSize();
-                                                var minMax = void 0;
-                                                var min = null;
-                                                var max = null;
-                                                var bufferViewIndex = attribute.bufferViewIndex;
-                                                if (bufferViewIndex != undefined) {
-                                                    if (attributeKind == BABYLON.VertexBuffer.PositionKind) {
-                                                        minMax = this.calculateMinMaxPositions(bufferData, 0, bufferData.length / strideSize);
-                                                        min = minMax.min;
-                                                        max = minMax.max;
-                                                    }
-                                                    var accessor = this.createAccessor(bufferViewIndex, attributeKind + " - " + babylonMesh.name, attribute.accessorType, 5126 /* FLOAT */, bufferData.length / strideSize, 0, min, max);
-                                                    this.accessors.push(accessor);
-                                                    switch (attributeKind) {
-                                                        case BABYLON.VertexBuffer.PositionKind: {
-                                                            meshPrimitive.attributes.POSITION = this.accessors.length - 1;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.NormalKind: {
-                                                            meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.ColorKind: {
-                                                            meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.TangentKind: {
-                                                            meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.UVKind: {
-                                                            meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
-                                                            uvCoordsPresent = true;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.UV2Kind: {
-                                                            meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
-                                                            uvCoordsPresent = true;
-                                                            break;
-                                                        }
-                                                        default: {
-                                                            BABYLON.Tools.Warn("Unsupported Vertex Buffer Type: " + attributeKind);
-                                                        }
-                                                    }
+                                    var vertexData = bufferMesh.getVerticesData(attributeKind);
+                                    if (vertexData) {
+                                        var stride = BABYLON.VertexBuffer.DeduceStride(attributeKind);
+                                        var minMax = void 0;
+                                        var min = null;
+                                        var max = null;
+                                        var bufferViewIndex = attribute.bufferViewIndex;
+                                        if (bufferViewIndex != undefined) {
+                                            if (attributeKind == BABYLON.VertexBuffer.PositionKind) {
+                                                minMax = this.calculateMinMaxPositions(vertexData, 0, vertexData.length / stride);
+                                                min = minMax.min;
+                                                max = minMax.max;
+                                            }
+                                            var accessor = this.createAccessor(bufferViewIndex, attributeKind + " - " + babylonMesh.name, attribute.accessorType, 5126 /* FLOAT */, vertexData.length / stride, 0, min, max);
+                                            this.accessors.push(accessor);
+                                            switch (attributeKind) {
+                                                case BABYLON.VertexBuffer.PositionKind: {
+                                                    meshPrimitive.attributes.POSITION = this.accessors.length - 1;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.NormalKind: {
+                                                    meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.ColorKind: {
+                                                    meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.TangentKind: {
+                                                    meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.UVKind: {
+                                                    meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
+                                                    uvCoordsPresent = true;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.UV2Kind: {
+                                                    meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
+                                                    uvCoordsPresent = true;
+                                                    break;
+                                                }
+                                                default: {
+                                                    BABYLON.Tools.Warn("Unsupported Vertex Buffer Type: " + attributeKind);
                                                 }
                                             }
                                         }

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/serializers/babylon.glTF2Serializer.min.js


+ 59 - 75
dist/preview release/serializers/babylonjs.serializers.js

@@ -344,17 +344,17 @@ var BABYLON;
              * Returns the bytelength of the data.
              * @param vertexBufferKind - Indicates what kind of vertex data is being passed in.
              * @param meshAttributeArray - Array containing the attribute data.
-             * @param strideSize - Represents the offset between consecutive attributes
              * @param byteOffset - The offset to start counting bytes from.
              * @param dataBuffer - The buffer to write the binary data to.
              * @returns - Byte length of the attribute data.
              */
-            _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer) {
+            _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, byteOffset, dataBuffer) {
                 var byteOff = byteOffset;
-                var end = meshAttributeArray.length / strideSize;
+                var stride = BABYLON.VertexBuffer.DeduceStride(vertexBufferKind);
+                var end = meshAttributeArray.length / stride;
                 var byteLength = 0;
                 for (var k = 0; k < end; ++k) {
-                    var index = k * strideSize;
+                    var index = k * stride;
                     var vector = [];
                     if (vertexBufferKind === BABYLON.VertexBuffer.PositionKind || vertexBufferKind === BABYLON.VertexBuffer.NormalKind) {
                         var vertexData = BABYLON.Vector3.FromArray(meshAttributeArray, index);
@@ -596,28 +596,17 @@ var BABYLON;
                     bufferMesh = babylonMesh.sourceMesh;
                 }
                 if (bufferMesh) {
-                    var vertexBuffer = null;
-                    var vertexBufferOffset = null;
-                    var vertexData = null;
-                    var vertexStrideSize = null;
-                    if (bufferMesh.isVerticesDataPresent(kind)) {
-                        vertexBuffer = bufferMesh.getVertexBuffer(kind);
-                        if (vertexBuffer) {
-                            vertexBufferOffset = vertexBuffer.getOffset();
-                            vertexData = vertexBuffer.getData();
-                            if (vertexData) {
-                                vertexStrideSize = vertexBuffer.getStrideSize();
-                                if (dataBuffer && vertexData) {
-                                    byteLength = this.writeAttributeData(kind, vertexData, vertexStrideSize, vertexBufferOffset, byteOffset, dataBuffer);
-                                    byteOffset += byteLength;
-                                }
-                                else {
-                                    byteLength = vertexData.length * 4;
-                                    var bufferView = this.createBufferView(0, byteOffset, byteLength, vertexStrideSize * 4, kind + " - " + bufferMesh.name);
-                                    byteOffset += byteLength;
-                                    this.bufferViews.push(bufferView);
-                                }
-                            }
+                    var vertexData = bufferMesh.getVerticesData(kind);
+                    if (vertexData) {
+                        if (dataBuffer && vertexData) {
+                            byteLength = this.writeAttributeData(kind, vertexData, byteOffset, dataBuffer);
+                            byteOffset += byteLength;
+                        }
+                        else {
+                            byteLength = vertexData.length * 4;
+                            var bufferView = this.createBufferView(0, byteOffset, byteLength, undefined, kind + " - " + bufferMesh.name);
+                            byteOffset += byteLength;
+                            this.bufferViews.push(bufferView);
                         }
                     }
                 }
@@ -690,55 +679,50 @@ var BABYLON;
                                 for (var _c = 0, attributeData_2 = attributeData; _c < attributeData_2.length; _c++) {
                                     var attribute = attributeData_2[_c];
                                     var attributeKind = attribute.kind;
-                                    if (bufferMesh.isVerticesDataPresent(attributeKind)) {
-                                        var vertexBuffer = bufferMesh.getVertexBuffer(attributeKind);
-                                        if (vertexBuffer) {
-                                            var bufferData = vertexBuffer.getData();
-                                            if (bufferData) {
-                                                var strideSize = vertexBuffer.getStrideSize();
-                                                var minMax = void 0;
-                                                var min = null;
-                                                var max = null;
-                                                var bufferViewIndex = attribute.bufferViewIndex;
-                                                if (bufferViewIndex != undefined) {
-                                                    if (attributeKind == BABYLON.VertexBuffer.PositionKind) {
-                                                        minMax = this.calculateMinMaxPositions(bufferData, 0, bufferData.length / strideSize);
-                                                        min = minMax.min;
-                                                        max = minMax.max;
-                                                    }
-                                                    var accessor = this.createAccessor(bufferViewIndex, attributeKind + " - " + babylonMesh.name, attribute.accessorType, 5126 /* FLOAT */, bufferData.length / strideSize, 0, min, max);
-                                                    this.accessors.push(accessor);
-                                                    switch (attributeKind) {
-                                                        case BABYLON.VertexBuffer.PositionKind: {
-                                                            meshPrimitive.attributes.POSITION = this.accessors.length - 1;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.NormalKind: {
-                                                            meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.ColorKind: {
-                                                            meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.TangentKind: {
-                                                            meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.UVKind: {
-                                                            meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
-                                                            uvCoordsPresent = true;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.UV2Kind: {
-                                                            meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
-                                                            uvCoordsPresent = true;
-                                                            break;
-                                                        }
-                                                        default: {
-                                                            BABYLON.Tools.Warn("Unsupported Vertex Buffer Type: " + attributeKind);
-                                                        }
-                                                    }
+                                    var vertexData = bufferMesh.getVerticesData(attributeKind);
+                                    if (vertexData) {
+                                        var stride = BABYLON.VertexBuffer.DeduceStride(attributeKind);
+                                        var minMax = void 0;
+                                        var min = null;
+                                        var max = null;
+                                        var bufferViewIndex = attribute.bufferViewIndex;
+                                        if (bufferViewIndex != undefined) {
+                                            if (attributeKind == BABYLON.VertexBuffer.PositionKind) {
+                                                minMax = this.calculateMinMaxPositions(vertexData, 0, vertexData.length / stride);
+                                                min = minMax.min;
+                                                max = minMax.max;
+                                            }
+                                            var accessor = this.createAccessor(bufferViewIndex, attributeKind + " - " + babylonMesh.name, attribute.accessorType, 5126 /* FLOAT */, vertexData.length / stride, 0, min, max);
+                                            this.accessors.push(accessor);
+                                            switch (attributeKind) {
+                                                case BABYLON.VertexBuffer.PositionKind: {
+                                                    meshPrimitive.attributes.POSITION = this.accessors.length - 1;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.NormalKind: {
+                                                    meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.ColorKind: {
+                                                    meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.TangentKind: {
+                                                    meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.UVKind: {
+                                                    meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
+                                                    uvCoordsPresent = true;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.UV2Kind: {
+                                                    meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
+                                                    uvCoordsPresent = true;
+                                                    break;
+                                                }
+                                                default: {
+                                                    BABYLON.Tools.Warn("Unsupported Vertex Buffer Type: " + attributeKind);
                                                 }
                                             }
                                         }

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.min.js


+ 1 - 2
dist/preview release/serializers/babylonjs.serializers.module.d.ts

@@ -183,12 +183,11 @@ declare module BABYLON.GLTF2 {
          * Returns the bytelength of the data.
          * @param vertexBufferKind - Indicates what kind of vertex data is being passed in.
          * @param meshAttributeArray - Array containing the attribute data.
-         * @param strideSize - Represents the offset between consecutive attributes
          * @param byteOffset - The offset to start counting bytes from.
          * @param dataBuffer - The buffer to write the binary data to.
          * @returns - Byte length of the attribute data.
          */
-        private writeAttributeData(vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer);
+        private writeAttributeData(vertexBufferKind, meshAttributeArray, byteOffset, dataBuffer);
         /**
          * Generates glTF json data
          * @param shouldUseGlb - Indicates whether the json should be written for a glb file.

+ 2 - 215
dist/preview release/typedocValidationBaseline.json

@@ -1,7 +1,7 @@
 {
-  "errors": 7080,
+  "errors": 6675,
   "babylon.typedoc.json": {
-    "errors": 7080,
+    "errors": 6675,
     "AnimationKeyInterpolation": {
       "Enumeration": {
         "Comments": {
@@ -5552,45 +5552,6 @@
           "MissingText": true
         }
       },
-      "Constructor": {
-        "new Buffer": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "engine": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "data": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "updatable": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "stride": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "postponeInternalCreation": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "instanced": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        }
-      },
       "Method": {
         "_rebuild": {
           "Comments": {
@@ -5624,11 +5585,6 @@
             "MissingText": true
           }
         },
-        "getStrideSize": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
         "isUpdatable": {
           "Comments": {
             "MissingText": true
@@ -5645,28 +5601,6 @@
               }
             }
           }
-        },
-        "updateDirectly": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "data": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "offset": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "vertexCount": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
         }
       }
     },
@@ -9832,18 +9766,6 @@
             }
           }
         },
-        "createDynamicVertexBuffer": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "vertices": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
         "createEffect": {
           "Comments": {
             "MissingText": true,
@@ -10409,18 +10331,6 @@
             }
           }
         },
-        "createVertexBuffer": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "vertices": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
         "deleteInstancesBuffer": {
           "Comments": {
             "MissingText": true
@@ -12026,33 +11936,6 @@
             }
           }
         },
-        "updateDynamicVertexBuffer": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "vertexBuffer": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "vertices": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "offset": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "count": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
         "updateMultipleRenderTargetTextureSampleCount": {
           "Comments": {
             "MissingText": true
@@ -33688,60 +33571,6 @@
           "MissingText": true
         }
       },
-      "Constructor": {
-        "new VertexBuffer": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "engine": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "data": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "kind": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "updatable": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "postponeInternalCreation": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "stride": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "instanced": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "offset": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "size": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        }
-      },
       "Property": {
         "ColorKind": {
           "Comments": {
@@ -35622,34 +35451,6 @@
         }
       }
     },
-    "IActiveMeshCandidateProvider": {
-      "Interface": {
-        "Comments": {
-          "MissingText": true
-        }
-      },
-      "Property": {
-        "checksIsEnabled": {
-          "Comments": {
-            "MissingText": true
-          }
-        }
-      },
-      "Method": {
-        "getMeshes": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "scene": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        }
-      }
-    },
     "IAnimatable": {
       "Interface": {
         "Comments": {
@@ -35976,20 +35777,6 @@
         }
       }
     },
-    "IDisposable": {
-      "Interface": {
-        "Comments": {
-          "MissingText": true
-        }
-      },
-      "Method": {
-        "dispose": {
-          "Comments": {
-            "MissingText": true
-          }
-        }
-      }
-    },
     "IEasingFunction": {
       "Interface": {
         "Comments": {

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 45 - 45
dist/preview release/viewer/babylon.viewer.js


+ 332 - 91
dist/preview release/viewer/babylon.viewer.max.js

@@ -8058,13 +8058,15 @@ var BABYLON;
         /**
          * Provides a slice function that will work even on IE
          * @param data defines the array to slice
+         * @param start defines the start of the data (optional)
+         * @param end defines the end of the data (optional)
          * @returns the new sliced array
          */
-        Tools.Slice = function (data) {
+        Tools.Slice = function (data, start, end) {
             if (data.slice) {
-                return data.slice();
+                return data.slice(start, end);
             }
-            return Array.prototype.slice.call(data);
+            return Array.prototype.slice.call(data, start, end);
         };
         Tools.SetImmediate = function (action) {
             if (window.setImmediate) {
@@ -12333,33 +12335,43 @@ var BABYLON;
             this.bindArrayBuffer(null);
             this._cachedVertexBuffers = null;
         };
-        Engine.prototype.createVertexBuffer = function (vertices) {
+        /**
+         * Creates a vertex buffer
+         * @param data the data for the vertex buffer
+         * @returns the new WebGL static buffer
+         */
+        Engine.prototype.createVertexBuffer = function (data) {
             var vbo = this._gl.createBuffer();
             if (!vbo) {
                 throw new Error("Unable to create vertex buffer");
             }
             this.bindArrayBuffer(vbo);
-            if (vertices instanceof Float32Array) {
-                this._gl.bufferData(this._gl.ARRAY_BUFFER, vertices, this._gl.STATIC_DRAW);
+            if (data instanceof Array) {
+                this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(data), this._gl.STATIC_DRAW);
             }
             else {
-                this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(vertices), this._gl.STATIC_DRAW);
+                this._gl.bufferData(this._gl.ARRAY_BUFFER, data, this._gl.STATIC_DRAW);
             }
             this._resetVertexBufferBinding();
             vbo.references = 1;
             return vbo;
         };
-        Engine.prototype.createDynamicVertexBuffer = function (vertices) {
+        /**
+         * Creates a dynamic vertex buffer
+         * @param data the data for the dynamic vertex buffer
+         * @returns the new WebGL dynamic buffer
+         */
+        Engine.prototype.createDynamicVertexBuffer = function (data) {
             var vbo = this._gl.createBuffer();
             if (!vbo) {
                 throw new Error("Unable to create dynamic vertex buffer");
             }
             this.bindArrayBuffer(vbo);
-            if (vertices instanceof Float32Array) {
-                this._gl.bufferData(this._gl.ARRAY_BUFFER, vertices, this._gl.DYNAMIC_DRAW);
+            if (data instanceof Array) {
+                this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(data), this._gl.DYNAMIC_DRAW);
             }
             else {
-                this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(vertices), this._gl.DYNAMIC_DRAW);
+                this._gl.bufferData(this._gl.ARRAY_BUFFER, data, this._gl.DYNAMIC_DRAW);
             }
             this._resetVertexBufferBinding();
             vbo.references = 1;
@@ -12380,25 +12392,38 @@ var BABYLON;
             this._gl.bufferData(this._gl.ELEMENT_ARRAY_BUFFER, arrayBuffer, this._gl.DYNAMIC_DRAW);
             this._resetIndexBufferBinding();
         };
-        Engine.prototype.updateDynamicVertexBuffer = function (vertexBuffer, vertices, offset, count) {
+        /**
+         * Updates a dynamic vertex buffer.
+         * @param vertexBuffer the vertex buffer to update
+         * @param data the data used to update the vertex buffer
+         * @param byteOffset the byte offset of the data (optional)
+         * @param byteLength the byte length of the data (optional)
+         */
+        Engine.prototype.updateDynamicVertexBuffer = function (vertexBuffer, data, byteOffset, byteLength) {
             this.bindArrayBuffer(vertexBuffer);
-            if (offset === undefined) {
-                offset = 0;
+            if (byteOffset === undefined) {
+                byteOffset = 0;
             }
-            if (count === undefined) {
-                if (vertices instanceof Float32Array) {
-                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, offset, vertices);
+            if (byteLength === undefined) {
+                if (data instanceof Array) {
+                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, byteOffset, new Float32Array(data));
                 }
                 else {
-                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, offset, new Float32Array(vertices));
+                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, byteOffset, data);
                 }
             }
             else {
-                if (vertices instanceof Float32Array) {
-                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, vertices.subarray(offset, offset + count));
+                if (data instanceof Array) {
+                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, new Float32Array(data).subarray(byteOffset, byteOffset + byteLength));
                 }
                 else {
-                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, new Float32Array(vertices).subarray(offset, offset + count));
+                    if (data instanceof ArrayBuffer) {
+                        data = new Uint8Array(data, byteOffset, byteLength);
+                    }
+                    else {
+                        data = new Uint8Array(data.buffer, data.byteOffset + byteOffset, byteLength);
+                    }
+                    this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, data);
                 }
             }
             this._resetVertexBufferBinding();
@@ -12554,7 +12579,7 @@ var BABYLON;
                     }
                     var buffer = vertexBuffer.getBuffer();
                     if (buffer) {
-                        this.vertexAttribPointer(buffer, order, vertexBuffer.getSize(), this._gl.FLOAT, false, vertexBuffer.getStrideSize() * 4, vertexBuffer.getOffset() * 4);
+                        this.vertexAttribPointer(buffer, order, vertexBuffer.getSize(), vertexBuffer.type, vertexBuffer.normalized, vertexBuffer.byteStride, vertexBuffer.byteOffset);
                         if (vertexBuffer.getIsInstanced()) {
                             this._gl.vertexAttribDivisor(order, vertexBuffer.getInstanceDivisor());
                             if (!this._vaoRecordInProgress) {
@@ -27188,8 +27213,21 @@ var BABYLON;
 var BABYLON;
 (function (BABYLON) {
     var Buffer = /** @class */ (function () {
-        function Buffer(engine, data, updatable, stride, postponeInternalCreation, instanced) {
+        /**
+         * Constructor
+         * @param engine the engine
+         * @param data the data to use for this buffer
+         * @param updatable whether the data is updatable
+         * @param stride the stride (optional)
+         * @param postponeInternalCreation whether to postpone creating the internal WebGL buffer (optional)
+         * @param instanced whether the buffer is instanced (optional)
+         * @param useBytes set to true if the stride in in bytes (optional)
+         */
+        function Buffer(engine, data, updatable, stride, postponeInternalCreation, instanced, useBytes) {
+            if (stride === void 0) { stride = 0; }
+            if (postponeInternalCreation === void 0) { postponeInternalCreation = false; }
             if (instanced === void 0) { instanced = false; }
+            if (useBytes === void 0) { useBytes = false; }
             if (engine instanceof BABYLON.Mesh) {
                 this._engine = engine.getScene().getEngine();
             }
@@ -27199,7 +27237,7 @@ var BABYLON;
             this._updatable = updatable;
             this._instanced = instanced;
             this._data = data;
-            this._strideSize = stride;
+            this.byteStride = useBytes ? stride : stride * 4;
             if (!postponeInternalCreation) {
                 this.create();
             }
@@ -27211,11 +27249,15 @@ var BABYLON;
          * @param size defines the size in floats of attributes (position is 3 for instance)
          * @param stride defines the stride size in floats in the buffer (the offset to apply to reach next value when data is interleaved)
          * @param instanced defines if the vertex buffer contains indexed data
+         * @param useBytes defines if the offset and stride are in bytes
          * @returns the new vertex buffer
          */
-        Buffer.prototype.createVertexBuffer = function (kind, offset, size, stride, instanced) {
+        Buffer.prototype.createVertexBuffer = function (kind, offset, size, stride, instanced, useBytes) {
+            if (useBytes === void 0) { useBytes = false; }
+            var byteOffset = useBytes ? offset : offset * 4;
+            var byteStride = stride ? (useBytes ? stride : stride * 4) : this.byteStride;
             // a lot of these parameters are ignored as they are overriden by the buffer
-            return new BABYLON.VertexBuffer(this._engine, this, kind, this._updatable, true, stride ? stride : this._strideSize, instanced === undefined ? this._instanced : instanced, offset, size);
+            return new BABYLON.VertexBuffer(this._engine, this, kind, this._updatable, true, byteStride, instanced === undefined ? this._instanced : instanced, byteOffset, size, undefined, undefined, true);
         };
         // Properties
         Buffer.prototype.isUpdatable = function () {
@@ -27227,23 +27269,15 @@ var BABYLON;
         Buffer.prototype.getBuffer = function () {
             return this._buffer;
         };
+        /**
+         * Gets the stride in float32 units (i.e. byte stride / 4).
+         * May not be an integer if the byte stride is not divisible by 4.
+         * DEPRECATED. Use byteStride instead.
+         * @returns the stride in float32 units
+         */
         Buffer.prototype.getStrideSize = function () {
-            return this._strideSize;
+            return this.byteStride / 4;
         };
-        // public getIsInstanced(): boolean {
-        //     return this._instanced;
-        // }
-        // public get instanceDivisor(): number {
-        //     return this._instanceDivisor;
-        // }
-        // public set instanceDivisor(value: number) {
-        //     this._instanceDivisor = value;
-        //     if (value == 0) {
-        //         this._instanced = false;
-        //     } else {
-        //         this._instanced = true;
-        //     }
-        // }
         // Methods
         Buffer.prototype.create = function (data) {
             if (data === void 0) { data = null; }
@@ -27275,12 +27309,20 @@ var BABYLON;
         Buffer.prototype.update = function (data) {
             this.create(data);
         };
-        Buffer.prototype.updateDirectly = function (data, offset, vertexCount) {
+        /**
+         * Updates the data directly.
+         * @param data the new data
+         * @param offset the new offset
+         * @param vertexCount the vertex count (optional)
+         * @param useBytes set to true if the offset is in bytes
+         */
+        Buffer.prototype.updateDirectly = function (data, offset, vertexCount, useBytes) {
+            if (useBytes === void 0) { useBytes = false; }
             if (!this._buffer) {
                 return;
             }
             if (this._updatable) {
-                this._engine.updateDynamicVertexBuffer(this._buffer, data, offset, (vertexCount ? vertexCount * this.getStrideSize() : undefined));
+                this._engine.updateDynamicVertexBuffer(this._buffer, data, useBytes ? offset : offset * 4, (vertexCount ? vertexCount * this.byteStride : undefined));
                 this._data = null;
             }
         };
@@ -27303,27 +27345,66 @@ var BABYLON;
 var BABYLON;
 (function (BABYLON) {
     var VertexBuffer = /** @class */ (function () {
-        function VertexBuffer(engine, data, kind, updatable, postponeInternalCreation, stride, instanced, offset, size) {
+        /**
+         * Constructor
+         * @param engine the engine
+         * @param data the data to use for this vertex buffer
+         * @param kind the vertex buffer kind
+         * @param updatable whether the data is updatable
+         * @param postponeInternalCreation whether to postpone creating the internal WebGL buffer (optional)
+         * @param stride the stride (optional)
+         * @param instanced whether the buffer is instanced (optional)
+         * @param offset the offset of the data (optional)
+         * @param size the number of components (optional)
+         * @param type the type of the component (optional)
+         * @param normalized whether the data contains normalized data (optional)
+         * @param useBytes set to true if stride and offset are in bytes (optional)
+         */
+        function VertexBuffer(engine, data, kind, updatable, postponeInternalCreation, stride, instanced, offset, size, type, normalized, useBytes) {
+            if (normalized === void 0) { normalized = false; }
+            if (useBytes === void 0) { useBytes = false; }
             if (data instanceof BABYLON.Buffer) {
-                if (!stride) {
-                    stride = data.getStrideSize();
-                }
                 this._buffer = data;
                 this._ownsBuffer = false;
             }
             else {
-                if (!stride) {
-                    stride = VertexBuffer.DeduceStride(kind);
-                }
-                this._buffer = new BABYLON.Buffer(engine, data, updatable, stride, postponeInternalCreation, instanced);
+                this._buffer = new BABYLON.Buffer(engine, data, updatable, stride, postponeInternalCreation, instanced, useBytes);
                 this._ownsBuffer = true;
             }
-            this._stride = stride;
+            this._kind = kind;
+            if (type == undefined) {
+                var data_1 = this.getData();
+                this.type = VertexBuffer.FLOAT;
+                if (data_1 instanceof Int8Array)
+                    this.type = VertexBuffer.BYTE;
+                else if (data_1 instanceof Uint8Array)
+                    this.type = VertexBuffer.UNSIGNED_BYTE;
+                else if (data_1 instanceof Int16Array)
+                    this.type = VertexBuffer.SHORT;
+                else if (data_1 instanceof Uint16Array)
+                    this.type = VertexBuffer.UNSIGNED_SHORT;
+                else if (data_1 instanceof Int32Array)
+                    this.type = VertexBuffer.INT;
+                else if (data_1 instanceof Uint32Array)
+                    this.type = VertexBuffer.UNSIGNED_INT;
+            }
+            else {
+                this.type = type;
+            }
+            var typeByteLength = VertexBuffer.GetTypeByteLength(this.type);
+            if (useBytes) {
+                this._size = size || (stride ? (stride / typeByteLength) : VertexBuffer.DeduceStride(kind));
+                this.byteStride = stride || this._buffer.byteStride || (this._size * typeByteLength);
+                this.byteOffset = offset || 0;
+            }
+            else {
+                this._size = size || stride || VertexBuffer.DeduceStride(kind);
+                this.byteStride = stride ? (stride * typeByteLength) : (this._buffer.byteStride || (this._size * typeByteLength));
+                this.byteOffset = (offset || 0) * typeByteLength;
+            }
+            this.normalized = normalized;
             this._instanced = instanced !== undefined ? instanced : false;
             this._instanceDivisor = instanced ? 1 : 0;
-            this._offset = offset ? offset : 0;
-            this._size = size ? size : stride;
-            this._kind = kind;
         }
         Object.defineProperty(VertexBuffer.prototype, "instanceDivisor", {
             /**
@@ -27364,7 +27445,7 @@ var BABYLON;
             return this._buffer.isUpdatable();
         };
         /**
-         * Returns an array of numbers or a Float32Array containing the VertexBuffer data.
+         * Returns an array of numbers or a typed array containing the VertexBuffer data.
          */
         VertexBuffer.prototype.getData = function () {
             return this._buffer.getData();
@@ -27376,19 +27457,21 @@ var BABYLON;
             return this._buffer.getBuffer();
         };
         /**
-         * Returns the stride of the VertexBuffer (integer).
+         * Returns the stride as a multiple of the type byte length.
+         * DEPRECATED. Use byteStride instead.
          */
         VertexBuffer.prototype.getStrideSize = function () {
-            return this._stride;
+            return this.byteStride / VertexBuffer.GetTypeByteLength(this.type);
         };
         /**
-         * Returns the offset (integer).
+         * Returns the offset as a multiple of the type byte length.
+         * DEPRECATED. Use byteOffset instead.
          */
         VertexBuffer.prototype.getOffset = function () {
-            return this._offset;
+            return this.byteOffset / VertexBuffer.GetTypeByteLength(this.type);
         };
         /**
-         * Returns the VertexBuffer total size (integer).
+         * Returns the number of components per vertex attribute (integer).
          */
         VertexBuffer.prototype.getSize = function () {
             return this._size;
@@ -27436,6 +27519,14 @@ var BABYLON;
                 this._buffer.dispose();
             }
         };
+        /**
+         * Enumerates each value of this vertex buffer as numbers.
+         * @param count the number of values to enumerate
+         * @param callback the callback function called for each value
+         */
+        VertexBuffer.prototype.forEach = function (count, callback) {
+            VertexBuffer.ForEach(this._buffer.getData(), this.byteOffset, this.byteStride, this._size, this.type, count, this.normalized, callback);
+        };
         Object.defineProperty(VertexBuffer, "PositionKind", {
             get: function () {
                 return VertexBuffer._PositionKind;
@@ -27562,6 +27653,128 @@ var BABYLON;
                     throw new Error("Invalid kind '" + kind + "'");
             }
         };
+        /**
+         * Gets the byte length of the given type.
+         * @param type the type
+         * @returns the number of bytes
+         */
+        VertexBuffer.GetTypeByteLength = function (type) {
+            switch (type) {
+                case VertexBuffer.BYTE:
+                case VertexBuffer.UNSIGNED_BYTE:
+                    return 1;
+                case VertexBuffer.SHORT:
+                case VertexBuffer.UNSIGNED_SHORT:
+                    return 2;
+                case VertexBuffer.INT:
+                case VertexBuffer.FLOAT:
+                    return 4;
+                default:
+                    throw new Error("Invalid type '" + type + "'");
+            }
+        };
+        /**
+         * Enumerates each value of the given parameters as numbers.
+         * @param data the data to enumerate
+         * @param byteOffset the byte offset of the data
+         * @param byteStride the byte stride of the data
+         * @param componentCount the number of components per element
+         * @param componentType the type of the component
+         * @param count the total number of components
+         * @param normalized whether the data is normalized
+         * @param callback the callback function called for each value
+         */
+        VertexBuffer.ForEach = function (data, byteOffset, byteStride, componentCount, componentType, count, normalized, callback) {
+            if (data instanceof Array) {
+                var offset = byteOffset / 4;
+                var stride = byteStride / 4;
+                for (var index = 0; index < count; index += componentCount) {
+                    for (var componentIndex = 0; componentIndex < componentCount; componentIndex++) {
+                        callback(data[offset + componentIndex], index + componentIndex);
+                    }
+                    offset += stride;
+                }
+            }
+            else {
+                var dataView = data instanceof ArrayBuffer ? new DataView(data) : new DataView(data.buffer, data.byteOffset, data.byteLength);
+                var componentByteLength = VertexBuffer.GetTypeByteLength(componentType);
+                for (var index = 0; index < count; index += componentCount) {
+                    var componentByteOffset = byteOffset;
+                    for (var componentIndex = 0; componentIndex < componentCount; componentIndex++) {
+                        var value = VertexBuffer._GetFloatValue(dataView, componentType, componentByteOffset, normalized);
+                        callback(value, index + componentIndex);
+                        componentByteOffset += componentByteLength;
+                    }
+                    byteOffset += byteStride;
+                }
+            }
+        };
+        VertexBuffer._GetFloatValue = function (dataView, type, byteOffset, normalized) {
+            switch (type) {
+                case VertexBuffer.BYTE: {
+                    var value = dataView.getInt8(byteOffset);
+                    if (normalized) {
+                        value = (value + 0.5) / 127.5;
+                    }
+                    return value;
+                }
+                case VertexBuffer.UNSIGNED_BYTE: {
+                    var value = dataView.getUint8(byteOffset);
+                    if (normalized) {
+                        value = value / 255;
+                    }
+                    return value;
+                }
+                case VertexBuffer.SHORT: {
+                    var value = dataView.getInt16(byteOffset, true);
+                    if (normalized) {
+                        value = (value + 0.5) / 16383.5;
+                    }
+                    return value;
+                }
+                case VertexBuffer.UNSIGNED_SHORT: {
+                    var value = dataView.getUint16(byteOffset, true);
+                    if (normalized) {
+                        value = value / 65535;
+                    }
+                    return value;
+                }
+                case VertexBuffer.FLOAT: {
+                    return dataView.getFloat32(byteOffset, true);
+                }
+                default: {
+                    throw new Error("Invalid component type " + type);
+                }
+            }
+        };
+        /**
+         * The byte type.
+         */
+        VertexBuffer.BYTE = 5120;
+        /**
+         * The unsigned byte type.
+         */
+        VertexBuffer.UNSIGNED_BYTE = 5121;
+        /**
+         * The short type.
+         */
+        VertexBuffer.SHORT = 5122;
+        /**
+         * The unsigned short type.
+         */
+        VertexBuffer.UNSIGNED_SHORT = 5123;
+        /**
+         * The integer type.
+         */
+        VertexBuffer.INT = 5124;
+        /**
+         * The unsigned integer type.
+         */
+        VertexBuffer.UNSIGNED_INT = 5125;
+        /**
+         * The float type.
+         */
+        VertexBuffer.FLOAT = 5126;
         // Enums
         VertexBuffer._PositionKind = "position";
         VertexBuffer._NormalKind = "normal";
@@ -29798,7 +30011,7 @@ var BABYLON;
         };
         Mesh.prototype._draw = function (subMesh, fillMode, instancesCount, alternate) {
             if (alternate === void 0) { alternate = false; }
-            if (!this._geometry || !this._geometry.getVertexBuffers() || !this._geometry.getIndexBuffer()) {
+            if (!this._geometry || !this._geometry.getVertexBuffers() || (!this._unIndexed && !this._geometry.getIndexBuffer())) {
                 return this;
             }
             this.onBeforeDrawObservable.notifyObservers(this);
@@ -29994,7 +30207,7 @@ var BABYLON;
                 return this;
             }
             // Checking geometry state
-            if (!this._geometry || !this._geometry.getVertexBuffers() || !this._geometry.getIndexBuffer()) {
+            if (!this._geometry || !this._geometry.getVertexBuffers() || (!this._unIndexed && !this._geometry.getIndexBuffer())) {
                 return this;
             }
             this.onBeforeRenderObservable.notifyObservers(this);
@@ -36233,7 +36446,7 @@ var BABYLON;
             if (mesh) {
                 if (mesh.getClassName() === "LinesMesh") {
                     this.boundingBias = new BABYLON.Vector2(0, mesh.intersectionThreshold);
-                    this.updateExtend();
+                    this._updateExtend();
                 }
                 this.applyToMesh(mesh);
                 mesh.computeWorldMatrix(true);
@@ -36254,7 +36467,7 @@ var BABYLON;
                     return;
                 }
                 this._boundingBias = value.clone();
-                this.updateBoundingInfo(true, null);
+                this._updateBoundingInfo(true, null);
             },
             enumerable: true,
             configurable: true
@@ -36348,6 +36561,9 @@ var BABYLON;
          */
         Geometry.prototype.setVerticesData = function (kind, data, updatable, stride) {
             if (updatable === void 0) { updatable = false; }
+            if (kind === BABYLON.VertexBuffer.PositionKind) {
+                this._totalVertices = data.length / (stride || 3);
+            }
             var buffer = new BABYLON.VertexBuffer(this._engine, data, kind, updatable, this._meshes.length === 0, stride);
             this.setVerticesBuffer(buffer);
         };
@@ -36364,18 +36580,20 @@ var BABYLON;
         /**
          * Affect a vertex buffer to the geometry. the vertexBuffer.getKind() function is used to determine where to store the data
          * @param buffer defines the vertex buffer to use
+         * @param totalVertices defines the total number of vertices for position kind (could be null)
          */
-        Geometry.prototype.setVerticesBuffer = function (buffer) {
+        Geometry.prototype.setVerticesBuffer = function (buffer, totalVertices) {
+            if (totalVertices === void 0) { totalVertices = null; }
             var kind = buffer.getKind();
             if (this._vertexBuffers[kind]) {
                 this._vertexBuffers[kind].dispose();
             }
             this._vertexBuffers[kind] = buffer;
             if (kind === BABYLON.VertexBuffer.PositionKind) {
-                var data = buffer.getData();
-                var stride = buffer.getStrideSize();
-                this._totalVertices = data.length / stride;
-                this.updateExtend(data, stride);
+                if (totalVertices != null) {
+                    this._totalVertices = totalVertices;
+                }
+                this._updateExtend();
                 this._resetPointsArrayCache();
                 var meshes = this._meshes;
                 var numOfMeshes = meshes.length;
@@ -36423,15 +36641,13 @@ var BABYLON;
             }
             vertexBuffer.update(data);
             if (kind === BABYLON.VertexBuffer.PositionKind) {
-                var stride = vertexBuffer.getStrideSize();
-                this._totalVertices = data.length / stride;
-                this.updateBoundingInfo(updateExtends, data);
+                this._updateBoundingInfo(updateExtends, data);
             }
             this.notifyUpdate(kind);
         };
-        Geometry.prototype.updateBoundingInfo = function (updateExtends, data) {
+        Geometry.prototype._updateBoundingInfo = function (updateExtends, data) {
             if (updateExtends) {
-                this.updateExtend(data);
+                this._updateExtend(data);
             }
             var meshes = this._meshes;
             var numOfMeshes = meshes.length;
@@ -36480,7 +36696,7 @@ var BABYLON;
             return this._totalVertices;
         };
         /**
-         * Gets a specific vertex data attached to this geometry
+         * Gets a specific vertex data attached to this geometry. Float data is constructed if the vertex buffer data cannot be returned directly.
          * @param kind defines the data kind (Position, normal, etc...)
          * @param copyWhenShared defines if the returned array must be cloned upon returning it if the current geometry is shared between multiple meshes
          * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it
@@ -36491,18 +36707,36 @@ var BABYLON;
             if (!vertexBuffer) {
                 return null;
             }
-            var orig = vertexBuffer.getData();
-            if (!forceCopy && (!copyWhenShared || this._meshes.length === 1)) {
-                return orig;
+            var data = vertexBuffer.getData();
+            if (!data) {
+                return null;
             }
-            else {
-                var len = orig.length;
-                var copy = [];
-                for (var i = 0; i < len; i++) {
-                    copy.push(orig[i]);
+            var defaultStride = BABYLON.VertexBuffer.DeduceStride(vertexBuffer.getKind());
+            var defaultByteStride = defaultStride * BABYLON.VertexBuffer.GetTypeByteLength(vertexBuffer.type);
+            var count = this._totalVertices * defaultStride;
+            if (vertexBuffer.type !== BABYLON.VertexBuffer.FLOAT || vertexBuffer.byteStride !== defaultByteStride) {
+                var copy_1 = new Array(count);
+                vertexBuffer.forEach(count, function (value, index) {
+                    copy_1[index] = value;
+                });
+                return copy_1;
+            }
+            if (!(data instanceof Array || data instanceof Float32Array) || vertexBuffer.byteOffset !== 0 || data.length !== count) {
+                if (data instanceof Array) {
+                    var offset = vertexBuffer.byteOffset / 4;
+                    return BABYLON.Tools.Slice(data, offset, offset + count);
                 }
-                return copy;
+                else if (data instanceof ArrayBuffer) {
+                    return new Float32Array(data, vertexBuffer.byteOffset, count);
+                }
+                else {
+                    return new Float32Array(data.buffer, data.byteOffset + vertexBuffer.byteOffset, count);
+                }
+            }
+            if (forceCopy || (copyWhenShared && this._meshes.length !== 1)) {
+                return BABYLON.Tools.Slice(data);
             }
+            return data;
         };
         /**
          * Returns a boolean defining if the vertex data for the requested `kind` is updatable
@@ -36708,12 +36942,12 @@ var BABYLON;
                 mesh._boundingInfo = this._boundingInfo;
             }
         };
-        Geometry.prototype.updateExtend = function (data, stride) {
+        Geometry.prototype._updateExtend = function (data) {
             if (data === void 0) { data = null; }
             if (!data) {
-                data = this._vertexBuffers[BABYLON.VertexBuffer.PositionKind].getData();
+                data = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
             }
-            this._extend = BABYLON.Tools.ExtractMinAndMax(data, 0, this._totalVertices, this.boundingBias, stride);
+            this._extend = BABYLON.Tools.ExtractMinAndMax(data, 0, this._totalVertices, this.boundingBias, 3);
         };
         Geometry.prototype._applyToMesh = function (mesh) {
             var numOfMeshes = this._meshes.length;
@@ -36727,7 +36961,7 @@ var BABYLON;
                     buffer.references = numOfMeshes;
                 if (kind === BABYLON.VertexBuffer.PositionKind) {
                     if (!this._extend) {
-                        this.updateExtend(this._vertexBuffers[kind].getData());
+                        this._updateExtend();
                     }
                     mesh._boundingInfo = new BABYLON.BoundingInfo(this._extend.minimum, this._extend.maximum);
                     mesh._createGlobalSubMesh(false);
@@ -57672,7 +57906,7 @@ var BABYLON;
             return this;
         };
         LinesMesh.prototype._draw = function (subMesh, fillMode, instancesCount) {
-            if (!this._geometry || !this._geometry.getVertexBuffers() || !this._geometry.getIndexBuffer()) {
+            if (!this._geometry || !this._geometry.getVertexBuffers() || (!this._unIndexed && !this._geometry.getIndexBuffer())) {
                 return this;
             }
             var engine = this.getScene().getEngine();
@@ -91536,7 +91770,14 @@ var BABYLON;
         NullEngine.prototype.updateDynamicIndexBuffer = function (indexBuffer, indices, offset) {
             if (offset === void 0) { offset = 0; }
         };
-        NullEngine.prototype.updateDynamicVertexBuffer = function (vertexBuffer, vertices, offset, count) {
+        /**
+         * Updates a dynamic vertex buffer.
+         * @param vertexBuffer the vertex buffer to update
+         * @param data the data used to update the vertex buffer
+         * @param byteOffset the byte offset of the data (optional)
+         * @param byteLength the byte length of the data (optional)
+         */
+        NullEngine.prototype.updateDynamicVertexBuffer = function (vertexBuffer, vertices, byteOffset, byteLength) {
         };
         NullEngine.prototype._bindTextureDirectly = function (target, texture) {
             if (this._boundTexturesCache[this._activeChannel] !== texture) {