Просмотр исходного кода

new `Mesh.convertToUnIndexedMesh()` to create meshes with no indices (which could be faster when vertex reuse is low and vertex structure is small)

David Catuhe 10 лет назад
Родитель
Сommit
a210eb2b9c

Разница между файлами не показана из-за своего большого размера
+ 19 - 21
dist/preview release/babylon.core.js


+ 291 - 282
dist/preview release/babylon.d.ts

@@ -239,6 +239,7 @@ declare module BABYLON {
         applyStates(): void;
         applyStates(): void;
         draw(useTriangles: boolean, indexStart: number, indexCount: number, instancesCount?: number): void;
         draw(useTriangles: boolean, indexStart: number, indexCount: number, instancesCount?: number): void;
         drawPointClouds(verticesStart: number, verticesCount: number, instancesCount?: number): void;
         drawPointClouds(verticesStart: number, verticesCount: number, instancesCount?: number): void;
+        drawUnIndexed(useTriangles: boolean, verticesStart: number, verticesCount: number, instancesCount?: number): void;
         _releaseEffect(effect: Effect): void;
         _releaseEffect(effect: Effect): void;
         createEffect(baseName: any, attributesNames: string[], uniformsNames: string[], samplers: string[], defines: string, fallbacks?: EffectFallbacks, onCompiled?: (effect: Effect) => void, onError?: (effect: Effect, errors: string) => void): Effect;
         createEffect(baseName: any, attributesNames: string[], uniformsNames: string[], samplers: string[], defines: string, fallbacks?: EffectFallbacks, onCompiled?: (effect: Effect) => void, onError?: (effect: Effect, errors: string) => void): Effect;
         createEffectForParticles(fragmentName: string, uniformsNames?: string[], samplers?: string[], defines?: string, fallbacks?: EffectFallbacks, onCompiled?: (effect: Effect) => void, onError?: (effect: Effect, errors: string) => void): Effect;
         createEffectForParticles(fragmentName: string, uniformsNames?: string[], samplers?: string[], defines?: string, fallbacks?: EffectFallbacks, onCompiled?: (effect: Effect) => void, onError?: (effect: Effect, errors: string) => void): Effect;
@@ -903,6 +904,8 @@ declare module BABYLON {
         private _switchAudioModeForNormalSpeakers();
         private _switchAudioModeForNormalSpeakers();
         enableDepthRenderer(): DepthRenderer;
         enableDepthRenderer(): DepthRenderer;
         disableDepthRenderer(): void;
         disableDepthRenderer(): void;
+        freezeMaterials(): void;
+        unfreezeMaterials(): void;
         dispose(): void;
         dispose(): void;
         disposeSounds(): void;
         disposeSounds(): void;
         getWorldExtends(): {
         getWorldExtends(): {
@@ -2039,6 +2042,123 @@ declare module BABYLON {
 }
 }
 
 
 declare module BABYLON {
 declare module BABYLON {
+    class BoundingBox {
+        minimum: Vector3;
+        maximum: Vector3;
+        vectors: Vector3[];
+        center: Vector3;
+        extendSize: Vector3;
+        directions: Vector3[];
+        vectorsWorld: Vector3[];
+        minimumWorld: Vector3;
+        maximumWorld: Vector3;
+        private _worldMatrix;
+        constructor(minimum: Vector3, maximum: Vector3);
+        getWorldMatrix(): Matrix;
+        _update(world: Matrix): void;
+        isInFrustum(frustumPlanes: Plane[]): boolean;
+        isCompletelyInFrustum(frustumPlanes: Plane[]): boolean;
+        intersectsPoint(point: Vector3): boolean;
+        intersectsSphere(sphere: BoundingSphere): boolean;
+        intersectsMinMax(min: Vector3, max: Vector3): boolean;
+        static Intersects(box0: BoundingBox, box1: BoundingBox): boolean;
+        static IntersectsSphere(minPoint: Vector3, maxPoint: Vector3, sphereCenter: Vector3, sphereRadius: number): boolean;
+        static IsCompletelyInFrustum(boundingVectors: Vector3[], frustumPlanes: Plane[]): boolean;
+        static IsInFrustum(boundingVectors: Vector3[], frustumPlanes: Plane[]): boolean;
+    }
+}
+
+declare module BABYLON {
+    class BoundingInfo {
+        minimum: Vector3;
+        maximum: Vector3;
+        boundingBox: BoundingBox;
+        boundingSphere: BoundingSphere;
+        constructor(minimum: Vector3, maximum: Vector3);
+        _update(world: Matrix): void;
+        isInFrustum(frustumPlanes: Plane[]): boolean;
+        isCompletelyInFrustum(frustumPlanes: Plane[]): boolean;
+        _checkCollision(collider: Collider): boolean;
+        intersectsPoint(point: Vector3): boolean;
+        intersects(boundingInfo: BoundingInfo, precise: boolean): boolean;
+    }
+}
+
+declare module BABYLON {
+    class BoundingSphere {
+        minimum: Vector3;
+        maximum: Vector3;
+        center: Vector3;
+        radius: number;
+        centerWorld: Vector3;
+        radiusWorld: number;
+        private _tempRadiusVector;
+        constructor(minimum: Vector3, maximum: Vector3);
+        _update(world: Matrix): void;
+        isInFrustum(frustumPlanes: Plane[]): boolean;
+        intersectsPoint(point: Vector3): boolean;
+        static Intersects(sphere0: BoundingSphere, sphere1: BoundingSphere): boolean;
+    }
+}
+
+declare module BABYLON {
+    class DebugLayer {
+        private _scene;
+        private _camera;
+        private _transformationMatrix;
+        private _enabled;
+        private _labelsEnabled;
+        private _displayStatistics;
+        private _displayTree;
+        private _displayLogs;
+        private _globalDiv;
+        private _statsDiv;
+        private _statsSubsetDiv;
+        private _optionsDiv;
+        private _optionsSubsetDiv;
+        private _logDiv;
+        private _logSubsetDiv;
+        private _treeDiv;
+        private _treeSubsetDiv;
+        private _drawingCanvas;
+        private _drawingContext;
+        private _rootElement;
+        _syncPositions: () => void;
+        private _syncData;
+        private _syncUI;
+        private _onCanvasClick;
+        private _clickPosition;
+        private _ratio;
+        private _identityMatrix;
+        private _showUI;
+        private _needToRefreshMeshesTree;
+        shouldDisplayLabel: (node: Node) => boolean;
+        shouldDisplayAxis: (mesh: Mesh) => boolean;
+        axisRatio: number;
+        accentColor: string;
+        customStatsFunction: () => string;
+        constructor(scene: Scene);
+        private _refreshMeshesTreeContent();
+        private _renderSingleAxis(zero, unit, unitText, label, color);
+        private _renderAxis(projectedPosition, mesh, globalViewport);
+        private _renderLabel(text, projectedPosition, labelOffset, onClick, getFillStyle);
+        private _isClickInsideRect(x, y, width, height);
+        isVisible(): boolean;
+        hide(): void;
+        show(showUI?: boolean, camera?: Camera, rootElement?: HTMLElement): void;
+        private _clearLabels();
+        private _generateheader(root, text);
+        private _generateTexBox(root, title, color);
+        private _generateAdvancedCheckBox(root, leftTitle, rightTitle, initialState, task, tag?);
+        private _generateCheckBox(root, title, initialState, task, tag?);
+        private _generateButton(root, title, task, tag?);
+        private _generateRadio(root, title, name, initialState, task, tag?);
+        private _generateDOMelements();
+        private _displayStats();
+    }
+}
+
+declare module BABYLON {
     class Collider {
     class Collider {
         radius: Vector3;
         radius: Vector3;
         retry: number;
         retry: number;
@@ -2280,143 +2400,6 @@ declare module BABYLON {
 }
 }
 
 
 declare module BABYLON {
 declare module BABYLON {
-    class BoundingBox {
-        minimum: Vector3;
-        maximum: Vector3;
-        vectors: Vector3[];
-        center: Vector3;
-        extendSize: Vector3;
-        directions: Vector3[];
-        vectorsWorld: Vector3[];
-        minimumWorld: Vector3;
-        maximumWorld: Vector3;
-        private _worldMatrix;
-        constructor(minimum: Vector3, maximum: Vector3);
-        getWorldMatrix(): Matrix;
-        _update(world: Matrix): void;
-        isInFrustum(frustumPlanes: Plane[]): boolean;
-        isCompletelyInFrustum(frustumPlanes: Plane[]): boolean;
-        intersectsPoint(point: Vector3): boolean;
-        intersectsSphere(sphere: BoundingSphere): boolean;
-        intersectsMinMax(min: Vector3, max: Vector3): boolean;
-        static Intersects(box0: BoundingBox, box1: BoundingBox): boolean;
-        static IntersectsSphere(minPoint: Vector3, maxPoint: Vector3, sphereCenter: Vector3, sphereRadius: number): boolean;
-        static IsCompletelyInFrustum(boundingVectors: Vector3[], frustumPlanes: Plane[]): boolean;
-        static IsInFrustum(boundingVectors: Vector3[], frustumPlanes: Plane[]): boolean;
-    }
-}
-
-declare module BABYLON {
-    class BoundingInfo {
-        minimum: Vector3;
-        maximum: Vector3;
-        boundingBox: BoundingBox;
-        boundingSphere: BoundingSphere;
-        constructor(minimum: Vector3, maximum: Vector3);
-        _update(world: Matrix): void;
-        isInFrustum(frustumPlanes: Plane[]): boolean;
-        isCompletelyInFrustum(frustumPlanes: Plane[]): boolean;
-        _checkCollision(collider: Collider): boolean;
-        intersectsPoint(point: Vector3): boolean;
-        intersects(boundingInfo: BoundingInfo, precise: boolean): boolean;
-    }
-}
-
-declare module BABYLON {
-    class BoundingSphere {
-        minimum: Vector3;
-        maximum: Vector3;
-        center: Vector3;
-        radius: number;
-        centerWorld: Vector3;
-        radiusWorld: number;
-        private _tempRadiusVector;
-        constructor(minimum: Vector3, maximum: Vector3);
-        _update(world: Matrix): void;
-        isInFrustum(frustumPlanes: Plane[]): boolean;
-        intersectsPoint(point: Vector3): boolean;
-        static Intersects(sphere0: BoundingSphere, sphere1: BoundingSphere): boolean;
-    }
-}
-
-declare module BABYLON {
-    class DebugLayer {
-        private _scene;
-        private _camera;
-        private _transformationMatrix;
-        private _enabled;
-        private _labelsEnabled;
-        private _displayStatistics;
-        private _displayTree;
-        private _displayLogs;
-        private _globalDiv;
-        private _statsDiv;
-        private _statsSubsetDiv;
-        private _optionsDiv;
-        private _optionsSubsetDiv;
-        private _logDiv;
-        private _logSubsetDiv;
-        private _treeDiv;
-        private _treeSubsetDiv;
-        private _drawingCanvas;
-        private _drawingContext;
-        private _rootElement;
-        _syncPositions: () => void;
-        private _syncData;
-        private _syncUI;
-        private _onCanvasClick;
-        private _clickPosition;
-        private _ratio;
-        private _identityMatrix;
-        private _showUI;
-        private _needToRefreshMeshesTree;
-        shouldDisplayLabel: (node: Node) => boolean;
-        shouldDisplayAxis: (mesh: Mesh) => boolean;
-        axisRatio: number;
-        accentColor: string;
-        customStatsFunction: () => string;
-        constructor(scene: Scene);
-        private _refreshMeshesTreeContent();
-        private _renderSingleAxis(zero, unit, unitText, label, color);
-        private _renderAxis(projectedPosition, mesh, globalViewport);
-        private _renderLabel(text, projectedPosition, labelOffset, onClick, getFillStyle);
-        private _isClickInsideRect(x, y, width, height);
-        isVisible(): boolean;
-        hide(): void;
-        show(showUI?: boolean, camera?: Camera, rootElement?: HTMLElement): void;
-        private _clearLabels();
-        private _generateheader(root, text);
-        private _generateTexBox(root, title, color);
-        private _generateAdvancedCheckBox(root, leftTitle, rightTitle, initialState, task, tag?);
-        private _generateCheckBox(root, title, initialState, task, tag?);
-        private _generateButton(root, title, task, tag?);
-        private _generateRadio(root, title, name, initialState, task, tag?);
-        private _generateDOMelements();
-        private _displayStats();
-    }
-}
-
-declare module BABYLON {
-    class Layer {
-        name: string;
-        texture: Texture;
-        isBackground: boolean;
-        color: Color4;
-        onDispose: () => void;
-        alphaBlendingMode: number;
-        private _scene;
-        private _vertexDeclaration;
-        private _vertexStrideSize;
-        private _vertexBuffer;
-        private _indexBuffer;
-        private _effect;
-        constructor(name: string, imgUrl: string, scene: Scene, isBackground?: boolean, color?: Color4);
-        render(): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
     class LensFlare {
     class LensFlare {
         size: number;
         size: number;
         position: number;
         position: number;
@@ -2461,6 +2444,26 @@ declare module BABYLON {
 }
 }
 
 
 declare module BABYLON {
 declare module BABYLON {
+    class Layer {
+        name: string;
+        texture: Texture;
+        isBackground: boolean;
+        color: Color4;
+        onDispose: () => void;
+        alphaBlendingMode: number;
+        private _scene;
+        private _vertexDeclaration;
+        private _vertexStrideSize;
+        private _vertexBuffer;
+        private _indexBuffer;
+        private _effect;
+        constructor(name: string, imgUrl: string, scene: Scene, isBackground?: boolean, color?: Color4);
+        render(): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON {
     class DirectionalLight extends Light implements IShadowLight {
     class DirectionalLight extends Light implements IShadowLight {
         direction: Vector3;
         direction: Vector3;
         position: Vector3;
         position: Vector3;
@@ -2581,40 +2584,8 @@ declare module BABYLON {
         setDirectionToTarget(target: Vector3): Vector3;
         setDirectionToTarget(target: Vector3): Vector3;
         computeTransformedPosition(): boolean;
         computeTransformedPosition(): boolean;
         transferToEffect(effect: Effect, positionUniformName: string, directionUniformName: string): void;
         transferToEffect(effect: Effect, positionUniformName: string, directionUniformName: string): void;
-        _getWorldMatrix(): Matrix;
-        serialize(): any;
-    }
-}
-
-declare module BABYLON {
-    interface ISceneLoaderPlugin {
-        extensions: string;
-        importMesh: (meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => boolean;
-        load: (scene: Scene, data: string, rootUrl: string) => boolean;
-    }
-    class SceneLoader {
-        private static _ForceFullSceneLoadingForIncremental;
-        private static _ShowLoadingScreen;
-        static ForceFullSceneLoadingForIncremental: boolean;
-        static ShowLoadingScreen: boolean;
-        private static _registeredPlugins;
-        private static _getPluginForFilename(sceneFilename);
-        static RegisterPlugin(plugin: ISceneLoaderPlugin): void;
-        static ImportMesh(meshesNames: any, rootUrl: string, sceneFilename: string, scene: Scene, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, progressCallBack?: () => void, onerror?: (scene: Scene, e: any) => void): void;
-        /**
-        * Load a scene
-        * @param rootUrl a string that defines the root url for scene and resources
-        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
-        * @param engine is the instance of BABYLON.Engine to use to create the scene
-        */
-        static Load(rootUrl: string, sceneFilename: any, engine: Engine, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
-        /**
-        * Append a scene
-        * @param rootUrl a string that defines the root url for scene and resources
-        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
-        * @param scene is the instance of BABYLON.Scene to append to
-        */
-        static Append(rootUrl: string, sceneFilename: any, scene: Scene, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
+        _getWorldMatrix(): Matrix;
+        serialize(): any;
     }
     }
 }
 }
 
 
@@ -2738,6 +2709,9 @@ declare module BABYLON {
         pointsCloud: boolean;
         pointsCloud: boolean;
         fillMode: number;
         fillMode: number;
         constructor(name: string, scene: Scene, doNotAdd?: boolean);
         constructor(name: string, scene: Scene, doNotAdd?: boolean);
+        isFrozen: boolean;
+        freeze(): void;
+        unfreeze(): void;
         isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
         isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
         getEffect(): Effect;
         getEffect(): Effect;
         getScene(): Scene;
         getScene(): Scene;
@@ -2891,6 +2865,38 @@ declare module BABYLON {
 }
 }
 
 
 declare module BABYLON {
 declare module BABYLON {
+    interface ISceneLoaderPlugin {
+        extensions: string;
+        importMesh: (meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => boolean;
+        load: (scene: Scene, data: string, rootUrl: string) => boolean;
+    }
+    class SceneLoader {
+        private static _ForceFullSceneLoadingForIncremental;
+        private static _ShowLoadingScreen;
+        static ForceFullSceneLoadingForIncremental: boolean;
+        static ShowLoadingScreen: boolean;
+        private static _registeredPlugins;
+        private static _getPluginForFilename(sceneFilename);
+        static RegisterPlugin(plugin: ISceneLoaderPlugin): void;
+        static ImportMesh(meshesNames: any, rootUrl: string, sceneFilename: string, scene: Scene, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, progressCallBack?: () => void, onerror?: (scene: Scene, e: any) => void): void;
+        /**
+        * Load a scene
+        * @param rootUrl a string that defines the root url for scene and resources
+        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
+        * @param engine is the instance of BABYLON.Engine to use to create the scene
+        */
+        static Load(rootUrl: string, sceneFilename: any, engine: Engine, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
+        /**
+        * Append a scene
+        * @param rootUrl a string that defines the root url for scene and resources
+        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
+        * @param scene is the instance of BABYLON.Scene to append to
+        */
+        static Append(rootUrl: string, sceneFilename: any, scene: Scene, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
+    }
+}
+
+declare module BABYLON {
     class SIMDVector3 {
     class SIMDVector3 {
         static TransformCoordinatesToRefSIMD(vector: Vector3, transformation: Matrix, result: Vector3): void;
         static TransformCoordinatesToRefSIMD(vector: Vector3, transformation: Matrix, result: Vector3): void;
         static TransformCoordinatesFromFloatsToRefSIMD(x: number, y: number, z: number, transformation: Matrix, result: Vector3): void;
         static TransformCoordinatesFromFloatsToRefSIMD(x: number, y: number, z: number, transformation: Matrix, result: Vector3): void;
@@ -3517,6 +3523,7 @@ declare module BABYLON {
         _intersectionsInProgress: AbstractMesh[];
         _intersectionsInProgress: AbstractMesh[];
         private _onAfterWorldMatrixUpdate;
         private _onAfterWorldMatrixUpdate;
         private _isWorldMatrixFrozen;
         private _isWorldMatrixFrozen;
+        _unIndexed: boolean;
         _waitingActions: any;
         _waitingActions: any;
         _waitingFreezeWorldMatrix: boolean;
         _waitingFreezeWorldMatrix: boolean;
         constructor(name: string, scene: Scene);
         constructor(name: string, scene: Scene);
@@ -4031,6 +4038,7 @@ declare module BABYLON {
         applyDisplacementMap(url: string, minHeight: number, maxHeight: number, onSuccess?: (mesh: Mesh) => void): void;
         applyDisplacementMap(url: string, minHeight: number, maxHeight: number, onSuccess?: (mesh: Mesh) => void): void;
         applyDisplacementMapFromBuffer(buffer: Uint8Array, heightMapWidth: number, heightMapHeight: number, minHeight: number, maxHeight: number): void;
         applyDisplacementMapFromBuffer(buffer: Uint8Array, heightMapWidth: number, heightMapHeight: number, minHeight: number, maxHeight: number): void;
         convertToFlatShadedMesh(): void;
         convertToFlatShadedMesh(): void;
+        convertToUnIndexedMesh(): void;
         flipFaces(flipNormals?: boolean): void;
         flipFaces(flipNormals?: boolean): void;
         createInstance(name: string): InstancedMesh;
         createInstance(name: string): InstancedMesh;
         synchronizeInstances(): void;
         synchronizeInstances(): void;
@@ -4671,6 +4679,7 @@ declare module BABYLON {
         _distanceToCamera: number;
         _distanceToCamera: number;
         _id: number;
         _id: number;
         constructor(materialIndex: number, verticesStart: number, verticesCount: number, indexStart: any, indexCount: number, mesh: AbstractMesh, renderingMesh?: Mesh, createBoundingBox?: boolean);
         constructor(materialIndex: number, verticesStart: number, verticesCount: number, indexStart: any, indexCount: number, mesh: AbstractMesh, renderingMesh?: Mesh, createBoundingBox?: boolean);
+        IsGlobal: boolean;
         getBoundingInfo(): BoundingInfo;
         getBoundingInfo(): BoundingInfo;
         getMesh(): AbstractMesh;
         getMesh(): AbstractMesh;
         getRenderingMesh(): Mesh;
         getRenderingMesh(): Mesh;
@@ -5018,6 +5027,114 @@ declare module BABYLON {
 }
 }
 
 
 declare module BABYLON {
 declare module BABYLON {
+    class BoundingBoxRenderer {
+        frontColor: Color3;
+        backColor: Color3;
+        showBackLines: boolean;
+        renderList: SmartArray<BoundingBox>;
+        private _scene;
+        private _colorShader;
+        private _vb;
+        private _ib;
+        constructor(scene: Scene);
+        private _prepareRessources();
+        reset(): void;
+        render(): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON {
+    class DepthRenderer {
+        private _scene;
+        private _depthMap;
+        private _effect;
+        private _viewMatrix;
+        private _projectionMatrix;
+        private _transformMatrix;
+        private _worldViewProjection;
+        private _cachedDefines;
+        constructor(scene: Scene, type?: number);
+        isReady(subMesh: SubMesh, useInstances: boolean): boolean;
+        getDepthMap(): RenderTargetTexture;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON {
+    class EdgesRenderer {
+        private _source;
+        private _linesPositions;
+        private _linesNormals;
+        private _linesIndices;
+        private _epsilon;
+        private _indicesCount;
+        private _lineShader;
+        private _vb0;
+        private _vb1;
+        private _ib;
+        private _buffers;
+        private _checkVerticesInsteadOfIndices;
+        constructor(source: AbstractMesh, epsilon?: number, checkVerticesInsteadOfIndices?: boolean);
+        private _prepareRessources();
+        dispose(): void;
+        private _processEdgeForAdjacencies(pa, pb, p0, p1, p2);
+        private _processEdgeForAdjacenciesWithVertices(pa, pb, p0, p1, p2);
+        private _checkEdge(faceIndex, edge, faceNormals, p0, p1);
+        _generateEdgesLines(): void;
+        render(): void;
+    }
+}
+
+declare module BABYLON {
+    class OutlineRenderer {
+        private _scene;
+        private _effect;
+        private _cachedDefines;
+        constructor(scene: Scene);
+        render(subMesh: SubMesh, batch: _InstancesBatch, useOverlay?: boolean): void;
+        isReady(subMesh: SubMesh, useInstances: boolean): boolean;
+    }
+}
+
+declare module BABYLON {
+    class RenderingGroup {
+        index: number;
+        private _scene;
+        private _opaqueSubMeshes;
+        private _transparentSubMeshes;
+        private _alphaTestSubMeshes;
+        private _activeVertices;
+        onBeforeTransparentRendering: () => void;
+        constructor(index: number, scene: Scene);
+        render(customRenderFunction: (opaqueSubMeshes: SmartArray<SubMesh>, transparentSubMeshes: SmartArray<SubMesh>, alphaTestSubMeshes: SmartArray<SubMesh>) => void): boolean;
+        prepare(): void;
+        dispatch(subMesh: SubMesh): void;
+    }
+}
+
+declare module BABYLON {
+    class RenderingManager {
+        static MAX_RENDERINGGROUPS: number;
+        private _scene;
+        private _renderingGroups;
+        private _depthBufferAlreadyCleaned;
+        private _currentIndex;
+        private _currentActiveMeshes;
+        private _currentRenderParticles;
+        private _currentRenderSprites;
+        constructor(scene: Scene);
+        private _renderParticles(index, activeMeshes);
+        private _renderSprites(index);
+        private _clearDepthBuffer();
+        private _renderSpritesAndParticles();
+        render(customRenderFunction: (opaqueSubMeshes: SmartArray<SubMesh>, transparentSubMeshes: SmartArray<SubMesh>, alphaTestSubMeshes: SmartArray<SubMesh>) => void, activeMeshes: AbstractMesh[], renderParticles: boolean, renderSprites: boolean): void;
+        reset(): void;
+        dispatch(subMesh: SubMesh): void;
+    }
+}
+
+declare module BABYLON {
     class AnaglyphPostProcess extends PostProcess {
     class AnaglyphPostProcess extends PostProcess {
         constructor(name: string, ratio: number, camera: Camera, samplingMode?: number, engine?: Engine, reusable?: boolean);
         constructor(name: string, ratio: number, camera: Camera, samplingMode?: number, engine?: Engine, reusable?: boolean);
     }
     }
@@ -5608,114 +5725,6 @@ declare module BABYLON {
 }
 }
 
 
 declare module BABYLON {
 declare module BABYLON {
-    class BoundingBoxRenderer {
-        frontColor: Color3;
-        backColor: Color3;
-        showBackLines: boolean;
-        renderList: SmartArray<BoundingBox>;
-        private _scene;
-        private _colorShader;
-        private _vb;
-        private _ib;
-        constructor(scene: Scene);
-        private _prepareRessources();
-        reset(): void;
-        render(): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
-    class DepthRenderer {
-        private _scene;
-        private _depthMap;
-        private _effect;
-        private _viewMatrix;
-        private _projectionMatrix;
-        private _transformMatrix;
-        private _worldViewProjection;
-        private _cachedDefines;
-        constructor(scene: Scene, type?: number);
-        isReady(subMesh: SubMesh, useInstances: boolean): boolean;
-        getDepthMap(): RenderTargetTexture;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
-    class EdgesRenderer {
-        private _source;
-        private _linesPositions;
-        private _linesNormals;
-        private _linesIndices;
-        private _epsilon;
-        private _indicesCount;
-        private _lineShader;
-        private _vb0;
-        private _vb1;
-        private _ib;
-        private _buffers;
-        private _checkVerticesInsteadOfIndices;
-        constructor(source: AbstractMesh, epsilon?: number, checkVerticesInsteadOfIndices?: boolean);
-        private _prepareRessources();
-        dispose(): void;
-        private _processEdgeForAdjacencies(pa, pb, p0, p1, p2);
-        private _processEdgeForAdjacenciesWithVertices(pa, pb, p0, p1, p2);
-        private _checkEdge(faceIndex, edge, faceNormals, p0, p1);
-        _generateEdgesLines(): void;
-        render(): void;
-    }
-}
-
-declare module BABYLON {
-    class OutlineRenderer {
-        private _scene;
-        private _effect;
-        private _cachedDefines;
-        constructor(scene: Scene);
-        render(subMesh: SubMesh, batch: _InstancesBatch, useOverlay?: boolean): void;
-        isReady(subMesh: SubMesh, useInstances: boolean): boolean;
-    }
-}
-
-declare module BABYLON {
-    class RenderingGroup {
-        index: number;
-        private _scene;
-        private _opaqueSubMeshes;
-        private _transparentSubMeshes;
-        private _alphaTestSubMeshes;
-        private _activeVertices;
-        onBeforeTransparentRendering: () => void;
-        constructor(index: number, scene: Scene);
-        render(customRenderFunction: (opaqueSubMeshes: SmartArray<SubMesh>, transparentSubMeshes: SmartArray<SubMesh>, alphaTestSubMeshes: SmartArray<SubMesh>) => void): boolean;
-        prepare(): void;
-        dispatch(subMesh: SubMesh): void;
-    }
-}
-
-declare module BABYLON {
-    class RenderingManager {
-        static MAX_RENDERINGGROUPS: number;
-        private _scene;
-        private _renderingGroups;
-        private _depthBufferAlreadyCleaned;
-        private _currentIndex;
-        private _currentActiveMeshes;
-        private _currentRenderParticles;
-        private _currentRenderSprites;
-        constructor(scene: Scene);
-        private _renderParticles(index, activeMeshes);
-        private _renderSprites(index);
-        private _clearDepthBuffer();
-        private _renderSpritesAndParticles();
-        render(customRenderFunction: (opaqueSubMeshes: SmartArray<SubMesh>, transparentSubMeshes: SmartArray<SubMesh>, alphaTestSubMeshes: SmartArray<SubMesh>) => void, activeMeshes: AbstractMesh[], renderParticles: boolean, renderSprites: boolean): void;
-        reset(): void;
-        dispatch(subMesh: SubMesh): void;
-    }
-}
-
-declare module BABYLON {
     class Sprite {
     class Sprite {
         name: string;
         name: string;
         position: Vector3;
         position: Vector3;
@@ -6579,9 +6588,6 @@ declare module BABYLON {
     }
     }
 }
 }
 
 
-declare module BABYLON.Internals {
-}
-
 declare module BABYLON {
 declare module BABYLON {
     class BaseTexture {
     class BaseTexture {
         name: string;
         name: string;
@@ -6789,6 +6795,9 @@ declare module BABYLON {
     }
     }
 }
 }
 
 
+declare module BABYLON.Internals {
+}
+
 declare module BABYLON {
 declare module BABYLON {
     class CannonJSPlugin implements IPhysicsEnginePlugin {
     class CannonJSPlugin implements IPhysicsEnginePlugin {
         private _world;
         private _world;

Разница между файлами не показана из-за своего большого размера
+ 25 - 29
dist/preview release/babylon.js


Разница между файлами не показана из-за своего большого размера
+ 1881 - 1759
dist/preview release/babylon.max.js


Разница между файлами не показана из-за своего большого размера
+ 24 - 28
dist/preview release/babylon.noworker.js


+ 1 - 0
dist/preview release/what's new.md

@@ -18,6 +18,7 @@
     - New `Mesh.CreateIcoSphere()` method. [Demo here](http://www.babylonjs-playground.com/#24DUYD) (G'kar)
     - New `Mesh.CreateIcoSphere()` method. [Demo here](http://www.babylonjs-playground.com/#24DUYD) (G'kar)
     - Introducing [babylon.core.js](http://doc.babylonjs.com/generals/Framework_versions) ([deltakosh](https://github.com/deltakosh))
     - Introducing [babylon.core.js](http://doc.babylonjs.com/generals/Framework_versions) ([deltakosh](https://github.com/deltakosh))
   - **Updates**
   - **Updates**
+    - new `Mesh.convertToUnIndexedMesh()` to create meshes with no indices (which could be faster when vertex reuse is low and vertex structure is small) ([deltakosh](https://github.com/deltakosh)) 
 	- Unity3D exporter will recognise instances of prefabs ([ozRocker](https://github.com/punkoffice))
 	- Unity3D exporter will recognise instances of prefabs ([ozRocker](https://github.com/punkoffice))
     - New parse mechanism (for loading .babylon file) ([deltakosh](https://github.com/deltakosh))   
     - New parse mechanism (for loading .babylon file) ([deltakosh](https://github.com/deltakosh))   
     - New button to log the camera position in the debug layer ([temechon](https://github.com/temechon))
     - New button to log the camera position in the debug layer ([temechon](https://github.com/temechon))

+ 0 - 1
src/Lights/babylon.light.ts

@@ -73,7 +73,6 @@
                 return false;
                 return false;
             }
             }
 
 
-
             if (this.excludeWithLayerMask !== 0 && this.excludeWithLayerMask & mesh.layerMask) {
             if (this.excludeWithLayerMask !== 0 && this.excludeWithLayerMask & mesh.layerMask) {
                 return false;
                 return false;
             }
             }

+ 3 - 3
src/Materials/babylon.effect.js

@@ -305,9 +305,9 @@ var BABYLON;
             return this;
             return this;
         };
         };
         Effect.prototype.setMatrix = function (uniformName, matrix) {
         Effect.prototype.setMatrix = function (uniformName, matrix) {
-            if (this._valueCache[uniformName] && this._valueCache[uniformName].equals(matrix))
-                return this;
-            this._cacheMatrix(uniformName, matrix);
+            //if (this._valueCache[uniformName] && this._valueCache[uniformName].equals(matrix))
+            //    return this;
+            // this._cacheMatrix(uniformName, matrix);
             this._engine.setMatrix(this.getUniform(uniformName), matrix);
             this._engine.setMatrix(this.getUniform(uniformName), matrix);
             return this;
             return this;
         };
         };

+ 14 - 14
src/Materials/babylon.effect.ts

@@ -5,8 +5,8 @@
         private _currentRank = 32;
         private _currentRank = 32;
         private _maxRank = -1;
         private _maxRank = -1;
 
 
-        private _mesh : AbstractMesh;
-        private _meshRank : number;
+        private _mesh: AbstractMesh;
+        private _meshRank: number;
 
 
         public addFallback(rank: number, define: string): void {
         public addFallback(rank: number, define: string): void {
             if (!this._defines[rank]) {
             if (!this._defines[rank]) {
@@ -24,14 +24,14 @@
             this._defines[rank].push(define);
             this._defines[rank].push(define);
         }
         }
 
 
-            public addCPUSkinningFallback(rank: number, mesh : BABYLON.AbstractMesh){
-                this._meshRank = rank;
-                this._mesh = mesh;
-    
-                if (rank > this._maxRank) {
-                    this._maxRank = rank;
-                }
+        public addCPUSkinningFallback(rank: number, mesh: BABYLON.AbstractMesh) {
+            this._meshRank = rank;
+            this._mesh = mesh;
+
+            if (rank > this._maxRank) {
+                this._maxRank = rank;
             }
             }
+        }
 
 
         public get isMoreFallbacks(): boolean {
         public get isMoreFallbacks(): boolean {
             return this._currentRank <= this._maxRank;
             return this._currentRank <= this._maxRank;
@@ -45,7 +45,7 @@
                 currentDefines = currentDefines.replace("#define " + currentFallbacks[index], "");
                 currentDefines = currentDefines.replace("#define " + currentFallbacks[index], "");
             }
             }
 
 
-            if (this._mesh && this._currentRank === this._meshRank){
+            if (this._mesh && this._currentRank === this._meshRank) {
                 this._mesh.computeBonesUsingShaders = false;
                 this._mesh.computeBonesUsingShaders = false;
                 currentDefines = currentDefines.replace("#define NUM_BONE_INFLUENCERS " + this._mesh.numBoneInfluencers, "#define NUM_BONE_INFLUENCERS 0");
                 currentDefines = currentDefines.replace("#define NUM_BONE_INFLUENCERS " + this._mesh.numBoneInfluencers, "#define NUM_BONE_INFLUENCERS 0");
                 Tools.Log("Falling back to CPU skinning for " + this._mesh.name);
                 Tools.Log("Falling back to CPU skinning for " + this._mesh.name);
@@ -380,10 +380,10 @@
         }
         }
 
 
         public setMatrix(uniformName: string, matrix: Matrix): Effect {
         public setMatrix(uniformName: string, matrix: Matrix): Effect {
-            if (this._valueCache[uniformName] && this._valueCache[uniformName].equals(matrix))
-                return this;
+            //if (this._valueCache[uniformName] && this._valueCache[uniformName].equals(matrix))
+            //    return this;
 
 
-            this._cacheMatrix(uniformName, matrix);
+           // this._cacheMatrix(uniformName, matrix);
             this._engine.setMatrix(this.getUniform(uniformName), matrix);
             this._engine.setMatrix(this.getUniform(uniformName), matrix);
 
 
             return this;
             return this;
@@ -508,4 +508,4 @@
         // Statics
         // Statics
         public static ShadersStore = {};
         public static ShadersStore = {};
     }
     }
-} 
+} 

+ 13 - 0
src/Materials/babylon.material.js

@@ -132,6 +132,19 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
+        Object.defineProperty(Material.prototype, "isFrozen", {
+            get: function () {
+                return this.checkReadyOnlyOnce;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Material.prototype.freeze = function () {
+            this.checkReadyOnlyOnce = true;
+        };
+        Material.prototype.unfreeze = function () {
+            this.checkReadyOnlyOnce = false;
+        };
         Material.prototype.isReady = function (mesh, useInstances) {
         Material.prototype.isReady = function (mesh, useInstances) {
             return true;
             return true;
         };
         };

+ 12 - 0
src/Materials/babylon.material.ts

@@ -140,6 +140,18 @@
             }
             }
         }
         }
 
 
+        public get isFrozen(): boolean {
+            return this.checkReadyOnlyOnce;
+        }
+
+        public freeze(): void {
+            this.checkReadyOnlyOnce = true;
+        }
+
+        public unfreeze(): void {
+            this.checkReadyOnlyOnce = false;
+        }
+
         public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
         public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
             return true;
             return true;
         }
         }

+ 23 - 21
src/Materials/babylon.standardMaterial.js

@@ -141,7 +141,7 @@ var BABYLON;
             this.useEmissiveAsIllumination = false;
             this.useEmissiveAsIllumination = false;
             this.linkEmissiveWithDiffuse = false;
             this.linkEmissiveWithDiffuse = false;
             this.useReflectionFresnelFromSpecular = false;
             this.useReflectionFresnelFromSpecular = false;
-            this.useSpecularOverAlpha = true;
+            this.useSpecularOverAlpha = false;
             this.disableLighting = false;
             this.disableLighting = false;
             this.roughness = 0;
             this.roughness = 0;
             this.useLightmapAsShadowmap = false;
             this.useLightmapAsShadowmap = false;
@@ -322,7 +322,7 @@ var BABYLON;
             }
             }
         };
         };
         StandardMaterial.prototype.isReady = function (mesh, useInstances) {
         StandardMaterial.prototype.isReady = function (mesh, useInstances) {
-            if (this.checkReadyOnlyOnce) {
+            if (this.isFrozen) {
                 if (this._wasPreviouslyReady) {
                 if (this._wasPreviouslyReady) {
                     return true;
                     return true;
                 }
                 }
@@ -680,12 +680,12 @@ var BABYLON;
             var scene = this.getScene();
             var scene = this.getScene();
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
             // Bones
             // Bones
             if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
             if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
                 this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
                 this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
             }
             }
             if (scene.getCachedMaterial() !== this) {
             if (scene.getCachedMaterial() !== this) {
+                this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
                 if (StandardMaterial.FresnelEnabled) {
                 if (StandardMaterial.FresnelEnabled) {
                     // Fresnel
                     // Fresnel
                     if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled) {
                     if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled) {
@@ -770,24 +770,26 @@ var BABYLON;
                 }
                 }
                 this._effect.setColor3("vEmissiveColor", this.emissiveColor);
                 this._effect.setColor3("vEmissiveColor", this.emissiveColor);
             }
             }
-            // Diffuse
-            this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
-            // Lights
-            if (scene.lightsEnabled && !this.disableLighting) {
-                StandardMaterial.BindLights(scene, mesh, this._effect, this._defines);
-            }
-            // View
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE || this.reflectionTexture) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
-            }
-            // Fog
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
-                this._effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
-                this._effect.setColor3("vFogColor", scene.fogColor);
-            }
-            // Log. depth
-            if (this._defines.LOGARITHMICDEPTH) {
-                this._effect.setFloat("logarithmicDepthConstant", 2.0 / (Math.log(scene.activeCamera.maxZ + 1.0) / Math.LN2));
+            if (scene.getCachedMaterial() !== this || !this.isFrozen) {
+                // Diffuse
+                this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+                // Lights
+                if (scene.lightsEnabled && !this.disableLighting) {
+                    StandardMaterial.BindLights(scene, mesh, this._effect, this._defines);
+                }
+                // View
+                if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE || this.reflectionTexture) {
+                    this._effect.setMatrix("view", scene.getViewMatrix());
+                }
+                // Fog
+                if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
+                    this._effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
+                    this._effect.setColor3("vFogColor", scene.fogColor);
+                }
+                // Log. depth
+                if (this._defines.LOGARITHMICDEPTH) {
+                    this._effect.setFloat("logarithmicDepthConstant", 2.0 / (Math.log(scene.activeCamera.maxZ + 1.0) / Math.LN2));
+                }
             }
             }
             _super.prototype.bind.call(this, world, mesh);
             _super.prototype.bind.call(this, world, mesh);
         };
         };

+ 23 - 21
src/Materials/babylon.standardMaterial.ts

@@ -147,7 +147,7 @@
         public useEmissiveAsIllumination = false;
         public useEmissiveAsIllumination = false;
         public linkEmissiveWithDiffuse = false;
         public linkEmissiveWithDiffuse = false;
         public useReflectionFresnelFromSpecular = false;
         public useReflectionFresnelFromSpecular = false;
-        public useSpecularOverAlpha = true;
+        public useSpecularOverAlpha = false;
         public disableLighting = false;
         public disableLighting = false;
 
 
         public roughness = 0;
         public roughness = 0;
@@ -376,7 +376,7 @@
         }
         }
 
 
         public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
         public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
-            if (this.checkReadyOnlyOnce) {
+            if (this.isFrozen) {
                 if (this._wasPreviouslyReady) {
                 if (this._wasPreviouslyReady) {
                     return true;
                     return true;
                 }
                 }
@@ -806,7 +806,6 @@
 
 
             // Matrices        
             // Matrices        
             this.bindOnlyWorldMatrix(world);
             this.bindOnlyWorldMatrix(world);
-            this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
 
 
             // Bones
             // Bones
             if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
             if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
@@ -814,6 +813,7 @@
             }
             }
 
 
             if (scene.getCachedMaterial() !== this) {
             if (scene.getCachedMaterial() !== this) {
+                this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
 
 
                 if (StandardMaterial.FresnelEnabled) {
                 if (StandardMaterial.FresnelEnabled) {
                     // Fresnel
                     // Fresnel
@@ -923,28 +923,30 @@
                 this._effect.setColor3("vEmissiveColor", this.emissiveColor);
                 this._effect.setColor3("vEmissiveColor", this.emissiveColor);
             }
             }
             
             
-            // Diffuse
-            this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
+            if (scene.getCachedMaterial() !== this || !this.isFrozen) {
+                // Diffuse
+                this._effect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
 
 
-            // Lights
-            if (scene.lightsEnabled && !this.disableLighting) {
-                StandardMaterial.BindLights(scene, mesh, this._effect, this._defines);
-            }
+                // Lights
+                if (scene.lightsEnabled && !this.disableLighting) {
+                    StandardMaterial.BindLights(scene, mesh, this._effect, this._defines);
+                }
 
 
-            // View
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE || this.reflectionTexture) {
-                this._effect.setMatrix("view", scene.getViewMatrix());
-            }
+                // View
+                if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE || this.reflectionTexture) {
+                    this._effect.setMatrix("view", scene.getViewMatrix());
+                }
 
 
-            // Fog
-            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
-                this._effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
-                this._effect.setColor3("vFogColor", scene.fogColor);
-            }
+                // Fog
+                if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
+                    this._effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
+                    this._effect.setColor3("vFogColor", scene.fogColor);
+                }
 
 
-            // Log. depth
-            if (this._defines.LOGARITHMICDEPTH) {
-                this._effect.setFloat("logarithmicDepthConstant", 2.0 / (Math.log(scene.activeCamera.maxZ + 1.0) / Math.LN2));
+                // Log. depth
+                if (this._defines.LOGARITHMICDEPTH) {
+                    this._effect.setFloat("logarithmicDepthConstant", 2.0 / (Math.log(scene.activeCamera.maxZ + 1.0) / Math.LN2));
+                }
             }
             }
 
 
             super.bind(world, mesh);
             super.bind(world, mesh);

+ 4 - 1
src/Mesh/babylon.abstractMesh.js

@@ -77,6 +77,7 @@ var BABYLON;
             this._intersectionsInProgress = new Array();
             this._intersectionsInProgress = new Array();
             this._onAfterWorldMatrixUpdate = new Array();
             this._onAfterWorldMatrixUpdate = new Array();
             this._isWorldMatrixFrozen = false;
             this._isWorldMatrixFrozen = false;
+            this._unIndexed = false;
             this._onCollisionPositionChange = function (collisionId, newPosition, collidedMesh) {
             this._onCollisionPositionChange = function (collisionId, newPosition, collidedMesh) {
                 if (collidedMesh === void 0) { collidedMesh = null; }
                 if (collidedMesh === void 0) { collidedMesh = null; }
                 //TODO move this to the collision coordinator!
                 //TODO move this to the collision coordinator!
@@ -403,7 +404,9 @@ var BABYLON;
             }
             }
             for (var subIndex = 0; subIndex < this.subMeshes.length; subIndex++) {
             for (var subIndex = 0; subIndex < this.subMeshes.length; subIndex++) {
                 var subMesh = this.subMeshes[subIndex];
                 var subMesh = this.subMeshes[subIndex];
-                subMesh.updateBoundingInfo(matrix);
+                if (!subMesh.IsGlobal) {
+                    subMesh.updateBoundingInfo(matrix);
+                }
             }
             }
         };
         };
         AbstractMesh.prototype.computeWorldMatrix = function (force) {
         AbstractMesh.prototype.computeWorldMatrix = function (force) {

+ 5 - 1
src/Mesh/babylon.abstractMesh.ts

@@ -127,6 +127,8 @@
 
 
         private _isWorldMatrixFrozen = false;
         private _isWorldMatrixFrozen = false;
 
 
+        public _unIndexed = false;
+
         // Loading properties
         // Loading properties
         public _waitingActions: any;
         public _waitingActions: any;
         public _waitingFreezeWorldMatrix: boolean;
         public _waitingFreezeWorldMatrix: boolean;
@@ -439,7 +441,9 @@
             for (var subIndex = 0; subIndex < this.subMeshes.length; subIndex++) {
             for (var subIndex = 0; subIndex < this.subMeshes.length; subIndex++) {
                 var subMesh = this.subMeshes[subIndex];
                 var subMesh = this.subMeshes[subIndex];
 
 
-                subMesh.updateBoundingInfo(matrix);
+                if (!subMesh.IsGlobal) {
+                    subMesh.updateBoundingInfo(matrix);
+                }
             }
             }
         }
         }
 
 

+ 82 - 13
src/Mesh/babylon.mesh.js

@@ -460,17 +460,22 @@ var BABYLON;
             var engine = this.getScene().getEngine();
             var engine = this.getScene().getEngine();
             // Wireframe
             // Wireframe
             var indexToBind;
             var indexToBind;
-            switch (fillMode) {
-                case BABYLON.Material.PointFillMode:
-                    indexToBind = null;
-                    break;
-                case BABYLON.Material.WireFrameFillMode:
-                    indexToBind = subMesh.getLinesIndexBuffer(this.getIndices(), engine);
-                    break;
-                default:
-                case BABYLON.Material.TriangleFillMode:
-                    indexToBind = this._geometry.getIndexBuffer();
-                    break;
+            if (this._unIndexed) {
+                indexToBind = null;
+            }
+            else {
+                switch (fillMode) {
+                    case BABYLON.Material.PointFillMode:
+                        indexToBind = null;
+                        break;
+                    case BABYLON.Material.WireFrameFillMode:
+                        indexToBind = subMesh.getLinesIndexBuffer(this.getIndices(), engine);
+                        break;
+                    default:
+                    case BABYLON.Material.TriangleFillMode:
+                        indexToBind = this._unIndexed ? null : this._geometry.getIndexBuffer();
+                        break;
+                }
             }
             }
             // VBOs
             // VBOs
             engine.bindMultiBuffers(this._geometry.getVertexBuffers(), indexToBind, effect);
             engine.bindMultiBuffers(this._geometry.getVertexBuffers(), indexToBind, effect);
@@ -486,10 +491,20 @@ var BABYLON;
                     engine.drawPointClouds(subMesh.verticesStart, subMesh.verticesCount, instancesCount);
                     engine.drawPointClouds(subMesh.verticesStart, subMesh.verticesCount, instancesCount);
                     break;
                     break;
                 case BABYLON.Material.WireFrameFillMode:
                 case BABYLON.Material.WireFrameFillMode:
-                    engine.draw(false, 0, subMesh.linesIndexCount, instancesCount);
+                    if (this._unIndexed) {
+                        engine.drawUnIndexed(false, subMesh.verticesStart, subMesh.verticesCount, instancesCount);
+                    }
+                    else {
+                        engine.draw(false, 0, subMesh.linesIndexCount, instancesCount);
+                    }
                     break;
                     break;
                 default:
                 default:
-                    engine.draw(true, subMesh.indexStart, subMesh.indexCount, instancesCount);
+                    if (this._unIndexed) {
+                        engine.drawUnIndexed(true, subMesh.verticesStart, subMesh.verticesCount, instancesCount);
+                    }
+                    else {
+                        engine.draw(true, subMesh.indexStart, subMesh.indexCount, instancesCount);
+                    }
             }
             }
         };
         };
         Mesh.prototype.registerBeforeRender = function (func) {
         Mesh.prototype.registerBeforeRender = function (func) {
@@ -972,6 +987,60 @@ var BABYLON;
             }
             }
             this.synchronizeInstances();
             this.synchronizeInstances();
         };
         };
+        Mesh.prototype.convertToUnIndexedMesh = function () {
+            /// <summary>Remove indices by unfolding faces into buffers</summary>
+            /// <summary>Warning: This implies adding vertices to the mesh in order to get exactly 3 vertices per face</summary>
+            var kinds = this.getVerticesDataKinds();
+            var vbs = [];
+            var data = [];
+            var newdata = [];
+            var updatableNormals = false;
+            var kindIndex;
+            var kind;
+            for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
+                kind = kinds[kindIndex];
+                var vertexBuffer = this.getVertexBuffer(kind);
+                vbs[kind] = vertexBuffer;
+                data[kind] = vbs[kind].getData();
+                newdata[kind] = [];
+            }
+            // Save previous submeshes
+            var previousSubmeshes = this.subMeshes.slice(0);
+            var indices = this.getIndices();
+            var totalIndices = this.getTotalIndices();
+            // Generating unique vertices per face
+            var index;
+            for (index = 0; index < totalIndices; index++) {
+                var vertexIndex = indices[index];
+                for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
+                    kind = kinds[kindIndex];
+                    var stride = vbs[kind].getStrideSize();
+                    for (var offset = 0; offset < stride; offset++) {
+                        newdata[kind].push(data[kind][vertexIndex * stride + offset]);
+                    }
+                }
+            }
+            // Updating indices
+            for (index = 0; index < totalIndices; index += 3) {
+                indices[index] = index;
+                indices[index + 1] = index + 1;
+                indices[index + 2] = index + 2;
+            }
+            this.setIndices(indices);
+            // Updating vertex buffers
+            for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
+                kind = kinds[kindIndex];
+                this.setVerticesData(kind, newdata[kind], vbs[kind].isUpdatable());
+            }
+            // Updating submeshes
+            this.releaseSubMeshes();
+            for (var submeshIndex = 0; submeshIndex < previousSubmeshes.length; submeshIndex++) {
+                var previousOne = previousSubmeshes[submeshIndex];
+                var subMesh = new BABYLON.SubMesh(previousOne.materialIndex, previousOne.indexStart, previousOne.indexCount, previousOne.indexStart, previousOne.indexCount, this);
+            }
+            this._unIndexed = true;
+            this.synchronizeInstances();
+        };
         // will inverse faces orientations, and invert normals too if specified
         // will inverse faces orientations, and invert normals too if specified
         Mesh.prototype.flipFaces = function (flipNormals) {
         Mesh.prototype.flipFaces = function (flipNormals) {
             if (flipNormals === void 0) { flipNormals = false; }
             if (flipNormals === void 0) { flipNormals = false; }

+ 92 - 13
src/Mesh/babylon.mesh.ts

@@ -505,17 +505,21 @@
             // Wireframe
             // Wireframe
             var indexToBind;
             var indexToBind;
 
 
-            switch (fillMode) {
-                case Material.PointFillMode:
-                    indexToBind = null;
-                    break;
-                case Material.WireFrameFillMode:
-                    indexToBind = subMesh.getLinesIndexBuffer(this.getIndices(), engine);
-                    break;
-                default:
-                case Material.TriangleFillMode:
-                    indexToBind = this._geometry.getIndexBuffer();
-                    break;
+            if (this._unIndexed) {
+                indexToBind = null;
+            } else {
+                switch (fillMode) {
+                    case Material.PointFillMode:
+                        indexToBind = null;
+                        break;
+                    case Material.WireFrameFillMode:
+                        indexToBind = subMesh.getLinesIndexBuffer(this.getIndices(), engine);
+                        break;
+                    default:
+                    case Material.TriangleFillMode:
+                        indexToBind = this._unIndexed ? null : this._geometry.getIndexBuffer();
+                        break;
+                }
             }
             }
 
 
             // VBOs
             // VBOs
@@ -535,11 +539,19 @@
                     engine.drawPointClouds(subMesh.verticesStart, subMesh.verticesCount, instancesCount);
                     engine.drawPointClouds(subMesh.verticesStart, subMesh.verticesCount, instancesCount);
                     break;
                     break;
                 case Material.WireFrameFillMode:
                 case Material.WireFrameFillMode:
-                    engine.draw(false, 0, subMesh.linesIndexCount, instancesCount);
+                    if (this._unIndexed) {
+                        engine.drawUnIndexed(false, subMesh.verticesStart, subMesh.verticesCount, instancesCount);
+                    } else {
+                        engine.draw(false, 0, subMesh.linesIndexCount, instancesCount);
+                    }
                     break;
                     break;
 
 
                 default:
                 default:
-                    engine.draw(true, subMesh.indexStart, subMesh.indexCount, instancesCount);
+                    if (this._unIndexed) {
+                        engine.drawUnIndexed(true, subMesh.verticesStart, subMesh.verticesCount, instancesCount);
+                    } else {
+                        engine.draw(true, subMesh.indexStart, subMesh.indexCount, instancesCount);
+                    }
             }
             }
         }
         }
 
 
@@ -1148,6 +1160,73 @@
             this.synchronizeInstances();
             this.synchronizeInstances();
         }
         }
 
 
+        public convertToUnIndexedMesh(): void {
+            /// <summary>Remove indices by unfolding faces into buffers</summary>
+            /// <summary>Warning: This implies adding vertices to the mesh in order to get exactly 3 vertices per face</summary>
+
+            var kinds = this.getVerticesDataKinds();
+            var vbs = [];
+            var data = [];
+            var newdata = [];
+            var updatableNormals = false;
+            var kindIndex: number;
+            var kind: string;
+            for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
+                kind = kinds[kindIndex];
+                var vertexBuffer = this.getVertexBuffer(kind);
+                vbs[kind] = vertexBuffer;
+                data[kind] = vbs[kind].getData();
+                newdata[kind] = [];
+            }
+
+            // Save previous submeshes
+            var previousSubmeshes = this.subMeshes.slice(0);
+
+            var indices = this.getIndices();
+            var totalIndices = this.getTotalIndices();
+
+            // Generating unique vertices per face
+            var index: number;
+            for (index = 0; index < totalIndices; index++) {
+                var vertexIndex = indices[index];
+
+                for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
+                    kind = kinds[kindIndex];
+                    var stride = vbs[kind].getStrideSize();
+
+                    for (var offset = 0; offset < stride; offset++) {
+                        newdata[kind].push(data[kind][vertexIndex * stride + offset]);
+                    }
+                }
+            }
+
+            // Updating indices
+            for (index = 0; index < totalIndices; index += 3) {
+                indices[index] = index;
+                indices[index + 1] = index + 1;
+                indices[index + 2] = index + 2;
+            }
+
+            this.setIndices(indices);
+
+            // Updating vertex buffers
+            for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
+                kind = kinds[kindIndex];
+                this.setVerticesData(kind, newdata[kind], vbs[kind].isUpdatable());
+            }
+
+            // Updating submeshes
+            this.releaseSubMeshes();
+            for (var submeshIndex = 0; submeshIndex < previousSubmeshes.length; submeshIndex++) {
+                var previousOne = previousSubmeshes[submeshIndex];
+                var subMesh = new SubMesh(previousOne.materialIndex, previousOne.indexStart, previousOne.indexCount, previousOne.indexStart, previousOne.indexCount, this);
+            }
+
+            this._unIndexed = true;
+
+            this.synchronizeInstances();
+        }
+
         // will inverse faces orientations, and invert normals too if specified
         // will inverse faces orientations, and invert normals too if specified
         public flipFaces(flipNormals: boolean = false): void {
         public flipFaces(flipNormals: boolean = false): void {
             var vertex_data = VertexData.ExtractFromMesh(this);
             var vertex_data = VertexData.ExtractFromMesh(this);

+ 21 - 6
src/Mesh/babylon.subMesh.js

@@ -19,7 +19,17 @@ var BABYLON;
                 mesh.computeWorldMatrix(true);
                 mesh.computeWorldMatrix(true);
             }
             }
         }
         }
+        Object.defineProperty(SubMesh.prototype, "IsGlobal", {
+            get: function () {
+                return (this.verticesStart === 0 && this.verticesCount == this._mesh.getTotalVertices());
+            },
+            enumerable: true,
+            configurable: true
+        });
         SubMesh.prototype.getBoundingInfo = function () {
         SubMesh.prototype.getBoundingInfo = function () {
+            if (this.IsGlobal) {
+                return this._mesh.getBoundingInfo();
+            }
             return this._boundingInfo;
             return this._boundingInfo;
         };
         };
         SubMesh.prototype.getMesh = function () {
         SubMesh.prototype.getMesh = function () {
@@ -41,6 +51,9 @@ var BABYLON;
         };
         };
         // Methods
         // Methods
         SubMesh.prototype.refreshBoundingInfo = function () {
         SubMesh.prototype.refreshBoundingInfo = function () {
+            if (this.IsGlobal) {
+                return;
+            }
             var data = this._renderingMesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
             var data = this._renderingMesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
             if (!data) {
             if (!data) {
                 this._boundingInfo = this._mesh._boundingInfo;
                 this._boundingInfo = this._mesh._boundingInfo;
@@ -59,16 +72,16 @@ var BABYLON;
             this._boundingInfo = new BABYLON.BoundingInfo(extend.minimum, extend.maximum);
             this._boundingInfo = new BABYLON.BoundingInfo(extend.minimum, extend.maximum);
         };
         };
         SubMesh.prototype._checkCollision = function (collider) {
         SubMesh.prototype._checkCollision = function (collider) {
-            return this._boundingInfo._checkCollision(collider);
+            return this.getBoundingInfo()._checkCollision(collider);
         };
         };
         SubMesh.prototype.updateBoundingInfo = function (world) {
         SubMesh.prototype.updateBoundingInfo = function (world) {
-            if (!this._boundingInfo) {
+            if (!this.getBoundingInfo()) {
                 this.refreshBoundingInfo();
                 this.refreshBoundingInfo();
             }
             }
-            this._boundingInfo._update(world);
+            this.getBoundingInfo()._update(world);
         };
         };
         SubMesh.prototype.isInFrustum = function (frustumPlanes) {
         SubMesh.prototype.isInFrustum = function (frustumPlanes) {
-            return this._boundingInfo.isInFrustum(frustumPlanes);
+            return this.getBoundingInfo().isInFrustum(frustumPlanes);
         };
         };
         SubMesh.prototype.render = function (enableAlphaMode) {
         SubMesh.prototype.render = function (enableAlphaMode) {
             this._renderingMesh.render(this, enableAlphaMode);
             this._renderingMesh.render(this, enableAlphaMode);
@@ -85,7 +98,7 @@ var BABYLON;
             return this._linesIndexBuffer;
             return this._linesIndexBuffer;
         };
         };
         SubMesh.prototype.canIntersects = function (ray) {
         SubMesh.prototype.canIntersects = function (ray) {
-            return ray.intersectsBox(this._boundingInfo.boundingBox);
+            return ray.intersectsBox(this.getBoundingInfo().boundingBox);
         };
         };
         SubMesh.prototype.intersects = function (ray, positions, indices, fastCheck) {
         SubMesh.prototype.intersects = function (ray, positions, indices, fastCheck) {
             var intersectInfo = null;
             var intersectInfo = null;
@@ -113,7 +126,9 @@ var BABYLON;
         // Clone    
         // Clone    
         SubMesh.prototype.clone = function (newMesh, newRenderingMesh) {
         SubMesh.prototype.clone = function (newMesh, newRenderingMesh) {
             var result = new SubMesh(this.materialIndex, this.verticesStart, this.verticesCount, this.indexStart, this.indexCount, newMesh, newRenderingMesh, false);
             var result = new SubMesh(this.materialIndex, this.verticesStart, this.verticesCount, this.indexStart, this.indexCount, newMesh, newRenderingMesh, false);
-            result._boundingInfo = new BABYLON.BoundingInfo(this._boundingInfo.minimum, this._boundingInfo.maximum);
+            if (!this.IsGlobal) {
+                result._boundingInfo = new BABYLON.BoundingInfo(this.getBoundingInfo().minimum, this.getBoundingInfo().maximum);
+            }
             return result;
             return result;
         };
         };
         // Dispose
         // Dispose

+ 19 - 6
src/Mesh/babylon.subMesh.ts

@@ -30,7 +30,15 @@
             }
             }
         }
         }
 
 
+        public get IsGlobal(): boolean {
+            return (this.verticesStart === 0 && this.verticesCount == this._mesh.getTotalVertices());
+        }
+
         public getBoundingInfo(): BoundingInfo {
         public getBoundingInfo(): BoundingInfo {
+            if (this.IsGlobal) {
+                return this._mesh.getBoundingInfo();
+            }
+
             return this._boundingInfo;
             return this._boundingInfo;
         }
         }
 
 
@@ -59,6 +67,9 @@
 
 
         // Methods
         // Methods
         public refreshBoundingInfo(): void {
         public refreshBoundingInfo(): void {
+            if (this.IsGlobal) {
+                return;
+            }
             var data = this._renderingMesh.getVerticesData(VertexBuffer.PositionKind);
             var data = this._renderingMesh.getVerticesData(VertexBuffer.PositionKind);
 
 
             if (!data) {
             if (!data) {
@@ -80,18 +91,18 @@
         }
         }
 
 
         public _checkCollision(collider: Collider): boolean {
         public _checkCollision(collider: Collider): boolean {
-            return this._boundingInfo._checkCollision(collider);
+            return this.getBoundingInfo()._checkCollision(collider);
         }
         }
 
 
         public updateBoundingInfo(world: Matrix): void {
         public updateBoundingInfo(world: Matrix): void {
-            if (!this._boundingInfo) {
+            if (!this.getBoundingInfo()) {
                 this.refreshBoundingInfo();
                 this.refreshBoundingInfo();
             }
             }
-            this._boundingInfo._update(world);
+            this.getBoundingInfo()._update(world);
         }
         }
 
 
         public isInFrustum(frustumPlanes: Plane[]): boolean {
         public isInFrustum(frustumPlanes: Plane[]): boolean {
-            return this._boundingInfo.isInFrustum(frustumPlanes);
+            return this.getBoundingInfo().isInFrustum(frustumPlanes);
         }
         }
 
 
         public render(enableAlphaMode: boolean): void {
         public render(enableAlphaMode: boolean): void {
@@ -115,7 +126,7 @@
         }
         }
 
 
         public canIntersects(ray: Ray): boolean {
         public canIntersects(ray: Ray): boolean {
-            return ray.intersectsBox(this._boundingInfo.boundingBox);
+            return ray.intersectsBox(this.getBoundingInfo().boundingBox);
         }
         }
 
 
         public intersects(ray: Ray, positions: Vector3[], indices: number[] | Int32Array, fastCheck?: boolean): IntersectionInfo {
         public intersects(ray: Ray, positions: Vector3[], indices: number[] | Int32Array, fastCheck?: boolean): IntersectionInfo {
@@ -152,7 +163,9 @@
         public clone(newMesh: AbstractMesh, newRenderingMesh?: Mesh): SubMesh {
         public clone(newMesh: AbstractMesh, newRenderingMesh?: Mesh): SubMesh {
             var result = new SubMesh(this.materialIndex, this.verticesStart, this.verticesCount, this.indexStart, this.indexCount, newMesh, newRenderingMesh, false);
             var result = new SubMesh(this.materialIndex, this.verticesStart, this.verticesCount, this.indexStart, this.indexCount, newMesh, newRenderingMesh, false);
 
 
-            result._boundingInfo = new BoundingInfo(this._boundingInfo.minimum, this._boundingInfo.maximum);
+            if (!this.IsGlobal) {
+                result._boundingInfo = new BoundingInfo(this.getBoundingInfo().minimum, this.getBoundingInfo().maximum);
+            }
 
 
             return result;
             return result;
         }
         }

+ 4 - 4
src/Physics/Plugins/babylon.cannonJSPlugin.ts

@@ -392,7 +392,7 @@
             }
             }
         }
         }
 
 
-        public updateBodyPosition = function(mesh: AbstractMesh): void {
+        public updateBodyPosition = function (mesh: AbstractMesh): void {
             for (var index = 0; index < this._registeredMeshes.length; index++) {
             for (var index = 0; index < this._registeredMeshes.length; index++) {
                 var registeredMesh = this._registeredMeshes[index];
                 var registeredMesh = this._registeredMeshes[index];
                 if (registeredMesh.mesh === mesh || registeredMesh.mesh === mesh.parent) {
                 if (registeredMesh.mesh === mesh || registeredMesh.mesh === mesh.parent) {
@@ -439,9 +439,9 @@
                     } else if (registeredMesh.type === CANNON.Shape.types.TRIMESH) {
                     } else if (registeredMesh.type === CANNON.Shape.types.TRIMESH) {
                         center.copyFromFloats(mesh.position.x, mesh.position.y, mesh.position.z);
                         center.copyFromFloats(mesh.position.x, mesh.position.y, mesh.position.z);
                     }
                     }
-                    
+
                     body.position.set(center.x, center.y, center.z);
                     body.position.set(center.x, center.y, center.z);
-                    
+
                     return;
                     return;
                 }
                 }
             }
             }
@@ -493,4 +493,4 @@
             return null;
             return null;
         }
         }
     }
     }
-}
+}

+ 0 - 1
src/Shaders/default.fragment.fx

@@ -898,7 +898,6 @@ void main(void) {
 #endif
 #endif
 #endif
 #endif
 
 
-
 #ifdef OPACITY
 #ifdef OPACITY
 	vec4 opacityMap = texture2D(opacitySampler, vOpacityUV);
 	vec4 opacityMap = texture2D(opacitySampler, vOpacityUV);
 
 

+ 11 - 1
src/babylon.engine.js

@@ -355,7 +355,7 @@ var BABYLON;
          */
          */
         function Engine(canvas, antialias, options, adaptToDeviceRatio) {
         function Engine(canvas, antialias, options, adaptToDeviceRatio) {
             var _this = this;
             var _this = this;
-            if (adaptToDeviceRatio === void 0) { adaptToDeviceRatio = false; }
+            if (adaptToDeviceRatio === void 0) { adaptToDeviceRatio = true; }
             // Public members
             // Public members
             this.isFullscreen = false;
             this.isFullscreen = false;
             this.isPointerLock = false;
             this.isPointerLock = false;
@@ -1066,6 +1066,16 @@ var BABYLON;
             }
             }
             this._gl.drawArrays(this._gl.POINTS, verticesStart, verticesCount);
             this._gl.drawArrays(this._gl.POINTS, verticesStart, verticesCount);
         };
         };
+        Engine.prototype.drawUnIndexed = function (useTriangles, verticesStart, verticesCount, instancesCount) {
+            // Apply states
+            this.applyStates();
+            this._drawCalls++;
+            if (instancesCount) {
+                this._caps.instancedArrays.drawArraysInstancedANGLE(useTriangles ? this._gl.TRIANGLES : this._gl.LINES, verticesStart, verticesCount, instancesCount);
+                return;
+            }
+            this._gl.drawArrays(useTriangles ? this._gl.TRIANGLES : this._gl.LINES, verticesStart, verticesCount);
+        };
         // Shaders
         // Shaders
         Engine.prototype._releaseEffect = function (effect) {
         Engine.prototype._releaseEffect = function (effect) {
             if (this._compiledEffects[effect._key]) {
             if (this._compiledEffects[effect._key]) {

+ 14 - 1
src/babylon.engine.ts

@@ -568,7 +568,7 @@
          * @param {boolean} [antialias] - enable antialias
          * @param {boolean} [antialias] - enable antialias
          * @param options - further options to be sent to the getContext function
          * @param options - further options to be sent to the getContext function
          */
          */
-        constructor(canvas: HTMLCanvasElement, antialias?: boolean, options?: { antialias?: boolean, preserveDrawingBuffer?: boolean }, adaptToDeviceRatio = false) {
+        constructor(canvas: HTMLCanvasElement, antialias?: boolean, options?: { antialias?: boolean, preserveDrawingBuffer?: boolean }, adaptToDeviceRatio = true) {
             this._renderingCanvas = canvas;
             this._renderingCanvas = canvas;
 
 
             options = options || {};
             options = options || {};
@@ -1239,6 +1239,19 @@
             this._gl.drawArrays(this._gl.POINTS, verticesStart, verticesCount);
             this._gl.drawArrays(this._gl.POINTS, verticesStart, verticesCount);
         }
         }
 
 
+        public drawUnIndexed(useTriangles: boolean, verticesStart: number, verticesCount: number, instancesCount?: number): void {
+            // Apply states
+            this.applyStates();
+            this._drawCalls++;
+
+            if (instancesCount) {
+                this._caps.instancedArrays.drawArraysInstancedANGLE(useTriangles ? this._gl.TRIANGLES : this._gl.LINES, verticesStart, verticesCount, instancesCount);
+                return;
+            }
+
+            this._gl.drawArrays(useTriangles ? this._gl.TRIANGLES : this._gl.LINES, verticesStart, verticesCount);
+        }
+
         // Shaders
         // Shaders
         public _releaseEffect(effect: Effect): void {
         public _releaseEffect(effect: Effect): void {
             if (this._compiledEffects[effect._key]) {
             if (this._compiledEffects[effect._key]) {

+ 10 - 0
src/babylon.scene.js

@@ -1651,6 +1651,16 @@ var BABYLON;
             this._depthRenderer.dispose();
             this._depthRenderer.dispose();
             this._depthRenderer = null;
             this._depthRenderer = null;
         };
         };
+        Scene.prototype.freezeMaterials = function () {
+            for (var i = 0; i < this.materials.length; i++) {
+                this.materials[i].freeze();
+            }
+        };
+        Scene.prototype.unfreezeMaterials = function () {
+            for (var i = 0; i < this.materials.length; i++) {
+                this.materials[i].unfreeze();
+            }
+        };
         Scene.prototype.dispose = function () {
         Scene.prototype.dispose = function () {
             this.beforeRender = null;
             this.beforeRender = null;
             this.afterRender = null;
             this.afterRender = null;

+ 12 - 0
src/babylon.scene.ts

@@ -2066,6 +2066,18 @@
             this._depthRenderer = null;
             this._depthRenderer = null;
         }
         }
 
 
+        public freezeMaterials(): void {
+            for (var i = 0; i < this.materials.length; i++) {
+                this.materials[i].freeze();
+            }
+        }
+
+        public unfreezeMaterials(): void {
+            for (var i = 0; i < this.materials.length; i++) {
+                this.materials[i].unfreeze();
+            }
+        }
+
         public dispose(): void {
         public dispose(): void {
             this.beforeRender = null;
             this.beforeRender = null;
             this.afterRender = null;
             this.afterRender = null;