소스 검색

Add support for KHR_texture_transform to glTF loader

Gary Hsu 7 년 전
부모
커밋
7f70616dec

+ 1 - 1
dist/preview release/gltf2Interface/babylon.glTF2Interface.d.ts

@@ -769,7 +769,7 @@ declare module BABYLON.GLTF2 {
     /**
      * Reference to a texture
      */
-    interface ITextureInfo {
+    interface ITextureInfo extends IProperty {
         /**
          * The index of the texture
          */

+ 51 - 0
loaders/src/glTF/2.0/Extensions/KHR_texture_transform.ts

@@ -0,0 +1,51 @@
+/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
+
+module BABYLON.GLTF2.Extensions {
+    const NAME = "KHR_texture_transform";
+
+    interface IKHRTextureTransform {
+        offset?: number[];
+        rotation?: number;
+        scale?: number[];
+        texCoord?: number;
+    }
+
+    /**
+     * [Specification](https://github.com/AltspaceVR/glTF/blob/avr-sampler-offset-tile/extensions/2.0/Khronos/KHR_texture_transform/README.md) (Experimental)
+     */
+    export class KHR_texture_transform extends GLTFLoaderExtension {
+        public readonly name = NAME;
+
+        protected _loadTextureAsync(context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Nullable<Promise<void>> {
+            return this._loadExtensionAsync<IKHRTextureTransform>(context, textureInfo, (extensionContext, extension) => {
+                return this._loader._loadTextureAsync(context, textureInfo, babylonTexture => {
+                    if (extension.offset) {
+                        babylonTexture.uOffset = extension.offset[0];
+                        babylonTexture.vOffset = extension.offset[1];
+                    }
+
+                    // Always rotate around the origin.
+                    babylonTexture.uCenter = 0;
+                    babylonTexture.vCenter = 0;
+
+                    if (extension.rotation) {
+                        babylonTexture.wAng = -extension.rotation;
+                    }
+
+                    if (extension.scale) {
+                        babylonTexture.uScale = extension.scale[0];
+                        babylonTexture.vScale = extension.scale[1];
+                    }
+
+                    if (extension.texCoord != undefined) {
+                        babylonTexture.coordinatesIndex = extension.texCoord;
+                    }
+
+                    assign(babylonTexture);
+                });
+            });
+        }
+    }
+
+    GLTFLoader._Register(NAME, loader => new KHR_texture_transform(loader));
+}

+ 5 - 0
loaders/src/glTF/2.0/babylon.glTFLoader.ts

@@ -1442,6 +1442,11 @@ module BABYLON.GLTF2 {
 
         /** @hidden */
         public _loadTextureAsync(context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Promise<void> {
+            const promise = GLTFLoaderExtension._LoadTextureAsync(this, context, textureInfo, assign);
+            if (promise) {
+                return promise;
+            }
+
             const texture = GLTFLoader._GetProperty(`${context}/index`, this._gltf.textures, textureInfo.index);
             context = `#/textures/${textureInfo.index}`;
 

+ 8 - 0
loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts

@@ -32,6 +32,9 @@ module BABYLON.GLTF2 {
         /** 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>> { return null; }
 
+        /** Override this method to modify the default behavior for loading textures. */
+        protected _loadTextureAsync(context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Nullable<Promise<void>> { return null; }
+
         /** Override this method to modify the default behavior for loading uris. */
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>> { return null; }
 
@@ -82,6 +85,11 @@ module BABYLON.GLTF2 {
             return loader._applyExtensions(extension => extension._loadMaterialAsync(context, material, babylonMesh, babylonDrawMode, assign));
         }
 
+        /** Helper method called by the loader to allow extensions to override loading textures. */
+        public static _LoadTextureAsync(loader: GLTFLoader, context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Nullable<Promise<void>> {
+            return loader._applyExtensions(extension => extension._loadTextureAsync(context, textureInfo, assign));
+        }
+
         /** Helper method called by the loader to allow extensions to override loading uris. */
         public static _LoadUriAsync(loader: GLTFLoader, context: string, uri: string): Nullable<Promise<ArrayBufferView>> {
             return loader._applyExtensions(extension => extension._loadUriAsync(context, uri));

+ 18 - 9
src/Materials/Textures/babylon.texture.ts

@@ -65,14 +65,23 @@
         @serialize()
         public wAng = 0;
 
+        /**
+         * Defines the center of rotation (U)
+         */
         @serialize()
-        public uAngCenter = 0.5;
+        public uCenter = 0.5;
 
+        /**
+         * Defines the center of rotation (V)
+         */
         @serialize()
-        public vAngCenter = 0.5;
+        public vCenter = 0.5;
 
+        /**
+         * Defines the center of rotation (W)
+         */
         @serialize()
-        public wAngCenter = 0.5;
+        public wCenter = 0.5;
 
         get noMipmap(): boolean {
             return this._noMipmap;
@@ -238,15 +247,15 @@
             x *= this.uScale;
             y *= this.vScale;
 
-            x -= this.uAngCenter * this.uScale;
-            y -= this.vAngCenter * this.vScale;
-            z -= this.wAngCenter;
+            x -= this.uCenter * this.uScale;
+            y -= this.vCenter * this.vScale;
+            z -= this.wCenter;
 
             Vector3.TransformCoordinatesFromFloatsToRef(x, y, z, this._rowGenerationMatrix, t);
 
-            t.x += this.uAngCenter * this.uScale + this.uOffset;
-            t.y += this.vAngCenter * this.vScale + this.vOffset;
-            t.z += this.wAngCenter;
+            t.x += this.uCenter * this.uScale + this.uOffset;
+            t.y += this.vCenter * this.vScale + this.vOffset;
+            t.z += this.wCenter;
         }
 
         public getTextureMatrix(): Matrix {

BIN
tests/validation/ReferenceImages/gltfExtensionKhrTextureTransform.png


+ 5 - 0
tests/validation/config.json

@@ -303,6 +303,11 @@
       "referenceImage": "gltfUnlit.png"
     },
     {
+      "title": "GLTF Extension KHR_texture_transform",
+      "playgroundId": "#RNT7K4#2",
+      "referenceImage": "gltfExtensionKhrTextureTransform.png"
+    },
+    {
       "title": "Asset Containers",
       "playgroundId": "#P3U079#19",
       "referenceImage": "assetContainer.png"